Out-of-sample evaluation against market lines, 2026-27
An out-of-sample evaluation of the frozen model against market lines, on paper, under a pre-registered rule: nothing here places a wager and nothing here is a pick. One snapshot a day of one book's player-points lines from a documented odds API, compared with the nightly prediction under a rule that was written down before the first game and is never tuned on this season's results. Raw lines and prices stay in a private repository; this page shows only the aggregates the warehouse computes from them. Every number below is labelled out of sample; the in-sample replay numbers on the decisions page are never pooled with them.
The pre-registered rule
ledger_rule_v1, status final, registered 2026-10-10 for a first live date of 2026-10-20; sha256 ae7b1a2e0053 of the rule text is written on every ledger row. Model fb427de (asof_v1), unchanged.
- Lines
- draftkings Points at 20:00 UTC (The Odds API free plan, one snapshot a day); games whose commence_time is after the snapshot; games already started are out of scope and counted. Hand-typed draftkings / caesars lines for points, rebounds, assists are reported separately.
- Eligibility
- At least 1 earlier game this season, a last-10 minutes mean of at least 15, inputs at most 10 days old.pre-game proxy for the training population (min10): at a 15-minute floor 95.7% of the proxy rows are min10 and 86.3% of min10 rows are kept; 98.2% of min10 rows have inputs at most 10 days old (reports/ledger_rule_evidence_2025-26.json).
- Entry when
- |prediction − line| exceeds points 1.75, rebounds 0.7, assists 0.5; over above the line, under below it. one unit risked per bet, every bet; from the captured American price on the bet side.the edge constants already pre-registered per target on the training population (reports/policy_2025-26.json populations.min10.targets.<target>.threshold).
- Settlement and reading
- Won, lost, push on the line, void only when the box score exists and the player has no row in it; pending until the box score arrives. Verdicts start at 100 settled entries and only when the 95% interval excludes the break-even rate implied by the prices.separating a 55% hit rate from the 52.4% break-even of -110 takes about 1,400 settled bets: n = (1.96 * sqrt(0.55 * 0.45) / (0.55 - 0.524))^2 = 1,406.
the model is a LightGBM regressor trained on squared error (a conditional mean); a book's line sits near the median and points are right-skewed, so the rule may lean to overs; not adjusted for, reported by side in mart_ledger_by_side. source api only; manual lines never enter the headline numbers. Full text: nba/ledger/rule.py and ADR-0030 in docs/DECISIONS.md.
Coverage and open entries
No 2026-27 rows yet: the first live date is 2026-10-20, and the coverage mart has a row only once a game night has passed.
Headline ledger (API lines, one book, points market)
No entries yet (0 settled, 0 pending). The rule expects none on opening night, when no player has an earlier game this season.
What this is not
Not advice and not picks: an evaluation record of a frozen model, with no wager placed and nothing to act on. Not a profitability claim: in-sample (2025-26 replay) and out-of-sample (2026-27 ledger) are labelled and never pooled; no profitability claim without n and a confidence interval. The model knows nothing about injuries or rest; a line set after news the model has not seen is a line it will look "wrong" about. Lines are captured once a day and compared with a prediction made before them; a dbt test fails the build if any entry's prediction was generated after its line or any line was read after tip-off.