The answer is unavailable. The supplied NFL snapshot has 7,548 game rows, 36 columns, a closing spread, and a closing total. It has zero opening-line columns. No honest calculation can turn one closing observation into an opening-to-closing move.
That is the result, not an empty page. A data limit should say what failed, what remains valid, and what would be needed to answer the question. This snapshot can grade games against the close. It can describe the distribution of closing numbers. It cannot measure movement, direction, steam, or whether an entry beat the closing line.
What is present
| Question | Snapshot answer |
|---|---|
| Total game rows | 7,548 |
| Columns per row | 36 |
| Closing spread | Present as spread_line |
| Closing total | Present as total_line |
| Opening spread | Unavailable; no field |
| Opening total | Unavailable; no field |
| Opening timestamp | Unavailable; no field |
| Sportsbook identity | Unavailable; no field |
Within the completed regular-season window used by the other posts, 6,967 games from 1999 through 2025 have a closing spread and closing total. That makes the close useful for ATS and over-under grading. It does not create a second observation.
The column named roof can contain the value open. That is a stadium-roof state, not an opening price. Searching for the word “open” without reading the dictionary would produce a particularly creative data bug: a retractable roof masquerading as market history.
What a line-move calculation requires
A valid move is a difference between two prices on the same market. Those prices need identities and times. “Opening spread” without a source is ambiguous because books can open at different numbers. “Closing spread” without a cutoff is ambiguous because a number can change near kickoff. A consensus series needs a declared aggregation rule.
The minimum row should identify the game, market, side, source, opening value, opening capture time, closing value, and closing capture time. If prices are included, the side price belongs beside each spread. A move from one spread to another does not fully describe a move from one price to another at the same spread.
The direction also depends on sign convention. The snapshot uses positive spread_line for a home favorite. The application’s event-odds convention uses the opposite sign, according to the data dictionary. Any join between those systems must normalize signs before subtraction. Otherwise every move points backward.
Why final result is not an opening line
The snapshot defines result as home score minus away score. Subtracting the closing spread gives the home team’s ATS margin. That answers whether the home side beat the close. It does not estimate the opening number.
A large ATS win can follow a market move in either direction or no recorded move at all. A push at close can also follow a large early move. Outcome and market path are separate variables. Treating the outcome as a missing open would leak future information into the feature and make a backtest look better for the worst possible reason.
The same rule applies to totals. Final points minus closing total is the over-under result. It cannot reveal the opening total. A game that finishes far over says nothing by itself about whether the total rose, fell, or stayed flat before kickoff.
What the closing distribution can tell us
The completed regular-season closing spreads have a median absolute value of 4.0 points and a mean absolute value of 5.34 points. There are 3,082 half-point closes and 3,885 whole-point closes, including 30 pick’em games. Closing totals range from 28.5 to 63.5.
Those numbers describe the market’s final stored targets. They are useful for designing spread buckets, identifying key-number exposure, and checking whether a chart’s domain covers the actual data. They are not movement statistics. The median close cannot be subtracted from a game’s close and renamed “line move.”
The 2026 shard contains 272 schedule rows with no final result yet. Those rows are not losses, wins, or zero movement. They are unplayed. An analysis must return an explicit unavailable state for grading fields rather than rendering an empty record that looks graded.
What “beat the close” would mean
For a recorded pick, the useful English chip is simple: beat the close, matched the close, or missed the close. The underlying calculation still needs the pick’s captured line and the declared closing line on the same side. Without the pick line, there is no comparison. Without a stable side convention, the sign is unsafe.
A market study could then count how often recorded entries beat the close and by how many points. It could separate spread movement from price movement. It could report missing captures as failures to observe, not as zero. None of those fields exists in the supplied schedule snapshot.
This distinction matters because ATS record and closing-line quality answer different questions. A pick can lose the game and still beat the close. A pick can win and still have taken a worse number than the market later offered. The product should show both when both are recorded. It should never infer one from the other.
What the Number Says
The number says “closing only.” That is useful. It is enough for the seven other posts in this batch to grade historical sides and totals at the close. It is not enough to publish a movement average.
The correct product behavior is the same as the correct article behavior: name the unavailable field. Do not draw a blank chart. Do not replace an error with an empty state. Do not calculate from a neighboring column because its name feels close. The Analytics surface should expose a line-history dataset only when a producer and source contract exist.
For the concept itself, read the closing line value guide. For current graded outputs, use the NFL picks page. Those surfaces should display recorded facts. This snapshot supplies closing facts and no opening facts.
A landable line-history contract
A future ingestion contract should make illegal states hard to construct. An observation should require a game id, market type, side, source, captured timestamp, line value, and price. An opening-to-closing pair should exist only when both observations share the same normalized market and side.
The loader boundary should return either a typed pair or a typed reason: opening observation missing, closing observation missing, source mismatch, side mismatch, or timestamp invalid. The UI can then say exactly what failed. A null pair rendered as “no movement” is false data.
A backfill also needs provenance. The manifest should record source, extraction time, row count, date range, and hash. That is how a later rerun can distinguish a real market revision from a changed input file. The current snapshot already models that discipline for its schedule shards; a line-history dataset should do the same.
Questions this snapshot can answer instead
It can answer how favorites performed at close by season. It can answer how home teams performed relative to their closing number. It can grade monthly totals. It can compare Week 1 dogs and divisional dogs. It can rank road-underdog cover counts from 2023 through 2025.
Those are not consolation prizes. They are complete questions matched to present columns. Good analysis does not begin with the headline and force the table to comply. It begins with the table’s contract and asks the strongest question the contract can answer.
Where these numbers come from
How we counted: We read data/training-snapshots/nfl/manifest.json for the 7,548-row total, 1999–2026 season range, 36-column list, and shard hashes. We inspected DICTIONARY.json for field meanings and all four CSV headers for opening fields. None contains a column whose name or definition is an opening spread, opening total, opening price, or opening timestamp. The 6,967 completed regular-season count keeps seasons 1999–2025 with non-null result, total, spread_line, and total_line. Closing-distribution counts come from those same rows. Because no opening observation exists, no line-move statistic was computed.
Model calibration: predicted vs observed
Predicted win probability bucket vs the empirical win rate inside that bucket on the test set. Points on the y=x reference line are perfectly calibrated; points below mean the model is overconfident in that bucket.
EV per $100 across win rate × odds grid
Expected value of a $100 stake at each combination of true win rate and market odds. Anywhere the cell is positive you have a long-run profitable bet; the magnitude shows how aggressive Kelly will size it.


