QU100 Top-N + QQQ MA Gate Tuning

Sweeping the (fast-in, slow-out) moving-average band of the QQQ regime gate over the top-N money-flow basket — N=1..100 × 114 valid (fast,slow) pairs. Gross of trading costs (0 bp). Window 2020-10-01 → 2026-06-04 (5.7 yr).

The parameterized gate (hysteresis band — one rule, two knobs):
For a pair (fast, slow) with fast < slow, evaluated at each ranking-day t on QQQ adjusted close:
• if QQQ[t] ≥ MA(fast)[t]RISK-ON (hold equal-weight top-N basket)
• elif QQQ[t] < MA(slow)[t]RISK-OFF (100% cash, 0% return)
• else (MA(slow) ≤ QQQ < MA(fast)) → HOLD previous state (the band)
An invested boolean carries across days; start flat. Only ≥MA(fast) sets True, only <MA(slow) sets False, the band leaves it unchanged. The existing report's gate is exactly this with (fast,slow)=(22,55); the operator's example is (5,10). MAs are on QQQ adjusted close, seeded from 2020-06 so even MA200 is valid from the first ranking-day.
Verdict. Tuning the band gives a real but modest risk-adjusted lift over the (22,55) baseline, and the win is a broad upper-region plateau, not the single max cell. At the Sharpe sweet-spot N=44, the best cell (30,40) reaches Sharpe 1.278 vs 1.137 for (22,55) (+0.14) and lifts return +306% vs +260% — but (30,40) clears its neighbors by only ~0.05 Sharpe, so the exact 40-vs-55 slow leg is sample noise, not signal. The robust read is a region: fast-MA in {20,22,30}, slow-MA in {40,55,65}, all clustered at Sharpe 1.14–1.28 with shallow drawdowns (−32% to −37%). The global best by Sharpe is the same (30,40) riding a diversified high-N basket (N=90, Sharpe 1.278); best raw return stays the existing N=6 (22,55) at +362%. Faster bands lose: the (5,10) example whipsaws — 136 round-trips, Sharpe 0.82 at N=44, worse than ungated — because it reacts to every wiggle. Slower bands (slow-MA ≈40–65) ride through the 2022 noise and capture the drawdown benefit without the chop. Practical pick: stay with a (22,55)-style slow band, or nudge to (30,40)/(30,55) for the extra ~0.1 Sharpe — but treat that nudge as cosmetic, since the whole grid is one 2022-dominated 5.7-yr sample and the search itself inflates the in-sample peak.

1 · Sharpe heatmap over the (fast × slow) band

Each cell = annualized Sharpe of the gated top-N strategy at fixed N for that (fast, slow) pair. Greener = higher Sharpe. Rows = fast (entry) MA; columns = slow (exit) MA; the upper triangle (fast ≥ slow) is invalid (gray). □ (22,55) = existing baseline; □ (5,10) = operator example. Hover a cell for full stats.

N = 44  (Sharpe sweet-spot)

N = 6  (raw-return sweet-spot)

Sharpe  low → high  ·  (22,55) baseline   (5,10) example

Structure is legible: Sharpe climbs left-to-right toward slow-MA 40–65 then fades past 100, and climbs top-to-bottom toward fast-MA 20–30. The bright corner is the (fast 20–30, slow 40–65) block. Tiny-slow columns (5/8/10) and tiny-fast rows (2/3) are dim — too twitchy. At N=6 the picture shifts: only a deep slow-MA (=200) tames the concentrated basket's drawdown enough to top the Sharpe ranking, while (22,55) still wins raw return.

2 · Top-10 combos by Sharpe

Across the full N × (fast,slow) grid. Baselines pinned at the bottom for reference.

3 · Top-10 combos by total return

4 · Robustness: plateau or spike?

The honest test of a tuned parameter is whether its neighbors are nearly as good. If the best cell towers over an otherwise-flat grid, it is overfit. Here is the neighborhood of the winner at N=44:

The winner (30,40) beats its immediate neighbors by only ~0.05–0.09 Sharpe — (22,40)=1.23, (30,55)=1.19, (30,65)=1.20, (22,65)=1.18 all sit just below it. That is a plateau, not a tower: the region (fast 20–30, slow 40–65) is robust, but picking 40 over 55 for the slow leg is within-sample noise. Separately, (30,40) is stable across N — Sharpe ≥ 1.20 for 54 of 100 basket sizes (N=29–100), so the band choice is not married to one lucky N. Contrast the fragile picks: the very-fast (5,10)/(8,10) cells and the N=6 slow-200 cells are isolated spikes whose neighbors fall off sharply — do not trust them.

5 · The two reference cells, explicitly

The (5,10) example reacts fast but flips ~4× as often as (22,55) (136 vs 34 round-trips at N=44) and lands below the ungated Sharpe — classic whipsaw. The slow (22,55) and the tuned (30,40)/(30,55) bands trade far less and capture the regime benefit cleanly.

Overfitting warning. This is a single 5.7-year sample whose risk-adjusted numbers are dominated by one event — dodging the 2022 bear. Searching across N (100) × fast (10) × slow (15) is ~11,400 cells; the maximum of that many in-sample Sharpes is upward-biased by construction. The +0.14 Sharpe edge of (30,40) over (22,55) is well inside what a search this wide produces by chance on one sample. Take the region, not the cell. Before trusting any tuned pair, validate out-of-sample (a different window / walk-forward) and re-run with realistic costs — the faster bands' extra round-trips will be penalized hardest, and even the slow bands add turnover at the flips.
Methodology & caveats. Base basket identical to the ungated study and the (22,55) regime report: equal-weight QU100 money-flow top-N, rebalanced at the close each ranking-day; fills at same-day adjusted close (no look-ahead); N swept 1→100. Gross of costs — 0 bp, no commissions or slippage. Gate: at each ranking-day, QQQ adjusted close vs its own fast/slow rolling MAs with hysteresis (≥MA(fast) enters, <MA(slow) exits, band holds previous state; start flat). On RISK-OFF the basket goes 100% cash and earns 0% until the next RISK-ON flip; equity is tracked continuously through cash periods. Time-in-market = fraction of ranking-day periods invested; round-trips = count of RISK-OFF→RISK-ON entries. MA seed: the cached price panel's QQQ only starts 2020-09-25 — too short for the long MAs at the window start — so QQQ was re-fetched alone (yfinance adjusted close, 2020-06-01→2026-06-05, one retry) and all fast/slow MAs computed from that longer series, valid from the first ranking-day (2020-10-01). Market-holiday / data-gap days are held (no rebalance); a held name with no price is carried at its last close. Delisted/acquired names with no yfinance price are dropped from the slot and equal-weight redistributed among priced names that day; ticker renames remapped (FB→META, SQ→XYZ, ANTM→ELV, DISCA→WBD, BRK.B→BRK-B, BF.B→BF-B, PBR.A→PBR-A). yfinance adjusted close folds in dividends/splits. Max drawdown measured close-to-close at ranking-day granularity (intraday was deeper). QU100 rankings: local TimescaleDB money_flow_snapshots, ranking_type top100. QU100 membership carries survivorship bias (we only see names QU included). Reproduction: with the gate disabled this harness reproduces ungated N=3 (+171.5%) / N=5 (+208.6%); with (fast,slow)=(22,55) it reproduces the prior regime report's N=44 (ret +259.9% / MaxDD −34.2% / Sharpe 1.14 / 73.5% time-in-market) — the per-N masking shortcut was validated against the full-harness result before the grid was trusted. Not investment advice — a research backtest with known survivorship bias on a single overfit-prone sample.