← All findingssource · memory/project_brier_vs_vegas_closed.md
Measured 2026-07-28 on 3,007 WNBA props (full 2026 season, 2026-06-04..07-22, base rate 48.1%). n is enough to detect a 1% Brier edge at 2-sigma (needs 1,253), so these are well-powered negatives, not "inconclusive".
The number that reframes everything: the market's entire edge over always guessing the base rate is +1.31% (Brier 0.24636 vs 0.24963). Market resolution is 0.00205 = 0.82% of available variance. Vegas barely separates hits from misses either. WNBA single-prop outcomes are close to irreducible.
Six closed paths (all vs market Brier on held-out data):
- Blend model P(over) with market — optimal model weight exactly 0.000
- Perfect calibration of our model — 0.2477 vs market 0.2466, still behind
- 26 features w/ logit(market_p) as fixed offset, n=1,099 — -3.30% OOS
- [internal detail removed]
- Thin-market (<=3 books) over-bias — in-sample z=-2.28 died OOS to z=-1.05; applying the fitted shift made Brier -0.04% WORSE
- Minutes — see below
The minutes oracle was an artifact. rate10 x TRUE minutes gives +4.04% (real; floor 0.65%). rate10 x PREDICTED minutes gives -7.11%. The whole oracle edge is realized game script (blowout benchings, foul trouble, mid-game injury) — unreachable at ANY MAE. So the "get minutes MAE under 3.2" target was chasing a number that could never have paid out. Don't re-set it. (Best model was 3.584; LOO player-constant floor 3.469.)
-
De-vig method — proportional vs power vs Shin: all within +0.02% on a 1.09% floor. 8. Book aggregation — median/mean/Pinnacle-only/ Pinnacle-else-median/sharp-pair: all within noise; Pinnacle ALONE is -0.31% vs the 5-book blend (consensus beats any single book). So the benchmark "median all books / proportional" was never naive. Book coverage: DK 98%, FD 95%, Caesars 85%, BetOnline 59%, Pinnacle 54%.
-
Cross-market shade (props-sum vs the sharper game-total market) — the best idea of the lot and it FAILED only after two leaks were removed. v1 took team membership from the boxscore, so scratched players kept their props but left their team's sum. v2 fixed that and still showed +1.49% OOS, monotone across quartiles — but its game-line consensus was in-play-contaminated. Strictly pre-tip: quartiles go non-monotone (all |z|~1), coefficient collapses 6x (-0.2437 -> -0.0394), Brier -0.36%.
10-13. Sharper price readings — best-price-each-side de-vig (+0.27%), hold-weighted consensus (+0.11%), fitted book weights (+0.20%), all on a 1.04% floor. Fitted weights zeroed Pinnacle/BetOnline/Caesars entirely and loaded FanDuel/DK: transparent train-noise fitting.
- Combo props (PRA/PR/PA/RA) — theory said books convolve the legs as independent and drop the covariance terms, understating Var(P+R+A). Tested with each player's OWN empirical combo distribution (carries the correlation for free). n=2,774, base 52.3%: market 0.24924, empirical -5.55%, normal-on-own-sd -3.41%, fitted blend -3.46%. The market prices combos correctly. Combos are NOT a soft spot.
FORWARD RECONFIRMATION (2026-07-28, fresh data): encompassing test on 2,077 props 06-20..07-27 (train 1,186 / held-out 891): logistic blend coefficient on the model b = −0.04 (market fully contains the model); logit blend z=−1.17 vs market, best convex mix λ=0.02 with held-out gain +0.000025 (z=+0.38), per-stat λ (assists 0.23 on train) z=−0.78. Path #1's "optimal weight 0.000" holds on data none of the models were tuned on.
MULTIPLE COMPARISONS: 14 paths tested. At p<0.05 roughly one spurious "win" is EXPECTED by chance — and exactly one appeared (cross-market v2, +1.49% over a 1.04% floor) and proved to be leakage. Any further search on this dataset manufactures false positives by construction. Stop searching; the negative is settled.
GAME-LINE FEED GOTCHA (reusable): odds-service /odds/game/{game_id}
game_odds rows have is_live=false UNCONDITIONALLY, and 897/1000 of the
freshest-per-book quotes are scraped AFTER game day (WNBA tips ~23:00Z, so
01:00-04:00Z next-day rows are in-play/post-final). Freshest-per-book on
game lines = reading the score. Bound it with the earliest is_live=true
timestamp among that game's PLAYER props, fallback 16:00Z. grading-service
internal/oddsclient/gamelines.go already does this via the prop-derived
latch — production is clean; ad-hoc analysis is what got burned.
The goal was also the wrong target. Brier is bounded by base rate, and WNBA props are priced to a coin flip by construction: 97% sit within +/-10pp of 0.500, only 3 of 3,007 exceed +/-15pp. Uncertainty alone is 0.2496. propsbot's advertised 0.1903 is ARITHMETICALLY IMPOSSIBLE on a 48% base-rate population — it must be a different market (favourite-heavy moneylines or alt lines), so it was never comparable to our 0.2464. A 0.19 is manufacturable in a day by scoring only lopsided props and wins no bets.
No external minutes feed exists to rescue it: SDS /nba/lineups/date
returns players: [] on every game; /wnba/lineups/date returns
"capability not implemented for this league". RotoWire read-path is present
but dark.
Why: the model's AUC is 0.506 — it cannot rank at all. That is more fundamental than the Brier gap: a model with no average edge can still pay if it selects the mispriced subset, and this one demonstrably cannot.
How to apply: stop treating average Brier over all props as the objective — you don't bet all props. This is consistent with project_decision_layer_audit: price is the only validated signal. Edge here comes from stale/off-consensus prices (what the slip builder checks, see project_slip_builder) or from information the market lacks at decision time — a latency game, not a modelling one. Related: feedback_model_edge_calibration, project_projections_engine_state.