research: volatility-standardized residual momentum screen, failed

Strategy review (2026-09-08) and a frozen, paired signal screen of
residual 12-1 momentum divided by its formation-window residual
volatility. Across 73 non-overlapping windows the normalized signal's IC
is 0.0128 against 0.0145 for the matched control, below the frozen 0.03
floor, so the conditional portfolio replay was not run and nothing in
production changes.

Code-review fixes to the runner, before first commit: a missing OHLC
price stops the run instead of reading as 0; the snapshot connection is
closed explicitly (on Windows it otherwise kept the file locked); the
paired-coverage check raises instead of asserting, so python -O cannot
strip it; and source files are recorded as git blob ids with line
endings normalized, so the report can be checked against history. The
report was regenerated with the fixed runner; its screen section is
byte-identical to the original run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
dennisthiessenandClaude Opus 5.5 committed 2026-10-10 18:45:24 +02:00
1 parent 70d17c1491
commit 7a9b3ad38b
9 files changed
+2659

No files matched your search

+8
View File
@@ -5,6 +5,13 @@ stop re-litigating settled questions: **if a row says "rejected", the experiment
was run and the data said no.** Detail lives in the linked docs and in
`reports/*.json` (all committed).
[Strategy research review (2026-09-08)](strategy-review-2026-09-08.md) compares
the existing evidence with published research and specifies a proposed
volatility-standardized residual-momentum experiment. The subsequent
[normalization screen failed](residual-normalization-findings.md): IC 0.0128
versus 0.0145 for matched control, below the frozen 0.03 floor. No portfolio
replay or production change followed.
**The one-line summary of the whole platform:** it is a **long-only
cross-sectional momentum book** — buy the top quintile by beta-adjusted 12-1
momentum, tilt toward higher volatility, hold ≤ 10 names, cut at 1.5× ATR, then
@@ -48,6 +55,7 @@ score, Structural S/R, the Gate Target Ladder, sentiment, fundamentals) is
| 11 | **FIP path-smoothness** as tie-breaker/filter | Non-monotonic within the qualified set; thinning the entry stream costs more compounding than the tilt returns | **Rejected as a filter** — but see §4, it's the strongest raw signal we've measured | — |
| 12 | **Fixed take-profit sweep** (R-multiples) | No interior optimum ever found — the best TP is "no TP" | **Rejected.** Momentum's edge lives in the right tail | `backtest_service.py:450` |
| 13 | **Sector-residual 12-1** (`mom_12_1_sector_resid` / sector demean) as replacement for market residual | Short-window IC/A/B looked knife-edge green; deep repaired + **liquid-1500** retest: weeks 83, mild +IC **0.027** / t 1.69, **below iron bar 0.03** (FAIL). Demean already weaker | **Rejected / closed.** Keep production market residual. Do not resurrect without a new pre-registered protocol | [sector-residual-momentum.md](sector-residual-momentum.md) · `sector-resid-deep-20260719-113319.json` · history-depth supersession note |
| 14 | **Volatility-standardized market-residual 12-1** | 73 non-overlapping windows: IC **0.01284** vs matched control **0.01446**, below frozen 0.03 floor. Paired delta -0.00162, 95% interval [-0.00496, +0.00156] | **Closed negative at signal screen.** No demonstrated improvement; difference is inconclusive. Conditional portfolio stage not run | [Findings](residual-normalization-findings.md) · [Protocol](residual-normalization.md) · `residual-normalization-20260908.json` |
| 15 | **Breakeven stop** (stop to entry once the trade is +1R / +2R, on top of the 3× ATR trail) | `be_1r` fails the frozen rule: train worse on Sharpe, CAGR and drawdown, test better on return but worse on drawdown. `be_2r` changed 2 of 480 trades, because the trail already reaches entry near +2R. A post-hoc arm that gates re-entry after breakeven exits does better but still fails on drawdown | **Rejected / closed for this snapshot.** Keep the production exit. Reopen only with a new pre-registered test on unseen data | [breakeven-stop.md](breakeven-stop.md) · `backtest-20261009-breakeven-stop.json` |
---