Margin-Aware Team Strength Model
Track team strength game by game, crediting margin of victory without letting blowouts run away with the rating.
What it measures
Winning is the signal; how much you won by is a weaker second signal that has to be damped, because margin inflates when a strong team plays a weak one.
How to read it
home_rating_pre; away_rating_pre; expected_home; mov_multiplier; home_rating_post; away_rating_post
Why it exists
A plain Elo treats a one-point win and a thirty-point win identically, which throws away information every basketball fan knows is real. The obvious fix - scale the update by margin - is worse than the disease, because margin is correlated with the rating gap Elo is already accounting for, so good teams get paid twice for beating bad ones. The margin multiplier here exists specifically to break that autocorrelation: it grows sublinearly in margin and shrinks as the winner's pregame edge grows. The constants are configured rather than fitted, and the plain Elo baseline is kept alongside this model rather than replaced, so the cost of the MOV adjustment stays measurable. The model refuses to guess: a zero margin, a non-integer score, or a degenerate autocorrelation denominator raises rather than silently producing a plausible-looking update.
Limits
- Constants are configured, not fitted; they have not been optimised against this league's data.
- Home advantage does not vary by venue, travel, or rest.
- Season regression is a flat 0.75 and ignores roster turnover entirely.
- Ratings early in a season are dominated by the previous season's carryover.
Calculation, evidence, and implementation
Calculation
Inputs
Date, Game Id, Home Team, Away Team, Home Score, Away Score, Season, Is Neutral
Method
No fitting step. Every constant - k of 20, home advantage of 100, mean rating 1505, season regression of 0.75, MOV exponent 0.8, autocorrelation intercept 7.5 and slope 0.006, and the multiplier cap of 5 - is configured in MarginAwareEloConfig rather than estimated from data.
Evaluation
Games are replayed in a deterministic order - date, then game id, with a stable mergesort - so a rerun reproduces ratings exactly. The unmodified plain Elo baseline is retained in the same module as a calibration reference. An expected home probability is emitted for every game, which is the quantity any calibration check consumes.
Outputs
Home Rating Pre, Away Rating Pre, Expected Home, Mov Multiplier, Home Rating Post, Away Rating Post
Sources
Src/Sports Intelligence/Shared/Forecasting/Team Strength.Py, Src/Sports Intelligence/Leagues/NBA/Models/Forecasting/Team Forecast.Py
Implementation
Registry identifier: MARGIN_AWARE_ELO. Version 1.0.0; status drafted.