For prediction markets — not to follow the lines, but to disagree with them.
Model coverage: NBA, WNBA, NCAAMB, NCAAWB, CFB, NFL, NHL, MLB. Not every covered sport places live orders at any given time — several run in shadow evaluation while they earn (or re-earn) live status; the changelog tracks pauses. Research and course extensions are called out separately below.
Current Proof Snapshot
Held-out ECE of 1.4%–9.2% by sport — the real out-of-sample number, not the near-zero in-sample fit. (The validation snapshot is being rebuilt after a July 2026 review; the CLV-gap claim that used to sit here was retracted.)
Methodology explains the model design. Validation shows the current exported backtest snapshot, results show live production outcomes, and /clv publishes descriptive per-sport closing-line observations. For in-play entries that terminal measure can encode the outcome, so it is not presented as a model-skill or profitability gate.
Retraction · 2026-07-21
This section used to present a 78.8-percentage-point CLV-conditioned win-rate gap (89.9% vs 11.2%) as empirical evidence of model skill. It was a measurement artifact: about 90% of our entries are in-play, and the captured close on those markets sits near the market's final resolution — so the split largely restates who won. The control that settled it: the opposite side of every trade — the side the model rejected — shows the same split. The live, unconditioned aggregate and its exchange-price correction history live on /clv.
Read the full retraction →Three views — what does each page show?
ZenHodl Weekly
One weekly email with live results, one model insight, and product updates.
A short weekly note for builders, traders, and researchers following the model.
Most sports analytics services derive "fair value" by devigging sportsbook lines — averaging Pinnacle, FanDuel, and DraftKings odds. This gives you a consensus probability that tracks the market by construction. It can be useful for line shopping, but it is not an independent model view — because the output already agrees with the market.
ZenHodl models are trained on game state and pregame priors: score differential, seconds remaining, period, Elo ratings, sport-specific features, and (in most sports) a pregame win-probability prior derived from ESPN's pregame number. ESPN's live in-game win probability is deliberately excluded, and no odds, lines, or market prices are used as inputs. This keeps our output independent from the market price you compare it against — useful for line shopping and auditing, but still subject to fees, slippage, and model error.
The tradeoff: our models trade some absolute Brier score for genuine independence — but the per-sport values reported below (NBA Brier 0.128, held-out ECE 0.053; NCAAMB Brier 0.146; NHL Brier 0.184) show the gap is competitive in practice. Independence is useful because it gives you a separate fair-value reference to compare with market prices, not a guaranteed edge. See /clv-evidence for the audit and retraction of our former outcome-conditioned CLV claim, /validation for the exported backtest snapshot, and /results for current live production performance.
| Market-Derived | ZenHodl (Independent) | |
|---|---|---|
| Inputs | Sportsbook odds/lines | Score, time, Elo only |
| Output | Tracks market by construction | Genuinely independent |
| Brier Score | Better by construction | Competitive in practice (NBA Brier 0.128, held-out ECE 0.053) |
| Trading Value | Zero (agrees with market) | Measured publicly (unconditioned CLV scorecard; no profit guarantee) |
We scrape ESPN's play-by-play API across the core sports we model. Each game produces hundreds of snapshots — one per score change or significant event.
Sports: NBA, NCAAMB, NCAAWB, CFB, NFL, NHL, MLB
Data is stored as Apache Parquet files. One row = one game state (score, period, clock, ESPN WP, outcome label).
Module 1 of our course teaches you to build this exact scraper.
Each game state is featurized with 13–16 variables. We deliberately keep the feature set small — overfitting to noise destroys trading value.
| Feature | Sports | Description |
|---|---|---|
| score_diff | All | home_score − away_score |
| seconds_remaining | All | Total game seconds left |
| period | All | Current period/half/inning |
| time_fraction | All | Fraction of game elapsed (0→1) |
| elo_diff | All | Home Elo − Away Elo |
| pregame_wp | All | ESPN pre-game win probability (fixed prior) |
| score_diff_x_tf | All | Lead × time elapsed (interaction) |
| score_diff_sq | All | Lead² (quadratic, captures blowouts) |
| is_home_batting | MLB | 1 if home team is batting |
| down, distance | CFB/NFL | Football situation |
| yard_line | CFB/NFL | Field position |
| possession_home | CFB/NFL | 1 if home has the ball |
| pace features | NBA | total_score, ortg_diff, drtg_diff |
We use sport-specific models — no one-size-fits-all approach. The sections below distinguish the current live platform from adjacent research and course material.
The models cover NBA, WNBA, NCAAMB, NCAAWB, CFB, NFL, NHL, MLB with sport-specific pipelines, post-hoc isotonic calibration (held-out ECE 1.4%–9.2% by sport), and a four-layer prediction pipeline: base model, team/player overlays, isotonic calibration, and live rolling recalibration.
Split-Phase XGBoost with 16 features including team offensive/defensive ratings (ORtg, DRtg), pace, momentum (scoring runs over last 2 and 5 minutes), Elo ratings, and interaction terms (score_diff × time_fraction). NBA Brier: 0.128, held-out ECE: 0.053. Trained on 5,285 games (2021–2026) with walk-forward season-based splits. Post-hoc isotonic recalibration on the 2024–25 season.
Injury overlay: 58 NBA star players tracked in real-time via ESPN's injury API (10-minute cache). Each player has a pre-computed impact factor (e.g., Jokic: 10%, LeBron: 8%, Curry: 9%). When a player is OUT, the model subtracts their impact; QUESTIONABLE halves the adjustment. Total cap: ±15%.
Model selection uses a hybrid criterion: near-best Brier score AND best trading value (c/trade) on a held-out backtest window. This prevents selecting models that look good on calibration metrics but produce worse P&L.
XGBoost with 17 features including all basketball features plus hockey-specific metrics: power play %, penalty kill %, save %, faceoff win %, and penalty minutes differential. NHL Brier: 0.184 (improved ~10% from the 0.205 pre-calibration baseline), held-out ECE: 0.028. Trained on 4,225 games.
Injury overlay: 44 NHL skaters tracked via ESPN (goalies excluded — handled by the separate goalie quality adjustment). Star impact factors: McDavid 10%, Draisaitl 8%, MacKinnon 9%, etc.
Goalie & shot overlay: Starting goalie detection adjusts for goalie quality. Expected goals (xG), Corsi, and power play state provide real-time shot quality signals. Combined cap: ±12%.
Ensemble model with starting pitcher ERA, WHIP, K/9 as base features. MLB Brier: 0.152, held-out ECE: 0.014. Three post-model overlays stack on top of the base prediction:
Live soccer trading is currently frozen (force-shadowed). The XGBoost model trained on 2,949 matches had silently vanished from the server in April 2026, degrading the live bot to a Poisson fallback that measures worse than its own entry prices. A retrained challenger failed its promotion gates, so the freeze stands, and a daily artifact-presence monitor pages if any model file disappears again. Pregame research continues on the Poisson + XGBoost stack.
Both esports run models on the platform; live order flow varies with each sport's current risk status. CS2 has been sizing-paused on realized CLV; LoL was reverted to its v1 analytical model in August 2026 after the v2 XGBoost override lost two independent head-to-head evaluations (see below).
CS2: 15 features including round differential, Elo, map-specific win rates (per team per map), recent form, head-to-head record, and Elo momentum. Economy data from bo3.gg and HLTV scorebot provides equipment value and consecutive-loss tracking as post-model overlays. Entry restricted to underdogs (20–42c) with 20c+ minimum edge after a live P&L audit found the model overperforms on underdog lines and underperforms on favorites.
LoL: v1 analytical model — Elo ratings plus a binomial series model for BO1/BO3/BO5. The v2 XGBoost override (20 features: gold differential, kills, towers, dragons, barons, inhibitor advantage, and more) was reverted in August 2026 after two independent evaluations on 110 fire-anchored matches both favored v1 (Brier 0.1692 vs 0.2077). The revert stands; v2 remains a shadow challenger.
Hierarchical analytical model: player-specific serve win rates (by surface) → point probability → game probability → set probability → match probability. Serve rates are computed from 13,174 ATP matches (2020–2024) using the Sackmann dataset, giving us player-specific rates for hard, clay, and grass surfaces instead of tour averages. Elo ratings are surface-aware (4,606 players). The live recalibrator auto-activates after 50 resolved trades.
Every prediction passes through two correction layers after the base model, and the system wraps them in three measurement-and-risk controls:
Spread and total models require a different setup from moneyline markets: regression on remaining margin or total, then a distributional layer to convert that forecast into cover/over probabilities.
Our backtests are designed to avoid the common mistakes that inflate results.
We believe in showing failures alongside successes.
Read the proof, inspect live results, or go straight to the live platform.