mts1b-sports
Sports betting: DFS lineup optimization, sportsbook arb, esports, consensus aggregation, Bradley-Terry rating models.
Repo: github.com/MTS1B/mts1b-sports Layer: 6 Wave: 3 (months 8-12) Depends on: foundation, platform, llm, operations, httpx, pulp Audience: sports bettors + DFS players
What it is
A treasury-allocated sleeve focused on sports. Treats sports markets as another asset class: ingests odds + outcomes, builds rating models, finds inefficiencies, sizes positions.
| Sub-area | What |
|---|---|
| DFS optimizer | Lineup construction under salary + constraint rules |
| Sportsbook arb | Cross-book arb detection (FanDuel, DraftKings, BetMGM, ...) |
| Esports | League of Legends, CS, Dota, Valorant odds + outcomes |
| Consensus | Median odds across N books |
| Ratings | Bradley-Terry + Elo + bespoke per-league |
⚠️ The Odds API key is dead — we use FreeOddsAggregator (FanDuel public + ESPN pickcenter) instead. Documented constraint.
Module layout
mts1b_sports/
├── odds/
│ ├── free_aggregator.py # FanDuel public + ESPN pickcenter
│ ├── normalizer.py
│ └── parser.py
├── dfs/
│ ├── optimizer.py # PuLP MILP
│ ├── projections.py
│ └── correlation.py
├── arb/
│ ├── detector.py
│ └── sizer.py
├── ratings/
│ ├── bradley_terry.py
│ ├── elo.py
│ └── per_league/
│ ├── nfl.py
│ ├── nba.py
│ └── ...
├── markets/
│ ├── nfl.py
│ ├── nba.py
│ ├── mlb.py
│ ├── nhl.py
│ ├── soccer.py
│ └── esports.py
└── api/
└── rest.py
DFS lineup optimizer
from mts1b_sports.dfs import optimize_lineup
lineup = await optimize_lineup(
sport="nba",
site="draftkings",
slate_date=date(2026, 5, 25),
salary_cap=50_000,
projections=projections_df, # custom proj
correlations=correlation_matrix, # stack/anti-stack
n_lineups=20, # GPP entries
exposure_caps={"LeBron": 0.30, ...}, # max % of lineups using each player
)
# [Lineup(players=[...], projected_points=295.4, salary_used=49_900, ...), ...]
Backed by pulp (mixed-integer linear programming). Solving 20 lineups under typical constraints: ~10s on a workstation.
Sportsbook arb
from mts1b_sports.arb import find_arbs
arbs = await find_arbs(
sport="nfl",
books=["fanduel", "draftkings", "betmgm", "caesars", "pointsbet"],
min_edge_pct=2.0, # net edge after juice
)
# [Arb(event="KC @ DEN", market="ml",
# legs=[(book="fanduel", side="KC -3", odds=1.91),
# (book="betmgm", side="DEN +3", odds=2.00)],
# net_edge_pct=2.3, stake_per_$100=0.49)]
Quirk: FanDuel inPlay=True games must NOT cross ESPN non-pre-state games (causes spurious 30%+ arbs from state mismatch). Adapter handles this.
Bradley-Terry ratings
from mts1b_sports.ratings import bradley_terry
ratings = bradley_terry(
games=historical_games_df, # winner, loser, weight columns
prior_strength=10.0,
iterations=100,
)
# pd.Series indexed by team, sorted by rating
Used to:
- Predict head-to-head probabilities
- Identify mispriced moneylines
- Build power rankings for narrative content
Per-league custom models layer on top (NBA: tempo + ORtg/DRtg adjustments; NFL: EPA-based; NHL: Corsi-adjusted).
Esports
Esports has weaker data infrastructure but higher inefficiency. Markets covered:
- League of Legends (LCS, LEC, LCK, LPL)
- CS2 (premier ESL leagues)
- Dota 2 (DPC majors)
- Valorant (VCT)
Custom scrapers since major odds aggregators undercover these.
Treasury integration
mts mts1b-treasury fund create --fund-id sports-dfs --nav 10000 --type sports
Sports funds use the same treasury + reporting + risk infrastructure as trading funds. P/L flows into the firm-level NAV.
Build + test
pip install -e ".[dev]"
pytest -m unit
pytest -m live --sport=nba # live data fetch
Roadmap
| Version | Items |
|---|---|
| 0.1 (Wave 3) | Free odds aggregator, DFS optimizer, arb detector, Bradley-Terry, 6 sports |
| 0.2 (Wave 3) | Esports expansion, live in-game models |
| 0.3 | Player-prop markets (PrizePicks, Underdog) |
| 1.0 (LTS) | Stable interface |
See also
mts1b-prediction-markets— sibling repo for non-sports prediction marketsmts1b-treasury— fund managementmts1b-llm— narrative generation for picks