The sophistication upgrade: stop guessing, start measuring.
The shift
v1 estimated goals by judgment then priced from scratch — the inputs were guesses. v2.0 adds the proven retail edge: don't out-predict the market — beat the soft book (SportyBet) against the sharpest one (Pinnacle). Where SportyBet pays more than the sharp de-vigged "true" price, that gap is real value.
New (all pure-stdlib urllib, still zero-dependency)
engine/edge.py— sharp-line comparison core (reusesmarket.pyde-vig).engine/sources/— data adapters: The Odds API (Pinnacle + many books), Club Elo, Understat xG, Football-Data.co.uk.engine/backtest.py— soft-vs-sharp replay on real history → ROI / hit-rate / CLV (prove the edge before paying).engine/report.py— new SHARP% column (ODDS% vs SHARP% vs MY%).engine/config.py+.env.example— one free key (The Odds API) via gitignored.env.
Data-fed xG/Elo flow through the existing engine (run.py strengths/elo specs) — no math changed. Keyless except The Odds API (free, 500/mo).
Quality
- 64 → 104 tests across 4 suites; all run fully offline on committed sample fixtures.
- CI runs all four on Python 3.10–3.12.
Honest ceiling
Soft-vs-sharp value is real but fragile (limits, line moves, thin margins). v2.0 makes the inputs data-grounded and provable via backtest — a big upgrade over guesses — but profit is never guaranteed.
🤖 Generated with Claude Code