Optimizing your Daily Fantasy Sports Team using Python

A couple of months ago a friend insisted on betting me on the Daily Fantasy Sports game that is used where I live. I was a bit hesitant, because I don’t like the rules of this particular DFS. He insisted so much that I ended accepting and winning 11 out of the 13 contests.

The method I used for optimizing my lineup was based on the simulated annealing technique. This is a great method to have under one’s toolbox and use it to optimize problems with a huge search space. The problem of finding the optimum lineup is a combinatorial optimization where, in this case, I needed to choose 15 players from a pool of 460. My approach was to invest 90 % of the budget in the starters, so I needed to choose the 11 best players (per rules of the game) that satisfied the budget and formation constraints. The 4 players that needed to go the bench were exhaustively search using dynamic programming from a lot less candidates.

Simulated annealing is a probabilistic technique that finds a solution that is close to the global optimum. The basic idea is the following: you start with a random state (you choose 11 players that satisfy the budget and formation constraints) and you keep proposing random valid changes to the state until some defined condition is met. To avoid getting trapped in local minimums, both positive and negative changes are accepted with a probability that depends on the state of the system. For example the nearer the process is to completion, the lower the probability of accepting negative changes.

Ok, let’s see some code:

We have defined a base Selector class that uses a combination of annealing and exhaustive search to arrive at the optimized formation. Implementation for concrete games (like the GranDT selector) need to define a couple of attributes and we are good to go.

This is how the annealing file looks like

The objective is to minimize the energy of the state. The energy of the state is the sum of the value of the players * (-1). The value of a player is the sum of its stats weighted by the rules of the game.

Finally, this is the exhaustive search for selecting the bench