Regime Monitor
US market · as of 2026-09-18
Bitmask: 1 narrow (an uptrend carried by three sectors or fewer), 2 credit-stress (HY OAS at its 3y 90th percentile), 4 correlated (sector correlation at its 3y 90th). 0 is none; NULL when the label is unknown. A CODE, NOT A STATISTIC.
The nine axes
The readings worker/app/core/regime.py labels from, in its own order, each against its own three years, or its whole history where that is shorter (window all (<3y)). They are collected whether or not the label is: this table is the same whether the strip above says a regime or says pending. Their dates differ — the Cboe pair, ICE's spread and the Fed's reserves are knowable a session late, the other five the evening of their own session — which is why each row carries one and no single date sits above the table.
| trend | px_vs_200dma | SPY | 6.91% | 2026-09-18 | 3y | 29.5% | 752 |
| realized_vol | realized_vol_21d | SPY | 9.4% | 2026-09-18 | 3y | 17.6% | 752 |
| vix | vix | US | 15.4400 | 2026-09-17 | 3y | 35.3% | 774 |
| vix_term | vix_term_ratio | US | 0.8323 | 2026-09-17 | 3y | 13.8% | 752 |
| breadth | sector_breadth_200dma | US | 50.0% | 2026-09-18 | 3y | 7.8% | 752 |
| correlation | sector_corr_63d | US | 0.0492 | 2026-09-18 | 3y | 2.9% | 752 |
| dispersion | sector_dispersion_21d | US | 3.72% | 2026-09-18 | 3y | 50.6% | 752 |
| credit | hy_oas | US | 2.7000 | 2026-09-17 | 3y | 10.6% | 787 |
| liquidity | reserves | US | $3,013,794m | 2026-09-16 | 3y | 21.3% | 157 |
core.metric_context() for the nine (metric, entity) pairs in one statement. hy_oas is ICE BofA through FRED and the Cboe pair is Cboe: neither is exportable, so this page offers no CSV.
Timeline
100 spells over the window, 37 of them a single session — that count is the statement's own, not a filter over the rows. A one-session interruption ends a spell and starts another, so the thin bands are real and are drawn at their true width. The label of each band is the one today's rule gives that day's point-in-time axes — see the note below.
| uptrend, calm | 2026-07-31 | 2026-09-18 | 35 |
| uptrend, stressed | 2026-07-30 | 2026-07-30 | 1 |
| uptrend, calm | 2026-06-25 | 2026-07-29 | 24 |
| uptrend, stressed | 2026-06-24 | 2026-06-24 | 1 |
| uptrend, calm | 2026-06-15 | 2026-06-23 | 6 |
| uptrend, stressed | 2026-06-10 | 2026-06-12 | 3 |
| uptrend, calm | 2026-06-09 | 2026-06-09 | 1 |
| uptrend, stressed | 2026-06-08 | 2026-06-08 | 1 |
| uptrend, calm | 2026-04-23 | 2026-06-05 | 31 |
| uptrend, stressed | 2026-04-22 | 2026-04-22 | 1 |
| uptrend, calm | 2026-04-13 | 2026-04-21 | 7 |
| uptrend, stressed | 2026-04-08 | 2026-04-10 | 3 |
| downtrend, stressed | 2026-03-20 | 2026-04-07 | 12 |
| uptrend, stressed | 2026-03-02 | 2026-03-19 | 14 |
| uptrend, calm | 2026-02-26 | 2026-02-27 | 2 |
| uptrend, stressed | 2026-02-24 | 2026-02-25 | 2 |
| uptrend, calm | 2026-02-23 | 2026-02-23 | 1 |
| uptrend, stressed | 2026-02-13 | 2026-02-20 | 5 |
| uptrend, calm | 2026-02-09 | 2026-02-12 | 4 |
| uptrend, stressed | 2026-02-06 | 2026-02-06 | 1 |
| uptrend, calm | 2026-01-22 | 2026-02-05 | 11 |
| uptrend, stressed | 2026-01-21 | 2026-01-21 | 1 |
| uptrend, calm | 2025-11-26 | 2026-01-20 | 36 |
Every materialiser run recomputes regime_code over the whole history, so a past spell carries TODAY'S thresholds applied to that day's readings - not the label anyone saw at the time. Relabelling re-derives every historical statistic on this page with it.
What followed each prior occurrence
SPY's forward 20-session return from the first session of every earlier spell of uptrend, calm, from every session carrying that label, and from every labelled session as the baseline. The current spell began 2026-07-31 and has run 35 sessions. A label that flickers produces many occurrences a few sessions apart whose windows overlap, which is what the non-overlapping count exists to say.
| condition | dates | windows | p25 | median | p75 | up | span |
|---|---|---|---|---|---|---|---|
the first session of each prior spell each prior occurrence | 65 | 37 | -1.5% | +2.1% | +3.4% | 65% | 2016-09-01 2026-06-25 |
every session carrying this label uptrend, calm | 1,813 | 105 | -0.5% | +1.7% | +3.2% | 71% | 2016-09-01 2026-08-20 |
every labelled session the baseline | 2,505 | 126 | -0.7% | +1.8% | +3.7% | 70% | 2016-09-01 2026-08-20 |
| 2026-07-31 | 2026-09-18 | 35 | +3.0% |
| 2026-06-25 | 2026-07-29 | 24 | +0.6% |
| 2026-06-15 | 2026-06-23 | 6 | +0.3% |
| 2026-06-09 | 2026-06-09 | 1 | +2.3% |
| 2026-04-23 | 2026-06-05 | 31 | +4.8% |
| 2026-04-13 | 2026-04-21 | 7 | +7.8% |
| 2026-02-26 | 2026-02-27 | 2 | -6.2% |
| 2026-02-23 | 2026-02-23 | 1 | -3.7% |
| 2026-02-09 | 2026-02-12 | 4 | -2.4% |
| 2026-01-22 | 2026-02-05 | 11 | +0.1% |
| 2025-11-26 | 2026-01-20 | 36 | +1.9% |
| 2025-10-21 | 2025-11-17 | 20 | -1.7% |
| 2025-10-14 | 2025-10-14 | 1 | +3.1% |
| 2025-05-12 | 2025-10-10 | 106 | +3.4% |
| 2025-03-24 | 2025-03-25 | 2 | -8.2% |
| 2024-12-20 | 2025-03-03 | 47 | +3.1% |
| 2024-11-07 | 2024-12-18 | 29 | +2.0% |
| 2024-11-04 | 2024-11-04 | 1 | +6.0% |
| 2024-10-09 | 2024-10-31 | 17 | +2.4% |
| 2024-08-09 | 2024-10-07 | 41 | +2.5% |
| 2023-11-01 | 2024-08-02 | 189 | +8.0% |
| 2023-03-16 | 2023-10-24 | 154 | +4.5% |
| 2023-03-14 | 2023-03-14 | 1 | +4.6% |
Liquidity
DESIGN's liquidity panel is five legs — reserves, TGA, RRP, SOFR−EFFR and dealer positions. Four of them are metrics: reserve balances, which is also the "liquidity" axis in the table above, and tga, rrp and sofr_effr_spread_bp, which the worker added once its ALFRED pulls were windowed for series too long to fetch in one request. All four carry a reading below, each with its own value date. The fifth, primary dealer positions, is not collected at all: no collector reads the NY Fed's series and no table in this warehouse holds it. It is named below rather than drawn, because an empty frame says something this warehouse does not know.
| Reserve balances at the Fed | reserves | $3,013,794m | 2026-09-16 | 3y | 21.3% | 157 |
| Treasury General Account | tga | $877,028m | 2026-09-16 | 3y | 82.5% | 157 |
| Overnight reverse repo | rrp | $0.3bn | 2026-09-17 | 3y | 2.9% | 748 |
| SOFR minus EFFR | sofr_effr_spread_bp | -1.0 bp | 2026-09-16 | 3y | 36.4% | 747 |
- Primary dealer positions· not collected — no collector reads the NY Fed's series and no table in this warehouse holds it
All four legs come from FRED first-published vintages - WRESBAL, WTREGEN, RRPONTSYD, and SOFR minus EFFR - knowable a session late and registered exportable, though this page builds no CSV link. Their units differ because the registry registered them differently: millions, millions, billions, basis points. No net-liquidity composite is drawn: WALCL is not a registered metric, and DATA_SOURCES.md:134 refuses a composite with a term missing.
Yield curve
Two spreads, not a curve, and deliberately: core.fred_observations holds the constant-maturity yields, but an unregistered FRED series has no knowable lag, no n_min and no core.metric_context() row, so nothing here reads one directly. What is registered is the two differences the worker derives — curve_10y_2y and curve_10y_3m — and those are drawn, dated, with their own-history percentiles and nothing implied between them. Negative is an inverted curve, which is curve_10y_2y's own registered description and not a threshold this page chose. 10-year minus 2-year +0.27 pp on 2026-09-16 and 10-year minus 3-month +0.87 pp on 2026-09-16.
| 10-year minus 2-year | curve_10y_2y | +0.27 pp | 2026-09-16 | 3y | 45.2% | 748 |
| 10-year minus 3-month | curve_10y_3m | +0.87 pp | 2026-09-16 | 3y | 98.1% | 748 |
FRED DGS10 minus DGS2 and DGS10 minus DGS3MO, first-published vintages, knowable a session late. Both are registered exportable; this page builds no CSV link.
Not yet built
One of DESIGN's five parts for this page has no module at all yet. It is listed here so the page states its own coverage: nothing above is standing in for it.
- Risk-appetite composite, scored across 8 assets· no module computes this
The label and its flags are worker/app/core/regime.py's, stored as the codes regime_code and regime_flags. Neither is a statistic, so neither carries a percentile here or anywhere. web/src/lib/regime.ts mirrors the axis table and the code and flag names; its test reads the Python and fails if the mirror drifts.
The n beside every percentile on this page — in the headers, the axis table and the leg tables — is core.metric_context()'s n_3y: the readings in the three years that percentile is ranked against, not the metric's whole history. The headers and the tables' window column take their window from windowPercentile() in src/lib/metrics.ts, and a window reading “all (<3y)” is a metric whose every reading on record lies inside those three years, so there are not three years of it.
Forward returns use core.prices_asof for SPY on the as-of date's adjustment basis. Overlapping 20-session windows are de-overlapped before counting, and the floor of 20 non-overlapping windows is applied to that smaller count.