zlisto / Daily-Fantasy-Baseball-Contests-in-DraftKings

This is the code for constructing a portfolio of lineups for DraftKings baseball contests with a top heavy payoff structure. This code is based on the paper Picking Winners Using Integer Programming by David Hunter, Juan Pablo Vielma, and Tauhid Zaman (https://arxiv.org/abs/1604.01455).
37 stars 27 forks source link

Methodology behind the programs #5

Open bwatkin79 opened 6 years ago

bwatkin79 commented 6 years ago

This isn't really an issue, but more a question regarding your logic. I don't see a general question option though versus issues. Sorry if this is a Github sin.

In your hockey program, you had the players separated into goalies and skaters. In that program, you were also filling one slot for a utility player. In the baseball program, it appears the pitchers and batters are combined into players_lineup, then selected from there. In the baseball program, there is no utility player.

I'm wanting to add a utility player to the baseball program. Was there a reason you separated the players in the program where you had a utility player or could I just modify the baseball constraints to resemble the ones from lines 519-537 in the hockey program and fill the csv similar to the data_cleaning file on lines 92-152. It appears an array isn't necessary for utility players because of the constraint from the hockey program. Am I right? Please provide your insight. I'm new to Julia and trying to make some modifications. Thanks.

jnederlo commented 6 years ago

The hockey program was done by the authors of the paper "Picking Winners". Zlisto took this and adapted it for Baseball, and it appears he made it specifically for rotogrinders inputs. MLB contests as far as I'm aware, don't have utility players, so there won't be a point adding it, but if that's what you want to do then I think you want to change the position constraint. Because with a utility player you are now allowing the player to be any position, so you would do something like change this line of code to '==2' as follows:

BEFORE: @constraint(m, sum(OF[i]*players_lineup[i] for i=1:num_players)==3)

AFTER: @constraint(m, sum(OF[i]*players_lineup[i] for i=1:num_players)==2)

I believe doing this will just let the optimizer pick whoever it wants for the last outfield spot. Of course all of the other positions will still have to be filled, but you would have 1 spot that could be filled by anybody. If you wanted to do more than one, or you wanted to relax the constraints on other positions, then you would just do something similar for the other constraints. As far as I'm aware that's all you need to do.

bwatkin79 commented 6 years ago

Thanks for responding jnederlo. I believe zlisto was one of the authors of the paper, at least from what I can tell. I took the method used in the hockey program and applied it to the baseball program because I'm modifying the program to be used with Fanduel. I think I have that part working right, but I wouldn't guarantee it. Based on the example data, the program is filling the output file with the players and adding the utility player in the final slot. I've run several trial runs and the utility player does have a position that varies, so it makes me think I did it right at least. For this issue, I guess I was just wondering if there was a reason the program with a utility player had the players divided into two groups(goalies and skaters), while the program that did not have utility player did not separate the players. It appears to work without separating, but just checking.

The constraint that I'm struggling with is choosing players in lineup slots 1-5 or 1-6. Based on winning lineups from Fanduel, the lineups are almost always won with players in those slots. I think the constraint would use the :Batting_Order_Confirmed_ object, but I'm not sure because of how arrays are used in the program and other parts too. Arrays are totally new to me as is Julia. In issue 4, I provided the constraint I attempted to write, but I'm doing something wrong. Since I don't know julia or JuMP, I have no idea what. I'm reading some of the Julia docs right now to try to figure it out, but otherwise I have no idea what needs changed.

jnederlo commented 6 years ago

You are right, he is one of the authors of the paper. To answer your first part, the fact that it is split up into 2 parts for goalies and skaters whereas it's only one part for baseball is of no consequence. It's simply just an organization. You can access the data the same in either approach. For baseball it's in a Dataframe. You can print out the dataframe to see it (julia will display it nicely for you). In read_player_data() you can see that the two files, one for pitchers, and one for hitters, are put into a single Dataframe called 'players'. You can print players at the end of the function to see it.

As for you second part, if you want to limit batting orders to 6 and under, for example. Then just restrict who you input to the optimizer in the first place. Alternatively, you could just remove players with batting orders above 6 from the 'players' dataframe. Either way would only give you lineups with guys in the batting order 6 and under.