08 β Closing Line Value & Odds Data
TL;DR. Closing Line Value (CLV) β did our number beat the line at kickoff β is the gold-standard measure of betting skill (see Doc 1 Β§5 and Doc 6). The math is built and tested (in the probability model), and three tools wire it up. The blocker is data: computing real CLV needs opening and closing lines, which the free archives no longer hand out automatically and which don't exist yet for a season that hasn't started. This doc records what's available, where to get it, and exactly how to run the tools once you have it.
1. Why CLV, in one paragraph
By kickoff the line has absorbed all information and the week's biggest limits, so the closing line is the most efficient public predictor of a game. If we consistently bet numbers better than the close, we extracted value before the market got sharp β the statistical signature of edge, independent of whether any single bet won. Over small samples, win/loss is noise; CLV is the stable signal. So the right question isn't "did we win?" β it's "did the line move toward us after we'd have bet it?"
To answer that we need two numbers per game: the line when we bet (β the
opening / early line) and the line at close. One number (what spreadspoke
and most free datasets give) is not enough.
2. Is the data available? (As of 2026-05)
Not for free, and not yet. Three findings from a direct investigation:
- It's the offseason. First 2026 kickoff is 2026-09-10, and the posted look-ahead lines are completely static (0 of 16 Week-1 lines moved over seven weeks). There is no "closing" line and no movement to measure yet.
- Free open/close archives are now blocked from automated download.
sportsbookreviewsonline.com(historically the best free open+close archive) now redirects to an affiliate landing page, andaussportsbetting.comreturns 403 to scrapers (browser download only). - The free online source doesn't serve open/close for completed games β only a pre-match
moneyline and a per-provider, undocumented, recent-only movement endpoint
(
.../odds/{providerId}/history/0/movement). The historical scores dataset stores a single closing-ish number.
So a historical CLV backtest needs a manual browser download of an open/close file, or a paid feed. Live CLV only accrues in-season, via snapshots.
3. Where to get open/close data
Free (manual download β sites block scrapers)
| Source | Has | Notes |
|---|---|---|
| aussportsbetting.com | Open & close line + total, results, ~2006βpresent | Best free option; download the NFL .xlsx in a browser |
| sportsbookreviewsonline.com | Historically open+close 2007β2024 | Currently redirecting / effectively dead β check before relying on it |
| Kaggle (Crabtree), nflverse | Single pre-game line only | Not usable for CLV (no separate open/close) |
Paid (only worth it for Pinnacle benchmark or zero manual work)
| Source | ~Price | Notes |
|---|---|---|
| The Odds API (Business) | ~$99/mo | Historical snapshots back to 2020 (5-min), includes Pinnacle; reconstruct the close from the pre-kickoff snapshot. Cheapest Pinnacle-inclusive path. |
| SportsGameOdds | free tier / $99β499 | Explicit "closing odds", incl. Pinnacle |
| Goalserve | low indie tiers | Explicit open/close columns |
| SportsDataIO | quote | Labeled open+close+all changes, NFL since 2019 |
| OddsJam / OpticOdds / Unabated / Sportradar | $500 β $3,000+/mo | Enterprise; overkill |
Pinnacle's own API has been closed to the public since July 2025 β get Pinnacle (the sharpest close) only indirectly via the aggregators above.
4. The tools
The CLV math itself lives in the probability model (clv_points,
clv_winprob_delta), with its own unit tests.
Forward capture (works today)
Snapshots the market near kickoff to local snapshot storage. Uses
The Odds API if ODDS_API_KEY is set, else a free online source (no key).
# Run ~15-30 min before each game window, in-season:
capture closing lines --week 1
capture closing lines --week 1 --source espn # force the free online source
The latest snapshot per week is the "close"; our weekly bets file already records the line we "took." Schedule it alongside the weekly regen (see Doc 7 / the Thursday task).
Normalize a downloaded archive
Turns a manually-downloaded open/close spreadsheet into the schema the backtest reads. Fuzzy-matches the aussportsbetting / SBR column layouts (full team names β abbreviations, home line β home-margin convention).
import odds archive <downloaded>.xlsx
# -> normalized open/close CSV
Output schema: season, week, date, home_team, away_team, home_score, away_score,
open_home_margin, close_home_margin, open_total, close_total
(home-margin: positive β home favored by that many).
The real CLV test
Bets into the OPENING line and scores value vs the CLOSE. Reports average CLV, % of bets with positive CLV, and win-vs-open, for spreads and totals.
clv backtest --edge-spread 2 --edge-total 3
Positive average CLV β when our model disagrees enough to bet, the market tends to move toward us by kickoff β evidence of edge.
The local odds-archive and snapshot directories are gitignored (local data / manual downloads).
5. Recommended workflow
Backtest CLV (one-time, free):
1. Download the aussportsbetting NFL .xlsx in a browser into the local odds archive.
2. Run the archive-import tool on the downloaded file.
3. Run the CLV backtest.
Capture CLV (going forward, free):
1. Set ODDS_API_KEY (optional, for Pinnacle) β otherwise a free online source is used.
2. Schedule the closing-line capture near kickoffs each week.
3. Compare the line we took (in the weekly bets file) to the closing snapshot.
Cheapest path to a true Pinnacle close without manual work: The Odds API Business (~$99/mo) β a small adapter to pull the first and pre-kickoff snapshots per game would let the CLV backtest run on real open/close automatically.
β Back to the series overview Β· see also Doc 6 β Betting Strategy & Bankroll.