The repo market forecast, in plain words

What it forecasts, how well it does, and where it falls short. Every figure on this page is generated from the project's published records, and every section links to them.

The question

Banks, dealers and money funds lend each other cash overnight against U.S. Treasury securities. This is the repo market. The rate on that lending is called SOFR. The Federal Reserve also pays banks a rate on the money they keep with it, called IORB. Most days SOFR sits at or just below IORB. On some days spare cash runs short and SOFR jumps above it.

This project forecasts the gap between the two, SOFR minus IORB, for the next business day. The headline forecast is the chance that the gap is more than 5 and more than 10 basis points. A basis point is a hundredth of one percentage point. It uses public data only, and only what was public at 4 pm on the day before the forecast. The public data runs from 2018-04-03 to 2026-09-03.

Where this comes from: metadata/stress_thresholds.json, metadata/funding_panel_manifest.json, and the validation report.

How often it is right about pressure

Each day the model gives a probability that the gap will be above the line. A good probability forecast is neither too bold nor too timid. The usual measure is the Brier score: how far the forecast probability was from what happened, on average, where lower is better. Each result below is a paired difference: on every day, the benchmark's score minus the model's, averaged. A positive number means the model did better. The range after it is the 90% interval, found by resampling the days.

Two benchmarks keep the model honest. The calendar guess uses only how often pressure happens on each type of day (month-end, quarter-end, tax date, ordinary). The “tomorrow looks like today” model looks at today's gap and nothing else.

  • More than +5 bp. This happened on 7.5% of the 1873 days scored (every day up to 2025-12-31). against the calendar guess the model was better (+0.0219, 90% interval +0.0158 to +0.0282); against the “tomorrow looks like today” model the model was better (+0.0068, 90% interval +0.0031 to +0.0107).
  • More than +10 bp. This happened on 3.3% of the 1873 days scored (every day up to 2025-12-31). against the calendar guess the model was better (+0.0039, 90% interval +0.0015 to +0.0065); against the “tomorrow looks like today” model the model was not clearly different (+0.0007, 90% interval -0.0010 to +0.0024).

The gain is not the same everywhere. Against the “tomorrow looks like today” model at +5 bp, the model was better in 6 of 9 groups of days, not clearly different in 2, worse in 1, and 0 had too few days to say.

Show the numbers
Brier-score gain over each benchmark, by how far ahead the forecast looks
How far ahead Above +5 bp, against the calendar guess Above +5 bp, against the “tomorrow looks like today” model Above +10 bp, against the calendar guess Above +10 bp, against the “tomorrow looks like today” model
1 business day ahead+0.0219 (+0.0158 to +0.0282), better+0.0068 (+0.0031 to +0.0107), better+0.0039 (+0.0015 to +0.0065), better+0.0007 (-0.0010 to +0.0024), not clearly different
2 business days ahead+0.0180 (+0.0120 to +0.0247), better+0.0080 (+0.0037 to +0.0125), better+0.0030 (+0.0004 to +0.0056), better+0.0028 (+0.0006 to +0.0053), better
3 business days ahead+0.0166 (+0.0104 to +0.0235), better+0.0103 (+0.0053 to +0.0153), better+0.0024 (-0.0003 to +0.0053), not clearly different+0.0018 (-0.0003 to +0.0040), not clearly different
4 business days ahead+0.0141 (+0.0082 to +0.0206), better+0.0057 (+0.0013 to +0.0105), better+0.0019 (-0.0008 to +0.0047), not clearly different-0.0003 (-0.0022 to +0.0018), not clearly different
5 business days ahead+0.0136 (+0.0075 to +0.0204), better+0.0060 (+0.0011 to +0.0114), better+0.0017 (-0.0009 to +0.0043), not clearly different-0.0003 (-0.0021 to +0.0015), not clearly different
Gain over the “tomorrow looks like today” model at +5 bp, by market period and type of day
Group of days Days Gain Interval Verdict
Market period: 2018-19375+0.0292+0.0133 to +0.0463better
Market period: 2020251+0.0093+0.0051 to +0.0146better
Market period: 2021-23748-0.0003-0.0004 to -0.0002worse
Market period: 2024250+0.0012+0.0000 to +0.0028better
Market period: 2025-26249-0.0027-0.0136 to +0.0075not clearly different
Type of day: month end158+0.0115+0.0023 to +0.0226better
Type of day: ordinary1595+0.0052+0.0015 to +0.0093better
Type of day: quarter end31+0.0318+0.0028 to +0.0646better
Type of day: tax date89+0.0179-0.0004 to +0.0390not clearly different

Where this comes from: pressure_model_v1_h1.json, pressure_model_v1_h2.json, pressure_model_v1_h3.json, pressure_model_v1_h4.json, pressure_model_v1_h5.json, the validation report.

The forecast range for tomorrow

The model also forecasts the whole range of where the gap could land, not just one number. This is the five-quantile score: it measures how far off the forecast range was, and lower is better. The benchmark is as-of persistence, which says tomorrow will look like the latest gap already public.

  • Earlier years. From 2018-06-29 to 2025-12-31 (1873 forecasts) the model's score was 1.66 bp and persistence's was 2.09 bp. The gap is +0.43 bp, 90% interval +0.19 to +0.74 bp, so the model was better.
  • The final test, January to September 2026. Over 169 scored days the model's score was 1.66 bp and persistence's was 1.83 bp. The gap's 90% interval, +0.03 to +0.36 bp, lies above zero, so the model was better. A few days drive the mean, and 2026 was a calm year.

The final test was set up before it was run and run once, on days the model had not been tuned on by name. Those days had appeared inside earlier pooled results, so it is called near-blind, not blind. The first fully blind confirmation will come from the live daily record.

Show the numbers
Final test: persistence's score minus the model's, by type of day (positive favours the model)
Group of days Days Gain, bp Interval, bp
Type of day: month end14-0.125-0.262 to +0.024
Type of day: ordinary147+0.152-0.006 to +0.360
Type of day: quarter end2none
Type of day: tax date6none

Where this comes from: compare_persistence_vs_gbm_conformal_pid_nested_funding_crps.json, final_test_near_blind.json, the final-test page, the validation report.

What a month-end does to the average

Month-end, quarter-end and year-end "turns" are the days when the rate tends to jump. Funds and lenders watch the average of the rate over a month, and one jump day counts for as many calendar days as it stays in force. The model therefore reports, for a scheduled pressure day, how much that day's forecast adds to the period average.

It is worked out as follows. The forecast mean is the mean of the piecewise-linear quantile function through the grid's points, held flat beyond the outer levels. That mean is multiplied by the calendar days the day carries and divided by the calendar days in the period: the day's calendar month, weighted by calendar day as SOFR averages are computed: a weekend or holiday (market holiday table) carries the previous business day's rate; carried days in the next month count in that month's average.

Status of this output: not yet calibrated (#243): computed from the uncalibrated interior quantiles. At two to five business days ahead, at h = 2 to 5 the q25, q50 and q75 are the one-step gbm served stale, identical across horizons; only the PID outer pair (q05, q95) differs.

Where this comes from: scripts/desk_outputs.py, docs/decisions/pressure-probability.md, the validation report.

How scarce cash is

Pressure is more likely when bank reserves, the cash banks keep at the Fed, are scarce. The model therefore shows a scarcity state beside each forecast: one of abundant, ample, tight, scarce. It is a label for what is happening now. It is not an input to the forecast, and it is not itself a forecast.

The label is set by two cut-points. Reserves count as ample or tight depending on where they stand as a share of all commercial-bank assets: 12% to 13% is the band where banks stop treating reserves as abundant. And the Fed's overnight reverse repo facility is a buffer only while it holds more than $100 billion; below that it no longer absorbs a drain on reserves. Both cut-points were chosen from the literature and from the same history they are checked on, so they describe the market and have not been proven in a separate test.

Where this comes from: src/repo_model/scarcity.py, scripts/desk_outputs.py, the validation report.

What the data show about the repo market

These are three things about the repo market itself, not about the forecasting model. The market lends cash overnight against Treasury securities. SOFR is the rate on that borrowing. IORB is the interest the Fed pays banks on the cash they hold with it. The gap is SOFR minus IORB, counted in basis points (a hundredth of a percentage point). Pressure is a gap more than 5 basis points above zero. This is development evidence: a description of what happened, not a forecast and not a verdict on any model.

1. Stress lives on the turn, not on month-end in general

The turn is the last business day of a month and the first business day of the next. In 2018-19 the gap averaged +11.5 basis points on the last business day and +4.0 on the first business day after it. On the second-last business day it averaged +0.3, the same as on an ordinary day in the middle of a month (+1.7). The days before the turn are ordinary; the turn carries the pressure. The latest period, 2025-26, has the same shape, smaller: +3.5 on the last business day, +2.1 on the first and -0.5 on the second-last.

Average gap in basis points, by market period and type of day (days counted in brackets; months that end a quarter are left out)
Market periodLast business day of the monthFirst business day of the next monthSecond-last business dayOrdinary mid-month day
2018-19+11.5 (14 days)+4.0 (14 days)+0.3 (14 days)+1.7 (139 days)
2020-1.6 (8 days)-1.9 (8 days)-2.9 (8 days)-0.7 (77 days)
2021-23-9.2 (24 days)-8.8 (24 days)-9.7 (24 days)-9.7 (233 days)
2024-5.5 (8 days)-5.8 (8 days)-8.0 (8 days)-7.7 (78 days)
2025-26+3.5 (14 days)+2.1 (14 days)-0.5 (14 days)-3.8 (133 days)

2. The calendar sets the date; reserve scarcity sets the size

The same month-end added about +5.8 basis points to the gap in 2018-19, +0.3 in 2021-23 and +4.3 in 2025-26. A coupon settlement, the day the Treasury is paid for newly auctioned notes and bonds, which draws cash out of the market, added +8.5, +0.5 and +3.8 in the same three periods. The calendar tells you which days to watch. How much a date adds follows how scarce reserves (the cash banks hold at the Fed) are. That second half is the project's reading of the pattern; the table shows the sizes, not the cause.

Added to the gap on that kind of day, in basis points, with the 90% interval (state-scaled calendar model)
Market periodMonth-endCoupon settlement
2018-19+5.8 [+4.4, +7.2]+8.5 [+7.2, +9.8]
2020+2.2 [+1.3, +3.0]+2.5 [+1.7, +3.4]
2021-23+0.3 [+0.1, +0.5]+0.5 [+0.3, +0.7]
2024+1.8 [+1.3, +2.2]+1.5 [+1.0, +2.0]
2025-26+4.3 [+3.5, +5.0]+3.8 [+2.8, +4.9]

3. Stress episodes begin on known calendar dates

A stress episode starts on a day the gap is above 5 basis points after more than 10 business days without one. Since 2020-04-01 there have been 6. Of those, 5 began on or within a business day of a known calendar date: a month-end or quarter-end turn, a mid-month Treasury settlement or a tax date. For scale, 37% of all business days in that period sit on or next to such a date. The episodes all began in 2024 to 2026.

Stress episodes since 2020-04-01
StartGap, basis pointsKnown date on or next to it
2024-09-30+6.0quarter-end
2024-12-26+13.0none
2025-09-15+11.0tax date, mid-month settlement
2025-09-30+9.0quarter-end
2026-02-17+6.0mid-month settlement
2026-04-15+7.0tax date, mid-month settlement

Where this comes from: docs/research/market-findings-1177/result.json, docs/research/state-calendar-1145/result.json, the study page, the validation report.

Where it falls short

This is a research forecast of next-day overnight borrowing costs, not a warning system or a tool for managing risk. It has been tested mostly in calm conditions, so it needs re-checking if the market changes sharply.

  • Few severe days. Of the 169 days of the final test, 5 were above +5 bp and 0 above +10 bp. Such days are rare, so the evidence about them is thin.
  • The test above +10 bp is weak. On the earlier years the model's gain over the “tomorrow looks like today” model at +10 bp has a 90% interval of -0.0010 to +0.0024, so it was not clearly different. Against the calendar guess it was better.
  • Days that are locked. Some days are kept sealed so that no result can be tuned on them. A comparison scores only days before 2026-01-01. The older pooled distribution tables scored days through 2026-09-03 (the near-blind period); the results published since score only days before 2026-01-01.
The statement of record

A research forecast of the SOFR − IORB spread. It is not a stress-warning system and not a basis for VaR, limits, liquidity or capital, or desk sizing. Its central quantiles are not yet calibrated, its tail coverage is weaker on quarter-ends and turns, and it has little history in the current scarce-reserve regime. It needs revalidation after a material policy or regime change.

Where this comes from: pressure_model_v1_h1.json, final_test_near_blind.json, docs/use-limitation.md, metadata/lockbox.json, the lockbox rule, the validation report.

Where this sits among other work

To our knowledge, no public work forecasts the daily SOFR − IORB spread with strictly point-in-time public data and scores its exceedance probabilities with proper scoring rules against persistence baselines. Related efforts include Fed staff probability assessments for the fed funds − IOER spread (FOMC memo, 13 Sep 2019), a daily SOFR LSTM thesis scored by RMSE (Cornelissen, 2021), and futures-implied month-end premia, which tend to over-anticipate spikes (Gellert & Schlögl, 2021).

nicholasberoud/repo-market-model is a fork by Eleonora's collaborator, Nicholas Beroud. A reader who finds that repository with the same figures has found a copy of this project, not an independent replication.

Futures are left out, both as a benchmark and as an input. CME futures data needs a licence and cannot be redistributed with this repository, and futures-implied month-end premia are documented to over-anticipate spikes (Gellert and Schlögl, 2021; CME's March 2019 example).

Where this comes from: docs/model/external_sources.json, and the validation report.