Does anything here beat the market?
Every forecaster I keep, scored against what happened and against the market on exactly the same rows. A forecaster that knows something sits on the dashed diagonal: when it says 0.6, the thing happens six times in ten. The market is the bar to clear, because its prices are free. The score is Brier: lower is better, and a positive "me minus market" means I would have done better copying the prices.
the forecaster the market, same rows · dot size is how many outcomes fall in the bin · whiskers are 95% intervals
| Forecaster | Rows | Brier | Market | Me minus market |
|---|---|---|---|---|
| The Pitch's model | 34 | 0.6028 | 0.6061 | -0.0033 |
| The model on over 2.5 goals | 34 | 0.2956 | 0.2406 | +0.0550 |
| My judgement, odds in view | 49 | 0.5506 | 0.5450 | +0.0055 |
| My blind column | 33 | 0.5682 | 0.5597 | +0.0085 |
| My exchange calls | 11 | 0.1341 | 0.0311 | +0.1031 |
The Pitch's model
34 rows, 102 outcome forecasts. Brier 0.6028 against the market's 0.6061: 0.0033 better than the market per row.
Counted: kickoff after commit, result in, market odds captured at commit or backfilled from the results file. 175 predictions logged, 34 with a result. Market odds were captured at commit on 5 (me minus market -0.0701 on those alone); the other 29 were committed from the odds-free fallback calendar, so their market price is football-data's pre-match average from the results file, usually taken after my commit. That price has seen more than the model had, which favours the market.
No kill line: the model is scored at the week-8 review (PASS-MARKS.md).
The model on over 2.5 goals
34 rows, 34 outcome forecasts. Brier 0.2956 against the market's 0.2406: 0.0550 worse than the market per row.
Counted: same rows as the model panel that have an over 2.5 price; one yes/no forecast per match. 5 of the 34 have the price captured at commit; the rest are backfilled as above.
No kill line: the model is scored at the week-8 review (PASS-MARKS.md).
My judgement, odds in view
49 rows, 147 outcome forecasts. Brier 0.5506 against the market's 0.5450: 0.0055 worse than the market per row.
Counted: J-0009 on, committed before kickoff. 57 rows logged in all.
Pre-registered line: KILL at +0.010, KEEP at -0.005, 60 rows. 11 rows to the floor.
My blind column
33 rows, 99 outcome forecasts. Brier 0.5682 against the market's 0.5597: 0.0085 worse than the market per row.
Counted: blind call committed before the odds were opened and before kickoff. 57 rows logged in all.
Pre-registered line: KILL at +0.020, KEEP at 0.000, 60 rows. 27 rows to the floor.
My exchange calls
11 rows, 11 outcome forecasts. Brier 0.1341 against the market's 0.0311: 0.1031 worse than the market per row.
Counted: settled, with the market mid captured after my commit. 22 calls logged, 16 settled; only 11 had the market mid captured, so only those can be compared.
Pre-registered line: KILL at +0.020, KEEP at 0.000, 60 rows. 49 rows to the floor.
What this does not say yet
These are small samples. The whiskers are wide because most bins hold a few dozen outcomes at best, and every pre-registered book needs 60 rows before it can be kept or killed. Football rows count each match three times (home, draw, away), so the dots are not independent. The over 2.5 panel counts each match once. Nothing on this page has been bent after the fact: the counting rules are the kill check's, and the build stops if the two disagree.
Drawn by bin/calibration.py from pitch/PREDICTIONS.csv, pitch/MARKET-BACKFILL.csv, pitch/JUDGEMENT.csv and exchange/BOOK.csv; numbers in data.json. Every forecast was committed to git before its outcome was knowable. Back to the lab.