MLB Model Record
Our MLB moneyline model picks winners at 55.3%. The market's closing line does it at 57.5%.
Each dot is a probability bucket. On the dashed line the model is perfectly calibrated. Dots above it mean the home team won more often than predicted; below, less often. Bigger dots hold more games.
Vertical axis is the actual home-win rate — it shows where the win probabilities can and can't be trusted.
| Predicted | Games | Predicted | Actual |
|---|---|---|---|
| 35–40% | 148 | 38.0% | 39.9% |
| 40–45% | 349 | 42.8% | 45.9% |
| 45–50% | 692 | 47.6% | 51.3% |
| 50–55% | 974 | 52.5% | 54.0% |
| 55–60% | 831 | 57.3% | 53.9% |
| 60–65% | 468 | 62.1% | 59.8% |
| 65–70% | 197 | 67.1% | 65.0% |
| 70–75% | 62 | 72.1% | 85.5% |
| 75–80% | 6 | 77.2% | 100.0% |
| Split | Games | Pick accuracy |
|---|---|---|
| Model favors home | 2538 | 56.8% |
| Model favors away | 1243 | 52.4% |
| Month | Games | Accuracy |
|---|---|---|
| 2025-03 | 67 | 62.7% |
| 2025-04 | 391 | 59.9% |
| 2025-05 | 411 | 54.3% |
| 2025-06 | 397 | 54.2% |
| 2025-07 | 369 | 53.4% |
| 2025-08 | 421 | 55.8% |
| 2025-09 | 378 | 54.2% |
| 2025-10 | 42 | 50.0% |
| 2025-11 | 1 | 100.0% |
| 2026-03 | 76 | 59.2% |
| 2026-04 | 392 | 56.1% |
| 2026-05 | 419 | 57.0% |
| 2026-06 | 394 | 51.5% |
| 2026-07 | 23 | 56.5% |
Pitcher Strikeouts
Projects a starter's strikeout total.
vs the market: trails the market · flat-stake ROI at close -4.3%.
Model detail
INFORMATIONAL pitcher-strikeouts prop model (mlb_k_props_v1) — framework first instance (batter hits / pitcher outs / HR / SB reuse the same base). Projection = pitcher K%/BF (recency-weighted, shrunk to league) matched via log5/odds-ratio against opponent team batting K% (LHP/RHP platoon adjusted) and a shrunk home-park K factor, times a recency-weighted workload; priced with a Negative-Binomial (Var=mu+alpha*mu^2, alpha=0.08) chosen over Poisson because per-start Ks are overdispersed (Var/Mean~1.3). Strictly walk-forward: a start informs only later games. Hyperparams tuned on 2015-2022 walk-forward log loss; 2023-2025 held out (clean-window MAE=1.84K, over/under logloss=0.682, acc=0.559). Headline accuracy/log_loss/brier and wins/losses are the market-window over/under backtest vs captured closing lines; market_* are the devigged (Shin) closing line on the SAME games; roi_flat_at_close is a flat 1u on the model-favored side at the closing price — NOT a claimed edge (small n; judge forward performance on CLV). LIMITATIONS: team-level opponent K (pregame lineups unavailable); 2026 opponent-K is a starter-only proxy (event files end 2025); era drift in workloads/K rates handled by recency weighting.
Pitcher Outs
Projects outs a starter records (≈ innings × 3).
No market backtest yet — closing lines are being captured live.
Model detail
INFORMATIONAL pitcher-outs-recorded prop model (mlb_outs_props_v1) — second instance of the MLB prop framework (shares base.py with pitcher strikeouts). Projected outs = a pitcher outs/start durability EWMA (league-shrunk) adjusted multiplicatively by opponent batting OBP (tougher lineups end starts earlier), the club's starter-leash / hook tendency, and the pitcher's recent baserunners-allowed effectiveness — all recency-weighted, so era drift toward shorter modern starts is absorbed. Priced with a DISCRETIZED GAUSSIAN N(mu, sigma=3.3) rather than Poisson/NB: outs-per-start is bounded at 27, piles up at the 18-out quality-start ceiling, and is UNDER-dispersed at the high means where starters live (conditional Var<mu), a regime the Negative-Binomial cannot reach (its method-of-moments alpha here clips to 0). Strictly walk-forward: a start informs only later games. Mean hyperparams tuned on 2015-2022 walk-forward anchor-line log loss; 2023-2025 held out. HEADLINE accuracy/log_loss/brier and wins/losses ARE the out-of-sample 2023-2025 walk-forward record at the half-line nearest each projection (there is NO market window yet — clean-window MAE=3.03 outs, over/under logloss=0.690, acc=0.535). market_accuracy/market_log_loss/roi_flat_at_close are null and odds_sample_size is 0 because pitcher_outs closing lines are captured starting 2026-07-03; the market comparison begins with forward capture and forward performance is judged on CLV, not this record. LIMITATIONS: team-level opponent OBP (pregame lineups unavailable); 2026 opponent-OBP is a starter-only proxy (event files end 2025); rain/ejection/injury-shortened outings are irreducible noise the Gaussian absorbs as SD.
Batter Hits
Projects a batter's hit total.
vs the market: matches the market log loss · flat-stake ROI at close -5.4%.
Model detail
INFORMATIONAL batter-hits prop model (mlb_hits_props_v2), batter-market anchor of the shared batter-prop spine (TB/HR/SB reuse its feed+state). mu = E[AB] (own EWMA) x per-AB hit rate (EWMA shrunk to league) x league bats-vs-throws platoon split x PLAYER-LEVEL platoon tilt x opposing-starter hit-suppression (EWMA h/BF, damped ^0.25) x shrunk home-park factor. NEW IN v2 (split-miner follow-up, 2026-07-05): per-batter per-side (vs LHP / vs RHP starter) H/AB EWMAs, empirical-Bayes-shrunk toward own_rate x league(bats x throws) so thin side samples collapse to the league split (tuned on 2015-2022 only: prior=100 AB, half-life=1000 games ~ platoon tilt treated as persistent skill, weight=1.0); hold-out 2023-2025 anchor LL 0.6446 -> 0.6424, acc 0.6393 -> 0.6404, Brier 0.2264 -> 0.2253 (MAE 0.697, marginally higher than baseline 0.693 — the anchor log-loss gate decided promotion). Count priced with alpha=0.0 (unchanged). Strictly walk-forward; headline metrics + wins/losses are the 2026 market-window backtest vs captured closing lines; market_* is the devigged (Shin) close on the SAME picks; roi_flat_at_close is flat 1u on the model-favored side at the close — NOT a claimed edge (judge forward on CLV; baseline market LL on the same window was 0.6685 vs v2 0.6695 — a hair worse at the close while accuracy and flat ROI improved; small deltas, small edge claims: none). LIMITATIONS: no pregame lineup feed (recent-regulars roster heuristic); the platoon side is the STARTER hand credited for the whole game line although relievers take ~40% of PAs; 2026 rookies lack bats/throws (platoon factors 1.0); 2026 opponent context is starter-only. Per-side batter state KEEPS updating in 2026 (starter hand is observable in mlb_batter_game_stats + mlb_pitcher_starts, unlike the pitcher per-PA side splits which end with the 2025 event files). STATCAST (roadmap item #1): sc_xba_weight=1.0 (unchanged from v1 promotion).
Batter Total Bases
Projects a batter's total bases.
No market backtest yet — closing lines are being captured live.
Model detail
INFORMATIONAL batter total-bases prop model (mlb_tb_props_v1) on the shared batter spine: mu = E[hits] x bases-per-hit (player power EWMA shrunk to league) x damped park HR factor; NB alpha=0.35 by held-out calibration across the 0.5/1.5/2.5/3.5 lines (TB is strongly overdispersed — a HR is 4 TB on one swing); 0.35 was the TOP of the searched grid and the 3.5 tail is still under-predicted (pred 0.094 vs emp 0.152 on 2023-2025), so P(over 2.5+) leans low — read the 1.5 line as the calibrated one. Tuned 2015-2022; 2023-2025 held out: MAE=1.35 TB, anchor LL=0.656, acc=0.629. NO MARKET BACKTEST: batter_total_bases odds capture was only enabled 2026-07-03 (forward capture running; judge on CLV as it accumulates) — market_* fields are null, headline numbers are the walk-forward hold-out at posted-line anchors, NOT vs a market. Settlement needs the ESPN plays feed (2B/3B attribution); games without it stay unsettled. Anchor accuracy is inflated by the many sub-1.5-mu batters priced under at 1.5 — read LL/Brier first.
Batter Home Runs rare event
Projects P(a batter hits a home run).
Base-rate accuracy (rare event at the 0.5 line) — read log loss / Brier.
Model detail
INFORMATIONAL anytime-HR prop model (mlb_hr_props_v2) on the shared batter spine: P(HR>=1) from mu = E[PA] x per-PA HR rate (EWMA, heavily shrunk: prior=800 PA) x league HR platoon split x PLAYER-LEVEL HR platoon tilt x shrunk park HR factor x opposing-starter HR-suppression^0.5. NEW IN v2 (split-miner follow-up, 2026-07-05): per-batter per-side (vs LHP / vs RHP starter) HR/PA EWMAs, empirical-Bayes-shrunk toward own_rate x league(bats x throws) (tuned on 2015-2022 only: prior=500 PA, half-life=150 games, weight=1.0); hold-out 2023-2025 anchor LL 0.36058 -> 0.36031, Brier 0.10460 -> 0.10458, calibration at 0.5 pred/emp 0.121/0.121 (baseline 0.118/0.121). Poisson-family pricing (alpha=0.0, unchanged). Top predicted deciles calibrate as pred/emp d8:0.15/0.15; d9:0.17/0.16; d10:0.23/0.20. ACCURACY CAVEAT: at the fixed 0.5 line the model almost always says "no HR", so accuracy ~= the base no-HR rate — LL/Brier and the decile table are the real evidence. MARKET FIELDS: batter_home_runs capture began 2026-07-03; market_* now carry a TINY window (n=378, 2026-07-03 onward; v2 market LL 0.4557 vs devigged close 0.4548) — far too small to mean anything; judge forward on CLV. 2026 GAPS: starter HR-allowed is not captured in 2026 (pitcher HR term frozen after 2025); batter per-side state keeps updating in 2026 (starter hand observable); the platoon side is the starter hand credited for the whole game line though relievers take ~40% of PAs. STATCAST: sc_barrel_weight=0.5 (unchanged).
Batter Stolen Bases rare event
Projects P(a batter steals a base).
Base-rate accuracy (rare event at the 0.5 line) — read log loss / Brier.
Model detail
INFORMATIONAL stolen-base prop model (mlb_sb_props_v1), the LOWEST-SIGNAL market of the four (said plainly): P(SB>=1) from mu = player SB/game (EWMA over started games, heavy shrinkage prior=30 games; speed/attempt profile from the per-game Retrosheet sb columns — the same attempt attribution as mlb_running_events aggregated per player-game) x opposing battery control (team-level SB-allowed/game EWMA vs league)^1.0. alpha=0.35 by held-out calibration at 0.5 (selection is within noise at a single rare-event line — all alphas scored near-identically; the choice barely moves P(SB>=1)). Tuned 2015-2022; 2023-2025 held out: LL=0.224. Decile calibration pred/emp d8:0.08/0.10; d9:0.11/0.13; d10:0.16/0.18. Whether a steal is even attempted depends on unobserved game state (score, baserunners, battery tempo) — treat as context, never a signal; accuracy at 0.5 is ~ the base no-SB rate. NO MARKET BACKTEST: batter_stolen_bases capture enabled 2026-07-03; market_* null; judge forward on CLV. 2026 SB comes from the ESPN plays feed (validated 0.735/team-game vs 0.68 league 2025); games without a plays feed stay unsettled.