This implementation
A minimal Tier 1 build of the framework described in the research brief. 20 indicators, two panels, all sources free and key-less.
- Macro panel (10): 10y–2y curve, real 10y, 5y breakeven, HY OAS, DXY, initial jobless claims, VIX, copper/gold, S&P 50d/200d trend, IWM/SPY breadth — sources: FRED & Yahoo.
- On-chain panel (10): total DeFi TVL (level + 90d growth), total stablecoin float (level + 90d growth), BTC active addresses, ETH active addresses, BTC MVRV, BTC/ETH ratio, ETH 50d/200d trend, new DEX pools per 24h — sources: DefiLlama, blockchain.com, Coinmetrics community, Yahoo, GeckoTerminal. The last four are crypto market-/firehose-level signals rather than strictly on-chain metrics; included here as crypto risk-regime proxies. The two 90d-growth indicators sit alongside their level versions because position (level) and flow (growth) answer different questions. New DEX pools is an accumulate-forward indicator (GeckoTerminal exposes only the live firehose, not history), so it enters the composite once ~60 days of daily samples are persisted. Spot BTC/ETH ETF flow and SOL active addresses were prototyped via Farside and Coinmetrics community but dropped after upstream APIs added auth/IP restrictions; SoSoValue is a viable free replacement for ETF flows when re-added.
- Normalization: rolling 3-year percentile rank per indicator, sign-aligned so +1 always means risk-on.
- Within-panel weighting: inverse-correlation. Each indicator’s weight is inversely proportional to its mean absolute correlation with the rest of its panel — redundant inputs (e.g. correlated rate series) get auto-discounted without manual sub-grouping.
- Cross-panel: 50/50 average → top-line composite ∈ [0, 1].
- Bucketing: 3y rolling percentile of the composite — <33 risk-off, >67 risk-on, otherwise neutral.
- Smoothing: the published regime label requires 5 consecutive trading days in the new bucket before switching, OR a single-day move in composite percentile exceeding 2σ of its trailing 1y daily-change distribution (with direction consistent with the new bucket). Filters out boundary-noise flips while still responding quickly to legitimate fast regime shifts.
- Storage: long-format CSV (atomic write) committed daily to git; current snapshot in
public/data/regime-snapshot.json. No database.
Note on regime smoothing
A naive bucket-by-percentile rule (flip the day the composite crosses 0.33 or 0.67) is hypersensitive to noise: data revisions on a handful of recent days cascade through the inverse-correlation panel weights and can flip historical regime labels by 0.001–0.005 in percentile space — enough to cross a hard threshold but well below any meaningful signal. We observed exactly this in production: 8 historical days reclassified between two consecutive cron runs from a single DefiLlama TVL revision. The smoothing rule above (5-day confirmation + 2σ fast-track override) suppresses those single-day flickers while preserving fast response to genuine regime shifts.
The 5-day window sits at the middle of the published convention for daily-frequency regime-switching models: trend-following systems and volatility-regime literature commonly use 3–7 consecutive closes as a confirmation rule (longer windows kill more false positives at the cost of detection lag). The 2σ fast-track is the standard circuit-breaker overlay — calibrated to fire on roughly the top 5% of daily moves (about 12 events per year), which historically matches the cadence of legitimate fast regime shifts like the COVID March 2020 cascade or the August 2024 VIX spike. Both knobs are set from the data’s own noise distribution rather than tuned against backtest CAGR, to avoid p-hacking. See Hamilton (2005) on regime-switching, the BIS bulletin on the August 2024 VIX spike for fast-regime context, and the trend-following whipsaw literature (N-day confirmation filters) for the calibration ranges.
For the full prior-art survey, alternative methods, and design-space mapping behind this build, see the Regime Detection research brief.