iWPA: who moved the game
Every goal, penalty, shot and stretch of clock moves a team’s chance of winning. iWPA hands each move to the players who made it, and the credits of a game add up to exactly what happened in it. It is a box score in wins. It is not a forecast, and it does not pretend to be one.
What the number is
Read the win-probability model at the instant before a goal and the instant after it, and the difference is what the goal was worth. Do that for every goal, every penalty and every shot, blocked or not, and for the clock running between them, and you have accounted for every point of win probability a team gained or lost in a game, from puck drop to the final result. iWPA is that account, split among the players.
It is an identity, not a model. The only modelled input is the win-probability function itself. Everything else is a fixed rule written down before any number was computed. A team’s credits in a game sum to its result minus its chance at puck drop, to nine decimal places; the pricer stops if they do not. Only a shootout is left with the team, because nobody on the ice in regulation or overtime took it.
The bar is descriptive. iWPA says who was on the plays that moved the game and how far each play moved it. It is weighted by leverage — a goal in a tied third period is worth many times one in a 5–1 game — and that is the point of it. It does not say who will move the next game. For that, read xGAx and Net Rating.
Who gets what
Goals for are split by rungs, one rung per role: scorer 5, first assist 4, second assist 3, an on-ice forward not on the scoresheet 2, an on-ice defenceman not on it 1. Every share in a goal has the same denominator, so the order holds on every goal, not just on average. A goalie shares in a goal for only if he picked up an assist.
Goals against are the same shot that went in. The defending skaters carry its shot quality, defencemen two shares to a forward’s one; the rest falls to the goalie and the shot stages below.
Penalties charge the player who took the penalty and credit the player who drew it. Penalties called at the same second are priced together, so coincidentals cancel to zero, as they do on the ice.
The clock is credited. Time passing while a team leads, a penalty running down, the horn: each stretch between line changes goes to the skaters on the ice, in equal shares. That pays the penalty killers and the players who protect a lead. It also pays a player for time spent ahead, which dWPA was built to cancel; under a descriptive bar that is the account, not a flaw in it.
Why fixed rungs and not fitted weights
A fit needs a target for the credited share to track. The only records of involvement are the scoresheet and the shift chart, and the rungs already use both. Any other target — future on-ice goals, repeatability — is predictive, which is the bar set aside. Tuning toward a predictive target and then calling the result descriptive is the thing this site’s name warns against.
One magnitude can be checked descriptively: how often an on-ice forward is named on a goal compared with an on-ice defenceman. Measured over 2023–24 to 2025–26 it is 1.87-1.96, beside the rule’s 2. And the rungs barely move the order: under two other ladders, player-game iWPA keeps a Spearman correlation of 0.993 and 0.995 with the published one.
Shots, in two stages
Every unblocked shot gets a W: what a goal on that shot, in that game state, would have been worth. Then two things can happen to it, and each is priced on its own.
Reaching the net. A miss is a small win for the defence; a shot on net is a small win for the shooter. The amount is split in equal thirds between the shooter, the defending skaters and the goalie. The thirds are a decision, not a measurement.
On net to goal. The goalie’s alone. A save credits him the chance that shot would have scored, times W; a goal charges him the rest. Over a game it is his goals saved above expected on the shots that reached him, priced in wins.
A save or a miss moves no real win probability, so these credits are paid for out of each team’s own clock credit for that stretch of play. The account still balances to the ninth decimal.
The on-net rate, and what it costs
The second stage needs the chance that a shot on net scores, and our expected-goals model gives the chance that an unblocked shot scores. Dividing one by the other needs an on-net rate. A per-shot on-net model was built and failed both of its pre-registered checks, so this version uses one number per season and strength: the rate that makes the expected goals on net equal the goals actually scored on net. In 2025–26 that is .6829 at five-on-five, .7292 on the power play, .8587 short-handed and .7249 otherwise.
The cost, stated plainly. Centring on each season’s own goals removes any real league-wide goalie deviation. If goalies as a whole stop more shots than expected-goals implies in a season, this rule reads it as calibration and takes it away. Goalies are ranked against each other only. That stands until a model of the whole shot — blocked, on net, in — replaces it.
The leftover by strength, and why it is not removed
The first stage is centred only where expected goals is level, and by strength it is not quite. In 2025–26 the shooter-adjusted model ran 1.3% short of goals at five-on-five and over on special teams, so power-play shooters are debited and penalty killers credited a little, systematically. By strength the residuals sit at |z| 3.0 (five-on-five), 5.1 (short-handed) and 5.3 (power play). That is the expected-goals model’s level, carried in thirds, and it is reported rather than rescaled away.
What is not in it
Blocked shots are priced, by a model that failed its own test. A shot blocked by an opponent is a save made by a skater. The blocker is credited W times the chance the shot would have scored from where it was struck: our shooter-adjusted expected goals, averaged over where the shot most likely came from, never read off the spot where it hit the shin pad. The money comes out of his own bench’s clock credit, so no team total moves; the shooter is not charged, and nobody is paid for finding a lane. A shot blocked by a teammate counts as a miss.
Where the shot came from is estimated by a model trained on puck-tracking replays: a stick-on-stick release within a few feet of the block, more likely the closer the block is to the net, or a shot from well back along the lane, almost never from beyond the blue line. Each block’s value is then scaled by a factor for the shooter’s position and how far the block was from the net, fitted so the values match the replays. None of it passed a clean test: the origin model failed its pre-registered checks, the replays from 2025–26 were looked at again and again while it was built, and it was adopted as the owner’s call, because some credit for a block, with its limits printed, beats none. It is now frozen, and its test on 2026–27 replays is written down before any of them exist. How the origins are estimated is in the blocked-shots writeup.
In 2025–26 it prices 36,890 opponent blocks, worth 207.87 wins across the league. A block is worth 0.48 of an average unblocked attempt in expected goals; the lowest group, shots by defencemen at four-on-four, three-on-three and the like, comes out at 0.321. These block values are carefully estimated, not measured, and they have known biases near the net: blocks close in, by defencemen most of all, are probably under-credited. Blocks move 19% of player-season iWPA, against 10% to 12% for any reasonable choice of goal-credit rungs, and they move defencemen most. Which of the candidate models prices them matters far less: the adopted one against the one before it moves 2.9%. Esa Lindell led the league with 1.47 wins of block credit from 179 blocks, before his share of the clock that pays for it.
Seasons start at 2023–24, the span the win-probability model was trained on, and the regular season only: the model has not been checked on playoff overtime, which is twenty minutes of five-on-five, not five of three-on-three.
The current season is priced with its on-net rates so far, recomputed every night, blended with last season’s. Early in a season this year’s rates rest on a handful of goals, so each strength’s rate leans on last season and gives way as games are played: this season carries half the weight after 200 games, and a finished season is priced on its own rates alone.
What checks it
It balances. Every event, every stretch of clock and every game balances to nine decimal places, or the pricer stops. The largest team residual over 2025–26 was 2.2e-16.
The shares obey the rule on every goal priced: scorer over first assist over second over on-ice forward over on-ice defenceman.
The win probabilities it reads are level where it reads them. At every goal of 2023–24 to 2025–26 the model’s post-goal chance was compared with how often the team actually won, by score, period and strength: no cell with at least 1,000 goals missed by more than 3 points.
One corner of the model is not. In the first period, with the team on the power play already up two, the win-probability model misses its own level check. iWPA reads that corner in well under 1% of its credit, but a shift there moves some player-seasons by up to 0.187 wins, and that failed the threshold set before measuring.
The model was checked again in October, game by game, against a candidate fix that treats a power play as the sum of its possible endings. Every cell passed under both models except this one. There the team on the power play won 4.95 points more often than the model in use said, and 4.08 more than the fix said, against the fix’s tolerance of 3.86, over 297 games. The fix closed 0.87 of those points and moved every other early power-play cell further from what happened, though all stayed inside their tolerance. Repricing iWPA under the fix moved no player-season by more than 0.406 wins, and season rankings correlated 0.9939 or better; no pass mark was set for that comparison in advance, so it is reported, not judged. The in-game curve rebuilt on the fix passed its own check.
Our reading, which is a reading and not a measurement, is that most of the miss is team quality: a side already up two on an early power play is usually the better team, and the model is blind to who is playing on purpose. iWPA uses the model in use and is not adjusted inside the corner. That corner, and only that corner, is exempted from the check. The exemption lapses if a rerun fails any other cell, or finds this one missing by more than 4.95 points.
Nothing falls through. Under 0.1% of goals in any season put any credit on a team row instead of a player, against a stop rule of 2%.
Why there is no interval
The pledge says models print with an interval. iWPA prints a point. It is a sum of observed events, each priced by one model, and there is no sampling question to put a band around: the goals happened, the penalties were called. The uncertainty that matters is whether the win-probability model is right, and that is answered by the checks above, not by an interval. It is the same exception expected goals takes.
Does it predict?
It was never meant to, and we checked anyway. Within 2025–26, each team’s schedule was split in half, and first-half iWPA per 60 was set against second-half on-ice goal share and points, beside dWPA and xGAx on the same split, for the 584 skaters with 200 minutes in each half. The iWPA in this comparison is priced without the credit for blocked shots; the iWPA we publish includes it.
It predicts about as well as the shift numbers, and worse than plain shot share. Against second-half on-ice goal share in all situations, the correlation is 0.481 for iWPA, 0.521 for dWPA, 0.471 for xGAx and 0.578 for on-ice expected-goal differential. At five-on-five the same four read 0.279, 0.289, 0.299 and 0.417. A player’s first-half iWPA rate repeats in the second half about as well as dWPA’s does: 0.675 against 0.672.
The team-level check, and why it says little
Summed to the team, first-half iWPA per game correlates 0.421 with second-half points share. First-half points share itself manages 0.429. That is no coincidence: a team’s iWPA over a game is its result less its chance at puck drop, so at team level iWPA is the standings with the schedule taken out, and it predicts like the standings. Thirty-two teams make every one of these numbers wide.
iWPA here is all situations only. A player-game carries no strength split, and the clock that pays for the shot stages crosses strength states, so a five-on-five iWPA would be a new definition, not a filter. Every figure in this section was measured on the shift tables as they stand after the October 1 recompute.
The result is reported, never a gate. Leverage adds noise about when things happened, and that is the price of describing the game the way it was decided.
How the front page ranks it
Goalies touch every shot, so their raw iWPA swings far wider than a skater’s: ranked by the raw number, goalies would take 70% of each night’s top five. So the front page ranks a player by how unusual his night was for his position — forwards against forwards, defencemen against defencemen, goalies against goalies — and prints his real iWPA beside it. Ranked that way, goalies take 3.2% of the nightly top five.
Early in a season the yardstick borrows from last season and hands over as games are played: after 200 games the current season carries half the weight.
The game pages’ three stars use the same yardstick: the game’s top three by it, goalies included, each printed at his real iWPA. While a game is on, the game page prices it as it goes, by the same rule, from the league’s live feed, blocked shots included: those numbers are provisional, carry no stars, and use last night’s shooter and league estimates for expected goals; the overnight run prices the final game and replaces them.
Appendix
The rules as the pricer applies them. Open the drawer you want.
Prices
goal d = WP(after) - WP(before), same second, home bench
penalty d = WP(with this second's penalties) - WP(without)
clock each stint between line changes: WP(end) - WP(start)
shot W = |WP(after a goal here) - WP(before)|
p = xG(sh), r* = on-net rate (season x strength), g = min(1, p / r*)
stage 1 miss: +p W to the defence; on net: -(g - p) W
stage 2 save: +g W to the goalie; goal: -(1 - g) W
block v = xG(sh) averaged over the estimated origins (A14, frozen) x position/band factor
stage 0 opponent block: +v W to the blockerSplits
goal for G 5 / A1 4 / A2 3 / on-ice F 2 / on-ice D 1
goal against skaters -p W (D 2 / F 1); -(g - p) W half skaters, half goalie;
-(1 - g) W goalie
stage 1 thirds: shooter / defending skaters (D 2 / F 1) / goalie
stage 0 the blocker (no blocker: the defending skaters, equally)
teammate block a stage-1 miss with v in place of p
clock equal among on-ice skaters, after the stage credits it funds
penalty committer charged, drawer credited, by minutes in the groupA goal whose swing is negative for the team that scored it (a power-play goal at a big lead, where the penalty ending costs more than the goal gains) leaves the shot stages and keeps the plain split, so a goalie is never credited for conceding.
Where every rule was decided
The pre-registration, backend/research/iwpa/PREREGISTRATION.md, records each rule before the numbers it governs, and labels each change made after seeing results as such: the on-net rate, and the adoption of the blocked-shot origin models after they failed their tests. The pricer is backend/scraper/compute_iwpa.py.