CAN TRE BEAT VEGAS? 🎰

Odds tracker · not betting advice

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%
  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. 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
  1. 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.

  2. 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.

  3. 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).

  4. 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
  1. DATA

    openfootball results per league, UEFA fixtures, Transfermarkt spend aggregates, market-value uploads and Understat xG per match.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. 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
  1. DATA

    Game logs, the remaining schedule, and probable starters pulled daily.

  2. RATING ENGINE AND TUNING

    Team Elo with margin weighting; the starter adjustment prices each probable pitcher.

  3. 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).

  4. 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%
  1. DATASET AND MODEL

    Feature construction, the walk-forward trainer and the calibrated scorecard.

  2. IMPORTANCE STUDY

    Permutation and SHAP importances across five model families; read by the weekly models-check email, which draws them as charts.

  3. WEEKLY REPORT

    Picks, the ledger and the bookmaker leaderboard, Tuesday and Friday nights.

SHARED PLUMBING

  1. CROSS-SPORT SUMMARY

    Every model’s graded record, game-weighted, for the home page’s track-record strip.

  2. 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.