NBA Four-Factors Composite

Calibration

When a forecast says 70%, does it happen 70% of the time? First the market (no-vig close against results), then the model, with the market's forecast on the same games beside it.

How to read these numbers Here the null is the diagonal: stated = actual. Market is Kalshi's last pre-tip price wherever a game has one (2025-26 on), else the sportsbook close; the hypotheses stay on the sportsbook prices they were registered on. ± is one standard error (1 SE). Colour marks only gaps of at least 2 SE from the null: green above, red below; everything else is left plain. Shaded columns are the ones to read first.
Glossary
Lean
The side the model gives ≥ 50% (as recorded on the row).
Value side
The side where the model's probability beats the market's no-vig probability. Graded only through the pre-registered hypotheses; the blanket value bet is retired (see the note under the hypotheses).
Model %
The picked side's mean model win probability.
Market %
The picked side's mean no-vig market probability (q): the price with the bookmaker's margin removed.
Win %
How often the picked side actually won.
Break-even
The win rate the posted price needs to pay back; above q by about the hold.
ROI
Profit per 1-unit bet.
Null
The ROI expected if the market is right (q × payout − 1). vs null = ROI − null.
z
(ROI − null) ÷ SE. Across many cells, about one in twenty shows |z| ≥ 2 by chance.
EV
Win % − break-even; its null is q − break-even.
Fav ROI
1u on the market favourite of the same games at the same price: the same-row baseline a pick rule has to beat (a tie at 50% goes to home).
Log loss, Brier
Proper scores of the probabilities; lower is better. Compared with the close on the same games.
Native
Written before tip and frozen: the forward test.
Reconstructed
Scored afterwards with that season left out of the fit and graded at the close: hindsight, never forward evidence.

Market: no-vig close vs actual

ESPN BET 1209 games
Favourites won
69.6%
vs 69.3% implied: +0.4 ± 1.3 (1 SE) — not resolved (z = +0.3) · n=1196
Home sides won
54.8%
vs 55.2% implied: -0.4 ± 1.3 (1 SE) — not resolved (z = -0.3) · n=1209
Market calibration, both sides of every game
Market (no-vig close)
0%0%20%20%40%40%60%60%80%80%100%100%Stated probabilityActual win rateMarket (no-vig close), 0.0–0.2: stated 14.6%, actual 11.6% (n=259, ±2 SE 4.4 pp)Market (no-vig close), 0.2–0.3: stated 25.4%, actual 26.4% (n=292, ±2 SE 5.1 pp)Market (no-vig close), 0.3–0.4: stated 35.2%, actual 38.1% (n=341, ±2 SE 5.2 pp)Market (no-vig close), 0.4–0.5: stated 44.5%, actual 41.4% (n=304, ±2 SE 5.7 pp)Market (no-vig close), 0.5–0.6: stated 55.0%, actual 57.9% (n=330, ±2 SE 5.5 pp)Market (no-vig close), 0.6–0.7: stated 64.8%, actual 61.9% (n=341, ±2 SE 5.2 pp)Market (no-vig close), 0.7–0.8: stated 74.6%, actual 73.6% (n=292, ±2 SE 5.1 pp)Market (no-vig close), 0.8–1.0: stated 85.4%, actual 88.4% (n=259, ±2 SE 4.4 pp)

Each point is one probability bin: across the x-axis what was stated, up the y-axis how often it happened. On the dashed diagonal = calibrated. The bar is ±2 SE, where a correct forecast would usually land; a bar that misses the diagonal is a real miss, not noise. Hover a point for its numbers; the table below has them all.

By price rung and side — actual vs implied, gap ± 1 SE
Price rungHome sideAway sideBoth sides
≤ -25079.0% vs 79.2% -0.2 ± 2.0 · n=39678.2% vs 78.0% +0.3 ± 2.9 · n=20278.8% vs 78.8% -0.1 ± 1.6 · n=598
-249 to -17561.8% vs 64.6% -2.9 ± 4.1 · n=13665.9% vs 64.5% +1.3 ± 4.3 · n=12663.7% vs 64.6% -0.8 ± 3.0 · n=262
-174 to -13063.3% vs 57.5% +5.8 ± 4.4 · n=12853.0% vs 57.2% -4.2 ± 4.6 · n=11558.4% vs 57.4% +1.1 ± 3.2 · n=243
-129 to -10044.3% vs 51.1% -6.8 ± 5.6 · n=7965.3% vs 51.1% +14.3 ± 5.8 · n=7554.5% vs 51.1% +3.5 ± 4.0 · n=154
+100 to +12941.8% vs 44.9% -3.1 ± 5.0 · n=9841.2% vs 45.2% -3.9 ± 5.1 · n=9741.5% vs 45.1% -3.5 ± 3.6 · n=195
+130 to +17440.5% vs 38.6% +1.9 ± 4.6 · n=11134.9% vs 39.0% -4.1 ± 4.3 · n=12937.5% vs 38.8% -1.3 ± 3.1 · n=240
+175 to +24933.3% vs 31.9% +1.4 ± 4.5 · n=10832.9% vs 31.4% +1.4 ± 3.8 · n=14633.1% vs 31.6% +1.4 ± 2.9 · n=254
≥ +25017.6% vs 19.4% -1.8 ± 3.2 · n=15319.7% vs 18.6% +1.2 ± 2.2 · n=31919.1% vs 18.9% +0.2 ± 1.8 · n=472

1209 games (0 native, 1209 reconstructed; seasons 2024-25). Two observations per game, one per side; ± is one SE under correct prices, so a gap under ~2± is indistinguishable from fair. No both-sides total: the sides sum to 1 and one wins, so it is 50% by construction. Favourites asks once per game.

Kalshi 1209 games
Favourites won
69.8%
vs 69.8% implied: +0.0 ± 1.3 (1 SE) — not resolved (z = -0.0) · n=1207
Home sides won
55.3%
vs 55.0% implied: +0.3 ± 1.3 (1 SE) — not resolved (z = +0.3) · n=1209
Market calibration, both sides of every game
Market (no-vig close)
0%0%20%20%40%40%60%60%80%80%100%100%Stated probabilityActual win rateMarket (no-vig close), 0.0–0.2: stated 13.5%, actual 14.8% (n=298, ±2 SE 3.9 pp)Market (no-vig close), 0.2–0.3: stated 25.2%, actual 23.2% (n=263, ±2 SE 5.3 pp)Market (no-vig close), 0.3–0.4: stated 35.1%, actual 34.4% (n=317, ±2 SE 5.3 pp)Market (no-vig close), 0.4–0.5: stated 44.7%, actual 45.9% (n=329, ±2 SE 5.5 pp)Market (no-vig close), 0.5–0.6: stated 55.2%, actual 54.2% (n=332, ±2 SE 5.4 pp)Market (no-vig close), 0.6–0.7: stated 64.9%, actual 65.4% (n=318, ±2 SE 5.3 pp)Market (no-vig close), 0.7–0.8: stated 74.8%, actual 76.8% (n=263, ±2 SE 5.3 pp)Market (no-vig close), 0.8–1.0: stated 86.5%, actual 85.2% (n=298, ±2 SE 3.9 pp)

Dashed diagonal = calibrated; bars are ±2 SE. Hover a point for its numbers.

By price rung and side — actual vs implied, gap ± 1 SE
Price rungHome sideAway sideBoth sides
≤ -25079.9% vs 80.3% -0.3 ± 2.0 · n=39981.4% vs 80.0% +1.3 ± 2.8 · n=20480.4% vs 80.2% +0.2 ± 1.6 · n=603
-249 to -17568.8% vs 64.7% +4.1 ± 4.3 · n=12562.0% vs 64.8% -2.8 ± 4.3 · n=12165.4% vs 64.7% +0.7 ± 3.0 · n=246
-174 to -13061.1% vs 57.4% +3.7 ± 4.3 · n=13155.8% vs 57.2% -1.4 ± 4.5 · n=12058.6% vs 57.3% +1.3 ± 3.1 · n=251
-129 to -10038.8% vs 50.6% -11.9 ± 5.6 · n=8055.2% vs 51.1% +4.1 ± 5.4 · n=8747.3% vs 50.9% -3.6 ± 3.9 · n=167
+100 to +12949.2% vs 44.5% +4.6 ± 4.5 · n=12042.9% vs 44.2% -1.3 ± 4.5 · n=11946.0% vs 44.4% +1.7 ± 3.2 · n=239
+130 to +17437.0% vs 37.6% -0.5 ± 4.7 · n=10839.2% vs 37.6% +1.6 ± 4.4 · n=12038.2% vs 37.6% +0.6 ± 3.2 · n=228
+175 to +24936.5% vs 30.7% +5.8 ± 5.0 · n=8525.0% vs 30.4% -5.4 ± 4.2 · n=12029.8% vs 30.5% -0.8 ± 3.2 · n=205
≥ +25014.3% vs 17.5% -3.2 ± 3.0 · n=16117.6% vs 17.3% +0.3 ± 2.1 · n=31816.5% vs 17.4% -0.9 ± 1.7 · n=479

1209 games (0 native, 1209 reconstructed; seasons 2025-26). Two observations per game, one per side; ± is one SE under correct prices, so a gap under ~2± is indistinguishable from fair. No both-sides total: the sides sum to 1 and one wins, so it is 50% by construction. Favourites asks once per game.

Model vs market, same games

Native · forward

No graded model rows with a close yet.

Reconstructed · hindsightESPN BET close · 2024-25log loss model − market +0.0118 ± 0.0050 · n=1209
Probabilities vs the close (log loss)
Market better
by 2.4 SE · model − market +0.0118 ± 0.0050 (1 SE)
0.5940 vs 0.5821 · n=1209
Brier (model / market)
0.2042 / 0.1995
model − market +0.0047 ± 0.0022 (1 SE) · market better by 2.2 SE
Picked the winner (model lean / market favourite)
68.2% / 69.1%
same games · accuracy is not calibration
Model vs market calibration, P(home win)
Model Market (no-vig close)
0%0%20%20%40%40%60%60%80%80%100%100%Stated probabilityActual win rateModel, 0.0–0.2: stated 15.0%, actual 10.5% (n=76, ±2 SE 8.2 pp)Model, 0.2–0.3: stated 25.6%, actual 26.2% (n=103, ±2 SE 8.6 pp)Model, 0.3–0.4: stated 35.1%, actual 37.3% (n=153, ±2 SE 7.7 pp)Model, 0.4–0.5: stated 45.6%, actual 45.1% (n=153, ±2 SE 8.0 pp)Model, 0.5–0.6: stated 55.1%, actual 54.6% (n=152, ±2 SE 8.1 pp)Model, 0.6–0.7: stated 64.9%, actual 64.6% (n=209, ±2 SE 6.6 pp)Model, 0.7–0.8: stated 75.0%, actual 74.9% (n=187, ±2 SE 6.3 pp)Model, 0.8–1.0: stated 86.4%, actual 81.2% (n=176, ±2 SE 5.1 pp)Market (no-vig close), 0.0–0.2: stated 14.8%, actual 4.0% (n=75, ±2 SE 8.2 pp)Market (no-vig close), 0.2–0.3: stated 25.3%, actual 31.4% (n=105, ±2 SE 8.5 pp)Market (no-vig close), 0.3–0.4: stated 35.2%, actual 35.0% (n=160, ±2 SE 7.5 pp)Market (no-vig close), 0.4–0.5: stated 44.6%, actual 44.3% (n=149, ±2 SE 8.1 pp)Market (no-vig close), 0.5–0.6: stated 55.1%, actual 57.7% (n=168, ±2 SE 7.7 pp)Market (no-vig close), 0.6–0.7: stated 64.8%, actual 59.1% (n=181, ±2 SE 7.1 pp)Market (no-vig close), 0.7–0.8: stated 74.5%, actual 76.5% (n=187, ±2 SE 6.4 pp)Market (no-vig close), 0.8–1.0: stated 85.5%, actual 85.3% (n=184, ±2 SE 5.2 pp)

Each point is one probability bin: across the x-axis what was stated, up the y-axis how often it happened. On the dashed diagonal = calibrated. The bar is ±2 SE, where a correct forecast would usually land; a bar that misses the diagonal is a real miss, not noise. Hover a point for its numbers; the table below has them all. Both forecasts are for the same games; each is binned on its own probability. Negative model − market on the scores means the model did better; an interval spanning 0 has not separated them.

Model bins in numbers — with the market's mean on the same games
Model P(home)nModel meanMarket mean (same games)ActualActual − model (± 1 SE)
0.0–0.27615.0%17.1%10.5%-4.5 ± 4.1
0.2–0.310325.6%27.9%26.2%+0.6 ± 4.3
0.3–0.415335.1%35.8%37.3%+2.2 ± 3.9
0.4–0.515345.6%45.4%45.1%-0.5 ± 4.0
0.5–0.615255.1%54.5%54.6%-0.5 ± 4.0
0.6–0.720964.9%64.1%64.6%-0.3 ± 3.3
0.7–0.818775.0%72.3%74.9%-0.1 ± 3.2
0.8–1.017686.4%84.4%81.2%-5.1 ± 2.6
Reconstructed · hindsightKalshi close · 2025-26log loss model − market +0.0159 ± 0.0055 · n=1209
Probabilities vs the close (log loss)
Market better
by 2.9 SE · model − market +0.0159 ± 0.0055 (1 SE)
0.5837 vs 0.5677 · n=1209
Brier (model / market)
0.1995 / 0.1937
model − market +0.0058 ± 0.0024 (1 SE) · market better by 2.4 SE
Picked the winner (model lean / market favourite)
69.0% / 69.7%
same games · accuracy is not calibration
Model vs market calibration, P(home win)
Model Market (no-vig close)
0%0%20%20%40%40%60%60%80%80%100%100%Stated probabilityActual win rateModel, 0.0–0.2: stated 15.8%, actual 14.3% (n=70, ±2 SE 8.7 pp)Model, 0.2–0.3: stated 25.6%, actual 21.1% (n=95, ±2 SE 8.9 pp)Model, 0.3–0.4: stated 35.2%, actual 33.8% (n=136, ±2 SE 8.2 pp)Model, 0.4–0.5: stated 45.1%, actual 45.3% (n=172, ±2 SE 7.6 pp)Model, 0.5–0.6: stated 54.9%, actual 53.9% (n=204, ±2 SE 7.0 pp)Model, 0.6–0.7: stated 65.0%, actual 65.8% (n=190, ±2 SE 6.9 pp)Model, 0.7–0.8: stated 75.0%, actual 78.7% (n=178, ±2 SE 6.5 pp)Model, 0.8–1.0: stated 85.7%, actual 85.4% (n=164, ±2 SE 5.4 pp)Market (no-vig close), 0.0–0.2: stated 13.7%, actual 12.1% (n=99, ±2 SE 6.9 pp)Market (no-vig close), 0.2–0.3: stated 25.2%, actual 22.3% (n=94, ±2 SE 8.9 pp)Market (no-vig close), 0.3–0.4: stated 35.2%, actual 38.9% (n=144, ±2 SE 7.9 pp)Market (no-vig close), 0.4–0.5: stated 45.0%, actual 45.6% (n=171, ±2 SE 7.6 pp)Market (no-vig close), 0.5–0.6: stated 55.5%, actual 53.8% (n=160, ±2 SE 7.8 pp)Market (no-vig close), 0.6–0.7: stated 65.1%, actual 69.4% (n=173, ±2 SE 7.2 pp)Market (no-vig close), 0.7–0.8: stated 74.9%, actual 76.3% (n=169, ±2 SE 6.7 pp)Market (no-vig close), 0.8–1.0: stated 86.6%, actual 83.9% (n=199, ±2 SE 4.8 pp)

Dashed diagonal = calibrated; bars are ±2 SE. Hover a point for its numbers. Both forecasts are for the same games; each is binned on its own probability. Negative model − market on the scores means the model did better; an interval spanning 0 has not separated them.

Model bins in numbers — with the market's mean on the same games
Model P(home)nModel meanMarket mean (same games)ActualActual − model (± 1 SE)
0.0–0.27015.8%15.1%14.3%-1.5 ± 4.3
0.2–0.39525.6%24.4%21.1%-4.5 ± 4.5
0.3–0.413635.2%34.4%33.8%-1.4 ± 4.1
0.4–0.517245.1%45.6%45.3%+0.2 ± 3.8
0.5–0.620454.9%53.6%53.9%-1.0 ± 3.5
0.6–0.719065.0%64.3%65.8%+0.7 ± 3.5
0.7–0.817875.0%75.2%78.7%+3.7 ± 3.2
0.8–1.016485.7%85.7%85.4%-0.4 ± 2.7

Bet grading by price band (ROI, EV and their nulls) is on the Ledger.

Built 2026-10-19 07:42 UTC. Win probabilities from prior-game four factors, roster talent and the NBA injury report; the market is a benchmark only and never enters the model. Full statistics: ledger_report.txt · model tags and coefficients: Model. Not betting advice.