A model that grades its own homework.
Lakeshore Edge is a personal sports betting edge dashboard. It compares sportsbook prices against a probability model, surfaces lines where the book disagrees, and (the part I actually care about) writes its own report card every night against the closing market.
Live numbers, pulled from the journal. The full audit lives on /model.
Why this exists
Most paid pick services hide their track record, count pushes as wins, and resurface old hits while the misses quietly disappear. I wanted the opposite: every recommendation snapshotted the moment it's published, auto-graded once the game settles, and reconciled against the closing line so the metric that actually matters (whether you got a sharper price than the market closed at) is in plain view.
Closing Line Value is the only metric that predicts long-run sharpness, and the only metric most touts refuse to publish. It's the first thing you'll see when you sign in.
How it works, in three pieces
- The model. Sport-specific Elo blended with recent form, plus context features (pitcher ERAs, weather, park factors, injuries, rest days). On top of that it watches the market itself: a Pinnacle-weighted multi-book consensus across FanDuel, DraftKings, BetMGM, and Pinnacle to flag when FanDuel's price is stale, plus line-movement, steam (synchronous cross-book moves), and reverse line movement (sharp vs. public divergence). Polymarket and Kalshi come in as real-money anchors when they list the market. It outputs a probability for each side and an honest verdict tier.
- The journal. Every recommendation gets snapshotted at publish time: model probability, market price, verdict tier, every feature value that fed the decision. When the game finishes, a nightly job auto-grades it and computes a closing-line snapshot.
- The calibration loop. The journal feeds back into the model. If MLB moneyline favorites have been running 11 points hot over the last 200 picks, tomorrow's model knows. Same for verdict tiers that overpromise.
The technical writeup of all three lives at /methodology.
What you'll find on the site
Honest about what this isn't
The model is currently overconfident on the magnitude of its edges. Hit rate sits around 43%, calibration gap around 10 points. The direction it picks is sharp (positive CLV), but it claims a bigger edge than the close ratifies. That's a calibration problem, not a signal problem. The loop is closing it.
This is a personal project, not a service. There's a sign-in (magic link, no card, no commitment) so you can save bet tickets and see stake recommendations, but the model audit, methodology, and the teaser slate are all open to read without an account.
Football is queued for late August 2026. The model isn't calibrated on NFL or NCAAF yet (no journal data), and I'd rather not surface uncalibrated picks. MLB, NBA, MMA, and tennis are live.
Stack and shape
Flask + Postgres + Alembic, deployed on Render. Background loops pull odds and Polymarket data every five minutes, line snapshots every five, and an overnight reflect job recomputes calibration offsets. ESPN scoreboards drive auto-grading. There's no front-end framework, just Jinja templates and a little vanilla JS. Boring on purpose; the interesting code is in the model and the journal.
Built by
One person, on nights and weekends. If you're a sharp who graded closing-line value before it was fashionable, or a developer who has seen this story play out and wants to point out where it'll break, I want to hear from you.