An xG engine across Europe's top leagues that rebuilds this site from live data twice an hour — every fixture, every rating, every test we have ever run. Judged in public against the closing price, with the losses left in.
Every line above is generated from the live data on each rebuild. No human wrote any of it — that is the point.
Every one of these is a tested number, not a claim. The workings are on the record.
Fixtures the collector is tracking. Model probabilities appear on the board once both sides have enough matches played this season.
11 days until the first fixture we track — 2. Bundesliga on Friday 07 August.
| Kick-off (UTC) | Home | Away | League |
|---|---|---|---|
| Fri 07 Aug 18:30 | VfL Bochum | Hertha BSC | 2. Bundesliga |
| Sat 08 Aug 11:00 | 1. FC Magdeburg | Eintracht Braunschweig | 2. Bundesliga |
| Sat 08 Aug 11:00 | 1. FC Heidenheim | VfL Osnabrück | 2. Bundesliga |
| Sat 08 Aug 11:00 | SV Darmstadt 98 | Holstein Kiel | 2. Bundesliga |
| Sat 08 Aug 11:00 | Karlsruher SC | Arminia Bielefeld | 2. Bundesliga |
| Sat 08 Aug 18:30 | VfL Wolfsburg | 1. FC Kaiserslautern | 2. Bundesliga |
| Sun 09 Aug 11:30 | 1. FC Nürnberg | Dynamo Dresden | 2. Bundesliga |
| Sun 09 Aug 11:30 | FC St. Pauli | SpVgg Greuther Fürth | 2. Bundesliga |
The parts of this that most people get wrong, explained properly.
Expected goals in plain English — what the number is, what it is good for, and the three things people constantly get wrong about it.
Why profit is a terrible way to judge whether someone is any good at this, and what we publish instead.
We replayed the model across full past seasons. It beat the closing price and it still lost. Here are the actual numbers and why this happens to everyone.
Add up the chances implied by a set of odds and you do not get 100%. The extra is the margin, and most of what looks like value is the margin in disguise.