Back to projects
Completed2025

NBA Sports Betting Analytics Platform

A full research platform for NBA player-prop betting: a weighted-average prediction model, an expected-value parlay analyzer, a paper-trading workflow, and a browser extension. Built to explore why predicting performance is not enough to establish a betting edge.

49,000+

Historical games

600+

Players tracked

10

Database tables

13+

Stat categories

The question

A prediction is only half the bet.

This project explores the full path from NBA game logs to player-stat predictions, probabilities, and expected value. The engineering challenge was connecting a data pipeline, prediction engine, API, and paper-trading workflow into one research platform.

The mathematical takeaway: predicting performance is not enough to beat the payout structure. Without reliable probability estimates and an evaluation against actual offered prices, an apparent edge is just an assumption.

From past games to a probability.

A recent game counts more than an old one.

A weighted average gives recent observations more influence. With exponential decay, the weight shrinks as a game gets older. Context adjustments for opponent, rest, and home/away try to account for differences that a simple average misses.

μ̂ = Σ(wᵢ × xᵢ) / Σwᵢ, with wᵢ = exp(−λ × ageᵢ)

Here xᵢ is a past stat, λ controls how quickly history fades, and μ̂ is the estimated mean. Faster decay adapts quickly but can overreact to a short streak.

An average is not a chance of winning.

The model uses a normal-distribution approximation to translate an estimated mean and spread into a probability of exceeding a line L. Φ is the standard normal cumulative distribution function.

P(X > L) ≈ 1 − Φ((L − μ̂) / σ̂)

That approximation is a modeling choice, not a law of basketball. Stats can be discrete or skewed, playing time changes, and injuries can shift the distribution. Integer lines also require accounting for ties or pushes under the relevant rules.

The payout sets the hurdle.

At −110 odds, a $110 stake wins $100 in net profit. Expected net is 100p − 110(1 − p), so break-even is 110 / 210 ≈ 52.38%. A true 50% chance has negative expected value at that price.

EV = p × profit if won − (1 − p) × stake

Try the math yourself.

The price of a prediction

Change your assumed win probability and the offered odds. A good prediction only becomes positive expected value when the price is favorable.

$4.55

Expected net per $100 staked

50.0%

Chance all picks win

EV = $100 × [P(all win) × total decimal payout − 1]

Break-even per pick: 52.38%. This hypothetical example multiplies both independent probabilities and decimal payouts. Real same-game picks can be correlated, and platforms may use different payout rules. Positive calculated EV is only as reliable as the assumed probabilities; it is not a forecast or a measured project result.

Why the edge is so fragile.

The margin is already in the price.

If both sides of a two-outcome market are −110, their implied probabilities total roughly 104.76%. That excess over 100% illustrates the bookmaker’s margin. Being right half the time is not enough.

Small errors can reverse the answer.

At −110, assuming a 55% chance produces about +$5 expected net per $100. If the true chance is 51%, it becomes about −$2.64. A four-point estimation error changes the sign of the supposed edge.

Parlays multiply uncertainty.

Five independent 50% picks all win only 3.125% of the time. Picks involving the same game can share causes—pace, minutes, or injuries—so multiplying individual probabilities may be wrong.

More games do not fix a biased model.

Collecting more history helps research, but does not automatically correct a flawed distribution or missing context. A useful evaluation needs chronological holdouts, odds available at decision time, and calibration checks.

Evidence & limitations

Built as a research tool. No profitability claim.

I do not have a documented win rate, ROI, or completed backtest to report. The findings above are mathematical examples and modeling limitations, not measured betting returns. The paper-trading workflow provides infrastructure for evaluation; building it does not itself validate the model.

A next evaluation would freeze the model, log predictions against timestamped lines, and measure calibration and net returns on future games, including uncertainty. Until then, the work demonstrates software engineering and probabilistic reasoning—not a proven betting strategy.

Technologies

PythonPostgreSQLSQLAlchemyFlaskStreamlitNBA API

Components

Prediction engineParlay / EV analyzerPaper-trading backtesterBrowser extensionData pipeline

Implementation details

  • Built a weighted-moving-average prediction model with exponential recency decay over player game logs, adjusted for opponent defensive rating, rest days, and home/away — then modeled the outcome as normal and used the CDF to compute the probability of clearing a given sportsbook line.
  • Converted that probability into expected value against standard −110 odds (break-even at ~52.4%), and built a multi-pick analyzer that computes joint probability and EV across multiple picks. Correlation between picks remains an important modeling limitation.
  • Added a paper-trading system — bankroll tracking, ROI, and bankroll snapshots over time — to support evaluation against real lines. No documented backtest returns or profitability results are available.
  • Shipped a Chrome extension that overlays live predictions in a sidebar directly on PrizePicks.com, backed by a Flask API serving the model.
  • Designed a normalized 10-table PostgreSQL schema over SQLAlchemy (players, teams, defensive stats, game logs, paper-trading accounts, bets, parlays) and a rate-limited NBA API pipeline across 600+ players and 13+ statistical categories.