Sports Betting Model Building
A simple sports betting model turns historical data into win probabilities, compares those probabilities with sportsbook odds, and identifies bets with positive expected value. You do not need machine learning to start—clean data, a clear target, honest backtesting, and disciplined staking matter more than a complicated algorithm.
This guide walks through a beginner-friendly workflow you can build in a spreadsheet or Python: choose one market, collect historical data, create team ratings, estimate probabilities, calculate expected value, backtest the model, and manage your bankroll.

Start with one narrow question
Do not try to predict every sport, bet type, and player prop at once. Start with one sport and one clearly defined market, such as:
- NFL moneyline winners
- NBA point-spread winners
- MLB totals
- NHL puck lines
- Soccer match results
- College football spreads
Your model should answer a specific question: “What is the probability that Team A covers the spread against Team B?” or “What is the probability this game goes over the total?”
A narrow model is easier to test, debug, and improve. Once it works, you can expand to related markets rather than rebuilding everything from scratch.
Collect the right data
Your first model needs historical games, team performance, and historical odds. Useful fields include:
| Data type | Examples |
|---|---|
| Game details | Date, season, home team, away team, neutral-site flag |
| Results | Final score, winner, point margin, total points |
| Team stats | Offensive and defensive efficiency, pace, turnover rate, shooting or finishing metrics |
| Situational data | Rest days, travel, injuries, weather, altitude |
| Market data | Opening odds, closing odds, spread, total, moneyline |
| Results fields | Actual cover, actual over/under, final margin |
Use at least three seasons of data where possible, and retain an “as-of” timestamp for each input so you do not accidentally use information that was unavailable before kickoff.
Avoid relying on raw counting stats such as total wins, points per game, or yards per game. They are often already reflected in the betting line. More predictive inputs include opponent-adjusted efficiency, schedule strength, turnover differential, pace, injuries, and recent form.
Build a basic ratings system
A simple model can begin with a power rating for every team. The rating estimates overall team strength, and the difference between two ratings—plus home-field advantage—can produce a projected spread.
A basic NFL-style formula looks like this:
\text{Projected Margin} = \text{Home Rating} - \text{Away Rating} + \text{Home-Field Advantage}
For example, if:
- Home team rating: +8.0
- Away team rating: +2.0
- Home-field advantage: 2.5
Then:
\text{Projected Margin} = 8.0 - 2.0 + 2.5 = +8.5
If the sportsbook has the home team favored by 5.5 points, your model projects the home team to cover by three points. That does not automatically mean the bet is profitable—you still need to convert the projected margin into a probability and compare it with the odds.
Convert projections into probabilities
For spread betting, you can use a normal distribution to estimate the probability that a team covers.
Z = \frac{\text{Projected Margin} - \text{Spread}}{\text{Standard Deviation}}
For NFL spreads, a reasonable starting standard deviation is around 13 to 14 points. For basketball, it is usually higher; for hockey and soccer, a Poisson-based approach is often more appropriate because scoring is lower and more discrete.
Example:
- Your model projects the home team to win by 8.5 points.
- The sportsbook spread is home -5.5.
- Standard deviation: 13.5.
Z = \frac{8.5 - 5.5}{13.5} = 0.22
Using a normal distribution, a Z-score of 0.22 corresponds to roughly a 59% chance that the home team covers. That becomes your model probability.
Compare your probability to the odds
Sportsbook odds imply a probability. For American odds:
\text{Implied Probability} = \frac{\text{Risk}}{\text{Risk} + \text{Profit}}
For negative odds:
\text{Implied Probability} = \frac{|\text{Odds}|}{|\text{Odds}| + 100}
For positive odds:
\text{Implied Probability} = \frac{100}{\text{Odds} + 100}
If the sportsbook offers the home team at -110, the implied probability is:
\frac{110}{110 + 100} = 52.38\%
Your model says the home team has a 59% chance to cover. That difference is the potential edge.
Calculate expected value
Expected value tells you whether a bet is profitable over a large number of similar wagers.
\text{EV} = (p \times \text{Profit}) - ((1-p) \times \text{Stake})
Where:
pis your model’s estimated win probability.- Profit is the amount won on a winning bet.
- Stake is the amount risked.
For a $100 bet at -110:
\text{EV} = (0.59 \times 90.91) - (0.41 \times 100)
\text{EV} = 53.64 - 41.00 = +12.64
That is roughly +12.6% expected value on a $100 stake. A practical approach is to ignore bets below a minimum edge threshold, such as 2% to 3%, because model error, line movement, and sportsbook limits can erase thin edges.
Backtest before betting real money
Backtesting means running your model on historical games it did not help create. This is the most important step in building a credible model.
Simple backtest workflow
- Split your data into a training set and a test set.
- Build ratings and calibrate probabilities using only the training set.
- Run the model on the test set.
- Simulate every bet that met your minimum-edge rule.
- Record stake, odds, result, profit or loss, ROI, and closing line value.
- Review results by season, month, bet type, favorite/dog, and odds range.
A common approach is to reserve the final 20% of games as a holdout set, or use rolling out-of-sample testing where the model is updated only with data available before each game.
Do not judge a model on 20 bets. Aim for a meaningful sample—hundreds of bets if possible—and look for consistent performance across multiple seasons rather than one lucky stretch.
Track closing line value
Closing line value, or CLV, measures whether you beat the market’s final price.
For example:
- You bet the home team at -3.0.
- The line closes at -5.0.
- You got positive CLV because you locked in a better number than the final market price.
Consistently beating the closing line is one of the strongest early indicators that a model is finding real value, even before long-term profit becomes statistically clear.
Track CLV for every bet, especially during the first few months. If your model rarely beats the closing line, revisit your inputs, probability conversion, or minimum-edge threshold.
Manage your bankroll
A model with an edge can still lose money if bet sizing is reckless. Use flat staking or conservative fractional Kelly rather than betting large amounts on perceived locks.
A simplified Kelly formula is:
\text{Kelly Fraction} = \frac{bp - q}{b}
Where:
bis the net odds received per unit staked.pis your estimated win probability.qis1-p, the probability of losing.
For example, at -110 odds:
b = 0.909p = 0.59q = 0.41
\text{Kelly Fraction} = \frac{0.909 \times 0.59 - 0.41}{0.909} = 0.139
Full Kelly suggests about 13.9% of bankroll, which is far too aggressive for most bettors because model estimates are imperfect. Many bettors use one-quarter Kelly or less, or simply bet 0.5% to 1% of bankroll per play.
Set rules before you go live:
- Use 1 unit as your standard bet.
- Cap any single bet at 1% to 2% of bankroll.
- Reduce exposure when bets are correlated.
- Pause and review after a significant drawdown.
- Never chase losses by increasing stakes.
Common model-building mistakes
- Using future information: Do not include season-ending stats, final standings, or injury news that was unknown before kickoff.
- Overfitting: A model that perfectly explains past games often fails on new games.
- Ignoring vig: A 52.4% implied probability at -110 is not the same as a fair 50/50 probability.
- Too many variables: More inputs do not automatically improve predictions.
- No out-of-sample test: Backtesting on the same data used to build the model is not proof of an edge.
- Betting every output: Only place bets where your model probability meaningfully exceeds the implied probability.
- Ignoring CLV: Profit alone can be noisy; CLV gives faster feedback on whether you are finding value.
Simple spreadsheet setup
Create a game log with these columns:
| Column | Purpose |
|---|---|
| Game ID | Unique identifier |
| Date | Game date |
| Season | Season or year |
| Sport | NFL, NBA, MLB, etc. |
| Home team | Home side |
| Away team | Away side |
| Home rating | Model rating before kickoff |
| Away rating | Model rating before kickoff |
| Home-field advantage | Venue adjustment |
| Projected margin | Model projection |
| Market spread | Sportsbook spread |
| Market odds | Best available price |
| Model probability | Your estimated cover probability |
| Implied probability | Probability from odds |
| Edge | Model probability minus implied probability |
| Bet flag | Yes/no based on minimum-edge rule |
| Stake | Units or dollar amount |
| Result | Win, loss, push, or no bet |
| Profit/Loss | Actual result |
| Closing spread | Final market spread |
| CLV | Whether you beat the closing number |
This structure keeps your model transparent and makes it easy to identify which sports, bet types, and price ranges are actually profitable.
Example: NFL spread model
Suppose your model produces these ratings:
| Team | Rating |
|---|---|
| Home team | +8.0 |
| Away team | +2.0 |
With 2.5 points for home field, your projected margin is +8.5 for the home team. The market has the home team at -5.5 and -110.
- Model probability to cover: 59%
- Implied probability at -110: 52.38%
- Edge: 6.62 percentage points
- Expected value on $100: about +$12.64
If the closing line moves to -7, you also captured positive CLV. That combination—positive model edge and positive CLV—is the type of signal worth tracking over a large sample.
Improve the model gradually
Once your basic model is live, improve it one variable at a time:
- Add opponent-adjusted efficiency ratings.
- Include injuries and rest-day adjustments.
- Add weather for outdoor sports.
- Adjust for schedule strength.
- Test separate models for favorites and underdogs.
- Track performance by odds range.
- Compare your model probability with market-implied probability before every bet.
A good model is never finished. The goal is not to predict every game correctly—it is to consistently identify a small number of mispriced bets, size them responsibly, and let a positive edge play out over time.