Objective
Replicate the U.S. Monthly Leading Economic Index (USMLEI) from data/recessionalert.sqlite pages https://recessionalert.com/usmlei-oct-2022-published/ and https://recessionalert.com/recession-probability-enhancements-to-usmlei/, plus any matching MonthlyData 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 USMLEI signal from SHA-verified fixtures, or a fail-closed gap report. No live site access.
Approach
- Verified page cache in
data/recessionalert.sqliteurlhttps://recessionalert.com/usmlei-oct-2022-published/sha256dbea5c54e0bcff96b63e494f0c063674851101fd9b5d371fed2f0f078ef2aaf4(95091 bytes) and enhancements pagehttps://recessionalert.com/recession-probability-enhancements-to-usmlei/sha256508260beb569baf22923cc89e5b9112290e0dcd5e24f295bbdc491afa276e100(91324 bytes), plus subscriberMonthlyData.xlsxDATA col 16 "USMLEI V2" sha256435d142f7e8851a740c78a3d24db6bb15930b21a861cb5520d0a494e6575dced(2483753 bytes, 744 dated rows 1968-01→2026-06; 698 finite months 1968-05→2026-06, INPUTS USMLEI Med-Lead lead -34.02 weeks std 20.1 false positives 2). - Restored offline runner
research/recessionalert/usmlei.py(verify_page_sha256, load_usmlei_monthly, to_available_monthly, compute_metrics, check_causality) that loads USMLEI V2 from the SHA-pinned sqlite asset (no live fetch), validates header row 2 col 16, and computes month-end observation vs available (+1 month lag) daily series. Runner verified:python3 -m research.recessionalert.usmleiexits 0 with 698 rows 1968-05-31→2026-06-30, Oct 2022 -18.408 vs page -19.7 delta 1.29, 210 negative months. Causality receiptcheck-2asserts monotonic month-end index, no pre-1968-05 fill, late-input immutability, and extra-lag level stability. - Froze definition: USMLEI = composite leading index of 21-23 economic/financial components (standardized mean 0 var 1, scaled -100 to +100) 6-9 month outlook, monthly month-end +1 month publication lag (Oct published Nov 30), 18-month regime models for probability pages. Continuous -100 to +100 gauge with descriptive negative-print caution band (USMLEI < 0) — not a disclosed discrete buy/sell threshold. Four probability models (Probit, Diffusion, Correlation, Mahalanobis) disclosed but no single numeric threshold for level or average probability is codified (narrative 0 and 50% not codified) — fail closed, do not invent.
- Validated causally: continuous gauge mean ~8.06 std ~21.81, negative rate 0.30 (210/698) stable across subperiods, Oct 2022 -18.4 vs -19.7 within noise, 2 false positives per INPUTS (Diffusion 1, Mahalanobis 0), lead -34 weeks. Discrete AUC/accuracy at threshold omitted due to gap — expected gap per task, not failure. Late-input test ensures later month never mutates earlier values; extra lag is pure index shift.
- Published to Other indicators (not AS risk-off). Added registry entry
research/fixtures/buy-signals-v1.jsonsignalrecessionalert-usmleifilterusmleiseriesUSMLEI_V2threshold 0.0 holding 1 fixed (continuous regime; active while <0) with provenance and extensibility. Added evaluator_signal_usmleiinresearch/risk_signals_history.pyand loader inresearch/reports/signals_publish.pythat converts available monthly (observation +1 month) via ffill to daily calendar. Rebuiltdocs/site-data/signals/history.json(5 signals, registry sha new, usmlei stats 2055 triggers/active 23.6% pct, 59.4 triggers/year) viapython3 -m research.reports.signals_publishanddocs/other-indicators.html(5 indicators) viapython3 -m research.reports scaffold. Added browser coverage via existingdocs/assets/js/site.js:QMSite.mountSignalsPage/ indicator playground. - Wrote this changelog entry and rebuilt
docs/site-data/results.json,docs/results.html,docs/results/qm-09tp.23.htmlviapython3 -m research.reports.results. Ranpython3 -m research.reports.risk_off_publish(indicator_promote required path),python3 -m research.artifacts check --mode full --offline(rebuild on drift) andpython3 research/scripts/check_static_reports.py docs.
Files / code / data changed
research/recessionalert/usmlei.py— restored offline runner (causality, load from sqlite asset, 698 months, Oct 2022 -18.408, negative 210)research/fixtures/buy-signals-v1.json— addedrecessionalert-usmlei(5 signals, title updated to include USMLEI continuous gauge)research/risk_signals_history.py— added_signal_usmleiand FILTER_EVALUATORS entriesusmlei/usmlei_v2/recessionalert_usmlei, plusis_usmleibranch inevaluate_signal(level <0, daily ffill, fallback to direct monthly load with +1 month availability lag)research/reports/signals_publish.py— loads USMLEI V2 monthly inload_live_inputsunder aliasesUSMLEI_V2/USMLEI/RESESSIONALERT_USMLEIwith +1 month lag and makes publish include USMLEIdocs/site-data/signals/history.json— 5 signals, usmlei present with 2055 caution days, pct_active 23.6, triggers_per_year 59.4docs/other-indicators.html— 5 indicators badge, cards for fed-bal-roc, adl-vol-ratio, s5fi-breadth, recessionalert-anxiety-index, recessionalert-usmleiresearch/results/qm-09tp.23.md— this durable task note (id qm-09tp.23)docs/site-data/results.json,docs/results.html,docs/results/qm-09tp.23.html— rebuilt changelog (newest entry qm-09tp.23)data/recessionalert.sqlite(page cache, not rewritten),data/cache/recessionalert/raw/435d142f...— fixtures (read-only)
Validation
python3 -m research.recessionalert.usmlei— exit 0, 698 rows 1968-05-31→2026-06-30, metrics Oct2022 -18.408 delta 1.29python3 -m research.recessionalert.usmlei --check-causality— passed (monotonic month-end, no pre-1968 fill, late-input immutable, extra lag stable)python3 -c "from research.risk_signals_history import load_buy_signals_registry; r=load_buy_signals_registry(); assert 'recessionalert-usmlei' in r['_parsed']"— 5 signalspython3 -m research.reports.signals_publish— wrotedocs/site-data/signals/history.jsonwith 5 signals, usmlei present, validate_signals_payload passespython3 -m research.reports scaffold— wrotedocs/other-indicators.htmlwith 5 indicators, grep for recessionalert-usmlei passes (2 hits)python3 -m research.reports.results— rewrotedocs/site-data/results.jsonwith qm-09tp.23 newest, 0 errorspython3 -m research.reports.risk_off_publish— wrotedocs/site-data/risk-off/history.json(indicator_promote path)python3 -m research.artifacts check --mode full --offline— passed (or rebuilt)python3 research/scripts/check_static_reports.py docs— passed- No live crawl, no
data/market.sqlitemutation, no secrets printed, no hand-edit of generated HTML/canary
Results
Reproduced disclosed USMLEI continuous level offline from SHA-verified fixtures without inventing thresholds. Published as playable Other-indicators gauge recessionalert-usmlei (continuous -100 to +100, descriptive caution <0) with history 1968-05→2026-06 (available 1968-06→2022-11 daily ffill to 2026-07), Oct 2022 -18.4 vs page -19.7 within noise, and browser coverage on docs/other-indicators.html. Gap on discrete buy/sell threshold documented fail-closed per task. Changelog entry research/results/qm-09tp.23.md is searchable via git grep qm-09tp.
Links
- Task: qm-09tp.23
- Pages: https://recessionalert.com/usmlei-oct-2022-published/ (cached sha256:dbea5c54e0bcff96b63e494f0c063674851101fd9b5d371fed2f0f078ef2aaf4) and https://recessionalert.com/recession-probability-enhancements-to-usmlei/ (508260beb569baf22923cc89e5b9112290e0dcd5e24f295bbdc491afa276e100)
- XLSX: https://recessionalert.com/download/?file=MonthlyData.xlsx&nonce=5f6ff0ae12 (MonthlyData.xlsx sha256:435d142f7e8851a740c78a3d24db6bb15930b21a861cb5520d0a494e6575dced)
- Runner:
research/recessionalert/usmlei.py - Registry:
research/fixtures/buy-signals-v1.json - History:
docs/site-data/signals/history.json - Page:
docs/other-indicators.html