1. Data

matches with usable prices across the Premier League, Championship, Bundesliga, La Liga, Serie A and Ligue 1, from football-data.co.uk. 2018/19 only warms up the ratings. The last match is .

2. Fair probability

Remove the margin

q(k) = (1/O(k)) / Σ(1/O(j))

Rate the teams

Each team has attack and defence ratings, refitted per fixture date using only earlier matches.

λ(home) = μ · h · attack(home) · defence(away)
λ(away) = μ · attack(away) · defence(home)

Older matches fade with a half-life of days. The input mixes goals and shots on target . Scorelines use a Poisson grid with the Dixon-Coles low-score correction (ρ = −0.08).

Blend with the market

A second-stage softmax fitted on 2019/20–2022/23:

p(k) ∝ exp( a·ln model(k) + b·ln q(k) + c(k) )

Fitted weights for the 1X2 market: a = , b = .

3. Edge and staking

EV = p · O − 1
stake = bankroll · min( cap, K · EV / (O − 1) )

Sample settings: EV at least , odds between , K = 0.25, cap = 2%, one bet per match and market.

4. Test protocol

StepSeasonsWhat happens
Warm-up2018/19Ratings only
Calibrate2019/20–2022/23Rating settings and blend fitted
Tune2023/24–2024/25 rule sets ranked by lower CLV bound
Holdout2025/26Frozen rules, opened once
Forward replay2026/27 to dateFrozen rules, opened once

Two changes came before the holdout was opened: the minimum tuning sample fell from 300 to 100 bets, because no Bet365 rule set reached 300, and the best-price route was added. Both are disclosed because they widen the search.

5. Assumptions and limits

6. Result

7. Quick start (planned shape)

The research pipeline below runs today on Node 20 or later. The live bot would be delivered and documented at this level, and the language can be Python if you prefer.

node --version               # Node 20+
node pipeline/01_model.js    # fit ratings and blend, walk-forward
node pipeline/02_backtest.js # tune, freeze, test, export report

Live setup would need your exchange API key and app key in environment variables, with paper mode on by default. Monitoring covers daily P/L, drawdown, CLV and an emergency stop.