← Results index

Replicate RecessionAlert: Zweig Breadth Thrust

2026-08-23T05:45:00Z Research completed Reproduced the RecessionAlert Zweig Breadth Thrust Redux (ZBT-A) from SHA-verified offline fixtures (page 6cc53ced 93502 bytes and WeeklyData.xlsx fc2be5f1) as a buy-only Other-indicators signal with 12 Redux markers 2004-05-21→2022-10-04 replayed exact, classic 0.40/0.615/10d disclosed, ZBT-B 12-day rapid retained, and causal +1-bar edge beating baseline at all disclosed horizons.
qm-09tp zweig breadth-thrust recessionalert zbt-a

Objective

Replicate Zweig Breadth Thrust - The RecessionALERT Redux from data/recessionalert.sqlite page https://recessionalert.com/zweig-breadth-thrust-redux/ and any matching fixture sheet. Spreadsheet/DB fixtures are the source of truth. Never invent thresholds. Never live-crawl. Fail closed on missing disclosed rules. Acceptance: offline runner/spec reproduces the disclosed Zweig-redux signal from SHA-verified fixtures, or a fail-closed gap report. No live site access.

Approach

  1. Verified page cache in data/recessionalert.sqlite: https://recessionalert.com/zweig-breadth-thrust-redux/ sha256 6cc53cedbef312323ba69e787639a2b4d5a0dc2eee5e72c371431b9dd42f66d7 93502 bytes fetched 2026-08-22T23:44:07Z. The page discloses the classic Zweig rule (10-day EMA of NYSE Advances/(Advances+Declines) from below 0.40 to above 0.615 within 10 trading days) and describes the Redux ZBT-A variant only qualitatively as stricter lower + relaxed upper + extended window (~4× frequency, 13 chart signals to 2013) without numeric disclosure; a copyright gate hides the actuarial table. A rapid ZBT-B variant is partially disclosed as retaining 0.40 lower, relaxing 0.615 upper, 12-day window.
  1. Inventoried offline workbook assets. Six cached xlsx assets were enumerated; WeeklyData.xlsx sha256 fc2be5f1fc2a2e38949ae566f6e8cb4699a95562975a498fb5a53510cc40d67c (8209462 bytes) sheet SP500 BREADTH DATA contains the calculated ZBT BUY col 33 (15 signals), ZBT-B BUY col 34 (89), ZBT-A BUY col 35 (12) for 2003-01-02→2026-08-14 (5942 rows). The Redux machine-readable span is 2004-05-21→2022-10-04 (12 markers). No other workbook contains Zweig thresholds; formulas are absent (calculated values only). This matches the Great Trough snapshot pattern for exact replay.
  1. Built offline runner research/recessionalert/zweig_breadth_thrust.py (verify_page_sha256, verify_workbook_sha256, load_zweig, fixture_summary, check_causality, gap_report) that recomputes both SHAs before parsing, validates headers DATE/SP500/ZBT BUY/ZBT-B BUY/ZBT-A BUY at cols 0/1/33/34/35, and normalizes workbook 0/1 to boolean Redux impulses without inventing thresholds. Runner verified: 5942 rows, Redux 12, classic 15, rapid 89. Causality receipt python3 -m research.recessionalert.zweig_breadth_thrust --check-causality --json shows +1-bar edge retained at all 37/83/119/150 horizons vs unconditional baseline and +2-bar extra lag stable.
  1. Froze definition in research/findings/specs/recessionalert-zweig-breadth-thrust-redux.json: buy-only Zweig Redux, classic disclosed as above, Redux replayed exact from ZBT-A BUY, rapid documented as 12-day, NYSE daily-close cadence, next-session (+1 bar) execution, no disclosed exit, 20-session viewer window only. Fail-closed gaps list exact ZBT-A/B numeric thresholds, proprietary EMA construction, pre-2004/pre-1945 history, and revision policy.
  1. Validated causally: forward S&P 500 close-to-close returns at 37/83/119/150 trading days with +1 bar. Redux beats unconditional at every horizon (37d mean 0.018 vs 0.012 win 66.7% vs 66.5%, 83d 0.045 vs 0.027 win 83.3% vs 70.3%, 119d 0.074 vs 0.039, 150d 0.102 vs 0.049). Extra lag T+2 is stable and stronger (83d 0.054 vs 0.027). Subperiod 10 pre-2020 vs 2 post-2020 is documented but not gated due to small post sample; adjacent variants confirm tradeoff (classic 15-signal 83d 0.078 vs Redux 0.045 vs rapid 89-signal 0.035). No failures beyond small-n caveat; negative-adjacent evidence retained.
  1. Promoted to Other indicators (not AS risk-off). Added registry entry research/fixtures/buy-signals-v1.json signal recessionalert-zweig-breadth-thrust-redux filter zweig_breadth_thrust series ZWEIG_REDUX_A threshold 0.5 holding 20 fixed with full provenance, gaps, and validation. Added evaluator _signal_zweig_breadth_thrust in research/risk_signals_history.py and loader in research/reports/signals_publish.py that replays the SHA-verified daily Redux fixture via load_zweig. Rebuilt docs/site-data/signals/history.json (7 signals, 12 Redux trigger dates) via python3 -m research.reports.signals_publish --offline and python3 -m research.reports scaffold which wrote docs/other-indicators.html with 7 indicators and recessionalert-zweig-breadth-thrust-redux card.
  1. Wrote this changelog entry and rebuilt docs/site-data/results.json, docs/results.html, docs/results/qm-09tp.20.html via python3 -m research.reports.results. Ran python3 research/scripts/check_static_reports.py docs and python3 -m research.artifacts check --mode full --offline (rebuild on drift).

Files / code / data changed

Validation

Results

Reproduced the disclosed Zweig Breadth Thrust Redux signal offline from SHA-verified fixtures without inventing numeric thresholds. Published as a playable Other-indicators signal recessionalert-zweig-breadth-thrust-redux with 12 exact Redux markers 2004-05-21→2022-10-04, +1-bar causality, and browser-visible overlay on docs/other-indicators.html. Classic 0.40/0.615/10d remains the disclosed anchor while Redux is workbook-replayed; validation shows consistent edge vs unconditional baseline (small-n caveat retained) and extra-lag stability. Changelog entry research/results/qm-09tp.20.md is searchable via git grep qm-09tp.20.

Links

Source artifact: research/results/qm-09tp.20.md