How to Build a Football Betting Model | CONSENSUS

How to build a football betting model

A complete, honest path: data collection, fitting attack and defence strengths, building the score matrix, de-vigging the market for comparison, and backtesting without the four biases that make every naive backtest look profitable.

By CONSENSUS Research Published Updated

Building a football betting model is five steps: collect match results and odds, fit team attack and defence strengths, generate a score matrix, project every market from that matrix, and backtest against prices that were actually available. The modelling is the easy part; the backtest is where almost every model that "works" turns out not to.

Step 1 — data

Odds data is the expensive part and the part people skip. A model backtested without real historical prices is not backtested; it is described.

Step 2 — fit attack and defence strengths

The classic specification gives each team an attack parameter and a defence parameter, with a league baseline and a home-advantage term:

λ_home = exp(attack_home + defence_away + home_advantage) λ_away = exp(attack_away + defence_home)

Fit by maximum likelihood on historical scorelines, weighting recent matches more heavily via exponential decay (see Dixon–Coles). Two parameters govern behaviour more than anything else: the decay rate ξ and the low-score correction ρ.

Step 3 — build the score matrix and project markets

Turn the two lambdas into a matrix of scoreline probabilities, apply the Dixon–Coles correction to the four low-score cells, renormalise, and then derive every market by summing the appropriate cells, as set out in the Poisson model.

Do not skip the renormalisation. After applying tau, the matrix no longer sums to 1, and every probability derived from it is off by the same factor.

Step 4 — compare against the market correctly

Your model probability must be compared against a de-vigged market probability, not the raw price. Comparing model probability to raw implied probability manufactures an apparent edge equal to the bookmaker margin: every bet looks bad, and the ones that look least bad are simply the ones with the thinnest margin.

Then apply the settlement-aware EV formula rather than the binary one, because quarter lines and push-capable markets are exactly where naive implementations go wrong. See expected value.

Step 5 — backtest without fooling yourself

This is where models die. Four biases account for nearly every backtest that fails in production:

BiasHow it sneaks inThe fix
Look-aheadUsing data that did not exist at bet time: final line-ups, or a rating fitted on the full seasonStrict time-ordered cut-off per fixture
Closing-price biasBacktesting on closing odds you could not have takenUse the price timestamped before your cut-off
Random train/test splitCross-validation that shuffles matches, letting the model see later resultsSplit by date. Always
Multiple-testingTrying forty parameter sets and reporting the bestHold out a final period never used during development

Then judge it by the right target. Profit on a backtest is the weakest evidence, because it is the most sensitive to all four biases. Beating the de-vigged closing line is the strong signal, and it stabilises with far fewer observations; see closing line value.

What does a realistic result look like?

A competent football model that beats the closing line by one to two percent is doing well. A backtest showing twenty percent ROI has a bug, and the bug is usually one of the four in the table above. The order in which to disbelieve your own results: look-ahead first, then price availability, then sample size, then everything else.

And when it does work, the account gets limited. That is not a modelling problem, but it is a business problem, and it is why the serious literature focuses on closing line value rather than on realised profit.

Check any of this against our record

Every signal CONSENSUS publishes carries the bookmaker odds fixed before the event starts and the settled result afterwards — including the drawdowns and the losing runs. The running total is on the front page and every entry is in the log.

See the running result Open the full log