← Lab
S004

S004 (Stage 2): Relative-strength leadership with persistence filter

rs-leadership-rotation-v1-stage2
failed Stage 2 (Walk-forward validation) 2026-05-30
Share: Twitter / X LinkedIn
-63.7%-11.4%+40.8%+93.1%+145.4% 1,1560 3-month excess return vs S&P 500, net of 25 bps friction (Stage 2) Net excess return
Break-even Trade mean +3.52%
3-month excess return vs S&P 500, net of 25 bps friction (Stage 2) · n=13,050

ID: S004 Slug: rs-leadership-rotation-v1-stage2 Failed at: Stage 2 (Walk-forward validation) Fail reason: robustness Date: 2026-05-30 Stage 1 reference: lab/quickkill/rs-leadership-rotation-v1/result.md (PASSED)

What we tested

Stage 1 ran the rule (top 10% by 6-month relative strength vs S&P 500, with at least 4 of the last 6 months also in that top 10%) on roughly the 500 largest US stocks. It cleared all five Stage 1 criteria with an average +3.78% excess return per three-month holding period.

Stage 2 is the next-level test the lab pipeline always applies before a strategy can become a real signal. It changes three things from Stage 1:

  1. Wider universe. We expand from ~500 large-cap stocks to a top-2,000-by-trading-volume pool. Smaller stocks behave differently — they're less liquid, less institutionally followed, and leader-effects there can be more fragile.
  2. Realistic trading costs. Stage 1 reported gross numbers. Here we subtract 25 basis points per trade round-trip (the typical bid-ask + slippage cost for liquid US stocks), which works out to roughly 1% per year of drag at the strategy's quarterly rebalance cadence.
  3. Out-of-sample year-by-year testing. Instead of measuring the whole 2010-2026 sample at once, we treat each year from 2019 onwards as an independent held-out test against the prior years used as the empirical basis. The strategy should work in most individual years, not just on average.

The pre-set criteria — frozen before the test ran — required an annualised net excess of +5% over the S&P 500, at least 6 of 8 test years positive, no single year worse than −5%, plus parameter and friction-robustness checks and a regime split (does the strategy work in both bull and defensive market environments?).

What we found

Strategy failed on 5 of 7 criteria.

Criterion We needed We got
Annualised net excess return ≥ +5% +4.14%
Positive-net test years ≥ 6 of 8 4 of 8
Worst single year ≥ −5% −10.5% (2021)
Top-decile sweep: 5% / 10% / 20% all ≥ +3% net yes 5%=+5.7%, 10%=+4.6%, 20%=+2.6%
Persistence sweep: 3/6, 4/6, 5/6 all ≥ +3% net yes 3/6=+4.0%, 4/6=+4.6%, 5/6=+4.7%
Friction robustness at 40 bps: ≥ 6/8 folds positive yes 4 of 8
Regime split: positive in BOTH above- and below-SMA200 yes above=+2.5%, below=+7.7%

Year-by-year, the wider-universe story becomes clear:

Year Trades Net excess return
2019 805 −0.7%
2020 921 +22.4%
2021 865 −10.5%
2022 758 +1.5%
2023 732 −0.1%
2024 822 −1.2%
2025 813 +8.3%
2026 (YTD) 167 +17.3%

The arithmetic average across years is +4.6%, but the geometric annualised return (which is what an investor actually compounds) is +4.1% — below the gate. The pre-set arithmetic-only summary would have over-stated the realised compound return.

Why this matters / what surprised us

The Stage 1 result was correct but narrow. The +3.78% Stage 1 mean on the 500-stock universe was real. Adding the next 1,500 mid-cap and small-cap names dilutes the effect, not amplifies it. This is consistent with the long-running literature finding that classical momentum works best in liquid, institutionally-followed names — exactly where it gets arbitraged the most, but also where the persistence-filter story (slow institutional rotation) actually holds.

One great year is not a strategy. Without 2020's +22% blowout, the annualised number drops to roughly +1% net excess — clearly not tradeable. The strategy's edge is concentrated in dispersion peaks (years when leaders sharply outperform laggards). When dispersion is average, the effect washes out below the friction line.

The 2020 → 2021 round-trip is the killer pattern. +22% in 2020, −11% in 2021. The same names that ran hardest in the COVID-recovery dispersion peak gave back materially in 2021's mean-reversion. A strategy that loads up on momentum leaders right before the regime flips is structurally exposed to this whip-saw. Stage 1's "no single year > 30% of total" criterion didn't catch this because Stage 1 measured contribution to a positive total; here the issue is a positive year followed by a negative year, both large.

Regime split passed (notably). Net excess was positive both above and below SPY's 200-day moving average — and actually stronger below (+7.7% on 1,144 trades vs +2.5% on 4,739 trades above). This is unusual; classical momentum is supposed to work better in trending bull markets. The Stage 2 result suggests the persistence-filtered version is more defensive than the standard strategy. Worth noting for the next iteration (see below), but the strategy fails other gates regardless.

Persistence sweep passed. All three persistence thresholds (3/6, 4/6, 5/6) produced similar net excess (+4.0% to +4.7%). The strategy is not knife-edge-sensitive on that parameter, which is a genuinely good sign — just not enough to compensate for the rest.

What this doesn't tell us yet

  1. A narrower-universe version may still work. Restricting to the top 200 (Stage 1's universe) preserves the edge, just at much lower capacity. That's its own setup to pre-register, not a rescue of this one.
  2. A 12-month relative-strength version wasn't tested. Some academic momentum literature finds 12-month windows more robust than 6-month. Could be pre-registered separately as rs-leadership-12m-v1.
  3. A "leaders + earnings-quality" overlay (CANSLIM-style) wasn't tested. Mechaniq already has a CANSLIM module concept archived; combining the two could produce a stronger signal than either alone. Would need its own gates and its own H-NNN.

What happens next

The strategy is failed at Stage 2. The S004 setup is closed.

For the strategy lineage, three follow-ups worth flagging (none of which are this setup — each would be a new pre-registration):

For the lab pipeline itself, the most useful methodological lesson: arithmetic-mean reporting can flatter a strategy that depends on one or two extreme years. Future Stage 2 gates should default to geometric annualised + per-fold consistency, which is what this gate did — and which is exactly what caught the issue.

For the specialist — methodology details (click to expand)

Test setup

  • Universe: monthly point-in-time top-2,000 by trailing 60-day dollar volume, from the ~4,900-ticker Finnhub US Common Stocks candidate pool. Effective per-month membership: ~2,000; total distinct tickers across all months: 3,976.
  • Data: Tiingo Power EOD, 2010-01-01 → 2026-05-29, 12.4M bars total. Backfilled extension to 2010 was run on 2026-05-30 (216s parallel ingest for ~4,900 tickers × 12 years).
  • Signal generation: top-decile of 6-month relative strength vs SPY at each month-end, with rolling 6-month persistence count computed via .shift(1).rolling(6).sum() on the boolean top-decile flag (ensures signal at month M uses only M−1 through M−6 rankings).
  • Forward measure: 3-month excess return = (ticker_close[M+3] − ticker_close[M]) / ticker_close[M] − (spy_close[M+3] − spy_close[M]) / spy_close[M].
  • Friction: 25 bps round-trip subtracted from each trade's excess_3m to produce excess_3m_net. Applied uniformly; not per-stock-spread modelled.

Walk-forward design

  • Training basis: 2010 → 2018 (inclusive), used as the implicit empirical basis for the rule (the strategy parameters are not tuned; the train period is the regime where the rule was authored).
  • Test folds: 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026-YTD (8 annual out-of-sample windows).
  • No per-fold re-fit: the strategy is rules-based, so each fold is purely a held-out measurement, not a re-tuning step. This makes the walk-forward a stricter test than a parameter-tuning version would be — we cannot adjust to a fold's regime.

Pre-registered gates (FROZEN 2026-05-30, all required)

1. Annualised net excess (geometric across 8 folds) ≥ +5%
2. Positive-net folds ≥ 6/8
3. Worst fold net excess ≥ −5%
4. Top-decile parameter sweep: 5%, 10%, 20% all ≥ +3% net (per-fold avg)
5. Persistence parameter sweep: 3/6, 4/6, 5/6 all ≥ +3% net (per-fold avg)
6. Friction robustness at 40 bps: ≥ 6/8 folds still positive
7. Regime split: net excess positive in BOTH SPY-above-SMA200 and
   SPY-below-SMA200 fold-subsets

Detailed numbers

  • Primary run (top-10%, 4/6 persistence, 25 bps friction): 13,050 trades
  • Geometric annualised net excess: +4.141%
  • Arithmetic per-fold mean net excess: +4.617%
  • Per-fold table: see "What we found" above
  • 40 bps robustness: identical fold-sign pattern (4/8 positive), with the magnitudes shifted ~15 bps lower (about a 60 bps additional annual drag from the 15 bps round-trip increment, applied to ~4 rebalances/year)
  • Regime split: above-SMA200 trades 11,014 (84.4% of sample), below-SMA200 trades 2,036 (15.6%); OOS subsets: above n=4,739 net +2.50%, below n=1,144 net +7.69%

Artifacts

  • Trades: lab/postmortem/rs-leadership-rotation-v1-stage2/trades_stage2.parquet (13,050 rows: ticker, signal_ym, signal_date, ret_3m, spy_ret_3m, excess_3m, excess_3m_net)
  • Summary JSON: stage2_summary.json in same directory
  • Histogram bins: chart_data.json in same directory
  • Walk-forward module: src/lab/walkforward.py
  • Run script: /tmp/run_rs_stage2.py
  • Pre-registered gate: lab/setups/gates.md §rs-leadership-rotation-v1 Stage 2
  • Original Stage 1 result (passed): lab/quickkill/rs-leadership-rotation-v1/result.md

Stage 2 ran 2026-05-30. Pre-registered gates frozen earlier the same day before the test ran. No claims, gates, or methodology adjusted post-hoc.

← Olderrs-leadership-rotation-v1 Newer →rs-leadership-rotation-v1-stage2

Mechaniq provides information, not investment advice. We do not execute trades. Past results are no guarantee for future performance. You are solely responsible for your trading decisions.

Lab · Methodology · Greeks Lab · About · FAQ · Glossary · Privacy · Terms · mechaniq.trade © 2026

07 Jul 2026, 07:10