Why Do Leveraged ETFs Decay? Measuring Volatility Drag in Python
July 17, 2026
What's the question?
A 3x leveraged ETF promises three times the daily return of its index, and delivers it every day. Yet over three years TQQQ returned 219.7% while the Nasdaq 100 returned 86.3% — 2.5x, not 3x. Holders read this as a broken product.
It is not. Daily rebalancing compounds returns, and compounding is path-dependent: a 10% loss then a 10% gain leaves a position below where it started. A leveraged position’s expected log return is L·μ − (L²·σ²)/2, for leverage L, expected return μ, and variance σ². Against L times the underlying’s log return, the fund gives up a volatility drag of (L² − L)/2 · σ² per year.
The critical feature is the square: drag scales with L², not L. Moving from 2x to 3x triples the drag coefficient. How large is that drag, and does it follow the L² law closely enough to forecast?
The approach
Six leveraged funds are measured against the index ETF they track over three years of daily total returns ending July 16, 2026: four 3x (TQQQ/QQQ, UPRO/SPY, SOXL/SOXX, TNA/IWM) and two 2x (QLD/QQQ, SSO/SPY). QLD and TQQQ share an index, isolating leverage.
- Pull daily total returns from
return_daily, never raw close: leveraged ETFs reverse-split often, and raw close steps across splits. - Inner-join fund and index on date; a mismatched calendar corrupts the regression.
- Regress each fund’s daily return on its index’s; a slope near L confirms the daily promise.
- Compare actual cumulative return against the naive expectation (1 + L·U) and the no-drag benchmark (1 + U)^L.
- Decompose the annualised log shortfall into the drag term, the fees-and-financing cost from the intercept, and a residual.
- Split each pair into six sub-periods and fit realized drag against realized variance. The slope should reproduce (L² − L)/2.
Code
import numpy as np
import xfinlink as xfl
xfl.set_api_key("YOUR_API_KEY") # free at https://xfinlink.com/signup
PAIRS = [("TQQQ", "QQQ", 3), ("UPRO", "SPY", 3), ("SOXL", "SOXX", 3),
("TNA", "IWM", 3), ("QLD", "QQQ", 2), ("SSO", "SPY", 2)]
def daily_returns(ticker):
d = xfl.prices(ticker, period="3y", fields=["return_daily"]).sort_values("date")
return d[["date", "return_daily"]].rename(columns={"return_daily": ticker})
for lev, und, L in PAIRS:
m = daily_returns(lev).merge(daily_returns(und), on="date", how="inner").dropna()
rl, ru = m[lev].values, m[und].values
years = len(m) / 252.0
beta, alpha = np.polyfit(ru, rl, 1) # slope should be ~L
actual = np.prod(1 + rl) - 1
index = np.prod(1 + ru) - 1
naive = L * index # what holders expect
ideal = (1 + index) ** L - 1 # correct no-drag benchmark
sigma = np.std(ru, ddof=1) * np.sqrt(252)
realized_drag = (L * np.log(1 + index) - np.log(1 + actual)) / years
theory_drag = (L ** 2 - L) / 2 * sigma ** 2 # the variance penalty
carry = -alpha * 252 # fees + financing
residual = realized_drag - theory_drag - carry
print(f"{lev}/{und} slope={beta:.3f} actual={actual*100:.1f}% naive={naive*100:.1f}% "
f"ideal={ideal*100:.1f}% drag={realized_drag*100:.2f}% "
f"theory={theory_drag*100:.2f}% carry={carry*100:.2f}% resid={residual*100:+.2f}%")
Full script with formatting and visualisation: why-do-leveraged-etfs-decay-volatility-drag-python.py
Output
==============================================================================
1. DOES THE DAILY PROMISE HOLD? regression: fund daily return ~ index daily return
==============================================================================
pair target slope R2 intercept /yr
TQQQ/QQQ 3x 2.973 0.9994 -11.04%
UPRO/SPY 3x 2.912 0.9962 -9.13%
SOXL/SOXX 3x 2.947 0.9982 -12.21%
TNA/IWM 3x 2.986 0.9985 -11.49%
QLD/QQQ 2x 1.991 0.9994 -5.66%
SSO/SPY 2x 1.947 0.9963 -4.64%
==============================================================================
2. MULTI-PERIOD REALITY (3y, 752 trading days)
==============================================================================
pair index naive Lx (1+U)^L actual vs naive
TQQQ/QQQ 86.3% 259.0% 547.0% 219.7% -39.3pp
UPRO/SPY 69.9% 209.8% 390.8% 193.7% -16.1pp
SOXL/SOXX 205.9% 617.7% 2762.9% 413.7% -204.0pp
TNA/IWM 57.9% 173.6% 293.3% 87.0% -86.5pp
QLD/QQQ 86.3% 172.7% 247.2% 158.4% -14.3pp
SSO/SPY 69.9% 139.9% 188.8% 129.1% -10.8pp
==============================================================================
3. WHERE THE SHORTFALL COMES FROM (annualised, log terms)
==============================================================================
pair index vol realized (L2-L)/2 s2 fees+fin residual
TQQQ/QQQ 20.3% 23.62% 12.39% 11.04% +0.20%
UPRO/SPY 15.3% 17.20% 7.02% 9.13% +1.05%
SOXL/SOXX 38.6% 57.57% 44.72% 12.21% +0.64%
TNA/IWM 21.2% 24.91% 13.42% 11.49% +0.00%
QLD/QQQ 20.3% 9.90% 4.13% 5.66% +0.11%
SSO/SPY 15.3% 7.76% 2.34% 4.64% +0.77%
==============================================================================
4. SCALING TEST: drag vs variance across 6 sub-periods x 6 pairs
==============================================================================
2x funds: fitted drag/variance slope = 1.002 theory (L^2-L)/2 = 1.0 (n=12 sub-periods)
3x funds: fitted drag/variance slope = 3.022 theory (L^2-L)/2 = 3.0 (n=24 sub-periods)
correlation between realized drag and theoretical drag: 0.9977
What this tells us
The daily promise holds. Slopes land between 2.912 and 2.986 for the 3x funds and 1.947 to 1.991 for the 2x funds, with R² from 0.9962 to 0.9994. These funds do what their prospectuses say; the shortfall is not a tracking failure.
The naive benchmark is wrong, in an instructive direction. Compounding at 3x exposure with zero volatility delivers (1 + U)^L, far higher than three times the index’s cumulative return: 547.0% for TQQQ against a naive 259.0%, and 2762.9% for SOXL against a naive 617.7%. Convexity favours the leveraged holder when the index trends. Drag closes that gap and overshoots it, so SOXL gave up far more than its −204.0pp headline suggests.
The decomposition accounts for essentially all of it. Realized drag ranges from 7.76%/yr (SSO) to 57.57%/yr (SOXL), and the variance term plus the intercept leaves residuals of +0.00% to +1.05% per year. That residual is not zero and should not be: the log expansion drops third-order terms, and rebalancing happens at the close, not continuously. The intercept absorbs fees, financing on borrowed notional, and a dividend mismatch against the proxy — at −11.04%/yr for TQQQ, it rivals the drag itself.
The L² law is confirmed rather than assumed. QLD and TQQQ track the identical index at identical 20.3% volatility, yet their theoretical drags are 4.13% and 12.39% — exactly 3.0x, from one extra unit of leverage. SSO and UPRO give 2.34% and 7.02%, the same ratio. Across 36 sub-periods the fitted drag-to-variance slope is 1.002 for 2x funds against a theoretical 1.0, and 3.022 for 3x funds against 3.0, correlation 0.9977. The dashed lines in the lower panel are theory, not fits.
So what?
Decay in these products is forecastable. The annual cost of L times exposure is approximately (L² − L)/2 · σ² plus fees and financing, both estimable in advance. At 20% index volatility a 3x fund carries roughly 12% of drag and, at current short rates, a further 11% of carry — a hurdle near 23% per year. At SOXX’s 38.6% volatility that nears 58%.
This makes σ² the variable to watch: doubling realized volatility quadruples the drag, so the same index view produces very different outcomes at 15% and 40%. A leveraged position should be assessed against a volatility forecast, not a return forecast alone.
The arithmetic is not specific to ETFs. Any daily-rebalanced constant-leverage exposure carries it — margin accounts, futures overlays, volatility-targeted risk-parity sleeves — and substituting L and a volatility estimate prices it to about a percentage point per year.
Built with xfinlink — free financial data API for Python. pip install xfinlink
pip install xfinlink