BenBrostoff / draftfast

A tool to automate and optimize DraftKings and FanDuel lineup construction.
278 stars 113 forks source link

CSV ingestion for showdown multiplies CPT salary by 1.5x #140

Closed BenBrostoff closed 5 years ago

BenBrostoff commented 5 years ago

Issue from e-mail:

I'm using draftkings, and when i load the salaries from csv which i get from DK, it looks like this (i'm just using Kurucs as an example): Position,Name + ID,Name,ID,Roster Position,Salary,Game Info,TeamAbbrev,AvgPointsPerGame PF,Rodions Kurucs (12488920),Rodions Kurucs,12488920,CPT,5100,PHI@BKN 04/18/2019 08:00PM ET,BKN,16.4 ... PF,Rodions Kurucs (12488887),Rodions Kurucs,12488887,UTIL,3400,PHI@BKN 04/18/2019 08:00PM ET,BKN,16.4 his salary as CPT is already 1.5x his regular salary. when draftfast is run, it takes this CPT salary and multiples it once again by 1.5. if you notice the output: | CPT (PF) | Rodions Kurucs | BKN | PHI@BKN 04/18/2019 08:00PM ET | 7650 | 25.92 | ←[0;31;40m0.00←[0m | | i'm guessing this would throw off the linear optimization. was it meant to do this? should i be using the same salary for CPT and UTIL as input? bc that would change which file i download from draftkings.

sharkiteuthis commented 5 years ago

I didn't realize the draftkings exports had the player twice, one for each position, so there's a middleware bit that takes every eligible player and makes a CPT record for them from the "standard" record by multiplying salary and points by 1.5.

My first inclination is just to throw away any lines with the CPT position, because not doing so means I have to rewrite some non-trivial chunks of the code that handles creating player records for showdowns... but that means either having "business" logic in the parser or writing another piece of middleware to filter them, and also means risking ineligible CPTs if DK decides to tweak those rules.

Can you put the file you referenced somewhere in the test tree? I'll sort out the cleanest way to handle this.

BenBrostoff commented 5 years ago

The issue here is:

class ShowdownPlayer(Player):
    def __init__(self, player: Player, captain: bool = False):
        for k, v in player.__dict__.items():
            if hasattr(self, k) or k.startswith('__'):
                continue
            setattr(self, k, deepcopy(v))
        if captain:
            self.real_pos = self.pos
            self.pos = 'CPT'
            self.captain = True
            self.proj *= 1.5
            self.cost *= 1.5
        else:
            self.real_pos = self.pos
            self.pos = 'FLEX'
            self.captain = False

I'm not sure about this - part of me feels like we should just ingest the CSV because DK is setting the 1.5 themselves. You can always overwrite proj and cost if you want.

I've done this in my most recent PR

BenBrostoff commented 5 years ago

Closing this since I think it's the right move to let the CSV do the talking here. We can return to this issue if people want to somehow make the captain multiplier configurable.