Appendix C
Model-building checklist
Eleven checkpoints for building a football match model, in the order they have to be done, from data assembly to go or no-go.
Chapters 16 to 23 built a model one honest piece at a time: a Poisson spine, a correlation patch, a memory that fades on purpose, a shot-quality upgrade, and a set of tests designed to catch you lying to yourself before a bookmaker does it for you. This appendix is that pipeline flattened into eleven checkpoints, printable and photocopiable, meant to sit next to the keyboard while you build, not read once and filed away. It mirrors the structure of the companion-site notebooks, step for step, so a tick here should correspond to a cell that actually runs there, and a step you cannot tick honestly is a step the notebook has not earned yet either. Nothing below is new; every formula and figure is carried over from its source chapter, recomputed rather than retyped, and the order matters as much as the content, because each checkpoint assumes the ones above it were done properly rather than merely attempted.
1. Data assembly. Pick your sources from Appendix B, date-stamp the check, and canonicalise team names before any join ("Man Utd" and "Manchester United" are the same row, not two). Build a database schema in which every price and result carries the date it became true; Chapter 22 is the source, and everything downstream depends on this step being boring and done properly. A free source is a courtesy, not a contract, and FBref's own history proves it: check the notes file again before you trust it a second time.
2. League averages. Sum a season's home and away goals and divide by matches played. Chapter 22's specimen ten-fixture slice gives a home average of 1.6 and an away average of 1.0; Chapter 16's own worked example runs on 1.50 and 1.20. These two numbers are the floor the whole matrix stands on.
3. Attack/defence estimation. Rate each team's attack and defence against the league baseline, then multiply: λ = league home average × home attack × away defence; μ = league away average × away attack × home defence. Chapter 16's specimen four (1.30, 0.90, 1.10, 1.15) gives λ = 2.2425, μ = 1.188, unrounded until the final print.
4. Time decay choice. Decide how a match's usefulness fades. Dixon and Coles weight history with φ(t) = exp(−ξt); their own fitted ξ = 0.0065, in half-weeks, gives a half-life of ln(2)/ξ ≈ 106.6 half-weeks, or 53.3 weeks. Elo-style systems reach for the same idea with a K-factor instead (Chapter 18). Pick one, state it, and refit it on your own data rather than inheriting 1997's dial.
5. Dixon-Coles correction. Patch the four low-score cells only: τ(0,0) = 1 − λμρ; τ(1,0) = 1 + μρ; τ(0,1) = 1 + λρ; τ(1,1) = 1 − ρ. On Chapter 17's ρ = −0.10 worked example the four naive cells (3.24 per cent, 7.26 per cent, 3.85 per cent, 8.62 per cent) become 4.10 per cent, 6.40 per cent, 2.98 per cent and 9.49 per cent, and the match draw total climbs from 19.6 to 21.4 per cent. Fit your own ρ; do not borrow the sign convention of a source you have not checked.
6. xG integration. Where shot data exists, substitute xG averages for goal averages in step 3's ratings, everything else in the machinery unchanged. Chapter 19's specimen figures (1.70/1.05 for the home side, 1.30/1.50 for the away side, against league averages of 1.45 and 1.15) give λ = 1.759 and μ = 1.187, and a home-win probability of 50.8 per cent against the market's implied 48.8, a 4 per cent edge built from nothing but shots.
7. Calibration on held-out seasons. Judge the model on proper scoring rules before profit and loss enters the conversation, because a scoring rule tests whether your probabilities were honest, not whether one run got lucky. Log loss is −ln(p) for the outcome that happened. The Brier score is BS = (1/N)Σ(fᵢ − oᵢ)². The ranked probability score credits a near-miss over an opposite miss: RPS = (1/2)[(pH − oH)² + (pH + pD − oH − oD)²]. Chapter 23's worked pair shows why all three earn a place: two forecasts tied on log loss (0.693 apiece) and on Brier (0.395 apiece) split cleanly on RPS, 0.136 against 0.186, because only RPS notices which forecast hedged towards the draw and which hedged towards the wrong end of the table.
8. Walk-forward backtest. Rebuild ratings after every round, using only fixtures dated before the one being priced, and test forward through the calendar. Chapter 23's lookahead example shows the cost of skipping this: pricing October's fixture off a full-season average of 1.75 instead of the honest pre-match 1.33 inflates the rating by just over 31 per cent before a ball is kicked.
9. Leak audit. Run the four traps in order. Lookahead bias: could a person at their desk on match morning have printed this exact number? Leakage: does any feature, or any random train/test split, let a later match answer for an earlier one? Chronological splitting only. Overfitting and multiple testing: twelve leagues through four markets at three thresholds is 144 tests, and the arithmetic expects roughly 7.2 false positives by chance alone, with better than 99.9 per cent odds that at least one clears a conventional bar on noise. Stale odds: benchmark every result against the closing line, never a Friday snapshot. Write down, before the backtest runs once, exactly which league, market and threshold you are testing; a survivor that clears the bar only after the rule was quietly adjusted has proved nothing.
10. Edge threshold. Set your minimum before the season starts and refuse anything under it. Buchdahl's backtest is the evidence behind the book's own 4 per cent line: taking any positive edge against the de-vigged sharp close returned +3.4 per cent over 22,281 bets; demanding 4 per cent or better cut the sample to 3,243 bets and lifted the return to +12.70 per cent; taking prices below fair lost 3.08 per cent. The threshold is a filter for your own error bar, not a superstition.
11. Go/no-go. The Ten-Point Price Check's own footer sets the default output as NO BET, and that default should survive contact with a finished model too. A genuinely walk-forward, leak-free return sits somewhere between roughly zero and low double digits; anything sustained above that, in a liquid main market, is a leak still hiding in step 9, not a discovery. Clear all eleven checkpoints, size the stake in fractions of full Kelly (Chapter 29), and only then does a price get backed.
Fail any checkpoint and the honest answer is to fix it, not to relax the checkpoint until the model passes anyway; that is multiple testing again, one experiment at a time, with the self-deception intact.
This is reference lifted from the book. The chapters are where the arithmetic gets built and argued for.
Out now · free to read on Kindle Unlimited