$ show BenBrostoff/draftfast
This repository provides a Python library and CLI tool for optimizing daily fantasy sports (DFS) lineups on DraftKings and FanDuel. It reads player salary and projection data from CSV files, enforces contest-specific constraints (salary cap, position limits, custom rules like stacks and exposure), and uses Google OR-Tools to solve the constrained optimization problem, producing lineups that maximize projected points. The library supports a wide range of sports (NFL, NBA, MLB, NHL, soccer, golf, NASCAR, tennis, CS:GO, F1, XFL, and various Showdown/Pickem contest types) and includes utilities for downloading salary CSVs and generating upload files for mass lineup entry. The architecture is a classic monolithic Python package with a clear separation of concerns: data parsing (`csv_parse/`), player pool construction (`player_pool.py`), constraint definition (`lineup_constraints.py`, `settings.py`), optimization core (`optimizer.py`), and output formatting (`orm.py`, `uploaders.py`). The test suite is comprehensive with sport-specific tests and CSV fixtures. The codebase demonstrates practical application of constraint programming to a real-world combinatorial optimization problem, though some components are tightly coupled to the DFS domain.
The LLM identified 3 files worth highlighting for reuse:
Provides deterministic and random exposure argument generation to enforce min/max ownership percentages across a set of lineups. The algorithms are independent of sport-specific logic and could be repurposed for any scenario requiring controlled repetition of selections across multiple optimization runs (e.g., portfolio construction, team selection). It imports from internal ORM (Roster, Player) but the core logic for generating exposure limits is separable.
Defines LineupConstraints class that encapsulates banned/locked players and positions. The builder-style API (add_banned_player, add_locked_position) is self-contained and can be reused across different optimization setups. It depends on the Player class from orm.py for type hints, but the structure is a clean pattern for declaring discrete constraints in a combinatorial solver context.
Contains OptimizerSettings, PlayerPoolSettings, CustomRule, and Stack classes. CustomRule allows users to define arbitrary constraints via a (callback, rule_type, position_group) tuple, enabling complex rules like 'do not pair a QB with opposing defense' or 'force at least 2 players from one team'. The Stack class models stacking constraints (e.g., QB+WR from same team). This pattern provides a flexible DSL for extending OR-Tools constraints without modifying the optimizer core, and could be adapted to other optimization problems requiring user-defined constraints.