How the model works
Every number on this site comes from one statistical model and is checked against its own record in public. This page explains both — the method, and the way we hold ourselves to it.
The model
Forecasts come from a hierarchical Bayesian goals model. Each team carries a latent attacking and defensive strength that moves over time as a random walk, so form is a parameter that drifts with results rather than a rolling average of the last few games. League-level priors let promoted and thin-history teams borrow strength from their division instead of needing a full season of their own data to be estimated at all. Home advantage is pooled by league.
Goals are modelled with a Negative-Binomial likelihood — they are slightly more variable than a simple Poisson allows — fit on expected goals where we have them and on goals alone where we do not. A Dixon–Coles low-score correction (Dixon & Coles, 1997) is applied to the fitted scoreline matrix, the standard adjustment for the way 0–0, 1–0 and 1–1 occur slightly more often than independence would predict. From that scoreline matrix every market on the page is a sum: the match result is the cells either side of the diagonal, over 2.5 is every cell totalling three or more, and so on.
How it is fit
The model is fit by MCMC sampling over several seasons of results, and refit as new matches arrive so the strengths stay current. Every point estimate is published with an 80% interval calibrated by conformal prediction — a range wide enough that the true value falls inside it about four times in five, measured against held-out matches rather than asserted. A point estimate without its interval would overstate how much the model knows, so we do not show one.
The market, next to us
We show the bookmakers' consensus beside our own number, with the bookmaker margin removed so the two are comparable as probabilities. We do this because a forecast is only interesting relative to the price you would actually be offered; a large gap between our number and the market's means we disagree with the price, not that we are right. Whether we have been right is a separate question, answered on the accuracy page.
How we score ourselves
Two public pages hold the model to account, and both are linked from every briefing:
- Accuracy publishes the model's calibration — what we said against what actually happened — across tens of thousands of held-out matches, together with our performance versus the closing market price on the forecasts we published. It is shown unedited, whether a market passes our calibration gates or fails them.
- The forecast ledger is an append-only, hash-chained record of every forecast we have published. Because each entry seals the one before it, a forecast cannot be quietly revised after the result is known — the record would not verify. It is the evidence for the claim that we do not move the goalposts.
When we tell you not to bet
Most matches end with no recommendation. A price only becomes a recommendation when our forecast clears a bar set well inside our own uncertainty, and on most days nothing does. A tool that found a bet in every fixture would not be worth reading. We recommend; we never guarantee — and we say plainly, and often, when the honest answer is to skip.
We take no bets, place no bets, link to no bookmakers, and earn no affiliate revenue. The model runs on a schedule and writes its results to our own store; nothing you do on this site is priced by, or sent to, a betting company.