Predicting NFL Passing Yards with Nori: A 24% Backtest Return
We used Nori to predict NFL passing yards and price Kalshi bets. A 2025 quote-based backtest returned 24.1% after fees and modeled execution costs.
NFL passing-yard markets list a threshold, such as 250+ yards, and let traders buy a YES contract on whether the quarterback reaches it. If that contract costs 31 cents, it pays $1 when the quarterback throws for at least 250 yards and $0 when he does not.
We asked Nori to estimate the chance of a quarterback reaching each yardage threshold, then compared that estimate with the price to buy the contract. When the gap was large enough to cover costs and leave a margin, the strategy placed a bet. Here's how we built it.
What data helps predict NFL passing yards?
We built the historical features from free nflverse data. The target was the starting quarterback’s final official passing yards. Each decision row combined historical averages with the game so far:
- recent quarterback attempts, yards, yards per attempt, expected points added (EPA) per dropback, completion percentage over expected (CPOE), air yards, and sack rate;
- the QB’s average yards, attempts, yards per attempt, and remaining yards at Q1 and halftime over the previous three and eight games;
- offensive pace, pass rate, efficiency, and available personnel;
- the opposing defense's passing efficiency, pressure, sacks, and explosive passes allowed;
- home field, rest, roof, week of season, entering team and opponent records, conference and division position, spread, and game total;
- current-game passing yards, attempts, sacks, air yards, receiver usage, score differential, and time remaining.
| Quarterback-game | Quarterback form + checkpoint history | Offense | Opposing defense | Context + market | Postgame label | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| QB | Game | Yards L3 | YPA L3 | EPA/DB L3 | Q1 yards L3 | Halftime yards L3 | Plays/game L3 | Neutral pass rate | EPA/DB allowed | Sack rate | Venue | Rest | Team spread | Game total | Final pass yards |
| Justin Herbert | W8 · LAC vs MIN | 283 | 6.97 | +0.095 | 42.3 | 110.3 | 67.0 | 62.2% | +0.259 | 8.1% | Home | 4d | +3.0 | 45.5 | 227 |
| Josh Allen | W8 · BUF at CAR | 214 | 8.13 | +0.096 | 76.0 | 104.3 | 56.3 | 56.0% | +0.117 | 7.6% | Away | 13d | +7.0 | 47.5 | 163 |
| Caleb Williams | W8 · CHI at BAL | 212 | 6.91 | +0.044 | 48.7 | 93.3 | 62.7 | 60.0% | +0.367 | 4.8% | Away | 7d | -2.5 | 45.5 | 285 |
| Drake Maye | W8 · NE vs CLE | 252 | 9.57 | +0.419 | 48.7 | 128.0 | 58.0 | 63.4% | -0.067 | 6.5% | Home | 7d | +7.0 | 40.5 | 282 |
Figure 1 — Quarterback form, checkpoint history, offense, opposing defense, and game context become columns in the quarterback-game table.
Turning passing-yard predictions into betting probabilities
Nori learns from examples supplied in a table. We gave it historical games and their outcomes, then asked it to predict how many more yards a quarterback would throw from the current point in the game. As games finished, we added them to the historical context for the following week.
1import numpy as np
2from synthefy_nori import NoriRegressor
3
4model = NoriRegressor(model="nori-6m")
5remaining_yards = past_final_yards - past_checkpoint_yards
6model.fit(X_history, remaining_yards)
7prediction = model.predict(X_current, output_type="full")
8final_quantiles = prediction["quantiles"][0] + yards_so_far
9p_200_plus = 1 - np.interp(199.5, final_quantiles, prediction["taus"], left=0, right=1)This gives us a probability for every listed line. The strategy uses those probabilities to decide whether to buy at one of two checkpoints.
When does the strategy place a bet?
Figure 2 — The strategy makes one choice per quarterback-game: bet after Q1, bet at halftime, or do not bet. It never opens both positions.
Example: Joe Burrow’s 200+ passing-yard contract
The histogram below shows one 2025 decision. After the first quarter, Joe Burrow had 43 passing yards and Cincinnati trailed Baltimore 7–3. Nori estimated a median of 219 passing yards, with the middle 80% of its predicted outcomes between 131 and 310 yards. It assigned a 61.3% chance of reaching 200 yards. Because a winning YES contract pays $1, a 61.3% chance is equivalent to a 61.3¢ fair value.
Kalshi’s recorded YES asking price was 21¢. Adding our modeled 2¢ fee gave a 23¢ cost for a possible $1 payout. Nori estimated a 61.3% chance of winning, leaving a 38.3¢ edge, so the backtest selected the bet.
Figure 3 — Burrow finished with 261 passing yards.
What did the 2025 backtest return?
Across 272 NFL games in the 2025 sample, the strategy selected 42 bets in 39 games. Twenty-four won. Buying one contract per selected bet produced a 24.1% return on money deployed: profit divided by the total cost of those contracts, including fees and an extra 5¢ per contract for execution costs.
We used the same one-contract size for every bet to measure the strategy's selections consistently. The reported return comes from a backtest using historical quotes.
| 2025 strategy | Result |
|---|---|
| Simulated bets | 42 |
| Games with a bet | 39 |
| Winning bets | 24 |
| Simulated return after fees and modeled execution costs | 24.1% |
We allowed an extra 5¢ per contract for execution costs. Actual costs can differ with market liquidity and the size of the order.
On the selected bets, Nori's probabilities also predicted outcomes more accurately than the purchase prices did. Its Brier score, which measures probability error, was 0.224 versus 0.253 for the entry prices. Lower is better.
These 42 bets give us an encouraging result to build on. The strategy was selected through experimentation on this season, so the next step is to fix the rules and test them on new games, recording actual fills and available size. That will show how the result carries over to live trading.
How can I build my own NFL passing-yard prediction model?
Open in Google Colab or view the executed notebook on GitHub. It downloads public football data and Nori’s weights, builds the features, and reproduces the blog’s Q1-first, halftime-fallback strategy.
Want to try your own features or betting rules? Tell your agent:
1Help me build my own NFL passing-yard prediction model with Nori-6M. Use Python and synthefy_nori.NoriRegressor for the model forecasts.
2
3Use this published notebook as the starting point:
4https://github.com/Synthefy/synthefy-nori/blob/main/examples/notebooks/nori-nfl-passing-yards.ipynb
5
6Before writing code, ask me:
7- Do I want predictions, a historical backtest, or both?
8- Which season and quarterbacks do I want predictions for?
9- What other features or football knowledge do I want to include? For example: injuries, receiver availability, coaching changes, offensive line quality, quarterback and defense identity, or different rolling averages.
10
11Build the model
12- Start with the notebook's public nflverse downloads, feature-building helper, and pinned Nori setup. I can provide additional data if I have it.
13- Predict remaining passing yards at each checkpoint, then add yards already thrown to obtain a distribution of final passing yards.
14- Use only information available at the prediction time. Calculate historical averages from earlier games and encode any new categorical inputs using past context only.
15- List the proposed feature columns and confirm them with me. Flag unavailable data instead of inventing it.
16- Show each quarterback's predicted passing yards and P10–P90 interval. If I provide a yardage line, also show the probability of reaching it.
17
18Only if I choose a backtest
19- Ask whether I want to evaluate forecast accuracy, a betting strategy, or both. For betting, ask whether to use the blog's rule or try different entry rules, edge thresholds, or bet sizes.
20- Agree on the evaluation period and rules before running. Report forecast accuracy separately from simulated betting results, including fees and execution costs.
21- Use historical Kalshi quotes for betting evaluation when available. If they are unavailable, report that limitation rather than inventing prices or returns. Recorded quotes do not guarantee fills or available size. Never place real orders.
22- Use earlier data to develop the model and later data to evaluate it where possible. Label results on data used for tuning as exploratory.
23
24Explain each step for someone who knows football but is new to machine learning. Show sample rows, cache downloads, and record the configuration so I can rerun the model.Build with Nori
- Documentation: docs.synthefy.com
- Quickstart: docs.synthefy.com/nori/quickstart
- GitHub: github.com/Synthefy/synthefy-nori
- Model weights: huggingface.co/Synthefy
- NFL data: nflverse
Questions? contact@synthefy.com
Backtest note: The 24.1% return is a simulation using recorded quotes, modeled fees, and an extra 5¢ per contract, not actual earnings. Historical quotes do not establish available size or guarantee a fill. We refined the strategy on 2025 data, so these are exploratory results, not independent validation or a guarantee of future returns.


