v3 was calibrated by replaying the series offline, but that harness was never
committed -- so its published numbers could not be re-derived, and a v4 cut would
have had to choose anchors by argument rather than measurement. This is that
harness, and it reproduces the published figures.
scripts/run_regime_monitor_calibration.py replays State/Warning session by
session from the same inputs the live job uses (Alpaca for all 33 symbols, FRED
for VIX and HY OAS), with no database: breadth and divergence come from
breadth_service's pure helpers. It never reimplements an unchanged live sensor --
_compute_index, _score_pillars, P2, P4 and the Warning sensors are imported and
called. Only candidate formulas (proposed v4) and retired ones (v2, gone from the
codebase) are defined here and patched onto the module for a variant's duration.
Reproduction of the 408 sessions ending 2026-07-24, against the figures in
docs/research/regime-monitor-v3.md:
v2 State avg 22.6 -> 22.68
v2 State p80 35.1 -> 35.1 exact
v2 State max 91.2 -> 91.2 exact
v2 P3 pegged 39 -> 39 exact
v2 W1 live 108 -> 108 exact
v3 State max 87.4 -> 87.4 exact
v3 band shares 73.3/15.0/8.3/3.4 -> 73.0/15.4/8.1/3.4
Three things the harness had to get right to reach that, each of which was
initially wrong and caught by a gate rather than by inspection:
- "W1 live 108" counts NONZERO sessions, not non-null ones. v2's divergence
gate returned 0.0 during any decline (v3 tapers instead), so the retired
divergence formula had to be reconstructed too.
- v2 sliced HY_OAS_REFERENCE_YEARS = 10.0 per session, not v3's 700 days. The
percentile leg ranks against that window, so replaying it short shifted the
middle of the distribution while leaving the max exact.
- The published v2 numbers correspond to FULL OAS coverage. Replaying v2 with
the 400-calendar-day fetch it shipped with yields max 100.0 and 133
credit-less sessions -- so that truncation was not in force when the figures
were taken. Recorded rather than assumed.
The script refuses to emit a band recommendation unless every hard gate passes
(33 symbols fetched, per-symbol warm-up and final bar, full basket on every
session, calendar anchors, 100% coverage, and a row-wise state_v4 <= state_v3
invariant), and exits non-zero. It is meant to be structurally impossible to read
a calibration result out of a run whose pipeline did not validate. No v4 code
ships in this commit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
60 lines
1.2 KiB
Plaintext
60 lines
1.2 KiB
Plaintext
# Python
|
|
__pycache__/
|
|
*.py[cod]
|
|
*.egg-info/
|
|
*.egg
|
|
dist/
|
|
build/
|
|
.venv/
|
|
.env
|
|
|
|
# Hypothesis (PBT)
|
|
.hypothesis/
|
|
|
|
# Pytest
|
|
.pytest_cache/
|
|
|
|
# IDE
|
|
.vscode/
|
|
.idea/
|
|
.claude/settings.local.json
|
|
*.swp
|
|
*.swo
|
|
|
|
# Local AI tool metadata
|
|
mcps/
|
|
|
|
# OS
|
|
.DS_Store
|
|
Thumbs.db
|
|
|
|
# Frontend
|
|
frontend/node_modules/
|
|
frontend/dist/
|
|
frontend/tsconfig.tsbuildinfo
|
|
|
|
# Alembic
|
|
alembic/versions/__pycache__/
|
|
|
|
# Generated SSL bundle
|
|
combined-ca-bundle.pem
|
|
|
|
# Dolt local dev clones. Production keeps clones in DOLT_DATA_DIR OUTSIDE the
|
|
# repo tree (deploy is rsync --delete of the tree); this dir is dev-only.
|
|
dolt-data/
|
|
|
|
# Local research artifacts
|
|
# Backtest reports in reports/ are tracked: they are the evidence behind the
|
|
# production baseline in the README. The snapshot DBs they run against are not.
|
|
backtest_snapshots/
|
|
# Rebuildable pickle caches are local accelerators, not decision evidence.
|
|
reports/*.pkl
|
|
reports/*.pk1
|
|
reports/.cache/
|
|
# Runtime A5 parity bundles are generated on the production server. Research
|
|
# conclusions belong in docs/research, not as an ever-growing artifact archive.
|
|
reports/fundamentals-parity/
|
|
|
|
# Calibration harness raw-pull cache (Alpaca/FRED); regenerable, not a record.
|
|
.calib-cache/
|