We pre-register and walk a strategy forward across S&P 500 in 1-year steps, each tested out-of-sample on data the strategy had never touched, with survivorship-bias-free constituents reconstructed as of every anchor. Stitched end to end, the walk realises an annualised Sharpe of 0.45 over 2005 out-of-sample observations. Deflating for the 11 trials the search actually ran gives a probabilistic deflated Sharpe of 36% — the strategy does not survive the multiple-testing correction — most likely an artifact of the search. Every attempt made along the way — 11 registered circuits, pruned candidates included — is counted in the correction, so the headline number reflects the true cost of the search.
The study is sealed before it starts: the universe, the step size and the method are fixed at registration and cannot be changed while the walk is running, and the anchor advances only forward. This removes the two commonest ways a backtest flatters itself — moving the test window until the numbers look good, and changing the rules with hindsight.
At each step the strategy is fitted on the 2 years of history ending at the anchor and then tested on the subsequent out-of-sample window it had never seen. Index membership is reconstructed as of the anchor date from the exchange's dated constituent change-log, so names that were later removed or delisted still compete on the dates they actually traded and there is no survivorship bias. Under the evolving method, each step may try several candidate circuits; one is kept and the rest are pruned. Crucially, every candidate — kept or discarded — is registered and counts toward the trial total below.
The inferential statistic is the Deflated Sharpe Ratio (Bailey and López de Prado, 2014), which asks: given that 11 configurations were tried, what is the probability that the observed Sharpe is genuinely positive rather than the best of many noisy draws? The number of trials is frozen at compile time and taken as the larger of the registered circuit count and the number of logged runs, so it can never understate the search.
| # | Step | Out-of-sample window | N | Sharpe | Deflated |
|---|---|---|---|---|---|
| 1 | Regime aware portfolio · step 1 | 2016-01-04 → 2016-12-30 | 1 | 0.32 | 62% |
| 2 | Regime aware portfolio · step 2 | 2017-01-03 → 2017-12-29 | 4 | 1.89 | 77% |
| 3 | Regime aware portfolio · step 3 | 2018-01-02 → 2018-12-31 | 5 | -0.91 | 2% |
| 4 | Regime aware portfolio · step 4 | 2019-01-02 → 2019-12-31 | 6 | 0.25 | 15% |
| 5 | Regime aware portfolio · step 5 | 2020-01-02 → 2020-12-31 | 7 | 0.08 | 10% |
| 6 | Regime aware portfolio · step 6 | 2021-01-04 → 2021-12-31 | 8 | 1.21 | 40% |
| 7 | Regime aware portfolio · step 7 | 2022-01-03 → 2022-12-30 | 9 | -0.06 | 6% |
| 8 | Regime aware portfolio · step 8 | 2023-01-03 → 2023-12-29 | 10 | 1.03 | 29% |
The search registered 11 circuits in total (pruned candidates included); the correction uses this registered-circuit count, N = 11. The pooled deflated Sharpe is the inferential headline; the per-step deflated track in Table 1 is illustrative, since near-identical variants are correlated and per-step deflation over-penalises.
The circuit routes capital by market regime: a classifier labels each period calm, choppy or stressed and the strategy re-weights — and, crucially, de-risks — accordingly. Those states are the translucent bands behind Figure 1. This is where a regime overlay earns or loses its keep: the table below shows how often the book sat in each state and how much capital it actually put to work there versus held idle in cash. A model that retreats to cash in choppy and stressed periods gives up return for a smoother ride — the trade-off is visible here, not hidden in the headline.
| Regime | Time in state | Capital deployed | Idle cash |
|---|---|---|---|
| Calm | 54.5% | 100.0% | 0.0% |
| Choppy | 21.7% | 75.0% | 25.0% |
| Stressed | 23.8% | 50.0% | 50.0% |
Each step's strategy is a circuit of platform primitives, frozen at registration. The table lists the full component set per step and — where the hypothesis evolved — exactly what changed against the previous step: components added, removed, or re-tuned.
| # | Components (primitives & key parameters) | Evolution vs previous step |
|---|---|---|
| 1 | universe (preset=sp500) · price loader · factor loader · factor value · factor quality · factor momentum · factor growth · factor regime tilt · factor composite · regime gmm (n_regimes=auto) · vix regime · hmm vol · regime ensemble (method=majority) · factor top tier · portfolio backtest (horizon=1y, rebalance=quarterly, selection=reselect) · portfolio forward autopsy · monte carlo (horizon=1y) | — |
| 2 | universe (preset=sp500) · price loader · factor loader · factor value · factor quality · factor momentum · factor growth · factor regime tilt · factor composite · regime gmm (n_regimes=auto) · vix regime · hmm vol · regime ensemble (method=majority) · factor top tier · portfolio backtest (horizon=1y, rebalance=quarterly, selection=reselect) · portfolio forward autopsy · monte carlo (horizon=1y) | unchanged — carried forward |
| 3 | universe (preset=sp500) · price loader · factor loader · factor value · factor quality · factor momentum · factor growth · factor regime tilt · factor composite · regime gmm (n_regimes=auto) · vix regime · hmm vol · regime ensemble (method=majority) · factor top tier · portfolio backtest (horizon=1y, rebalance=quarterly, selection=reselect) · portfolio forward autopsy · monte carlo (horizon=1y) | unchanged — carried forward |
| 4 | universe (preset=sp500) · price loader · factor loader · factor value · factor quality · factor momentum · factor growth · factor regime tilt · factor composite · regime gmm (n_regimes=auto) · vix regime · hmm vol · regime ensemble (method=majority) · factor top tier · portfolio backtest (horizon=1y, rebalance=quarterly, selection=reselect) · portfolio forward autopsy · monte carlo (horizon=1y) | unchanged — carried forward |
| 5 | universe (preset=sp500) · price loader · factor loader · factor value · factor quality · factor momentum · factor growth · factor regime tilt · factor composite · regime gmm (n_regimes=auto) · vix regime · hmm vol · regime ensemble (method=majority) · factor top tier · portfolio backtest (horizon=1y, rebalance=quarterly, selection=reselect) · portfolio forward autopsy · monte carlo (horizon=1y) | unchanged — carried forward |
| 6 | universe (preset=sp500) · price loader · factor loader · factor value · factor quality · factor momentum · factor growth · factor regime tilt · factor composite · regime gmm (n_regimes=auto) · vix regime · hmm vol · regime ensemble (method=majority) · factor top tier · portfolio backtest (horizon=1y, rebalance=quarterly, selection=reselect) · portfolio forward autopsy · monte carlo (horizon=1y) | unchanged — carried forward |
| 7 | universe (preset=sp500) · price loader · factor loader · factor value · factor quality · factor momentum · factor growth · factor regime tilt · factor composite · regime gmm (n_regimes=auto) · vix regime · hmm vol · regime ensemble (method=majority) · factor top tier · portfolio backtest (horizon=1y, rebalance=quarterly, selection=reselect) · portfolio forward autopsy · monte carlo (horizon=1y) | unchanged — carried forward |
| 8 | universe (preset=sp500) · price loader · factor loader · factor value · factor quality · factor momentum · factor growth · factor regime tilt · factor composite · regime gmm (n_regimes=auto) · vix regime · hmm vol · regime ensemble (method=majority) · factor top tier · portfolio backtest (horizon=1y, rebalance=quarterly, selection=reselect) · portfolio forward autopsy · monte carlo (horizon=1y) | unchanged — carried forward |
The integrity of a walk-forward rests on registering each hypothesis before its out-of-sample window is scored. The order below is the order in which the hypotheses were sealed.
| # | Registered hypothesis | Anchor | Registered at |
|---|---|---|---|
| 1 | “S&P 500, rebalanced quarterly across the selected basket, conditioned on the wired regime classifiers, and run out-of-sample from the anchor — with no in-sample parameters to optimize, a walk-forward does not apply; its disposition is the realized forward path versus the benchmark, is expected to generate positive risk-adjusted returns over the forward test window.” | 2016-01-01 | 2026-07-22 |
| 2 | “S&P 500, rebalanced quarterly across the selected basket, conditioned on the wired regime classifiers, and run out-of-sample from the anchor — with no in-sample parameters to optimize, a walk-forward does not apply; its disposition is the realized forward path versus the benchmark, is expected to generate positive risk-adjusted returns over the forward test window.” | 2017-01-01 | 2026-07-22 |
| 3 | “S&P 500, rebalanced quarterly across the selected basket, conditioned on the wired regime classifiers, and run out-of-sample from the anchor — with no in-sample parameters to optimize, a walk-forward does not apply; its disposition is the realized forward path versus the benchmark, is expected to generate positive risk-adjusted returns over the forward test window.” | 2018-01-01 | 2026-07-22 |
| 4 | “S&P 500, rebalanced quarterly across the selected basket, conditioned on the wired regime classifiers, and run out-of-sample from the anchor — with no in-sample parameters to optimize, a walk-forward does not apply; its disposition is the realized forward path versus the benchmark, is expected to generate positive risk-adjusted returns over the forward test window.” | 2019-01-01 | 2026-07-22 |
| 5 | “S&P 500, rebalanced quarterly across the selected basket, conditioned on the wired regime classifiers, and run out-of-sample from the anchor — with no in-sample parameters to optimize, a walk-forward does not apply; its disposition is the realized forward path versus the benchmark, is expected to generate positive risk-adjusted returns over the forward test window.” | 2020-01-01 | 2026-07-22 |
| 6 | “S&P 500, rebalanced quarterly across the selected basket, conditioned on the wired regime classifiers, and run out-of-sample from the anchor — with no in-sample parameters to optimize, a walk-forward does not apply; its disposition is the realized forward path versus the benchmark, is expected to generate positive risk-adjusted returns over the forward test window.” | 2021-01-01 | 2026-07-22 |
| 7 | “S&P 500, rebalanced quarterly across the selected basket, conditioned on the wired regime classifiers, and run out-of-sample from the anchor — with no in-sample parameters to optimize, a walk-forward does not apply; its disposition is the realized forward path versus the benchmark, is expected to generate positive risk-adjusted returns over the forward test window.” | 2022-01-01 | 2026-07-22 |
| 8 | “S&P 500, rebalanced quarterly across the selected basket, conditioned on the wired regime classifiers, and run out-of-sample from the anchor — with no in-sample parameters to optimize, a walk-forward does not apply; its disposition is the realized forward path versus the benchmark, is expected to generate positive risk-adjusted returns over the forward test window.” | 2023-01-01 | 2026-07-22 |
A garden of forking paths (Gelman and Loken, 2013) is not cheating — it is what honest research feels like from the inside. At each step there were several defensible things to try, and trying them is the work. What separates research from a hunt for a flattering backtest is that the paths not taken are still counted. Here they are: an annualised Sharpe of 0.45 over the stitched walk, deflated to 36% once the 11 trials are accounted for. The strategy does not survive the multiple-testing correction — most likely an artifact of the search.
Pooled deflated Sharpe is the inferential number; the per-step DSR track is illustrative (near-identical variants are correlated, so per-step N over-deflates). N is a conservative upper bound on the multiple-testing penalty, frozen at compile time and taken as the larger of the lineage trial count and the explored-runs count so it cannot understate the search. Integrity rests on pre-registration: each step's submitted_at is the registration order, auditable against when its OOS was scored.
Each step is backed by a frozen run report. The study is re-derivable from the ledger below.
| # | Commit | Report | Anchor | OOS window |
|---|---|---|---|---|
| 1 | f5d34a004116 | 256 | 2016-01-01 | 2016-01-04 → 2016-12-30 |
| 2 | 007b403b1f75 | 257 | 2017-01-01 | 2017-01-03 → 2017-12-29 |
| 3 | 3e4d52220a7b | 258 | 2018-01-01 | 2018-01-02 → 2018-12-31 |
| 4 | 2c97fa4cd586 | 259 | 2019-01-01 | 2019-01-02 → 2019-12-31 |
| 5 | 0d446a9e665c | 260 | 2020-01-01 | 2020-01-02 → 2020-12-31 |
| 6 | b544e634397b | 262 | 2021-01-01 | 2021-01-04 → 2021-12-31 |
| 7 | bf99842d97c5 | 264 | 2022-01-01 | 2022-01-03 → 2022-12-30 |
| 8 | 9de35299dcf6 | 265 | 2023-01-01 | 2023-01-03 → 2023-12-29 |
What each step's run actually did beyond its return: capital allocation across lanes and regimes, the portfolio book's rebalancing and cost drag, and how positions were sized. Harvested from the frozen run reports — present where the circuit produced them.
Portfolio book — rebalanced quarterly · 4 constructions · 18 names held · selection: reselect · 0% in cash · turnover 0× · cost drag 0% · regime gate active
Portfolio book — rebalanced quarterly · 5 constructions · 16 names held · selection: reselect · 0% in cash · turnover 0× · cost drag 0% · regime gate active
Portfolio book — rebalanced quarterly · 5 constructions · 14 names held · selection: reselect · 0% in cash · turnover 0× · cost drag 0% · regime gate active
Portfolio book — rebalanced quarterly · 5 constructions · 11 names held · selection: reselect · 0% in cash · turnover 0× · cost drag 0% · regime gate active
Portfolio book — rebalanced quarterly · 4 constructions · 19 names held · selection: reselect · 0% in cash · turnover 0× · cost drag 0% · regime gate active
Portfolio book — rebalanced quarterly · 5 constructions · 19 names held · selection: reselect · 0% in cash · turnover 0× · cost drag 0% · regime gate active
Portfolio book — rebalanced quarterly · 5 constructions · 17 names held · selection: reselect · 0% in cash · turnover 0× · cost drag 0% · regime gate active
Portfolio book — rebalanced quarterly · 5 constructions · 19 names held · selection: reselect · 0% in cash · turnover 0× · cost drag 0% · regime gate active