The NBA optimizer is taking shape, and the shape is strange: the stacking panel is empty, the position rules are the site’s own, and the one feature I actually care about is a number nobody else gives away for free. This is where NBA DFS variance comes in, and why it stopped being something you have to pay for.
Short version of the last three posts: basketball creates no linked scoring unit, so there is nothing to stack; I measured that across three seasons and the correlations are about an order of magnitude weaker than football’s; and the old Excel model I dug up had already reached that conclusion by deleting the columns. What survived all of that is one idea, and it came out of the spreadsheet.

The feature that used to cost money
The Excel version of this optimizer bounded the variance of a lineup, not just its projected score. That was the best idea in the file. It also looked, at the time, like something only a subscriber could do — the workbook was built around a paid projection feed a friend had access to, and every per-player number came from it.
Except variance is not a projection. A projection is a forecast and forecasting is hard. Variance is just how much a player bounces around, and that is a fact about games he has already played. Every box score in NBA history is available free through the public stats API. Take a player’s last twenty games, score them, take the standard deviation. Done.
Across three seasons and 536 rotation players, the median standard deviation of a DraftKings score is 9.7 points, and the median coefficient of variation — standard deviation divided by mean, the boom-or-bust number — is 0.44. So a typical player’s real range is nearly half his projection in either direction. That is not a rounding error you can ignore in a tournament.
The split I have landed on: projections stay bring-your-own, because judgment about what will happen is the thing you cannot give away. Variance is computed and shipped, because arithmetic on public data is not a competitive secret.
Risk as a constraint, not a vibe
The constraint is the same shape as the salary cap — each player’s variance dotted with the pick variables, bounded. What makes it useful is what the old workbook did next: after solving, it set the bound to the variance the solver just used plus a hair, and solved again.
So the second lineup is the best lineup available that is slightly riskier than the first. The third is slightly riskier than the second. Twenty solves is not twenty lineups, it is a walk up the efficient frontier with the best lineup at every level of risk — cash games live at the bottom, tournaments at the top. Same model, one parameter, opposite ends.
Underneath it is still the same knapsack it has always been. The variance bound is one extra row.
The pair table, and what it found on its own
There is a second free table. For every pair of teammates I correlated their minutes and their fantasy scores. The chart above is all 3,302 pairs, and the relationship is strong for this sport: r = 0.48. Teammates who split playing time score against each other.
What convinced me was not the correlation, it was the names. The most negatively correlated pair in three seasons is Isaiah Hartenstein and Mitchell Robinson — the Knicks’ center rotation, two men taking turns at the same position. Below them: Wiseman and Duren in Detroit, Diabaté and Kalkbrenner in Charlotte. The table finds center timeshares without ever being told what a center is, and without any position data at all.
That matters because it is the useful version of an idea I had already tested and rejected. Capping players by listed position per team does not work — two players at the same listed position are no more likely to share minutes than any other pair, because modern rotations substitute across positions. Minutes correlation finds the real pairs. Position labels find noise.
And the rule inverts between formats, which is what makes it worth shipping. Negatively correlated teammates reduce a lineup’s variance, because one’s good night is the other’s bad night — useful in cash, fatal in a tournament where you need the right tail. Positively correlated teammates do the opposite. One table, opposite sign, depending on what you are entering.
DraftKings and FanDuel do not score the same, so variance is not the same either
A detail I nearly got wrong. FanDuel pays 3 points for a steal or a block where DraftKings pays 2, charges a full point for a turnover instead of half, and pays no three-pointer or double-double bonus at all. I assumed that washed out. It mostly does:
| Comparison of player variance, DK vs FD | |
|---|---|
| Correlation of the two standard deviations | 0.983 |
| Average ratio of the two | 1.004 |
| Players moving more than 50 places in the variance ranking | 52 of 536 |
Ten percent of the league moves substantially, and it is not random which ten percent: the movers are the steal-and-block specialists, who gain on FanDuel, and the turnover-prone, who lose. Those are exactly the players a variance constraint picks at the margin. A correlation of 0.98 was hiding a systematic difference in the part of the distribution I actually use, so the table carries a column per site.
What is not going in
No stacking rules, because the correlations are not there. No position caps per team, for the reason above. Nothing keyed to the Vegas spread — I tested whether the game-script effect is visible before lock and it is not; the spread explains about 4% of the variance in final margin. No ownership-based leverage, because ownership projections have no free source and I am not building a feature that only works if you pay someone else.
What is left is the site’s own roster and salary rules, a per-team cap, the eligibility filters, the variance bound, the pair rule, and set-level diversity. Fewer knobs than a baseball optimizer, and every one of them earns its place.
What I have not proved
Two things, and I would rather say them now than be asked later.
The salary files that DraftKings and FanDuel hand you contain player names. The variance table is keyed by the stats API’s player IDs. Those two disagree about accents, suffixes and nicknames, and if the match rate is not very high the feature cannot ship — a player who fails to match has to quietly keep his place in the pool rather than vanish from it. My old workbook had an entire worksheet devoted to reconciling names, which tells you how much of a problem this is.
And the larger one: everything above argues the variance bound should produce better tournament lineups. None of it is evidence that it does. That needs a backtest against real slates once the season starts, comparing a plain max-projection set against a variance-walked set. Until that runs, this is a well-motivated design and nothing more, and I have spent enough of this project retracting things to want the distinction on the record.
Things that I use, like, and am affiliated with:
Mint Mobile offers great cell phone service for $15 flat, get $15 off using the link. Get discounted phones with service activation and no contract.
I never spend money before I check Mr Rebates or Rakuten to get cashbacks, rebates, discounts, coupons or cheaper gift cards.
