TFF Fantasy League Optimiser
Tagline: Optimal TFF Fantezi Lig squads from form, fixtures, and integer programming — not vibes.
Built with: Python · PuLP · Pandas · Sofascore · FotMob · TFF Fantezi Lig API · Pillow
Inspiration
Fantasy football in Turkey’s Süper Lig is intense: 100M budget, strict squad rules, weekly fixtures, and scoring that rewards minutes, clean sheets, goals/assists, and bonuses. Most tools stop at price lists or gut picks. We wanted something that actually answers: given this week’s opponents and real form, what’s the best legal 15-man squad? Especially early in the season — when one good match can look like a season — we needed Bayesian-style caution, not hype.
What it does
TFF Fantasy League Optimiser builds a weekly recommended squad for the official TFF Fantezi Lig:
- Pulls player prices and availability from TFF
- Estimates expected points from Sofascore + FotMob (form, season stats, xG/xA, minutes)
- Respects official scoring (60+ minutes, CS, cards, bonuses, etc.)
- Solves an integer program for the best formation, starting XI, bench, and captain under 100M / 2-5-5-3 / max 3 per club
- Advises whether to play a manager card or save it
- Exports a clean weekly PNG report (pitch, fixtures, card call)
One command (calistir.bat or python -m src.main) → ready-to-use lineup.
How we built it
Python end-to-end pipeline:
- Ingest — TFF client for prices/availability; Sofascore & FotMob for performance (cached)
- Score — Per-player expected points with opponent strength, home/away, early-season blending of prior season when sample size is tiny
- Calibrate — External-league → Süper Lig translation from historical transfers (
league_translation.json), not a flat “foreign = weaker” guess - Optimize — PuLP integer program over formations; weighted bench for auto-subs
- Advise — Manager-card opportunity ranking vs. saving the card
- Report — Pillow-generated weekly pitch graphic
Challenges we ran into
- Early-season noise: One clean sheet can look like 100% CS probability; unplayed clubs look like 0%. We had to shrink small samples and blend with last season.
- Same-club goalkeepers: Without start probability, a backup with one lucky CS could beat the real #1.
- New transfers / foreign leagues: Mapping Ligue 1 or Championship rates into Super Lig TFF points needed real transfer history, not hand-waved multipliers.
- Name matching & availability: TFF vs Sofascore vs FotMob naming, plus injured/suspended exclusions.
- Card advice without inventory: We rank opportunity value (use vs save), not account stock.
Accomplishments that we're proud of
- A full legal fantasy squad in one run — not just a ranked list
- Transparent reasons per player (why this XP, start %, CS blend)
- Robust early-season / GK / form fallback logic that doesn’t overfit week 1
- League translation calibrated on real Super Lig arrivals
- A weekly PNG report you can actually share or screenshot into decisions
What we learned
Expected points ≠ last match points. Sample size, role (starter vs backup), fixture difficulty, and prior-season priors matter more than a viral one-off performance. Also: fantasy scoring is a product of team defense and individual minutes — modeling only goals misses half the game for GKs and defenders.
What's next for TFF Fantasy League Optimiser
- Live / confirmed XI signals when available
- Multi-week transfer planning (bank, hits, chip windows)
- Stronger integration of official TFF points for mid-season calibration
- Optional web UI on top of the same optimizer
- More automated regression checks on “week 1 traps” (hot GKs, zero-sample clubs)
Built With
- cursor
- fantasyleague
- football
- fotmob
- pandas
- sofascore
- tff
- ts
Log in or sign up for Devpost to join the conversation.