Nat TaylorObservations & more

A Naive Experiment in Programmatically Optimizing DraftKings NFL Lineups: Part 1

DraftKings is a daily fantasy sports (DFS) sports site that has awarded millions of dollars of payouts every season and enticed millions of players to join and deposit, all under of the premise of believing they are “smarter than the average fan.”  I set out to test how good players are at maximizing player value within the salary cap, compared to an algorithm.  The test had many shortcomings, but in 10 free Week 1 contests, the algorithm’s average finish was the 40th percentile which is promising for winning 50/50 and H2H contests.

The Algorithm

Each lineup must have 1 QB, 2 RB, 3 WR, 1 TE, 1 FLEX and 1 DST with a total salary less than $50,000, which allows for around half-a-billion combinations.  We want to maximize the total team score, so we will use freely available score projections to compare lineups, ensuring that they are projected according to DraftKings NFL scoring rules.

My algorithm compares a randomly selected lineup to the current top lineup and keeps the winner, `n` times.  Once it has selected a winner, it checks if there is a better player for each position at the remaining salary.

Note: after I did this, I learned this is a well documented as the “knapsack problem.”

You can read the resulting 300 LOC of PHP on Github, which is all triggered by main()

function main($draftGroupId) {
	$players = generatePlayers($draftGroupId);
	$players = filterTopPlayers($players);
	$maxTeam = array(0,array());
	$scores=array();

	for($i = 0; $i < TRIALS; $i++) {
		$team = pickRandomTeam($players);
		$score = calcTeamScoreSimple($team);
		$scores[] = $score;
		if( isMaxScore($score,$maxTeam[0]) ) {
			$maxTeam = array($score,$team);
		}
	}

	$previousMaxTeamScore = $maxTeam[0];
	$maxTeam[1] = maximizeTeamSimple($maxTeam[1],$players);
	$maxTeam[0] = calcTeamScoreSimple($maxTeam[1]);
	$maximizationGain = $maxTeam[0] - $previousMaxTeamScore;

	//Print Results
	echo printScores(calcScoreCounts($scores));
	echo "Score of ".$maxTeam[0]." for salary of $".calcTeamSalary($maxTeam[1]).
		" after a maximization gain of ".$maximizationGain."\n";
	echo printTeamInOrder($maxTeam[1]);
}

The Test

My test was simple and incomplete.

  1. Select a lineup with the algorithm
  2. Enter the lineup in a free tournament contest
  3. Measure performance as the finishing place out of the total entries

The Results

On average, the algorithm finished in the 40th percentile, with a max of 12th and min of 86%.  No analysis of the competitors has been attempted.

Game Rank Enrties Tier Points Max 1% 5% 10% 25% 50%
9169909 2664 6565 41% 122 204 170 155 147 132 116
9169898 3576 6953 51% 115 212 175 160 150 134 116
8296816 5622 47414 12% 150 215 179 161 152 137 120
8469652 48308 331428 15% 144 221 177 159 150 134 116
8777686 32303 42299 76% 108 223 185 168 159 144 127
9172130 6029 6974 86% 108 215 189 175 167 154 137
9273251 777 6426 12% 142 191 168 152 144 131 116
9169884 4116 6852 60% 103 189 164 149 140 125 109
9169853 1262 13108 10% 144 201 167 152 144 132 118
« »