The intuition
A team that creates 2.0 xG and concedes 0.5 xG most weeks will, on average, win most matches even if their actual results are mixed. xPoints captures that long-run expectation. If a team has 18 actual points but 28 xPoints after 10 games, the model says they have been unlucky and should expect their results to catch up over time. The reverse is also true: a team beating their xPoints by 8 points may be over-finishing the chances they create.
The headline formula
For a single match, expected points for the home team is:
xPoints = 3 · P(win) + 1 · P(draw)
Same shape for the away side, just with their P(win) and the same P(draw). The 3 and 1 are the football scoring rule (3 for a win, 1 for a draw, 0 for a loss).
Where the probabilities come from
We treat each side's goals as an independent Poisson draw seeded by their xG. With λh = home xG and λa = away xG, the joint probability of a final scoreline of i goals to j goals is:
P(i, j) = ((e^(-λh) · λh^i) / i!) · ((e^(-λa) · λa^j) / j!)
Sum P(i, j) over every cell where i > j to get P(home win), where i = j to get P(draw), and where i < j to get P(away win). KiqIQ uses a 0..10 by 0..10 grid (121 scorelines); the residual probability mass past 10 goals is well under one in a million for typical league xG values, so the model captures effectively all of the outcome distribution.
The full expanded form
Substituting the joint scoreline formula into the headline definition:
xPoints_home = 3 · Σ P(i, j) for all i > j + 1 · Σ P(i, j) for all i = j where: P(i, j) = ((e^(-λh) · λh^i) / i!) · ((e^(-λa) · λa^j) / j!) λh = home team xG λa = away team xG i = home goals scored (0, 1, 2, ...) j = away goals scored (0, 1, 2, ...) e = Euler's number i! = factorial of i j! = factorial of j
Worked example
Take a match with home xG = 1.80 and away xG = 1.10. The Poisson PMF gives, among other cells:
- P(home scores 2) = (e-1.80 · 1.802) / 2! ≈ 0.2678
- P(away scores 1) = (e-1.10 · 1.101) / 1! ≈ 0.3662
- P(2-1) = 0.2678 · 0.3662 ≈ 0.0981
Repeating this for every (i, j) cell and bucketing by outcome gives roughly P(home win) ≈ 0.535, P(draw) ≈ 0.231, P(away win) ≈ 0.234. Plugging into the headline formula:
xPoints_home = 3 · 0.535 + 1 · 0.231 ≈ 1.84 xPoints_away = 3 · 0.234 + 1 · 0.231 ≈ 0.93
The two xPoints values do not have to sum to a fixed number; on average across all matches they sum to roughly 2.6 (because draws are worth fewer total points than decisive results).
Season-level rollup
For league standings we sum the per-match xPoints across each team's fixtures, applying the home value to home matches and the away value to away matches. The rollup also tracks xWins, xDraws, and xLosses. A useful identity that always holds:
xPoints = 3 · xWins + xDraws xWins + xDraws + xLosses ≈ matches played
Matches with no recorded final xG are skipped. Where the table shows xPoints, the value is rounded to two decimal places.
Limitations
- Independent goals assumption. The Poisson model treats home and away goal counts as independent. Real matches are slightly correlated (a 1-0 leader sits on the lead, a 0-2 trailer pushes forward). For league-wide aggregates over a season, the bias is small. For one-off forecasting, more sophisticated joint models (Dixon-Coles) are better.
- Final xG only. Red cards, in-game injuries, and managerial changes show up in the xG totals as they accumulate but the model has no awareness of when they happened. xPoints is a backward look, not a forward forecast.
- No finishing-skill adjustment. Pure xPoints undervalues teams with elite finishers (Kane, Haaland) who consistently out-perform pre-shot xG. If you want a blended view, compare xPoints to actual points; a sustained positive gap is a finishing signal.