NBA 2026-27 Wins Model

built 2026-10-28 15:40 · darko 2026-10-28 15:40 · rosters 2026-10-28 15:40 · schedule 2026-10-28 15:40 · build 2026-10-28 15:40 · etr 2026-10-28 15:40 · monster_ros 2026-10-28 15:40 · fanduel 2026-10-28 15:40 · sim 2026-10-28 15:40

Last refresh 2026-10-28T15:40

StepStatusWhenDetail
darkook2026-10-28T15:40521 players, ratings through 2026-10-26, market rating 502 players as of 2026-10-27
rostersok2026-10-28T15:40519 players, 30 teams, file age 0h
scheduleok2026-10-28T15:401200 games, 56 played
buildok2026-10-28T15:40built
etrok2026-10-28T15:40303 ETR + 63 FPPG-imputed mpg + 139 depth-chart fill; mpg fit -19.8+14.26ln(fppg) rmse 2.5; team min 19,680-19,876; ETR pull 2026-10-18 12:04
monster_rosok2026-10-28T15:40dump 2026-10-27 11:46 ET (1.2 days old), 522 rostered, 58 with an est. return
fanduelok2026-10-28T15:40202 markets (2824 prices)
simok2026-10-28T15:4020,000 sims in 1.7s, 2147 FanDuel prices, 727 +EV

Input files

data/darko_talent_latest.csv2026-10-28 15:40
data/monster_ros_2026-27.csv2026-10-27 11:46
data/rosters_latest.csv2026-10-28 15:40
data/etr_projections_2026-27.csv2026-10-28 15:40
data/hashtag_projections_2026-27.csv2026-10-03 15:40
data/schedule_2026-27.csv2026-10-28 15:40
data/fanduel_futures_latest.json2026-10-28 15:40
data/market_win_totals.csv2026-09-28 11:01

Config files (edit these, then rerun build)

config/player_overrides.csv2026-09-28 11:01
config/name_aliases.csv2026-10-27 09:55
config/minutes_overrides.example.csv2026-09-28 12:01
config/rookie_model.csv2026-09-28 12:35
config/rookie_priors.csv2026-09-28 10:56
config/rookie_consensus.csv2026-09-28 12:23

Rating sources in use

{
 "darko": 517,
 "darko_feb2026": 2,
 "undrafted_prior": 1
}

Team sources

{
 "monster": 518,
 "espn": 2
}

Model constants

player rating = 50% DARKO DPM + 50% DARKO market rating (closing-spread implied, per 100; MARKET_WEIGHT=0.5); DPM alone where there is no market rating
DARKO ratings through 2026-10-26 · market as of 2026-10-27 · market covers 99% of projected minutes
minutes (per game, game_model.py): role MPG = mean of ETR original MPG and Monster ROS m/g; Monster INJ / OUT / D players play none of the games before their
  est. return (Q half, X none); once healthy, chance per game = Monster ROS games / team games left from the return; next game capped by P/Q/D (0.85/0.5/0.2)
each game: expected minutes over 240 come off the bottom of the rotation, a shortfall is spread over who is available (+20% of role, max 40), the rest filled at -2.2
team net that game = 5 × Σ(rating × minutes) / 240; Net = average over remaining games, Next = next game, Full = a typical game once everyone currently hurt is back
P(home win) = Φ((that game's net_home − net_away + 2.3) / 12.5); wins = actual + Σ remaining probs + unscheduled games (end-of-season roster) vs average
next slate: Monster's daily projected minutes + status (props board's 10-min cache of RJ's Monster daily export) replace the model for every player it lists
Monster ROS comes from a browser dump (RJ's login): python3 monster_ros.py <dump>, script in scripts/monster_ros_dump.js; /status flags it after 3 days
Rookies: college BPM + age at draft + ln(pick) model (config/rookie_model.csv), slot prior for internationals
Minutes (Per game): ETR games x ETR MPG; MPG from ETR FPPG where ETR gives games only; minutes ETR leaves open go to its unprojected depth-chart players
Refresh: python3 refresh.py (DARKO, ESPN rosters, Hashtag, schedule+results, ETR minutes rebuild) then build

ETR per-game stats: how they are recovered

StatPool mean / gPool sd / g
PTS12.805.861
REB4.732.283
AST2.941.880
STL0.860.325
BLK0.530.451
3PM1.440.871
TO1.480.738

Per-game stat = pool mean + z × pool sd. ETR's points-league FPPG (Underdog scoring) is exactly linear in its 9-cat z-scores (R² 0.99999, rmse 0.02 FP), so that regression gives each sd (3PM from DraftKings best-ball PPG). ETR doesn't reveal pool means: those are Monster's means on 297 matched players, scaled ×1.049 to hit ETR's FPPG intercept. FG% and FT% z-scores are volume-weighted in ETR's ranks, so they stay z-scores. Blank stats = ETR publishes no z-scores for that player (outside its 9-cat top 300). Team stats = Σ(per-game × games) / 82 over players with ETR stats. Off/Def = 5 × Σ(DARKO O/D-DPM × minute share); rookies on the college model carry only a total DPM.