FOMC · reaction function
Ordered logit on 36 years of decisions · point-in-time data · walk-forward scored
Frozen snapshot. The engine does not run on this host. These are the numbers cli.py produced on 10/18/2026, 5:15:31 PM, not a live read.
Incoming data since then is not in this page, and the futures read below is that day's pricing, not today's.
Next meeting 2026-10-28
10 days awayheadline · fed funds futures
hold 84.0%
14 days out, the futures strip called direction on 88.4% of 164 meetings against the model's 86.6% (3 more right).
The two disagree: the model says hike, the market prices hold.
model
Read the probability, not the argmax. The expected move is the distribution's mean in basis points, not a prediction that the Fed will move by that amount — the Committee only chooses in 25bp steps.
fed funds futures · headline
CME ZQ strip through the FedWatch arithmetic, the same number the scorecard grades. Options (Atlanta Fed) put P(hike) at 93.0% and P(cut) at 2.1%, but over the nearest option window, not this meeting.
| days out | n | model | market | moves m / mkt | false alarm m / mkt |
|---|---|---|---|---|---|
| 1 | 196 | 84.7% | 90.8% | 64.6% / 83.1% | 5.3% / 5.3% |
| 7 | 187 | 84.0% | 95.7% | 62.3% / 95.1% | 5.6% / 4.0% |
| 14 ← now | 164 | 86.6% | 88.4% | 62.0% / 86.0% | 2.6% / 10.5% |
| 21 | 132 | 84.8% | 87.1% | 57.9% / 81.6% | 4.3% / 10.6% |
| 28 | 130 | 85.4% | 86.2% | 55.6% / 91.7% | 3.2% / 16.0% |
| 42 | 67 | 83.6% | 83.6% | 50.0% / 77.8% | 4.1% / 14.3% |
CME watch — the priced path
walk-forward record
233 meetings, 1997-08-19 → 2026-09-16. Refit at every step on prior meetings only — scaler, imputation medians, cutpoints and coefficients, so no fit ever saw its own test row. Headline accuracy is meaningless on its own: the Fed held 68.7% of these meetings, so that is the floor, not the bar. Every figure below is read straight out of the engine's scorecard — this page does not recompute any of it.
| direction called by | scored on | all meetings | when it moved | false alarms on holds |
|---|---|---|---|---|
| this model | 233 | 84.5% | 65.8% | 6.9% |
| always say hold | 233 | 68.7% | 0.0% | 0.0% |
| repeat the last action | 233 | 79.0% | 65.8% | 15.0% |
| market-implied (1y - funds proxy) | 233 | 66.1% | 91.8%best | 45.6% |
| market-implied (fed funds futures) | 196 | 90.8%best | 83.1% | 5.3% |
| model edge vs. best baseline | −6.3pp | −26.0pp | read across, not down |
The "when it moved" column is recall and the column beside it is what that recall cost. A caller can buy the first with the second, which is exactly what the 1y-minus-funds proxy does. Coverage differs by row: the fed funds futures strip cannot price every meeting, and those meetings are left out of its denominator rather than scored against the Treasury proxy under its name. On the 196 meetings it does reach, every caller scores this model: 64.6% / 5.3% · always say hold: 0.0% / 0.0% · repeat the last action: 66.2% / 11.5% · market-implied (1y - funds proxy): 90.8% / 45.8% · market-implied (fed funds futures): 83.1% / 5.3% (moves / false alarms).
calibration — is the distribution trustworthy?
Read this before any single forecast. Each point is a bucket of meetings the model assigned a similar P(move); the diagonal is perfect calibration. A point above the line means the Fed moved more often than the model said, below means it moved less. Scored walk-forward over 233 meetings.
| model said | n | predicted | happened | gap |
|---|---|---|---|---|
| 0-20% | 141 | 7.3% | 8.5% | +1.2pp |
| 20-40% | 21 | 28.3% | 28.6% | +0.3pp |
| 40-60% | 20 | 51.2% | 60.0% | +8.8pp |
| 60-80% | 12 | 71.0% | 66.7% | −4.3pp |
| 80-100% | 39 | 92.9% | 89.7% | −3.1pp |
Buckets are the engine's own, from models/backtest.json. A bucket holding a handful of meetings is noise — read n before reading its gap.
conditional path — pressure already in the data
what is driving this meeting
Exact arithmetic, not an approximation: each contribution is βj · zj, the fitted coefficient times the standardised feature value, in latent policy-pressure units. They sum to the latent score the cutpoints are applied to, so this decomposition IS the forecast rather than a story told about it.
pushing toward tightening
| feature | value | β·z |
|---|---|---|
| mkt_3m | 0.36 | +1.17 |
| ff_p_cut | 0.02 | +0.85 |
| mkt_1y | 0.59 | +0.74 |
| mortgage_chg_6m | 0.86 | +0.73 |
| last_dir | 1.00 | +0.73 |
| breakeven_5y | 2.35 | +0.64 |
pushing toward easing
| feature | value | β·z |
|---|---|---|
| sentiment | 51.70 | −0.46 |
| vacancy_ratio | 1.00 | −0.35 |
| ff_p_hike | 0.93 | −0.33 |
| months_supply | 8.50 | −0.30 |
| months_since_move | 1.28 | −0.19 |
| hpi_yoy | 1.87 | −0.12 |
the fitted reaction function
One signed coefficient per feature, biggest first — the thing a desk would actually argue with. The latent is policy pressure, so a positive β means a higher value of that feature pushes toward tightening. These are L2-penalised and fitted on standardised columns, so they are comparable to each other in size but are not elasticities, and a feature correlated with three others will have its weight split across them.
- ff_exp_move_bp+1.412
- mkt_3m+0.794
- breakeven_5y+0.789
- mkt_1y+0.765
- chg_12m+0.712
- mkt_2y+0.674
- last_dir+0.565
- credit_chg−0.520
- mortgage_chg_6m+0.474
- newsales_yoy−0.462
- vacancy_ratio−0.411
- ff_p_cut−0.368
- nfci+0.339
- months_since_move+0.330
- slope_10y2y−0.321
- claims_yoy+0.301
- hpi_yoy+0.282
- level−0.249
recent decisions
| 2026-09-16 | +25bp | hike25 | 3.75% → 4.00% | |
| 2026-07-29 | 0bp | hold | 3.75% → 3.75% | |
| 2026-06-17 | 0bp | hold | 3.75% → 3.75% | |
| 2026-04-29 | 0bp | hold | 3.75% → 3.75% | |
| 2026-03-18 | 0bp | hold | 3.75% → 3.75% | |
| 2026-01-28 | 0bp | hold | 3.75% → 3.75% | |
| 2025-12-10 | -25bp | cut25 | 4.00% → 3.75% | |
| 2025-10-29 | -25bp | cut25 | 4.25% → 4.00% | |
| 2025-09-17 | -25bp | cut25 | 4.50% → 4.25% | |
| 2025-07-30 | 0bp | hold | 4.50% → 4.50% | |
| 2025-06-18 | 0bp | hold | 4.50% → 4.50% | |
| 2025-05-07 | 0bp | hold | 4.50% → 4.50% | |
| 2025-03-19 | 0bp | hold | 4.50% → 4.50% | |
| 2025-01-29 | 0bp | hold | 4.50% → 4.50% |