HOW THE MODELS WORK
Each model on the board, from its data source to its graded pick, one step at a time. Every step links to the file in the repository that does it, so the code can be read in the order it runs. The README beside each model explains the reasoning; this page is the map. Each model also carries a measured breakdown of what its inputs are actually worth — open What its inputs are worth under any of them — and the short version of every feature list is the feature sheet.
🏈 NFL ELO
README ↗A betting-blind Elo over every NFL game since 1999, replayed from scratch each morning, with a daily pipeline that grades picks, predicts the next week and simulates the season through the playoff bracket.
- Spine
- nflverse games file, 1999–present
- Tuned
- 2005–2023 · holdout 2024–25
- Holdout log loss
- 0.624 (always-home 0.691)
- Parameters
- K 20 · home +48 · bye +20 · cap 45 · regression 40%
- DATA
One row per game with scores, kickoff date, neutral flag, game type and rest days. The closing line is in the file but never reaches the rating.
- RATING ENGINE
Logistic expectation on the rating gap; K scaled by a capped, log-damped margin that shrinks when the favourite wins; a rest edge for a side off its bye; playoff K; fractional regression to 1500 each off-season; STL/SD/OAK carried onto LA/LAC/LV.
- TUNING
Coordinate descent on one-step-ahead log loss over every game, 2005–2023, with 2024–25 never touched. The tuned values are committed and read by the engine.
- SCORE MODEL
Expected margin is linear in the Elo gap (about 24 Elo per point, refit each run); the expected total comes from each team’s recent points for and against, shrunk to the league mean.
- SLATE AND GRADING
The next NFL week’s unplayed games get a win probability, the model’s own line and an expected score; grading is idempotent by game id against a paired always-pick-home baseline, and the first morning a game appears on a slate is the pick that counts.
- SEASON SIMULATION
Ten thousand replays of the remaining schedule with live in-sim Elo, then seeds 1–7 per conference and the full bracket; played playoff games are honoured.
- PUBLISHING
Site JSON, the Tue/Thu update email, and the archive copy of that email, run daily by GitHub Actions.
What its inputs are worth— component ablation
increase in holdout log loss when the component is neutralised. Baseline log loss 0.62424 over 586 games, 2024 onward (never tuned on).
- Margin of victory+0.025
- Season regression+0.019
- Home advantage+0.002
- Postseason K weight+0.000
- Rest (bye week)−0.0006
component ablation — Neutralising a component changes every rating after it, so these are contributions to the whole replay, not to one game. 'Margin of victory' clamps the margin to a point rather than removing the multiplier, which also shrinks the update size — read it as 'margin ignored', not as a clean K-preserving swap.
What the second-stage layer is worth— permutation importance
increase in holdout log loss when the feature is shuffled. Baseline log loss 0.61727 over 569 games, 2024-2025 (clean of the Elo's own 2005-2023 tuning window).
- elo_logit+0.011 ±0.002
- epa_matchup_net+0.004 ±0.001
- epa_per_drive_matchup_net+0.003 ±0.001
- elo_home_pre+0.002 ±0.001
- success_matchup_net+0.002 ±0.001
- db_epa_matchup_net+0.002 ±0.001
- points_per_drive_matchup_net+0.002 ±0.001
- explosive_matchup_net+0.001 ±0.001
- away_off_yards_per_drive_ewm+0.001 ±0.001
- early_epa_matchup_net+0.0009 ±0.001
- home_off_third_dist_ewm+0.0009 ±0.001
- away_off_success_adj+0.0008 ±0.001
- home_off_third_epa_ewm+0.0006 ±0.000
- home_off_success_adj+0.0005 ±0.001
- home_off_epa_ewm+0.0005 ±0.000
- home_off_epa_adj+0.0005 ±0.001
- home_def_sack_rate_ewm+0.0005 ±0.000
- home_def_epa_ewm+0.0005 ±0.000
- elo_away_pre+0.0004 ±0.001
- home_off_sack_rate_ewm+0.0004 ±0.000
- away_off_third_epa_ewm+0.0003 ±0.000
- away_def_epa_adj+0.0003 ±0.000
- home_off_neutral_pace_ewm+0.0002 ±0.000
- home_st_epa_net_ewm+0.0002 ±0.000
- rush_epa_matchup_net+0.0002 ±0.000
- home_off_rz_epa_ewm+0.0002 ±0.000
- away_off_series_success_ewm+0.0002 ±0.000
- away_def_epa_ewm+0.0002 ±0.000
- away_off_drives_ewm+0.0001 ±0.000
- away_st_epa_net_ewm+0.0001 ±0.000
- home_off_proe_ewm+0.0001 ±0.000
- away_off_proe_ewm+0.0001 ±0.000
- away_off_plays_per_drive_ewm+0.0001 ±0.000
- home_off_drives_ewm+0.0000 ±0.000
- away_off_epa_ewm−0.0000 ±0.001
- home_off_plays_per_drive_ewm−0.0001 ±0.000
- home_off_series_success_ewm−0.0001 ±0.000
- home_def_epa_adj−0.0001 ±0.000
- away_off_neutral_pace_ewm−0.0001 ±0.000
- home_off_yards_per_drive_ewm−0.0002 ±0.000
- away_off_third_dist_ewm−0.0004 ±0.000
- away_def_success_adj−0.0004 ±0.000
- home_def_success_adj−0.0004 ±0.000
- away_off_epa_adj−0.0005 ±0.000
- third_conv_matchup_net−0.0005 ±0.000
- away_off_rz_epa_ewm−0.0005 ±0.000
- away_def_sack_rate_ewm−0.0005 ±0.000
- away_off_sack_rate_ewm−0.0006 ±0.000
- rz_td_matchup_net−0.0006 ±0.000
permutation importance — This is the logistic layered on top of Elo (NFL/model/advanced.py), not the Elo engine itself — see the 'NFL Elo' section above for what the rating's own components are worth. A game with no play-by-play rating for either side falls back to Elo alone and is not in this window.
🎓 COLLEGE FOOTBALL ELO
README ↗An FBS Elo over every FBS-involved game since 2001 with conference-aware season regression, one pooled FCS opponent and a capped margin, plus the same daily grade / predict / simulate loop.
- Spine
- cfbfastR-data (ESPN-derived), 2001–present
- Tuned
- 2005–2023 · holdout 2024–25
- Holdout log loss
- 0.499 (always-home 0.652)
- Parameters
- K 35 · home +50 · regression 30% toward 75% conference mean
- DATA
One ESPN-derived CSV per season with per-season conference for both teams, an FBS/FCS tag, the neutral flag and scores; ESPN’s scoreboard fills the trailing week.
- RATING ENGINE AND TUNING
Shared Elo skeleton plus the four college rules: regression toward the new conference’s mean, a fixed pooled FCS rating, an FBS entry rating and a margin cap.
- DAILY PIPELINE
Replay, score model, two-day slate, idempotent grading with the paired always-home baseline, and a rest-of-regular-season Monte Carlo (expected wins, bowl, conference title; the 12-team playoff is a committee pick and is not modelled).
- PUBLISHING
Site JSON, the Mon/Thu update email and its archive copy.
What its inputs are worth— component ablation
increase in holdout log loss when the component is neutralised. Baseline log loss 0.48462 over 2,038 games, 2024 onward (never tuned on).
- FCS opponent rating+0.038
- Margin of victory+0.036
- Season regression+0.028
- Conference regression+0.011
- Home advantage+0.011
- FBS entry rating+0.0008
component ablation — Neutralising a component changes every rating after it, so these are contributions to the whole replay, not to one game. 'Margin of victory' clamps the margin to a point rather than removing the multiplier, which also shrinks the update size.
What the second-stage layer is worth— permutation importance
increase in holdout log loss when the feature is shuffled. Baseline log loss 0.49347 over 1,853 games, 2024-2025 (clean of the Elo's own 2005-2023 tuning window).
- elo_logit+0.046 ±0.002
- adj_epa_matchup_net+0.018 ±0.001
- elo_away_pre+0.009 ±0.001
- success_matchup_net+0.007 ±0.001
- epa_drive_matchup_net+0.006 ±0.001
- early_epa_matchup_net+0.005 ±0.001
- rush_epa_matchup_net+0.004 ±0.001
- third_success_matchup_net+0.003 ±0.001
- away_adj_epa_off+0.003 ±0.000
- elo_home_pre+0.003 ±0.001
- away_adj_epa_def+0.002 ±0.000
- away_success_off+0.002 ±0.000
- pass_epa_matchup_net+0.002 ±0.000
- rz_success_matchup_net+0.001 ±0.000
- away_yards_drive_off+0.0009 ±0.000
- home_adj_epa_def+0.0008 ±0.000
- home_adj_epa_off+0.0008 ±0.000
- away_havoc_off+0.0008 ±0.000
- away_drives_game_off+0.0007 ±0.000
- home_passrate_off+0.0005 ±0.000
- home_success_off+0.0005 ±0.000
- away_success_def+0.0004 ±0.000
- explosive_matchup_net+0.0004 ±0.000
- home_havoc_def+0.0004 ±0.000
- away_third_dist_off+0.0004 ±0.000
- away_passrate_off+0.0003 ±0.000
- home_havoc_off+0.0002 ±0.000
- home_yards_drive_off+0.0002 ±0.000
- home_plays_drive_off+0.0001 ±0.000
- home_success_def+0.0001 ±0.000
- away_plays_drive_off+0.0001 ±0.000
- home_drives_game_off+0.0001 ±0.000
- away_havoc_def−0.0000 ±0.000
- home_third_dist_off−0.0001 ±0.000
permutation importance — This is the logistic layered on top of Elo (CFB/model/advanced.py), not the Elo engine itself — see the 'College football Elo' section above for what the rating's own components are worth. A game with an FCS side, or no weekly-summary rating for either side, falls back to Elo alone and is not in this window.
⚽ CLUB SOCCER
README ↗One Elo pool per country spanning the top flight and its second division, glued across countries by European cross-play, feeding a three-way outcome model with squad-economics and xG-form features and a Poisson score model.
- Leagues
- EPL, Bundesliga, La Liga, Serie A, Ligue 1 and their second tiers; MLS unglued
- Outcome model
- multinomial logistic on six home-minus-away differentials
- Validated
- two-season holdout from 2024-25
- Picks
- three-way W/D/L, so log loss reads against ~1.10
- DATA
openfootball results per league, UEFA fixtures, Transfermarkt spend aggregates, market-value uploads and Understat xG per match.
- RATING ENGINE
Per-league tuned K, home edge, season regression and entry ratings; promoted and relegated clubs carry their rating through a tier blend; UEFA matches move ratings across pools at a reduced weight.
- FEATURES
The venue-adjusted Elo gap, transfer spend and net spend, squad value and wage bill (each z-scored within league-season and taken home minus away), and rolling xG net form.
- OUTCOME MODEL
A multinomial logistic over win / draw / loss, refit from the replay history on every run; the training script holds out two seasons and reports per-league metrics.
- SIDES VS. DIFFERENCES STUDY
Four alternatives — the production differentials, every feature split into home and away values, sides plus each side’s goals scored and allowed, and a Poisson goals regressor — trained before 2026 and tested on this year’s matches, with importances.
- SCORE MODEL, SLATE, GRADING, SIMULATION
Independent Poisson goal rates from the Elo expectancy and each league’s goals total; a two-day slate; per-match grading; a Monte Carlo of every top-flight table.
- PUBLISHING
Site JSON, the Mon/Thu update email and its archive copy.
What its inputs are worth— permutation importance
increase in holdout log loss when the feature is shuffled. Baseline log loss 1.01341 over 7,906 games, 2024-25 onward (never fitted on).
- elo_gap+0.009 ±0.001
- value_diff_z+0.007 ±0.001
- home_value_z+0.002 ±0.000
- elo_away_pre+0.002 ±0.000
- elo_home_pre+0.001 ±0.000
- xpts_ewm_diff+0.0008 ±0.000
- away_squad_value_eur_m+0.0008 ±0.000
- away_value_z+0.0008 ±0.000
- sot_net_diff+0.0004 ±0.000
- deep_share_diff+0.0004 ±0.000
- home_xg_for_split+0.0002 ±0.000
- tier+0.0001 ±0.000
- npxg_against_ewm_diff+0.0001 ±0.000
- home_npxg_for_ewm+0.0001 ±0.000
- home_deep_share_ewm+0.0001 ±0.000
- home_npxg_for_split+0.0001 ±0.000
- xg_net_diff+0.0001 ±0.000
- npxg_against_r10_diff+0.0001 ±0.000
- home_deep_for_r10+0.0001 ±0.000
- home_deep_share_r10+0.0001 ±0.000
- npxg_for_ewm_diff+0.0001 ±0.000
- home_xpts_for_ewm+0.0001 ±0.000
- home_deep_for_ewm+0.0001 ±0.000
- home_deep_against_ewm+0.0001 ±0.000
- away_ppda_for_ewm+0.0001 ±0.000
- xg_for_ewm_diff+0.0001 ±0.000
- away_xpts_for_ewm+0.0001 ±0.000
- home_squad_value_eur_m+0.0001 ±0.000
- home_att_vs_away_def+0.0001 ±0.000
- deep_diff+0.0001 ±0.000
- away_xg_against_ewm+0.0001 ±0.000
- away_npxg_for_ewm+0.0001 ±0.000
- home_ppda_for_r10+0.0000 ±0.000
- away_xg_per_shot_r10+0.0000 ±0.000
- home_npxg_against_split+0.0000 ±0.000
- npxg_away_att_vs_home_def+0.0000 ±0.000
- away_ppda_for_r10+0.0000 ±0.000
- home_npxg_against_ewm+0.0000 ±0.000
- home_ppda_for_ewm+0.0000 ±0.000
- lg_la_liga+0.0000 ±0.000
- away_deep_against_ewm+0.0000 ±0.000
- xg_against_ewm_diff+0.0000 ±0.000
- npxg_for_r10_diff+0.0000 ±0.000
- uefa7_home+0.0000
- lg_epl+0.0000 ±0.000
- lg_bundesliga_2+0.0000 ±0.000
- away_xg_for_r10+0.0000 ±0.000
- away_xg_against_r10+0.0000 ±0.000
- home_xpts_for_r10+0.0000 ±0.000
- away_xpts_for_r10+0.0000 ±0.000
- spend_diff_z+0.000no data over this window
- net_diff_z+0.000no data over this window
- wage_diff_z+0.000no data over this window
- uefa7_away+0.000
- lg_ligue_1+0.000 ±0.000
- season_idx+0.000
- home_npxg_against_r10+0.000 ±0.000
- home_deep_against_r10+0.000 ±0.000
- home_xg_against_ewm+0.000 ±0.000
- away_deep_for_ewm+0.000 ±0.000
- home_spend_z+0.000no data over this window
- away_spend_z+0.000no data over this window
- home_net_z+0.000no data over this window
- away_net_z+0.000no data over this window
- home_wage_z+0.000no data over this window
- away_wage_z+0.000no data over this window
- lg_bundesliga−0.0000 ±0.000
- lg_serie_a−0.0000 ±0.000
- away_npxg_against_r10−0.0000 ±0.000
- away_deep_for_r10−0.0000 ±0.000
- home_xg_for_ewm−0.0000 ±0.000
- away_xg_for_ewm−0.0000 ±0.000
- home_xg_against_split−0.0000 ±0.000
- xg_against_r10_diff−0.0000 ±0.000
- away_npxg_for_r10−0.0000 ±0.000
- away_deep_share_ewm−0.0000 ±0.000
- away_att_vs_home_def−0.0000 ±0.000
- lg_serie_b−0.0000 ±0.000
- lg_ligue_2−0.0000 ±0.000
- lg_mls−0.0000 ±0.000
- home_xg_against_r10−0.0000 ±0.000
- away_xg_against_split−0.0000 ±0.000
- away_npxg_against_split−0.0000 ±0.000
- npxg_home_att_vs_away_def−0.0000 ±0.000
- away_npxg_against_ewm−0.0000 ±0.000
- xg_per_shot_diff−0.0001 ±0.000
- rest_diff−0.0001 ±0.000
- congestion14_away−0.0001 ±0.000
- lg_championship−0.0001 ±0.000
- away_deep_against_r10−0.0001 ±0.000
- lg_la_liga_2−0.0001 ±0.000
- ppda_diff−0.0001 ±0.000
- home_xg_per_shot_ewm−0.0001 ±0.000
- home_xg_per_shot_r10−0.0001 ±0.000
- away_xg_per_shot_ewm−0.0001 ±0.000
- xg_for_r10_diff−0.0001 ±0.000
- away_npxg_for_split−0.0001 ±0.000
- home_npxg_for_r10−0.0001 ±0.000
- away_deep_share_r10−0.0001 ±0.000
- home_xg_for_r10−0.0001 ±0.000
- away_xg_for_split−0.0001 ±0.000
- congestion14_home−0.0001 ±0.000
permutation importance — A feature already feeding zeros on every live slate cannot be damaged by shuffling, so a zero here can mean 'no signal' or 'no data' — see the dormant features in docs/MODEL_FEATURES.md.
⚾ MLB ELO
README ↗A betting-blind team Elo with a starting-pitcher adjustment, rest and travel edges, a Poisson-style score model and a rest-of-season Monte Carlo, graded every morning.
- Spine
- game logs 2009–present, MLB Stats API for finals and probables
- Parameters
- K 3 · home +24 · margin-of-victory weighted
- Backtest
- 2009–2025: 56.7% straight up, log loss 0.680 vs 0.691 always-home
- Active model
- v2-sp (starting-pitcher adjusted), cut over 2026-08-15
- DATA
Game logs, the remaining schedule, and probable starters pulled daily.
- RATING ENGINE AND TUNING
Team Elo with margin weighting; the starter adjustment prices each probable pitcher.
- SLATE, GRADING, SIMULATION
Today’s slate with simulated scores, yesterday graded against the paired always-home baseline, and the season Monte Carlo (division, playoffs, top seed).
- PUBLISHING
Three morning emails (futures, slate, grade), the site JSON and the archive copies.
What its inputs are worth— component ablation
increase in log loss when the component is neutralised. Baseline log loss 0.67965 over 34,665 games, 2012 onward.
- Season carryover+0.003
- Home advantage+0.002
- Margin of victory+0.001
component ablation — Only the rating engine's own components are ablated here. The starting-pitcher, rest and travel adjustments are applied by the daily pipeline rather than the replay, so their contribution is not measured yet — see research/SP-BACKTEST.md for the pitcher layer's own out-of-sample test.
📈 NFL PICKS MODEL (MARKET-AWARE)
README ↗The older LightGBM / logistic picks model that also sees the closing line. It exists to answer “can we beat the close?” (no) and runs in the Tue/Fri weekly report; it is a different animal from the betting-blind Elo above.
- Features
- 45 market, rating, form, schedule and context features
- Validation
- walk-forward, one retrain per season, 2010–2025
- Result
- 64.3% straight up vs 66.4% for the closing line; ATS 50.5%
- DATASET AND MODEL
Feature construction, the walk-forward trainer and the calibrated scorecard.
- IMPORTANCE STUDY
Permutation and SHAP importances across five model families; read by the weekly models-check email, which draws them as charts.
- WEEKLY REPORT
Picks, the ledger and the bookmaker leaderboard, Tuesday and Friday nights.
SHARED PLUMBING
- CROSS-SPORT SUMMARY
Every model’s graded record, game-weighted, for the home page’s track-record strip.
- EMAIL ARCHIVE AND SEND LEDGER
Every report email is archived as sent with a permalink footer and listed by league; the ledger keeps reruns from double-sending.