benbrostoff / draftfast Goto Github PK
View Code? Open in Web Editor NEWA tool to automate and optimize DraftKings and FanDuel lineup construction.
A tool to automate and optimize DraftKings and FanDuel lineup construction.
FLEX (RB)
)Happy holidays all :) Is there a quick hack to support banning defenses? I've been digging around but figured I would ask!
Thanks!
him new to python, I'm getting this error
Traceback (most recent call last):
File "optimize.py", line 196, in
rosters.append(run(POSITIONS[args.l], args.l, remove))
File "optimize.py", line 107, in run
raise Exception('No solution error')
Exception: No solution error
any advice? much appreciated.
Would cover FanDuel and DraftKings.
Hi, great app you got here, I've never been able to truly understand google or tools to the fullest, but it's extremely fast and that's what got me interested in your app.
The issue I'm having is trying to generate let's say 100 lineups in the NBA, without randomly removing a player, just rather based on total projected points. I understand you implemented the randomness to get rid of similar lineups, but that's the thing I've been trying to reverse. Any tips on how?
Currently exists for NFL - same structure can be used.
Applies for NBA where DraftKings will list players as PF/SF
or something similar - the optimizer should handle this by placing the player in the optimal position. Right now, it simply picks the first position (PF
in the PF/SF
example) and uses that one.
I'm working off my branch and it doesn't seem like the 'duo' and 'dtype' constraints are actually implemented. Are these stashed on another branch somewhere?
# nosetests --exe
....F......................
======================================================================
FAIL: test.test_command_line.test_duo_constraint
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/nose/case.py", line 198, in runTest
self.test(*self.arg)
File "/dk/test/test_command_line.py", line 78, in test_duo_constraint
ntools.assert_equal(team_instances[team], 2)
AssertionError: 0 != 2
-------------------- >> begin captured stdout << ---------------------
Optimized over 622 players
Optimal roster for: NFL
+------------+-----------------+------+--------------------+--------+------------+----------+--------+
| Position | Player | Team | Matchup | Salary | Projection | vs. Avg. | Locked |
+------------+-----------------+------+--------------------+--------+------------+----------+--------+
| QB | Russell Wilson | Sea | Mia@Sea 04:05PM ET | 7900 | 20.6 | -1.17 | |
| RB | Lamar Miller | Hou | Chi@Hou 01:00PM ET | 7000 | 14.6 | -0.52 | |
| RB | Latavius Murray | Oak | Oak@NO 01:00PM ET | 5600 | 12.0 | -1.24 | |
| RB | Spencer Ware | KC | SD@KC 01:00PM ET | 4400 | 11.8 | 4.22 | |
| WR | Amari Cooper | Oak | Oak@NO 01:00PM ET | 7200 | 11.6 | -2.69 | |
| WR | Vincent Jackson | TB | TB@Atl 01:00PM ET | 4400 | 7.1 | -3.93 | |
| WR | Tajae Sharpe | Ten | Min@Ten 01:00PM ET | 3000 | 5.5 | 5.50 | |
| QB/TE (TE) | Eli Manning | NYG | NYG@Dal 04:25PM ET | 7500 | 17.8 | -2.41 | |
| DST | Bengals | Cin | Cin@NYJ 01:00PM ET | 3000 | 8.2 | -0.57 | |
+------------+-----------------+------+--------------------+--------+------------+----------+--------+
Projected Score: 109.20 Cost: $50000
--------------------- >> end captured stdout << ----------------------
----------------------------------------------------------------------
Ran 27 tests in 5.909s
FAILED (failures=1)
If I set my vs_avg to a certain number and then I lock a player who is outside of that vs_avg, the player does not lock.
Can the locking feature happen outside of the vs_avg constraint?
Thanks!
Not working in new pip module.
This makes it annoying to get set up after a fresh clone.
Hey man!
This is an awesome gem that I came across when I was looking to start working on something similar. I went through the entire codebase, ran different parts of it, stepped through some debug traces and such primarily to figure out how it worked. From the perspective of someone who knows nothing going through the README I think I can offer some edits and help to make it more clear how the library works, what data it pulls, command line options and examples.
Let me know if you are interested and I will submit a PR.
Other thoughts on data sources for projections:
I also want to try merging player data projections from all three sources and running the solver, I am thinking we can use edit distance and comparable fantasy point projection margins to match players with slightly different name spellings, otherwise we can use team/position data to match them. I also thought about including expert rankings consensus or other data sources. We could also backtest projections for the year and see which source has the most accurate fantasy projections and when we average the results together give the most accurate sources a weighted average that favors them more.
Traceback (most recent call last):
File "nfl/prepare_data.py", line 7, in
with open(dk_csv, 'rb') as f:
IOError: [Errno 2] No such file or directory: 'data/current-salaries.csv'
The only uploader that is complete and tested is the DraftKings NBA one. This should also be documented in the README.
see here:
def run(league, args, existing_rosters=None, exposure_bounds=None):
if exposure_bounds:
exposure_args = get_exposure_args(...)
args.locked = exposure_args['locked']
args.banned = exposure_args['banned']
This might be resolved when you pip-ify the module for #63 and get away from the namespace stuff.
Not doing this is causing an issue right now with Michael Thomas
and a few others. This will allow DUPLICATES
to finally be retired, because this was a dumb solution.
Hello -
I downloaded a Salaries.csv off DraftKings, and ran the bash script (sudo bash scripts/prepare_nba_contest_data.sh) which appeared to work fine.
However, when I ran the optimizer script(sudo python optimize.py -league NBA -source nba_rotogrinders) I received the following error:
Traceback (most recent call last):
File "optimize.py", line 338, in
rosters.append(run(args.league, remove, args))
File "optimize.py", line 83, in run
_check_missing_players(all_players, args.sp, args.mp)
File "optimize.py", line 266, in _check_missing_players
'Total missing players at price point: ' + str(miss_len))
dke_exceptions.MissingPlayersException: Total missing players at price point: 112
Any suggestions are much appreciated.
Thanks!
Stuff like data_cleaning_constants
should be in data. The whole repo could use a little reorganization.
Lint should run prior to commit.
Hi,
I am running the command python optimize.py -pids ../../Downloads/DKSalaries.csv and getting
NFL_Draftkings module does not exist.
I'm new to python and coding in general but any guidance would be awesome.
Best,
Nishon
The API here seems interesting and could serve as a model.
Thanks for this repo, it has potential. I thought about using another Python constraint library to do the same thing but I thought I'd play with this one.
First off, you should consider using Buildout so that the dependencies are met. I had to get three modules before I could get to this point.
Have you gotten this issue before? And are you using virtualenv by any chance?
Much appreciated Ben!
FanDuel drops the worst performance for NBA.
The attached CSV will produce a lineup with only 8 players. I am poking around but figured I would post.
+------------+-----------------------+------+--------------------+--------+------------+----------+--------+
| Position | Player | Team | Matchup | Salary | Projection | vs. Avg. | Locked |
+------------+-----------------------+------+--------------------+--------+------------+----------+--------+
| PG | Ricky Rubio | Min | Min@Ind 07:00PM ET | 7400 | 41.8 | 9.694 | |
| PG | Ish Smith | Det | Mia@Det 07:30PM ET | 5000 | 29.7 | 8.193 | |
| PG/SG (SG) | Lou Williams | Hou | GS@Hou 08:00PM ET | 5200 | 28.0 | 0.051 | |
| PG/SF (SF) | Giannis Antetokounmpo | Mil | Mil@Cha 07:00PM ET | 9700 | 49.8 | 1.341 | |
| SF/PF (SF) | Justin Anderson | Phi | Phi@Bkn 07:30PM ET | 3100 | 24.3 | 11.243 | |
| SF/PF (PF) | Paul George | Ind | Min@Ind 07:00PM ET | 8400 | 42.5 | 3.701 | |
| C | Alan Williams | Pho | Pho@Atl 07:30PM ET | 5400 | 32.8 | 14.986 | |
| C | Clint Capela | Hou | GS@Hou 08:00PM ET | 5400 | 31.1 | 4.212 | |
+------------+-----------------------+------+--------------------+--------+------------+----------+--------+
Projected Score: 280.0 Cost: $49600
Projection Source: numberFire
No solution found for command line query.
Try adjusting your query by taking away constraints.
Active constraints: {}
Player count: {}
Traceback (most recent call last):
File "nba.py", line 62, in <module>
existing_rosters=rosters,
From #82
It be nice to have group constraints. E.g. I want at least 30% each of MG3, CMC, Saquon, DJ, Chubb and I want each lineup to have at least 2 of those 5.
Group constraints could also handle things like "No RB against opposing DST" and "limit to X of Y players"
From discussions with people using this project (and my own workflow), I realize run
is the core functionality most people care about (and that's a bad name - it really should be called optimize
).
This would be exposed in a pip module if I ever ship one. Ideally, this library could be easily added to whatever scripts people have for their DFS workflow and it could be extended to any game that has positions, players and salaries. So if a new website or DFS game pops up, it would be easy to do something like:
import GameRules from draft_kings_fun
...
game_rules = GameRules(roster_size=10, position_limits=[['UTIL', 6]], salary_cap=30000)
roster = run(
game_rules=game_rules,
...
)
The reason this isn't possible now is that run
takes a Namespace
object from argparser
. This interface doesn't make sense and needs to be changed. While I still want to maintain the CLI - I often find it useful for experimenting with different strategies - there can be a layer between the CLI and the pip module so they can speak to each other. Said another way, the CLI should be independent from the library exposed by pip.
This also should remove run
/ optimize
's dependency on passing CSV file paths to it.
Running python2 -m pip install -r requirements.txt
gives me the following error:
Could not find a version that satisfies the requirement ortools==6.8.5452 (from -r requirements.txt (line 11)) (from versions: 4.1.3717, 4.2.3724, 4.2.3758, 4.2.3790, 4.3.3802, 4.3.3803, 4.3.3805, 4.4.3842, 5.0.3919, 5.1.4045, 6.0.4217, 6.1.4333, 6.3.4430, 6.3.4431, 6.4.4495, 6.5.4527, 6.6.4656, 6.6.4659)
No matching distribution found for ortools==6.8.5452 (from -r requirements.txt (line 11))
Has anyone else run into this?
Exposure currently doesn't have tests / does not play well with the new refactor.
via @BenBrostoff:
Not necessary on this PR but future idea - my process with exposure right now is also to look pretty closely at how players are paired across lineups. The best visualization for this IMO is matrix like thing:
Player A | Player B | Player C | |
---|---|---|---|
Player A | X | 2 | 1 |
Player B | 2 | X | 2 |
Player C | 1 | 2 | X |
Realize this probably is significantly more work / not necessarily suggesting it's the best way to visualize it, but I can open a separate issue since I think it's at least somewhat important. Before I looked at this info I used to make the mistake of thinking I was diversified when in reality I would have a lot of unique players but not a lot of player mixtures across lineups.
Originally posted by @BenBrostoff in https://github.com/_render_node/MDIzOlB1bGxSZXF1ZXN0UmV2aWV3VGhyZWFkMTQzMTE1NzMwOnYy/pull_request_review_threads/discussion
Current:
with open('data/current-projections.csv', 'w') as fp:
w = csv.writer(fp, delimiter=',')
w.writerows(hold)
This should be configurable and not hard coded.
CSV upload should be simplified and done the same way across leagues. This PR does some refactoring. The function signature for update_upload_csv
now takes a roster and the function body is shorter. This PR should remove the different files for different CSV downloads in favor of one module that can take league params.
Before I dive into making an attempt to provide some usefulness to this repo I just wanted to check whether my results are expected.
When I optimize a NBA Roster I generally will have to ban some players in order to satisfy the DK position constraints (PG,SG,SF,PF,etc...). Is this expected behavior or should I always be getting a lineup that easily fits into my DK lineup? I pulled this roster today that does not fit into DK automagically (It is missing a guard)
+------------+------------------+------+--------------------+--------+------------+----------+--------+
| Position | Player | Team | Matchup | Salary | Projection | vs. Avg. | Locked |
+------------+------------------+------+--------------------+--------+------------+----------+--------+
| SF | LeBron James | Cle | Cle@Por 10:30PM ET | 9700 | 54.11 | 1.943 | |
| PF/C (PF) | Kevin Love | Cle | Cle@Por 10:30PM ET | 8100 | 42.05 | -0.153 | |
| PG | Mike Conley | Mem | Mem@OKC 08:00PM ET | 6900 | 37.68 | 2.001 | |
| C | Marc Gasol | Mem | Mem@OKC 08:00PM ET | 6800 | 36.98 | -1.231 | |
| C | Marcin Gortat | Was | Was@Bos 08:00PM ET | 6000 | 33.35 | 1.135 | |
| PF/C (PF) | Gorgui Dieng | Min | Hou@Min 08:00PM ET | 5400 | 29.62 | 2.206 | |
| SF | Maurice Harkless | Por | Cle@Por 10:30PM ET | 4000 | 24.41 | 0.857 | |
| SG/SF (SG) | Corey Brewer | Hou | Hou@Min 08:00PM ET | 3000 | 16.63 | 7.515 | |
+-
Would need to change testing too. Possible use tox.
This isn't really an optimizer since players just choose from five tiers without salary constraints. The naive approach which will be first iteration here is just choosing the max projected in each tier. Note that DK also offers lineup upload here, so we will want to have that functionality and tests as well.
Additional features:
~/draft-kings-fun/data$ grep Todd *
current-projections.csv:Todd Gurley LAR ,17.59
current-salaries.csv:RB,Todd Gurley II,6000,IND@LAR 04:05PM ET,12.450,LAR
The idea here would be to be able to pass the optimizer a subset of the slate and have these be the only players the optimizer can choose from.
The next part here (which would be substantially more difficult) would be to allow passing a pool and maximum exposures as a CSV that looks something like this:
name, exposure
Player A, 0.90
Player B, 0.35
Player C, 0.5
Any player with a percentage not specified would be assumed to be allowed to be 100% of lineups, and at minimum would need to be in at least 1%.
high
, low
, average
, st_dev
, etc. in Player
It would be v nice if we could no longer use code to open files such as:
open('data/current-salaries.csv', 'r')
With this being used as a submodule in the other repo, I get errors related to paths all the time. Instead if we could use python's os.path to get the path relative to the file the code is in then it could be guaranteed to work.
path.join(path.split(path.realpath(__file__))[0], 'data', 'current-salaries.csv')
assert_equal
instead of assert
in nosetest
docker-compose
idk how to perform a commit or a pull request so ill just post the issue. Update this:
data_cleaning_constants.py
RENAMES = [
#{'dk_name': '', 'name': ''},
{'dk_name': 'Maurice Harkless', 'name': 'Moe Harkless'},
{'dk_name': 'Larry Nance Jr.', 'name': 'Larry Nance'},
{'dk_name': 'Glenn Robinson III', 'name': 'Glenn Robinson'},
{'dk_name': 'Cristiano Felicio', 'name': 'Cristiano Da Silva Felicio'},
{'dk_name': 'Juancho Hernangomez', 'name': 'Juan Hernangomez'},
{'dk_name': 'DeAndre' Bembry', 'name': 'DeAndre Bembry'},
{'dk_name': 'James Michael McAdoo', 'name': 'James McAdoo'},
{'dk_name': 'James Ennis III', 'name': 'James Ennis'},
{'dk_name': 'Kelly Oubre Jr.', 'name': 'Kelly Oubre'},
{'dk_name': 'Joe Young', 'name': 'Joseph Young'},
{'dk_name': 'Tomas Satoransky', 'name': 'Tomas Satoransky '},
]
I started working on some NBA utilities last year but it's messily lumped into optimize.py
. We should break this into a separate module and find some good data sources for it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.