Match model — probabilities and prices

How this works · generated 2026-08-20 06:23 UTC
Model output, not advice. These are probabilities from a statistical model, published for transparency about how it performs. They are not tips and not financial advice. In backtests this model does not reliably beat closing prices, which is the only benchmark that matters, so expect selections here to lose money over time. 18+. Gambling is addictive; if it stops being a modelling exercise, stop.

Competition codes

Short codes are used throughout because they keep the tables narrow. Hover any of them for the full name; the whole list is here for anything without a mouse.

CodeCompetitionWhere
AUT1Austrian BundesligaAustria
BEL1Belgian Pro LeagueBelgium
BRA1Brasileirão Série ABrazil
DEN1SuperligaDenmark
E0Premier LeagueEngland
E1ChampionshipEngland
EFLEFL CupEngland
F1Ligue 1France
GRE1Super LeagueGreece
I1Serie AItaly
J1J1 LeagueJapan
MLSMajor League SoccerUSA & Canada
MTN8MTN8South Africa
N1EredivisieNetherlands
N2Eerste DivisieNetherlands
P1Primeira LigaPortugal
P2Liga Portugal 2Portugal
PSLPremier DivisionSouth Africa
SA1First DivisionSouth Africa
SC0PremiershipScotland
SP1La LigaSpain
SP2Segunda DivisiónSpain
SUI1Super LeagueSwitzerland
SWE1AllsvenskanSweden
TUR1Süper LigTurkey
TUR21. LigTurkey
UCLUEFA Champions LeagueEurope
UECLUEFA Europa Conference LeagueEurope
UELUEFA Europa LeagueEurope

How the numbers are produced

A time-weighted Dixon-Coles bivariate Poisson model estimates each team's attack and defence strength from goals, and a second copy of the same model is fit on expected goals rather than goals. A gradient-boosted classifier adds form, rest and congestion effects. The three are blended with weights chosen on out-of-sample folds and the result is temperature-calibrated.

Every market on a match card — result, totals, both teams to score, clean sheets, correct score, and every combination — is a sum over the same joint scoreline distribution. That is why the numbers agree with each other: Over 2.5 and Under 2.5 sum to exactly 1, and a double chance equals the sum of its parts. Sites that model each market separately routinely publish boards that quietly contradict themselves.

Why goal markets are shown separately

Over/under and both-teams-to-score are listed apart from the match winner because they are a different question. They do not care who wins — they are driven by the total-goals distribution rather than by the difference between the two sides — and a goal model is being asked the thing it was actually built to answer, rather than having its output collapsed onto a three-way result.

They are also calibrated separately. The 1X2 row is temperature-scaled on out-of-fold predictions; the goal markets were not, and read straight off the scoreline matrix they are overconfident at both tails — confident predictions too confident in either direction, while the average looks unbiased. That is the worst possible shape of error for a table sorted by expected value, since sorting by EV is precisely a search for the tails. One temperature per market group, fit out of fold, shrinks them back toward the base rate. Complements are recomputed rather than scaled independently, so Over 2.5 and Under 2.5 still sum to exactly one.

Calibration cannot manufacture skill. Where a market turns out to be no better than its own base rate, shrinking simply makes the model say so — and the figure quoted above each table is that comparison, measured out of fold during training.

One inconsistency worth naming: same-match combinations are still computed from the raw joint distribution, so a combination involving a totals leg can disagree very slightly with the calibrated number on the card. They are shown to illustrate correlation rather than as priced selections, and recalibrating a joint distribution while preserving all its margins is a materially harder problem than scaling one number.

Each pair is de-vigged on its own rather than inheriting the match-winner overround. Books charge more margin on goals markets than on the 1X2 line, so borrowing the 1X2 margin would flatter every totals row. Only the side the model prefers is listed: the two sides of a two-way line are near mirror images, so showing both would double the table without adding information.

Why combinations are priced the way they are

Two selections in the same match are correlated. A home win and over 2.5 goals tend to occur together, because the home team scoring is what drives both. Multiplying the two probabilities understates the true chance — often by 15–60%. Because the joint distribution is available, no independence assumption is needed: the combination is simply the sum of the cells satisfying both conditions.

Selections in different matches genuinely are independent, so those probabilities do multiply. So does the margin, which is the problem with accumulators and the reason each one is shown with its compounding cost.

How it is tested

Walk-forward only: train on the past, predict the next block, step forward. Prices are closing odds where available, because beating the closing line is the only benchmark that means anything. The model's log loss is reported against that line on every backtest, and the engine refuses to endorse a profitable-looking run that fails the test.

ModelValue
trained_at2026-08-20T06:02:30.827102+00:00
n_matches65179
n_teams1151
date_from2019-02-22
date_to2026-06-20
val_log_loss1.0072
val_log_loss_market0.9702
blend{'dixon_coles': 0.392, 'dixon_coles_xg': 0.0, 'gbm': 0.608}
temperature1.0
extras['xg', 'congestion', 'h2h', 'injuries']

What this is not

It is not a tipping service and not financial advice. In honest backtesting this model does not consistently beat closing prices — which is the normal result, because liquid football markets absorb most of the available signal. Published selections should be expected to lose money over time. The site exists to show the model's reasoning and track its calibration in public, which is a much better reason to publish than pretending to have found free money.