S&P 500 momentum,
walk-forward verified.
Real daily closes from the S&P 500 universe, 2019→2026. A 126-day momentum signal, rebalanced monthly, top-25 equal-weighted, with 5 bps round-trip cost. Walk-forward — no in-sample tuning leaks into the equity curve below.
- Sharpe
- 1.70
- Deflated Sharpe P
- 1.000
- Annualized return
- 42.48%
- Window
- 2019→2026
The numbers, eight of them.
All figures computed from the equity curve below. No selection, no smoothing. Source: report.json.
- Sharpe
- 1.70
- Annualized return
- 42.48%
- Annualized vol
- 24.94%
- Max drawdown
- 19.56%
- Turnover
- 25.70×
- Deflated Sharpe P
- 1.000
- Skew
- 0.01
- Kurtosis
- 2.09
Annualized · raw, before deflation
Total 600.94% over the window
σ of monthly returns, annualized
Peak-to-trough on equity curve
25.70 portfolio rotations · 5 bps cost applied
n_trials=1 · σ_SR=0.50
Of monthly returns
Excess · monthly returns
What this is not.
Borderline — the in-sample winner is roughly coin-flip out of sample.
CSCV across 13 configs · 70 IS/OOS partitions · 35.00 aligned rebalances per config
Survivorship correction; LightGBM model when available:
- Momentum · survivors-only
- Sharpe 1.73 · 22.48% AnnRet
- Momentum · point-in-time S&P 500
- Sharpe 1.11 · 14.74% AnnRet
- LightGBM · trainer subset
- Sharpe 1.41 · 16.06% AnnRet
Headline gap = “joined-after” forward bias in the survivors-only dataset. ML row, when shown, is on a smaller training universe — informative but not strictly apples-to-apples.
- ·Survivorship correction: the naive backtest Sharpe of 1.04 dropped to 0.71 once we re-ran on a point-in-time SP500 panel that includes every Wikipedia-removed name (683 symbols, 2.75M rows, 2008–2026). Pooled p(naive > PIT) = 0.0000 — survivorship inflation is statistically real. 0.71 is what the project actually expects net of survivorship.
- ·These are backtest numbers, not live trading numbers. Live out-of-sample results are routinely lower than backtests for every strategy ever run.
- ·Past performance does not predict future returns. Anyone who tells you a model can guarantee a profit on any specific stock tomorrow is selling you a lie.
- ·This page is research output, not investment advice. No order routing, no real money, no recommendation to buy or sell any security. Treat it as a methodology demo.
- ·The model is gradient-boosted decision trees (LightGBM). It is not “AI”, not a transformer, not a neural network. It outputs calibrated probabilities, not point price forecasts.
From $100,000 to $700,939.
66 monthly rebalance points · total return 532.44% · source: equity_curve.csv.
Strategies that looked promising in a single window, then failed the paired multi-seed gate or Hansen-SPA test. Each one is committed to git under the SHA below — verifiable, not a marketing list.
- SEC 8-K LLM nowcasting on SP5002026-07-07
TBDRetraction-first: gate scheduled 2026-07-14, verdict pendingGatepaired multi-seed on yfinance deep panel (test_days=21, top_k=20, LLM classifies 8-K filings via OpenRouter DeepSeek V4 Flash, min_confidence=0.7, lookback=5 trading days, hold=20 trading days)ResultWhy - Google Trends timing (pytrends interest spikes)2026-07-07
TBDRetraction-first: gate scheduled 2026-07-14, verdict pendingGatepaired multi-seed on yfinance deep panel (test_days=21, top_k=20, z_threshold=2.0 over 30-day rolling window)ResultWhy - Chronos-Bolt-Base zero-shot as full replacement for momentum-1262026-07-07
TBDRetraction-first: gate scheduled 2026-07-14, verdict pendingGatepaired multi-seed on yfinance deep panel (test_days=21, top_k=20, Chronos-Bolt-Base zero-shot forecast, 128d context / 20d horizon)ResultWhy - FinRL portfolio PPO (multi-seed)2026-07-07
TBDGate pending — Horikawa-Nakagawa 2024 predicts failure at ~85-90% probabilityGatepaired multi-seed via scripts/challenger/finrl_significance.sh (env + PPO + 4-sub-test honest gate)ResultNot run yet. Sidecar shipped per honesty contract; result auto-appended when the gate runs.WhyHorikawa-Nakagawa (2024) shows portfolio-RL 'edge' is stat-arb overlay not risk reduction. Expected gate probability ~10-15%. Ship anyway; publish the retraction if it fails. - Sector momentum on 11 SPDR ETFs2026-06-30
TBDFailed paired multi-seed gate vs SP500 momentum-126 2026-06-30Gatepaired multi-seed on yfinance 18.5-yr panel (test_days=21, top_k=5, 11-ETF universe)Result0/3 seeds win, pooled p(1-sided) = 1.0000 (extremely WRONG direction); sector Sharpe 0.717 (fixed — 11 ETFs no seed variation) vs SP500 momentum 0.94/1.29/0.90 — sector WORSE by 0.2-0.6 Sharpe per seedWhyAudit suggested sector momentum could lift +2-5pp annualized by reducing multiple-testing burden (11 ETFs vs 500 stocks → smaller DSR penalty). Reality: the 11-ETF universe is too narrow — top-5 picks have too little dispersion vs SP500's 500-name selection. The fewer-multiple-tests advantage doesn't compensate for the lost cross-sectional dispersion. Signal class kept for future ensemble experiments at higher top_k or with mean-reversion overlays. - Post-Earnings Announcement Drift (Bernard-Thomas)2026-06-25
TBDFailed paired multi-seed gate vs momentum-126 baseline 2026-06-25Gatepaired multi-seed on yfinance deep panel (test_days=21, top_k=20, 12.5 yrs data, 23k earnings events)Result0/3 seeds win, pooled p(1-sided) = 0.9999 (WRONG direction, extremely significant); PEAD Sharpe 0.58/0.65/0.51 vs momentum 0.94/1.29/0.90 — PEAD WORSE per seed by 0.36-0.64WhyBall-Brown 1968 → Bernard-Thomas 1989 found PEAD lasts 30-60 days. The literature documented decay since 2010 and our 2014-2026 yfinance result confirms: at top-k=20 long-only with surprise+day0-confirmed filter, PEAD picks too few names too rarely vs an always-on momentum-126. The signal class (`PEADSignal`) stays in code so future variants (top-k=5, multi-horizon, short-side) can re-test. - Insider cluster-buying (SEC Form 4 P-codes)2026-06-25
TBDFailed paired multi-seed gate vs momentum-126 baseline 2026-06-25Gatepaired multi-seed on yfinance deep panel (test_days=21, top_k=20, 8.5 yrs data, 586k insider tx)Result0/3 seeds win, pooled p(1-sided) = 0.9395 (WRONG direction); insider Sharpe 0.83/0.41/0.47 vs momentum 1.40/1.25/1.13 — insider WORSE per seed by 0.4-0.8WhyCohen-Malloy-Pomorski (2012) found real edge in cluster-buy signals in small/mid-cap names; in our SP500-only large-cap window the signal fires too rarely to compete with the always-on momentum signal. Real edge may exist with a wider universe or different threshold — wire stays in `signals.py` so future tuning can re-test. - Storm shield (SMA200 trend filter)2026-06-24
1284ee0Disabled on the live path 2026-06-24Gatepaired multi-seed on yfinance deep panelResult0/3 seeds win, pooled p(1-sided) = 0.9935 (WRONG DIRECTION); shield reduced Sharpe by ~0.33 each seedWhyA trend-following overlay should defend against bear-regime drawdown. On the corrected dataset it neither lifts Sharpe nor reduces drawdown materially. Wire stays in code (env-gated) so a future tuning can re-evaluate without re-implementing it. - LightGBM V2 (tuned Optuna 30-trial)2026-05-22
e3d85fcRolled back to V1 after failing vs V1 on multi-seedGatepaired multi-seed: V2 vs V1 baselineResultV2 lost 0/3 seeds; Optuna's in-sample tuning didn't generalise to held-out foldsWhyHonest gate caught the selection-bias from a 30-trial hyperparameter search before live capital touched it. - FRED macro features2026-05-19
1137696Retracted after failing paired multi-seed robustnessGatepaired multi-seed (macro vs no-macro across seeds 42 / 7 / 99)ResultPooled p = 0.81, macro wins 1/3 seeds — single-window +43% Sharpe was selection biasWhyA single backtest window's improvement looked huge. The multi-seed gate caught that the +43% was a happy seed, not a real edge.
The manifest. Click to copy.
No manifest, no publish. Same SHA + same data fingerprint reproduces these numbers exactly. Source: manifest.json.
- Python
- 3.12.12
- Pinned packages
- 7
- Run created
Read the credibility contract.
A raw Sharpe of 1.70 on its own is not a claim. The number that matters is the Deflated Sharpe P-value — the probability that the true Sharpe is positive after correcting for selection bias across 1 candidate configs and the non-normality of returns (skew 0.01, kurtosis 2.09). For this run that probability is 1.000.
This is a momentum baseline — the null hypothesis any ML pipeline in this repo has to beat. It is what a 6-month price trend, equal- weighted across the top 25 names and rebalanced monthly with 5 bps transaction cost, actually returned on real S&P 500 daily closes. Walk-forward, no peeking. The full credibility contract — what is and is not used, how each mechanism prevents a specific way numbers get inflated — is in TRUST.md.