Same universe/split/costs/fill/liq-gate as expand2. Each variant judged by testbot_baseline.judge (bar: IS p<0.05, OOS Sharpe >= base, OOS DD within +5pp).
| Variant | IS Sharpe | IS maxDD | OOS Sharpe | OOS maxDD | OOS ret | turn/yr |
|---|---|---|---|---|---|---|
| S0 BASE replication | 0.88 | -54.7% | 1.74 | -28.5% | +221.9% | 8.5 |
judge: S0 BASE replication vs frozen baseline v1 (overlap 5030d)
| leg | base Sharpe | cand Sharpe | base maxDD | cand maxDD | | IS | 0.88 | 0.88 | -54.7% | -54.7% | | OOS | 1.74 | 1.74 | -28.5% | -28.5% | IS bootstrap p=0.000 | IS p<0.05: OK | OOS Sharpe >= base: OK | OOS DD within +5pp: OK verdict: PASS — advance to forward shadow
| S1 composite 126/63/21 | 0.73 | -52.8% | 1.75 | -21.5% | +170.0% | 15.0 |
judge: S1 composite 126/63/21 vs frozen baseline v1 (overlap 5030d)
| leg | base Sharpe | cand Sharpe | base maxDD | cand maxDD | | IS | 0.88 | 0.73 | -54.7% | -52.8% | | OOS | 1.74 | 1.75 | -28.5% | -21.5% | IS bootstrap p=0.992 | IS p<0.05: NO | OOS Sharpe >= base: OK | OOS DD within +5pp: OK verdict: FAIL — move on
| S2 skip-month | 0.87 | -57.6% | 1.55 | -31.1% | +188.5% | 9.3 |
judge: S2 skip-month vs frozen baseline v1 (overlap 5030d)
| leg | base Sharpe | cand Sharpe | base maxDD | cand maxDD | | IS | 0.88 | 0.87 | -54.7% | -57.6% | | OOS | 1.74 | 1.55 | -28.5% | -31.1% | IS bootstrap p=0.350 | IS p<0.05: NO | OOS Sharpe >= base: NO | OOS DD within +5pp: OK verdict: FAIL — move on
| S3 credit-gated BASE | 0.96 | -44.8% | 1.74 | -28.5% | +221.9% | 8.3 |
judge: S3 credit-gated BASE vs frozen baseline v1 (overlap 5030d)
| leg | base Sharpe | cand Sharpe | base maxDD | cand maxDD | | IS | 0.88 | 0.96 | -54.7% | -44.8% | | OOS | 1.74 | 1.74 | -28.5% | -28.5% | IS bootstrap p=0.345 | IS p<0.05: NO | OOS Sharpe >= base: OK | OOS DD within +5pp: OK verdict: FAIL — move on
Verdicts (2026-09-09)
ADOPT: nothing. All three FAIL — the baseline stands at 4-0-0 across two studies.
- S0 replication — PASS (sanity). Rebuild reproduces W0 to the printed digit (0.88/-54.7% IS, 1.74/-28.5% OOS). The frozen file is trustworthy; the p=0.000 on a zero-diff is degenerate bootstrap dust, ignore it.
- S1 composite — FAIL. IS decisively worse (0.73, p=0.992 against), OOS Sharpe tied with better DD but at 15/yr turnover (+76% trading for nothing). Blending shorter lookbacks adds churn, not signal, here.
- S2 skip-month — FAIL. Textbook 12-1 is a tie on IS (p=0.350) and worse OOS (1.55 vs 1.74). No evidence the last month contaminates this setup.
- S3 credit gate — FAIL on the bar, closest miss, kept as-is. IS 0.96 (+0.08) with DD cut 10pp (-44.8% vs -54.7%), zero OOS cost (gate never fired post-2022: identical OOS rows). Insurance with no premium in this window — but p=0.345, so it stays a standing risk control, not an adopted edge. Testbot default threshold corrected to 2.5 (= 250bps).
UNITS NOTE (live-system finding, NOT changed)
FRED BAA10Y/AAA10Y print in percent; the spread's median is 0.89 with an
all-time max of 3.5. EQMOM_CREDIT_THRESHOLD_BPS defaults to 250.0 in
production/equity_momentum_runner.py (and did in the testbot until this
study), a comparison that can never fire (0.89 > 250.0 is permanently
false; start_bots.py sets no override). The live eqmom credit gate is
almost certainly dead code in production — it has never gated anything.
Fix (live): threshold 2.5, verified in shadow first. Left untouched here;
live risk behavior changes go through the operator, not a research turn.