Timing leveraged ETFs with moving averages

Source: REPORT-leveraged-etf-ma-timing.md · Rendered: 2026-08-29 02:35 UTC · agents read the .md, humans read the .html.

Can a moving average measured on the unleveraged index tell you when to hold its 3× cousin? Three pairs, 158,404 entry/exit combinations each, two execution assumptions, data through 2026-08-24.

Research only — no live trading, no recommendation.

1. The experiment

The rule under test has exactly two moving averages and no discretion. Buy the 3× ETF when the signal ETF closes above an entry MA; sell to cash when it closes below a separate exit MA.

        signal close > entry MA
   ┌──────────────────────────────────┐
   │                                  ▼
┌──────┐                        ┌───────────┐
│ CASH │                        │ LONG 3x   │
│ ^IRX │                        │ ETF       │
└──────┘                        └───────────┘
   ▲                                  │
   └──────────────────────────────────┘
        signal close < exit MA
dimension values searched
pairs QQQ→TQQQ (from 2010-02-11), SPY→SPXL (2008-11-05), XBI→LABU (2015-05-28)
entry MA SMA or EMA, window 2–200
exit MA SMA or EMA, window 2–200, chosen independently of the entry
combinations 158,404 per pair (475k rows of results in total)
cash leg 13-week T-bill yield (^IRX)
costs 10 bp per transition
fills same close (trade at the close that produced the signal) and next close (trade one day later)

Everything below is reported under both fill assumptions, because that gap turns out to be the most informative robustness test in the study: a rule whose profit evaporates on a one-day delay was harvesting one-day momentum, not trend.

2. What the whole search space looks like

Before any single rule, the shape of the parameter space. Each dot is one entry/exit combination — its drawdown against its final multiple.

2026-08-29T02:35:14.878139 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 40 50 60 70 80 90 max drawdown % 1x 10x 100x final multiple B&H QQQ B&H SYN2 B&H SYN3 B&H TQQQ SMA22 → SMA44 QQQ → TQQQ 40 50 60 70 80 max drawdown % 1x 10x 100x B&H SPY B&H SYN2 B&H SYN3 B&H SPXL SMA22 → SMA44 SPY → SPXL 70 80 90 100 max drawdown % 0.01x 0.1x 1x B&H XBI B&H SYN2 B&H SYN3 B&H LABU SMA22 → SMA44 XBI → LABU
Every combination in the grid (8,000-point sample per pair). Stars are buy & hold; the diamond is the SMA22/SMA44 rule from the earlier research.

Three facts fall straight out of the cloud:

The same information as a map of the parameter space shows where the good rules live:

2026-08-29T02:35:13.160755 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 25 50 75 100 125 150 175 200 entry window (days) 25 50 75 100 125 150 175 200 exit window (days) QQQ → TQQQ: final multiple by entry/exit window 1 0 1 1 0 2 final multiple (log scale)
QQQ→TQQQ: final multiple for every entry/exit window pair (log colour scale). The bright band is a slow exit, not a clever entry.
2026-08-29T02:35:13.509377 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 25 50 75 100 125 150 175 200 entry window (days) 25 50 75 100 125 150 175 200 exit window (days) SPY → SPXL: final multiple by entry/exit window 1 0 0 1 0 1 1 0 2 final multiple (log scale)
SPY→SPXL: the same slow-exit band, slightly flatter.
2026-08-29T02:35:13.851432 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 25 50 75 100 125 150 175 200 entry window (days) 25 50 75 100 125 150 175 200 exit window (days) XBI → LABU: final multiple by entry/exit window 1 0 − 1 1 0 0 final multiple (log scale)
XBI→LABU: no structure worth the name — the surface is noise around a low mean.

The vertical structure is the story. Results vary far more with the exit window than with the entry window; the top of each map (slow exits) is bright across nearly all entries.

3. Exit speed is the dominant parameter

Plotting the best result reachable under a ceiling on the exit window makes the dependence explicit:

2026-08-29T02:35:14.334434 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 0 25 50 75 100 125 150 175 200 maximum exit window allowed (days) 1x 10x 100x best achievable multiple SMA120 exit cap What an exit-speed ceiling costs TQQQ SPXL LABU
Best achievable multiple when the exit MA is not allowed to be slower than the x-axis value.

For TQQQ the curve is still climbing at window 200. Forcing the position out before the 120-day average — the "sold before SMA120" constraint — cuts the best achievable result from 661× to 136×. SPXL gives up only about a quarter of its return under the same constraint, and LABU is indifferent because it has nothing to give up.

The mechanism is simple: a 3× ETF's daily noise breaches a fast average constantly, so fast exits sell into shakeouts and re-buy higher.

4. The three pairs

2026-08-29T02:35:12.318805 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 2010 2012 2014 2016 2018 2020 2022 2024 2026 1x 10x 100x 1000x growth of $1 (log) QQQ signal → TQQQ: best in-sample rule vs buy & hold B&H TQQQ B&H QQQ MA only alignment + MA
QQQ→TQQQ, growth of $1, log scale. "MA only" is the best in-sample rule; "alignment + MA" adds the bullish MA-stack entry filter.
2026-08-29T02:35:12.408680 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 1x 10x 100x growth of $1 (log) SPY signal → SPXL: best in-sample rule vs buy & hold B&H SPXL B&H SPY MA only alignment + MA
SPY→SPXL — the best-behaved pair: 99.8% of all combinations are profitable.
2026-08-29T02:35:12.513250 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 2016 2018 2020 2022 2024 2026 0.01x 0.1x 1x 10x growth of $1 (log) XBI signal → LABU: best in-sample rule vs buy & hold B&H LABU B&H XBI MA only alignment + MA
XBI→LABU — the timing rule beats LABU easily and still loses to plain XBI.
pair best rule full history max DD trades next close
QQQ→TQQQ SMA21 → SMA192 661× 50.0% 267 216×
QQQ→TQQQ (risk-first) EMA156 → SMA161 151× 48.2% 117 154×
SPY→SPXL EMA23 → SMA198 161× 51.0% 295 65×
SPY→SPXL (risk-first) SMA82 → SMA153 95× 48.0% 143 89×
XBI→LABU EMA66 → EMA181 5.0× ~90% 231 1.4×

Benchmarks over the same windows: QQQ 18.7× (−35% DD), TQQQ 335.7× (−81.7%); SPY 11.0× (−34%), SPXL 86.8× (−77%); XBI 2.13×, LABU 0.17×.

The "risk-first" rows are the ones worth attention: they are the highest-return rules whose drawdown and return survive under both fills. That constraint eliminates most of the leaderboard.

Drawdown, which is what the rules are actually buying:

2026-08-29T02:35:12.793560 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 2010 2012 2014 2016 2018 2020 2022 2024 2026 −80 −60 −40 −20 0 drawdown % QQQ → TQQQ B&H TQQQ (worst 82%) MA only (worst 50%) 2008 2010 2012 2014 2016 2018 2020 2022 2024 2026 −80 −60 −40 −20 0 drawdown % SPY → SPXL B&H SPXL (worst 77%) MA only (worst 51%) 2016 2018 2020 2022 2024 2026 −100 −80 −60 −40 −20 0 drawdown % XBI → LABU B&H LABU (worst 99%) MA only (worst 87%)
Underwater curves: the timing rule versus holding the 3× ETF.

5. Execution assumption is a first-class result

The top 12 rules per pair, each shown twice — filled at the signal close, and filled one day later:

2026-08-29T02:35:15.235725 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 100x 1000x SMA22 → SMA194 SMA22 → SMA188 SMA21 → SMA170 SMA22 → EMA199 SMA21 → SMA171 SMA21 → SMA193 SMA21 → SMA188 SMA22 → SMA191 SMA21 → SMA194 SMA22 → SMA192 SMA21 → SMA191 SMA21 → SMA192 551x → 73x (13% kept) 559x → 71x (13% kept) 571x → 79x (14% kept) 572x → 98x (17% kept) 582x → 79x (14% kept) 589x → 75x (13% kept) 598x → 76x (13% kept) 605x → 68x (11% kept) 606x → 78x (13% kept) 619x → 69x (11% kept) 646x → 73x (11% kept) 661x → 74x (11% kept) QQQ → TQQQ: top 12 by return same close next close 100x 6 × 1 0 1 2 × 1 0 2 3 × 1 0 2 4 × 1 0 2 6 × 1 0 2 EMA23 → SMA149 EMA23 → SMA162 EMA26 → EMA178 EMA23 → SMA152 EMA23 → EMA178 EMA23 → SMA153 EMA23 → SMA164 EMA31 → EMA177 EMA31 → EMA175 EMA23 → SMA151 EMA23 → SMA200 EMA23 → SMA198 144x → 91x (63% kept) 144x → 68x (47% kept) 146x → 64x (44% kept) 147x → 99x (67% kept) 148x → 57x (39% kept) 148x → 98x (66% kept) 149x → 68x (46% kept) 151x → 47x (31% kept) 151x → 48x (32% kept) 152x → 102x (67% kept) 161x → 68x (42% kept) 161x → 65x (40% kept) SPY → SPXL: top 12 by return same close next close 10x 2 × 1 0 0 3 × 1 0 0 4 × 1 0 0 6 × 1 0 0 2 × 1 0 1 EMA64 → EMA184 EMA64 → EMA182 EMA64 → EMA175 EMA65 → EMA183 EMA65 → EMA182 EMA65 → EMA175 EMA66 → EMA184 EMA66 → EMA182 EMA66 → EMA174 EMA64 → EMA181 EMA65 → EMA181 EMA66 → EMA181 4x → 1x (32% kept) 4x → 1x (31% kept) 4x → 1x (31% kept) 4x → 1x (30% kept) 4x → 1x (29% kept) 5x → 1x (29% kept) 5x → 1x (32% kept) 5x → 1x (30% kept) 5x → 1x (30% kept) 5x → 1x (28% kept) 5x → 1x (26% kept) 5x → 1x (27% kept) XBI → LABU: top 12 by return same close next close
Top 12 by return under both fill assumptions. The gap between the bars is fitting.

Several leaders keep barely a tenth of their return on a one-day delay. The survivors — the slow-exit, low-turnover rules — barely move. When choosing between two rules with similar backtest returns, the one whose bars match is the one that was measuring a trend.

6. The SMA22 / SMA44 rule

The earlier QQQ research settled on SMA22 → SMA44. This study confirms it inside that study's search space (SMA only, windows ≤ 50): it is #1 there by Calmar, and 99.4th percentile by Calmar across the full 158k grid. Widening the space is what changes the answer.

QQQ→TQQQ, SMA22 → SMA44: 85.1× full history, 30.9%/yr, 40.4% max drawdown, 416 trades. $10k from 2018 → $209,267 same close, $59,914 next close.

Two caveats outrank the headline:

  1. Its 40% drawdown is not real. Delay the fill one day and the drawdown becomes 65.5% and the return 19×. EMA156 → SMA161 holds ~150× and 48% on either fill.
  2. Its shortfall is concentrated before 2016.
2026-08-29T02:35:32.656675 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 2010 2012 2014 2016 2018 2020 2022 2024 2026 1x 10x 100x 1000x era split 2016-08 QQQ → TQQQ: where timing rules earned (and lost) their keep B&H TQQQ MA only
QQQ→TQQQ across the two eras. The rule earns its keep only where there are drawdowns to avoid.

From 2010-02 to 2016-08 the rule made 2.8× while TQQQ made 11.8×; from 2016-08 to 2026-08 it made 29.4× against TQQQ's 27.9×. In the earlier era it sat in cash for 490 days during which TQQQ rose 3.44×: the exit fired ~97 times and 49% of those exits re-bought at a higher price, a median of 2 days later.

It is a drawdown-control rule that costs return, measured over a period whose first half had no drawdowns to control. It does not transfer: on SPY→SPXL it makes 13.7× at 59% drawdown (34th percentile, 6× worse than holding SPXL), and on XBI→LABU it loses money in every framing.

7. Hitting a 20% or 25% drawdown target

No fully-invested rule can do it — the left wall of the cloud is at 39–40%. Reaching 20–25% is a sizing problem: hold a fraction of the account in the 3× ETF and the rest in T-bills.

2026-08-29T02:35:15.583942 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 10 20 30 40 50 max drawdown % 10x 100x final multiple 20% 40% 60% 80% 100% 20% cap 25% cap QQQ → TQQQ, EMA32 → SMA171 exposure sweep 10%-100% of account in TQQQ same close next close 10 20 30 40 50 max drawdown % 10x 100x 20% 40% 60% 80% 100% 20% cap 25% cap SPY → SPXL, SMA82 → SMA152 exposure sweep 10%-100% of account in SPXL
Sweeping exposure from 10% to 100% of the account traces the risk/return frontier. Dotted lines are the 20% and 25% drawdown budgets.
cap QQQ→TQQQ SPY→SPXL
20% EMA31 → SMA180 at 35% exposure → 11.4×, DD 19.9% EMA31 → SMA150 at 35% → 8.4×, DD 17.9%
25% SMA20 → EMA198 + 20% vol target → 21.2×, DD 21.4% SMA82 → SMA153 at 45% → 11.8×, DD 23.2%

Both hold under next-close fills (11.5× / 19.5× / 8.0× / 11.5×) — that filter is what eliminated most candidates. The honest benchmark is not buy & hold but sized buy & hold at the same drawdown: 4.4× (QQQ) and 3.4× (SPY) at the 20% cap, so the timing rule is worth roughly 2.5× that.

Worth stating plainly: 35% of an account in a 3× ETF is 1.05× effective exposure, with 65% in T-bills. At a 20% drawdown budget you are running slightly-levered beta, and the leveraged ETF is merely the capital-efficient way to hold it.

8. Risk overlays

Six overlays on top of the drawdown-controlled rule for each index pair:

2026-08-29T02:35:15.720804 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 10x 100x 35% fixed size 20% vol target 20% equity stop slope confirmation MA rule only hold QQQ when out 10x / 19% DD 27x / 20% DD 65x / 44% DD 120x / 50% DD 151x / 48% DD 285x / 55% DD QQQ → TQQQ, EMA156 → SMA161 10x 100x 35% fixed size 20% equity stop 20% vol target slope confirmation MA rule only hold SPY when out 7x / 18% DD 22x / 50% DD 28x / 19% DD 55x / 40% DD 95x / 48% DD 133x / 50% DD SPY → SPXL, SMA82 → SMA153 Risk overlays on the drawdown-controlled rule
Each overlay's final multiple, annotated with its max drawdown.
overlay verdict
Constant position size Works. Mechanical, nothing fitted, drawdown scales roughly linearly with exposure.
Volatility targeting — exposure = min(1, target ÷ realised 20-day vol) Works on QQQ (beat fixed sizing at the 25% cap); lost to fixed sizing on SPY.
Unleveraged fallback — hold QQQ/SPY instead of cash when out Largest return improvement: QQQ 151× → 285×, SPY 95× → 133×, for ~6 points more drawdown.
Equity stop-loss — sell everything 20% below the high-water mark, re-enter on the next signal Does not work. QQQ EMA156 → SMA161: 151× / 48% → 65× / 44% (13 stops). SPY SMA82 → SMA153: 95× / 48% → 22× / 50% — worse on both axes.
Volatility-ceiling entry filter Costs return, buys no drawdown.
Trend-slope confirmation — require the exit MA to be rising Costs return, buys no drawdown.

Why the stop-loss fails: these drawdowns are slow grinds that the MA exit is already handling. A 20% stop fires mid-shakeout and the re-entry signal then arrives at a higher price, converting drawdown into whipsaw instead of removing it. Sizing down is strictly better — a 35% position has a 20% drawdown by construction, with no timing skill required.

9. Constraining the exit to ≤ SMA120

Requiring the position to be out before the 120-day average caps the exit window at 120 and removes the entire slow-exit family:

exit ≤ 120 unconstrained
QQQ→TQQQ EMA159 → EMA115 136×, 43.5% DD SMA21 → SMA192 661×
SPY→SPXL EMA23 → EMA119 120×, 56.8% DD EMA23 → SMA198 161×

Under the same constraint, the drawdown-capped frontier (holding under both fills):

cap QQQ→TQQQ SPY→SPXL
20% SMA7 → EMA119 + 15% vol target → 8.4× (sizing: EMA31 → EMA94 at 35% → 7.4×) SMA85 → SMA102 at 40% → 7.0×, DD 19.2%
25% SMA6 → EMA119 + 20% vol target → 14.2× (sizing: EMA31 → EMA94 at 45% → 11.4×) SMA85 → EMA108 at 45% → 10.3×, DD 24.6%

That is 25–35% of the return given up at the same risk. Note that the constrained QQQ winners pair a fast entry (SMA6–7) with the ~EMA119 exit: once the exit is forced fast, entering early is how the lost upside is recovered.

10. Bullish MA alignment as an entry filter

An additional entry condition — fast MA > mid MA > slow MA on the signal ETF, e.g. SMA5 > SMA20 > SMA50:

11. Out of sample

Every leaderboard above is in-sample. Re-picking the parameters each January from only the data available at the time is the honest number:

2026-08-29T02:35:15.910042 image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 0 100 200 year return % QQQ → TQQQ: parameters re-picked each January MA rule (out of sample) QQQ TQQQ 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 −50 0 50 100 year return % SPY → SPXL: parameters re-picked each January MA rule (out of sample) SPY SPXL 2018 2019 2020 2021 2022 2023 2024 2025 2026 −50 0 50 100 150 year return % XBI → LABU: parameters re-picked each January MA rule (out of sample) XBI LABU
Walk-forward: yearly return of the re-picked MA rule against both buy & holds.

12. Conclusions

  1. The edge is real but small, and it is a risk-control edge, not a return edge. On both index pairs the best drawdown-constrained rules match or beat buy & hold at ~30 points less drawdown; none reliably beats holding the 3× ETF on raw return out of sample.
  2. Exit speed dominates everything else. Slow exits (150–200 days) beat fast ones by an order of magnitude on a 3× vehicle.
  3. The fill assumption is a result, not a footnote. Rules that lose most of their return on a one-day delay — SMA22/44 among them — should be read as fitted.
  4. Drawdown targets below ~40% are a sizing problem, not a signal problem. Stop-losses do not deliver them; position size does, mechanically.
  5. XBI→LABU is not risk-manageable this way. The best drawdown available anywhere in its grid is 87%; LABU decays too fast between XBI's trends. Only the alignment-filtered version is worth anything, and it still carries ~50% drawdowns.

13. Reproducing

Every generated data point lives in a local SQLite database (research.db): prices, three 158k-row grids under both fills, alignment searches, walk-forward folds, equity curves, yearly returns, and the sizing / vol-target / overlay frontiers — ~2.9M rows across 29 tables, keyed by pair. Key tables: ma_grid, ma_grid_lag1, ma_top20, ma_risk_frontier, ma_sized, ma_voltgt, ma_overlay, ma_exit_cap, ma_sized_exitcap, ma_voltgt_exitcap. Figures on this page are generated from those tables.

14. Disclaimer

Backtests on a single realised price history, with in-sample parameter selection in most sections. Nothing here is a recommendation to trade.