Track record
Every threshold, book line and touchdown chance the app showed before kickoff, checked against what happened. The numbers are the ones frozen at grade time, so they can't drift toward the result. Fills in on its own each time you upload a week.
Nothing graded yet. Once a week's player stats are uploaded, every projection from that week is scored here.
Get this week's numbers
If the weekly build runs for you (Thursday and Saturday mornings), everything below is already built into this file: scores, lines, injuries, prices and last week's stats are applied the moment it opens, and the log below says what came in. The buttons stay for a manual top-up between builds.
2. Download these four. Each opens in a new tab and saves straight to your downloads.
Prices for the 10+, 20+, 30+ lines
The main lines (over/under 264.5 and the like) are already built in for the week, with real prices. The threshold lines are shown with an estimated price, because no free source publishes those. If you want the real ones from your own sportsbook, this is how: download a sheet, type the prices in, upload it back. Anything you fill in replaces the estimate on that line and in the Parlay Builder.
"Just my parlay" is the practical one: a handful of rows for the lines you've ticked. The whole-week sheet is several thousand rows and exists for completeness.
What each file does
- Player stats is the one that matters. Every player's form, every team's volume and every defense update from it. It only exists once games have been played, so before Week 1 that link returns "not found", which is expected.
- Rosters keep everyone on the right team. The 2026 offseason is already built in, so Week 1 is correct out of the box, but signings and cuts happen all season and this is what catches them.
- Injury report pulls anyone ruled out or doubtful off this week's game pages so you aren't looking at a player who isn't dressing.
- Depth charts set who counts as the starter, so a game page shows QB1 and RB1 rather than whoever happened to touch the ball most last season. It's the big file, and it changes slowly, so every few weeks is enough.
- Price sheet is optional. Columns are
game_id, player, market, threshold, odds, with odds in American form like -115 or +260. The threshold matches the numbers on the game pages, so a row reading250, -120means your book pays -120 on 250 or more. Open it in Excel or Numbers, fill the odds column, save as CSV. - Re-uploading is safe. Weeks already counted are skipped.
What this app does
For every starter and rotation player in a game, it projects what they will do, then works out the chance of clearing each threshold: 20 or more pass attempts, 50 or more rushing yards, 6 or more catches, and so on. Each line gets its own percentage and a Low, Med or High rating.
How a projection is built
- The player's own recent form carries the most weight: a five-game and a three-game weighted average, their career rate, and last season's rate. The career and last-season numbers are pulled toward the league average when a player has barely any history, so one big game in limited action doesn't blow up his projection.
- Team volume, because a receiver's targets depend on how much his offense throws.
- The opponent, both overall and what they specifically give up to that position.
- Game context: the points each team is expected to score, home or away, and how lopsided the game looks. Where a sportsbook has posted a line, that is used, because the market predicts scoring better than we do (7.25 points of average error against our 7.60 on the 2025 season). Where no line exists yet, which is most of the season this far out, the game is built from our own team ratings instead of assuming an average game. Those weeks are marked.
Why the percentages aren't what you'd guess
- A projection is an average, and averages sit above a typical night. A receiver projected for 60 yards clears 60 well under half the time, because his quiet games are near zero and his big ones are huge, which drags the average up.
- So the app doesn't assume a neat bell curve. It carries the real shape of each stat's outcomes, measured across seven seasons, and reads the chance of clearing a number straight off that. This is why you'll see a player projected for 60 yards sitting under 50% to hit 60 or more, and it's the correct answer.
- High is 70% or better, Med is 45 to 70%, Low is under 45%.
Two different questions on every line
- The percentage answers "will it happen?" That is the model's own view, tested against seven seasons of results. Checked on established starters in 2025, it is unbiased: predicted averages match real averages within a few percent on every stat, and the chance of clearing its own median comes out at 47 to 51%.
- The estimated price answers "what would a sportsbook charge?" That is a different question, because the market disagrees with the model. In Week 1 the market sat about 5 points higher than the model on every main line. So the price estimate starts from where the market is, not where the model is.
- The gap between those two is the whole point. If the model says 55% and the book's price implies 48%, that is the disagreement worth looking at. Whether the model or the market is right is the open question this app cannot yet answer, because it has never been scored against real prices.
How the estimated price is built
- Where a real line is baked in (the "book line" shown beside the stat), the model's distribution is shifted until it agrees with the market at that number, with the bookmaker's cut stripped out first. Then the chance of each rung is read off the shifted distribution.
- Where no line exists, the projection is nudged by the average gap measured against the market in the most recent week with lines: roughly 3% on pass attempts, 6% on passing yards, 9% on rushing and receiving yards, 14% on receptions.
- Then the cut is added. Main lines run about 6.5% total hold, which is the -114/-114 you see everywhere. Alternate ladders run far higher, and the longer the shot the more they take. The shape of that curve is an assumption, not a measurement, because no free source publishes alternate prices to measure it against. The margin setting on each game page lets you make it lighter or heavier if your book runs differently.
- Reliability falls off in the tails. A few points of error barely moves a coin-flip price and wildly moves a longshot: 8% is +1150, 3% is +3233. Near the projection the estimate is worth using. At 300+ passing yards it is a rough direction.
- Every price is labelled: real is a sportsbook's actual number, est. is this estimate, fair is the model's chance with no cut at all.
What it can't do
- It has never been checked against a sportsbook. Old betting lines aren't published anywhere free, so everything below is the model against what players actually did. Whether these percentages beat a real book is a harder question and this hasn't answered it.
- Kickers are a coin flip. Across seven seasons the model is no better at field goals than guessing the league average. Kicker numbers are shown but treat them as noise.
- It doesn't know about news. A snap-count change, a new coordinator or a player working through something all move the picture before they show up in the stats.
- It only sees starters and the main rotation. Deep backups are hidden because projecting them from almost no history produces nonsense.
- Rookies aren't in it. Anyone who has never played an NFL game has nothing to project from, so first-year players are missing entirely until they've played three games. If a rookie is starting somewhere, you'll notice a name absent rather than a wrong number.
- Rosters are a snapshot. Teams are baked in from the 2026 roster as of the build date, with anyone released or on reserve already removed. Upload a fresh roster each week and it stays current through the season.
What's changed
A running log of fixes and features, most recent first. If something looks off, check here before assuming it's new. Bold entries are bugs that were producing wrong numbers rather than just looking wrong.
| v28 | A game now opens in a window over the games list instead of replacing it. Close it with the button, the Escape key, or a click outside; the list underneath keeps its place and any legs you ticked show there straight away. |
| v27 | Added the Track Record tab. Every threshold, book line and touchdown chance shown before kickoff is scored against the result and grouped by confidence band, by the percentage the model said, by week, by market, and for your locked parlays. The chances are frozen at grade time alongside the projections, so a played game is scored on exactly what it showed. Older graded weeks are scored from their frozen projection with the same tables. Each table carries a noise margin so a thin sample is not read as a trend. |
| v19 | The header of an expanded player had a rounded corner on one side and a square one on the other, with its border cut across the join. Caused by a typo, border-bottom-radius, which is not a real CSS property so browsers ignored it silently. Swept the rest of the stylesheet for the same mistake. |
| v18 | The week selector opened on week 2 because it picked the first week you hadn't uploaded stats for, and you had uploaded week 1's. It now reads the schedule: the current week is the earliest one still holding an unplayed game. Weeks after that stay closed, since a projection built on form from games that haven't happened would look authoritative and be stale. Finished-game stats moved from a table to tiles, with colour on the numbers rather than the row. Saved parlays gained a proper money panel: staked, price, payout, profit, chance, result, plus a running total across every ticket. |
| v17 | A played game read STARTED forever because nothing marked it finished. Games are now final once a score is in, or four hours after kickoff. Pulled the real result in, so week 1 shows NE 10 at SEA 13. Finished games drop the betting ladders entirely and show projected against actual instead. |
| v16 | Games lock at kickoff: no checkboxes, no adding legs, unsaved legs from a started game drop out of the builder. Added save and lock for parlays, which freezes legs, stake and price and moves the ticket to a Saved section that grades itself when stats arrive. Fixed a real error found while testing: a finished game's projection was being recomputed after that week's results were folded in, so it drifted toward the answer. Projections are now frozen before grading, so a recap shows what the model actually said beforehand. |
| v15 | The price sheet download built a link that was never attached to the page, which Chrome tolerates and Safari silently drops. Fixed, along with the same pattern on the backup export. Added a sheet covering just your parlay legs, since the full-week version is nearly five thousand rows. |
| v14 | Ran a full audit across every game, player and threshold in the season, 26,800 checks. It found three real bugs. The anytime-touchdown cap had silently switched off during a data rebuild, which had been holding backup running backs down from absurd numbers. Market anchoring failed on 40 of 303 lines, because the search assumed model and market were within twice each other, and Jacksonville's lead back differs by 2.6 times. The outcome distribution jumped at its internal tier boundaries, which would also have made odds twitch as a projection drifted. All fixed; the build now refuses to produce a file with any required piece missing. |
| v13 | Added estimated sportsbook prices to every threshold. Where a real line exists the distribution is shifted to agree with the market at that number, vig stripped first; elsewhere the average measured gap is applied. Then a bookmaker's cut goes on top, adjustable light, typical or heavy. Baked in 303 real Week 1 lines with both prices, and made the main line itself bettable on both sides. |
| v12 | Every threshold now shows what its chance is worth as a price, labelled fair since it carries no bookmaker margin. |
| v11 | The home page was unreadable on a phone. The game row is a seven-column grid and the mobile rule only told two of those seven where to go, so the rest landed wherever; the projections column was also being hidden by a leftover rule. Every cell is now placed explicitly as a stacked card. |
| v10 | Wired in the team model from the other project. Tested our own points model first and it lost to the betting market, 7.60 average error against 7.25, so the market is used wherever a line exists and our models only fill the 172 games without one. Those weeks previously assumed a flat league-average game. |
| v9 | Added the Parlay Builder with checkboxes on every projection. One pick per player per stat, enforced by how legs are stored, so choosing 30+ after 20+ replaces it. Corrected a misleading display: the first version showed an expected return even with no real odds loaded, computed from the model's own margin-free prices, which made every parlay look profitable. It now refuses to compute one until a real price is entered. |
| v8 | Filled the empty space on the games list with the three biggest projections per game, plus total points and the winner. |
| v7 | Team tags took the colours from the other project, including the rule that falls through to a team's secondary colour when the primary is too dark to read as anything but navy. |
| v6 | Players from the wrong teams. The saved copy in your browser was overriding the newly baked-in rosters, because the version check only looked at whether the model had changed, not the roster data. Roster data now carries its own stamp, and uploading a roster removes players no longer on one instead of only adding and moving. |
| v5 | Baked in the 2026 rosters and depth charts: 97 players changed teams, 97 more were released or retired and dropped. Depth charts set who counts as a starter, so pages show QB1 and RB1 rather than whoever touched the ball most last season, and name the starters who can't be projected because they have no NFL history. |
| v4 | Rebuilt around collapsible players and threshold ladders. Removed the betting tabs. Fixed backups appearing as starters, including Mac Jones alongside Purdy: players are now ranked by projected usage within their position and only the starter and main rotation show. |
| v3 | Reworked what the app flags. The earlier version measured edge against the de-vigged line, which tells you where you disagree with a sportsbook but not whether you'd profit. It now measures against the price you actually pay, cut included. Also fixed the odds template writing market names its own parser rejected, so those rows were silently dropped. |
| v2 | Added correlated parlay pricing after measuring how every pair of markets moves together across 2019 to 2024. Multiplying legs is off by 14 points on the strongest pairs. |
| v1 | Built the projection model from 124,000 player-games, 2019 to 2025. The first version was badly wrong about probability: it assumed a bell curve around each projection and said 50% where the real rate was 44%, because player stats are right-skewed. Replaced with the measured shape of each stat's outcomes. A second bug had backup running backs at 76% to score, from an unshrunk career rate: one touchdown in two games looked elite. Fixed with shrinkage toward the league average plus a cap tied to expected touches. |
Backup and reset
- Export backup saves everything to a file: player form, team numbers and every week you've loaded. It otherwise lives only in this browser, so clearing site data would wipe it.
- Import backup restores one of those, or moves your season to another computer.
- Reset to preseason throws away every week you've uploaded and rebuilds from the 2025 baseline.