Loading draft…
Loading draft…
A pipeline of small, versioned Python models (fantasy CLI). Agents only run them and act on their JSON; every output is recorded in model_runs with its version, git sha, parameters and input hashes.
12 teams, head-to-head over 9 categories: FG%, FT%, 3-pointers made, points, rebounds, assists, steals, blocks and turnovers (fewer is better). Each Mon–Sun week you play one opponent and win, lose or tie each category separately; the season standings count category wins. 13 roster spots (10 starters a day, 3 bench) plus 3 injured-list slots and 6 free-agent adds per week. The top 6 make the playoffs in weeks 18–20 (Mar 1–21, 2027). You draft 1st; the order is a snake with a third-round reversal, so your picks are 1, 24, 36, 37, 60, 61, 84, 85, … — big gaps, then back-to-back pairs.
gp_sd(15–24 games, larger for injury-prone players).Each player gets a per-category score standardised over the draftable pool (12 × 13 players). Counting stats use the expected per-game line (games played × production, with missed games partly back-filled by a streamed replacement player). FG% and FT% are computed from makes and attempts: the score is the player's "impact" makes − pool% × attempts, so a 90% shooter on 2 attempts matters less than an 85% shooter on 8.
Scores are G-scores (Rosenof 2024): the denominator adds week-to-week noise, so volatile categories (steals, blocks, 3PM, turnovers) count a little less — right for weekly H2H. The headline value is the sum over categories above replacement level. It is used for ranking and the fallback list; actual draft decisions come from the optimizer below.
A team's weekly total in each category is approximated as Normal (counting stats sum; percentages are total makes / total attempts with delta-method variance). The opponent is a league-average team, built by drafting the pool in ADP order, with the spread between league teams added as variance.
P(win category) = Φ(difference / combined sd); expected category wins = the sum of the nine probabilities; P(win matchup) treats categories as independent. This is the objective the optimizer maximises.
optimizer-0.4.0, per the latest draft simulation run).recommend_policy); if the value search fails, the optimizer's order is used with a warning.Many full drafts are simulated from my slot. The other 11 teams pick by Yahoo ADP plus noise; my picks come from the optimizer and, on the same simulated rooms, from a best-player-available baseline. The paired difference gives the edge with a proper standard error (sd/√n). It also yields who I tend to take at each pick, example rosters, and the spread of my category profile.
A Monte Carlo of the whole season (season-sim-0.3.0): every team's roster, the real 2026-27 NBA schedule (games per team per day), week-by-week H2H matchups, a daily 10-starter cap, streaming adds, standings and a re-seeded 6-team playoff bracket.
fantasy sim preseason drafts several simulated leagues (me = optimizer, others = noisy ADP), plays each one out and grades it with our own projections. That is the status-quo scenario, the optimistic end (96.5% playoffs / 54.8% title for slot 1). After the draft it runs on the real rosters.