Methodology
CLV evidence refreshed 2026-10-07

How we build independent win probability models

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.

Snapshot 2026-07-22 78 days old

Retraction · 2026-07-21

The "78-point CLV gap" claim has been retracted

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?

  • /validation — exported backtest snapshot. What the model would have done on a defined sample with current filters baked in.
  • /results — filtered public ledger. Confirmed positions under the published loader contract, including losses and nonbinary outcomes; the page also reports measured execution-identifier and direct-transaction-hash coverage.
  • /clv-evidence — retraction. Why the "78-pp CLV gap" we used to publish was a measurement artifact, with the control that proved it.

ZenHodl Weekly

Get the weekly results and one modeling note.

One weekly email with live results, one model insight, and product updates.

A short weekly note for builders, traders, and researchers following the model.

Why independent probabilities matter

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)

Data pipeline

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.

10k+
Games
Millions
Snapshots
Multi
Sports
Multi
Seasons

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.

Feature engineering

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

Model architecture

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.

Current live platform — supported sports

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.

Basketball & Football (NBA, NCAAMB, NCAAWB, CFB, NFL)

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.

Hockey (NHL)

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

Baseball (MLB)

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:

Soccer (Bundesliga, EPL, La Liga, Serie A, Ligue 1)

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.

Esports (CS2, LoL)

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.

Tennis (ATP, WTA)

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.

Post-model overlay stack (all sports)

Every prediction passes through two correction layers after the base model, and the system wraps them in three measurement-and-risk controls:

  1. Post-hoc isotonic calibration: Fitted on held-out calibration season. On the calibration season it is fitted to, the residual ECE is near zero — but the honest out-of-sample figure, measured on held-out test seasons the calibrator never saw, is 1.4%–9.2% by sport (best MLB 0.014, worst NFL 0.092). When a well-calibrated model says 70%, teams win about 70% of the time.
  2. Live rolling recalibration: Automatically refits an isotonic correction every 25 resolved trades per sport, using a 500-sample rolling buffer persisted to disk. Catches calibration drift from rule changes, roster turnover, or seasonal patterns without manual intervention.
  3. Closing-line value (CLV) audit: Admitted live fills are measured against our captured closing price where one exists; the scorecard publishes the current measured count and coverage rather than freezing an old percentage into this methodology page. The winner/loser split we used to cite here was retracted 2026-07-21 as a measurement artifact; the honest unconditioned aggregate (share of fills beating the close and mean CLV per trade) is published per sport at /clv. The four-failure-mode taxonomy (bad model / bad blend / bad timing / bad CLV label) is published at /clv/repair alongside the explicit reactivation criteria for any sport currently paused.
  4. Dynamic position sizing: Rolling 50-trade performance per sport determines a size multiplier (0.25x–1.5x). Hot sports (>55% WR + positive P&L) get sized up; cold sports (<40% WR) get sized down. Recomputed every 10 minutes.
  5. Meta-model edge filter (research, shadow mode only): A Gradient Boosting classifier trained on resolved trades was proposed to separate real edges from noise. It has never been trusted to block live trades — it runs in shadow mode as a research instrument. The "filters 28% of losing trades" figure we once cited was not reproducible and has been removed.

Spread/Total

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.

Backtesting methodology

Our backtests are designed to avoid the common mistakes that inflate results.

What we tried that doesn't work

We believe in showing failures alongside successes.

Choose your next step

Read the proof, inspect live results, or go straight to the live platform.