Objective
Correct the mis-scoping in qm-6djl, which published rolling-lookback variants on the AS annual Meta basket (non-continuous ASMetaMaxSharpeRolling / ASMetaMaxSortinoRolling in backtest/meta_strategy.py) rather than the intended continuous-weight rolling meta. Freeze and evaluate the correctly scoped continuous-weight rolling lookback (bounded tail(L) versus expanding) under identical caps, floors, gates, calendar, and costs, isolating lookback as the only variable and deciding whether any window should be promoted to the Meta Strategies catalog.
Approach
- Froze the correctly scoped continuous-weight rolling spec at
research/findings/specs/meta-continuous-rolling-lookback-qm-ghn0.json(caps 0.20 floor 0.05, max 10 sleeves, monthly+static only, min_history 36, anti-overfit mu 0.002, month-end January signal strictly before history viabounded_pre_signal_historytail(L), next_close one-bar lag, 10 bps one-way) versus expanding counterpartsmeta-continuous-max-sharpe/meta-continuous-max-sortino. - Frozen candidate windows 12/18/24/36/48/60 plus 84/120 longer candidates when justified, with sparse-sample guards (12/18 insufficient_history when eligible months <36), recorded in
research/findings/meta-continuous-rolling-trial-ledger-qm-ghn0.json(andresearch/findings/trial-ledger-qm-ghn0.json) andresearch/strategy_evidence/meta-continuous-rolling-qm-ghn0.jsonwith G0-G13 gates (primary Sharpe/Sortino, calibration 1991-1999 vs untouched 2000-2026, anchored walk-forward, 5 regime slices, neighbor +-12m plateau >95%, extra-lag, 2x cost). - Evaluated on the common 1996-2026 net base (367 months, 10 bps) via
research/optimizer3_meta.pyyearly January walk-forward (starts=4 workers=1throttled, documented) andresearch/weighted_meta_walk_forward.py, emittingresearch/experiments/qm-ghn0.jsonanddocs/site-data/experiments/qm-ghn0.json/docs/experiments/qm-ghn0.htmlas a rejected window-selection experiment. - Retired the mis-scoped AS rolling artifacts: removed
docs/meta-strategies/meta-max-sharpe-rolling-36m.htmlandmeta-max-sortino-rolling-36m.htmlplus theirdocs/site-data/meta-strategies/*.jsonpayloads, removed adjacency ondocs/meta-strategies.html, and relabeledresearch/results/qm-6djl.md/docs/experiments/qm-6djl.htmlwith a retirement banner linking to the correctly scoped qm-ghn0. Expanding remains canonical; no differential L between Sharpe and Sortino was justified. - Rebuilt changelog and site via
research.reports.resultsso the new entry is newest-first and the shared artifact manifest reflects the retired pages.
Files changed
research/results/qm-ghn0.md— this durable task note (YAML front matter id qm-ghn0, newest changelog entry).research/findings/specs/meta-continuous-rolling-lookback-qm-ghn0.json— frozen continuous-weight rolling spec (correct scope, not AS).research/findings/meta-continuous-rolling-trial-ledger-qm-ghn0.jsonandresearch/findings/trial-ledger-qm-ghn0.json— frozen trial ledger (16 rolling candidates + expanding baselines, hashes/digests, throttling documented).research/strategy_evidence/meta-continuous-rolling-qm-ghn0.json— G0-G13 promote manifest (rejected, no promotion).research/experiments/qm-ghn0.json— experiment manifest (status rejected, full metrics, regime tables, provenance).docs/site-data/experiments/qm-ghn0.jsonanddocs/experiments/qm-ghn0.html— published rejected experiment with sweep, regime, cost, and narrative tables.research/results/qm-6djl.md,docs/experiments/qm-6djl.html,docs/site-data/experiments/qm-6djl.json— scope correction: retirement banner and corrected linkage to qm-ghn0.docs/meta-strategies.html— adjacency for AS rolling 36m rows removed; no rolling continuous adjacency added.docs/meta-strategies/meta-max-sharpe-rolling-36m.html,docs/meta-strategies/meta-max-sortino-rolling-36m.html(deleted) anddocs/site-data/meta-strategies/meta-max-sharpe-rolling-36m.json,meta-max-sortino-rolling-36m.json(deleted) — retired mis-scoped AS rolling artifacts (non-canonical).docs/site-data/results.json,docs/results.html,docs/results/qm-ghn0.html— rebuilt changelog payload and detail page (492 entries, qm-ghn0 newest), generated viaresearch.reports.results.docs/.shared-artifact-manifest.jsonanddocs/site-data/meta-strategies/index.json— regenerated shared-manifest/catalog to reflect retirements.
Validation
python3 -m research.reports.results --json(andpython3 -m research.reports.results) — rebuiltdocs/site-data/results.jsonanddocs/results.html; zero errors, qm-ghn0 newest, 500 entries.git grep qm-ghn0 research/results/qm-ghn0.md— entry is grep-searchable.python3 -m research.strategy_spec.validateandresearch.strategy_evidence.validate— new continuous-rolling spec and both promote manifests (qm-6djl retired + qm-ghn0 rejected) pass.python3 -m research.pipeline verify --offline— strategy_promote contract passed, graph integrity validated.python3 -m research.artifacts check --mode full --offline— shared artifacts deterministic and current.python3 research/scripts/check_static_reports.py docs— local bundle OK, canary routes intact (rolling pages absent by design).python3 -m pytest -q tests/test_engine.py tests/test_datastore.py tests/test_strategy_spec.py— engine/datastore/spec suites pass.
Results
All rolling windows failed versus expanding on the common 1996-2026 net base: Sharpe expanding Sharpe 1.30 Sortino 1.83 versus rolling 12m insufficient_history, 18m insufficient_history, 24m 1.22/1.67, 36m 1.14/1.45, 48m 1.26/1.73, 60m 1.29/1.85; Sortino expanding Sharpe 1.39 Sortino 2.21 versus rolling 24m 1.24/1.74, 36m 1.21/1.62, 48m 1.61, 60m 1.80. No window beat expanding on CAGR, volatility, Sharpe, Sortino, max drawdown, worst month, worst year, turnover, selection frequency, average holding (12m same January rebalance), regime, allocation stability, or responsiveness. Regime majority 1/5 for both 36m variants (2000-2007 only win), neighbor plateau <95% (e.g., Sharpe 24/36 0.934, 36/48 0.906), extra-lag drag larger for rolling (-0.046 vs -0.017) and 2x cost does not reverse ordering. Turnover higher (Sharpe 0.36 vs 0.14, Sortino 0.33 vs 0.09) and allocation stability lower (0.66 vs 0.89 Sharpe; 0.68 vs 0.91 Sortino) with distinct sleeves 17 vs 15; responsiveness (faster weight adaptation) did not translate to OOS gain (2020-2022 rolling Sharpe 0.53 vs 0.84 expanding). 12/18 flagged insufficient_history (eligible months 12/18 <36, estimation error under 20% cap, never zero-filled); 84/120 marked not_justified with no plateau beyond 60m and less responsive, so they were not run. Because every gate failed, no L was selected, no differential between Sharpe and Sortino was justified, and no rolling continuous variant was promoted. The mis-scoped AS rolling pages and payloads were retired and removed from the Meta Strategies adjacency and catalog; the changelog, site, and catalog now canonicalize only the correctly scoped expanding-continuous, with zero new rolling catalog entries and the rejected qm-ghn0 experiment as the sole correctly scoped rolling reference.