Inside the Algo

Every number on the board, start to finish

One player, one number, 0 to 99. This page is how we get there. There is no black box — the rating is arithmetic, and you can redo every step yourself. Where a step is a judgment call rather than a tested result, we say so.

The short version

  1. We work out what a player will do per game next season — not what he already did.
  2. We grade every stat against real rotation players, so rebounds and blocks can be added together.
  3. We add those grades up. That total is his value.
  4. We charge him for the games we expect him to miss, by mixing in the player you'd start instead.
  5. We stretch everyone onto a 0–99 scale. Best player is 99, worst is 0.

The rest of this page is those five steps in detail. If you only read this box, you have the shape of it right.

You're reading the board's default equation:category scoringhead-to-headwindow: projectionsdurability onTurn an Algo Input and the math changes with it. Every section below names the control that moves it. The board always computes the equation for your settings, and a player's dossier shows this same walkthrough with his numbers filled in.
pool who's rankedline per gamegrades vs the poolcharges riskgames expectedaging one yearALGO 0–99

In the formulas below, the colours just group related terms. You don't need to memorise them. The one colour that carries a meaning is the blue taglike this — yours which marks a control you can change.

Contents

One real player, in five lines

Before the detail, here is the whole thing happening to one player. This is Alperen Sengun, computed live by the engine that ranks the board — not typed in by hand.

Alperen Sengun, the rating in five lines
We expect him to play65 of 82 gamesstage 5
His stats grade out at+6.56stage 3
Minus the streakiness charge−1.16stage 4
Mixed with the man you'd start instead+3.32stage 6
Stretched onto the 0–99 scale77stage 7

That is an ALGO of 77, which puts him at #8 of 422 ranked players. Every intermediate number, including all ten category grades, is in the full worked example at the bottom.

What actually moves a rating

Everything below is measured in grade points — the unit the next few stages build. This is what one is worth, so the numbers mean something when you meet them.

Rough sizes of each effect, in grade points
One category, from average to best in the leagueabout 3 grade points
The streakiness charge1.16 for Alperen Sengun; 0.7 to 2.6 across the board
Missing a quarter of the season (Alperen Sengun)about 2.45 grade points
One ALGO point0.22 grade points

Today the whole board runs from −13.28 to +8.09 grade points. So being elite in one extra category is worth roughly 14 ALGO points, and a typical streakiness charge costs a handful.

01

Who gets ranked — the pool

Fantasy value is relative. "Good" means "better than what you could roster instead." So before any math, the board decides who counts as the competition.

Roughly 650–700 players are considered. To be ranked, a player needs 25 games and 15 minutes a night in his most recent full season. Both floors are yours to move.min GP · min MPG — yours

A second, smaller group sets the grading curve— the top 200 by minutes per game. Those are real rotation players, not end-of-bench noise. Connect a league and the curve resizes to your league's actual roster demand: 156 players for a 12-team, 13-slot league, more for a deeper one. That is who is genuinely rosterable in your world.

Filtering never changes a rating. Exactly two of the board's filters re-grade anyone. The games and minutes floors do, because they decide who is in the pool everyone is measured against. Turning off a stat column does, because it drops that category out of the scoring entirely. (Punting does the same to one category — stage 3 covers it.)

Everything else only decides which already-graded rows get drawn: the position filter, hiding injured players, the rookie and veteran chips, search, and how many rows you show. A center who reads 92 on the open board still reads 92 with C selected. Filtering does renumber the # column to close the gaps. Searching doesn't even do that.

02

His per-game line

Everything starts from one question. What do we expect him to give you per game? The board opens on Projections, so the answer is not what he already did. It is what he is now, carried forward.window — yours

The default — Projections

We take his last three seasons and count them per minute of floor time, not per game. Recent seasons count more. Then we set that rate at the minutes he plays now.

That second half is what makes it a projection rather than a history. A bench player who earned a rotation role stops being priced at his eight-minute seasons. A veteran whose minutes have fallen stops being priced at minutes he no longer gets.

Then the line is aged one year forward, one stat at a time. Every stat has its own curve by position and years in the league. A center's blocks and a guard's assists don't decline alike. Aging makes and attempts separately is also the only way a shooting percentage can move at all. This is the only place aging happens. There is no aging multiplier later on.

Show the math
His last three seasons are weighted 3 : 2 : 1 toward the most recent, applied per minute of floor time. The minutes level he is set at is last season's, pulled toward the three-year blend by a prior worth 10 games, so one thin year can't lock in a slump. A season he missed entirely is absent from this window rather than counted as zero — it is charged to expected games in stage 5 instead. Shooting percentages are rebuilt from the aged makes and attempts, so an aged line always stays internally consistent.
Tested: pricing production per minute, at today's minutes, ranked players closer to what actually happened than the old per-game blend.
The numbers
Walk-forward 2010–2025. Points-league rank correlation +1.17% (better in 14 of 16 seasons, sign test p = 0.004); 9-category +1.18% (t = 3.08). Per-game error 5.30 → 5.12 fantasy points. Players moving into bigger roles were misranked by 15.9 board places before and 6.2 after. Losing arms, so they stay lost: per-game lines with minutes weights, per-36 scaled by blended minutes, raw last-season minutes, and last-season-only. The seasons overlap heavily, so treat 14 of 16 as consistency, not as 16 independent trials.
Tested: aging each stat on its own curve, rather than scaling the whole line by one number, cut next-season projection error — and cut it most for long-career veterans.
The numbers
Walk-forward over 1,835 player-seasons, curve rebuilt per test season so it never sees what it is scored on. Error in fantasy points per game: overall 5.573 → 5.172 (−7.2%); ages 0–2 −6.3%; prime 3–6 −1.7%; 7–10 −7.4%; 11+ years −22.5%. The prime band barely moving is the check that matters — a curve fitting noise would "improve" every band alike.
It moves as the season does. Once games are played, this season simply enters the window as its most recent year, at weight 3 against 2 and 1. There is no separate in-season rule. Against two full prior seasons, eight games is worth about a tenth of the line, and it takes most of a season for the current year to become the majority of it. That is what stops a hot start from being mistaken for a new player. One thing that does not move: the control itself. The board opens on Projections in October and in January alike.

If you'd rather look backward

Four other windows are yours to pick: this season on its own, or the last 2, 3, or 5 seasons. Those answer "what did he do" rather than "what is he now." They are allowed to disagree with the projection. That is the point of having both.

How the backward windows are weighted
Most recent season heaviest, stepping down by one: 3 : 2 : 1 over three seasons, 2 : 1 over two, 5 : 4 : 3 : 2 : 1 over five. Two details do the honest work. The weights apply per game, so a 12-game injury year can't count as a third of a three-year window. And a season he missed entirely is dropped from the stat math rather than scored as a zero — it is charged against his expected games instead, so an injury never counts twice. On the single-season window, a player who missed the year is shown on his last healthy one, and his row says so. These weights are a convention, not a measured optimum: 3 : 2 : 1 was chosen, and linear decay is the smallest honest generalisation of it.
Rookies
No NBA games exist, so his line is built from a decade of players picked where he was picked — draft slot, opportunity, and closest comparables. His row says his rating is a projection, not production.
Which games count
Regular-season games that count for fantasy scoring. Playoffs and play-in games are excluded everywhere — from the lines, from games played, from everything.

03

Grading against the pool

Twelve rebounds and two blocks live on different scales. Grading converts every stat into the same unit: how unusual is this, among real rotation players?

z = ( xμ ) ÷ σ then = 3 · tanh( z ÷ 3 ) then Z = Σ ±

In plain words: take his number for a stat, subtract what an average rotation player does, and divide by how spread out players are in that stat. That gives a grade in a shared unit. Squash the very extreme grades so one freak category can't run away with the rating. Then add the ten grades up, subtracting the ones where less is better.

μ σthe pool average and spread. The average of that stat across the grading pool, and how far apart players are in it. The spread is the unit conversion — both 12.8 rebounds and 2.1 blocks become “how far above the pack.”
zhis grade. Zero is exactly an average rotation player. +1 is clearly above the pack, +2 is star territory in that stat, negative is below average.
his counted grade. Extremes are compressed so one freak category can’t run away with the rating. It’s a curve, not a ceiling — nothing ever quite reaches ±3.
Zhis total grade. The counted grades summed across the ten scored categories. Turnovers subtract. Around zero is an average starter; the very best land near +8.
How raw grades are compressed
raw grade z+1+2+3+4+6
counted ẑ+0.96+1.75+2.28+2.61+2.89
Tested: compressing the extremes is right, but how hard to compress depends on which question you ask — and the two tests we ran disagree. We kept the looser setting, because it is the one that wins the test closer to how leagues are actually decided.
The numbers
Player against player(walk-forward, truth = next season's all-play-all category record): compression beat the uncompressed sum in every season tested, and so did every hard cap we tried. Tighter compression beat ours. One caveat we found later and are correcting here: that run scored nine seasons, not the ten it reported.

Team against team(drafted rosters, truth = roto standings and weekly head-to-head win rate, 10 seasons, 36 leagues per cell): no tighter setting beat ours in any of 72 cells, and several lost outright. Compression against no compression was a wash. The reason the two disagree is that a category monopolist beats almost everyone either way, so player-against-player can't see the value of his excess — but on a real roster that excess turns a likely category win into a certain one.

A league is won team against team, so that test governs, and the setting stayed where it is. It is the best tested value, not a proven optimum.

Punting.punt — yours A punted category isn't zeroed. It's deleted from the market. No average, no spread, no grade, no term. Up to three. The column stays on the board, struck through, so you can see what you're conceding.

When percentage categories are on (they're off by default — the default set scores makes, not rates): FG% is never graded as a bare percentage. It becomes shooting impact— makes above what a pool-average shooter would make on his attempts. So a 95% free-throw shooter on two attempts a game can't move a rating. Volume is the point.
Two known quirks of adding grades up
Turnovers reward not touching the ball. A low-usage player gets a positive turnover grade for free, without doing anything useful. Everyone who plays these leagues knows this. It is a real artifact of scoring turnovers as a category, and the board does not correct for it.

Adding grades treats categories as separate and equally valuable. In a real matchup they are neither. A category you already win by a mile is worth nothing extra, and what a player is worth depends on the rest of your roster. The compression above is a partial answer to the first half of that. The second half — roster context — is a matchup question, and it lives on the Matchup Engine rather than in this rating.

04

The streakiness charge

One charge comes off the total before anything else: how much he swings from night to night.matchup — yours

V = Z − 3 · cv

In plain words: take his total grade, and subtract three times a streakiness number. That number is how much his points bounce around, measured against how many points he scores.

cvhis streakiness. His points standard deviation divided by his points, capped at 1. A 30-point night and a 6-point night average out fine on paper and still lose you a head-to-head week. Measured on his most recent full season, not on the projected line, so it stays put when you change the stat window.
Vhis value. His value so far — still in grade points. Stage 6 spends his expected games against it before the board sorts.

This charge belongs to head-to-head, because head-to-head is where a bad night loses a whole week. Switch to roto and it comes off entirely. Roto totals a season, so it forgives variance.

The one number here we have not tested. Everything else on this page was measured against real seasons before it shipped. This charge was not, and it has a bias we can name.

Points bounce around more, relative to the average, the fewer points a player scores. That is arithmetic, not unreliability — it happens to a perfectly steady player too. So the charge lands harder on low-scoring players. Measured across today's ranked pool, players around 10 points a night pay about 1.7 grade points and players around 23 pay about 1.0.

The effect on the board's order is small — a couple of places for most players. That is the reason it has not been urgent, not a reason it is right. It is being tested next. Until then it is here, in the open, rather than buried.
Games missed is not charged here. There are three places in the code that could dock a player for games missed, and on the default board all three stand down. The projection already carries his expected games, and the next stage spends them properly. Availability enters this rating exactly once, and it is not here. A rating that charged for missed games in two places would be quietly double-counting the same injury.

05

Expected games

The xGP number on the board is not last season's games played. It is an estimate of how much of a season he'll actually give you, built in three steps.

raw = Σ u·games played ÷ Σ u·team games over 5 seasons, u = 5,4,3,2,1
shrunk = ( raw·N + pool avg·123 ) ÷ ( N + 123 )
a = shrunk + age adj xGP = 82 · a

In plain words: first, what share of his team's games he actually played over five seasons, counting recent seasons more. Second, pull that toward the average player, hard if we have little history on him and barely at all if we have a lot. Third, nudge it up or down for how far into his career he is. Multiply by a season to get games.

rawhis recent record. Weighted toward now, counted on games. A fully missed season enters as zeros played against a full season of team games, so it counts hard. Seasons before his debut don’t exist and aren’t counted. A player whose injuries are behind him climbs; one whose injuries are recent falls below his career rate.
poolthe reality check. Small samples get pulled toward the ranked pool’s average availability. N is his team games of history; 123 is the strength of the pull, about a season and a half. One season of history lands closer to the pool average than to his own rate; five seasons and his own record carries most of the weight. No history at all? He is the pool average — never assumed healthy.
agethe age adjustment. A small addition or subtraction by years in the league, capped at about ±20 games. Young players get lifted, long-tenured ones marked down. Fitted from history, applied after the pull.
Tested: weighting recent seasons more describes the player you're about to draft, rather than an average of two different players.
The numbers
Paired with the age correction it was the best arm tested in both formats: points rank correlation +0.47% (better in 16 of 16 seasons), category +0.28% (12 of 16). It also all but removed the bias on players returning from a fully missed season, from +7.8 games over-forecast to +0.5 — which no explicit "recovery bonus" managed to do. The age correction itself wins on ranking in 16 of 16 seasons but by only +0.37%; we took it because expected games is a number you read, and being eight games wrong on a 34-year-old is visible in a way a rank is not. The 123-game pull strength was chosen, not fitted.
The 82 is a placeholder until the schedule lands. Before the NBA publishes next season's calendar there are no real game dates to count, so expected games is a share of a nominal 82. Once the schedule is out we count his team's real remaining games instead, which is already how expected games works on a connected league's pages. And each past season is measured against the length of that regular season — 2019-20 and 2020-21 were short, and counting them as 82 would invent absences that never happened.

06

Spending the expected games

Now the two halves meet. This is the only place availability touches the rating — and it is not a multiplier.durability — yours

V′ = a · V + ( 1 − a ) · R

In plain words: on the nights he plays, you get him. On the nights he doesn't, you get whoever you started instead. His value is those two mixed together, in proportion to how often each happens.

Rreplacement level. The value of roughly the best player nobody has rostered — in a standard 12-team league with 13 slots, the 157th-best player on the board. It is a real number from this same board, and it is usually negative.
ahis share of the season. From stage 5. The fraction of games we expect to get from him.

That is the whole idea. A missed game costs you the gap between the player and his replacement, not the whole player. You are not left with nothing when a star sits. You are left with the waiver-wire guy. So an injury-prone star stays a star, and a fringe player's availability barely matters, because he was worth about replacement anyway.

Tested: the obvious version — multiplying value by availability — is much worse. It prices a missed game at zero, as if the roster slot produced nothing.
The numbers
Walk-forward 2010–2025. Multiplying ranked worse than ignoring availability altogether in 16 of 16 seasons (rank correlation 0.709 against 0.745), because a 0.54-to-1.00 multiplier swamped every real difference in skill. The blend scored 0.746, the best of five arms tested. This is the largest single correction on the page: the form of the availability term is worth roughly 5%, where most other results here are worth well under 1%.
What happens on a dynasty runway
Aging already happened, back in stage 2, inside the stat line where it can move a shooting percentage. Applying an aging multiplier to the value as well would age him twice, so the board doesn't.

Set a dynasty runwayrunway — yours and that changes. The board sums 2 or 5 successively aged seasons into a multi-year total, which is why dynasty numbers run bigger than redraft ones. The year-over-year curve those seasons are aged on is the expectedchange — the average of what happened to comparable players, collapses included, not the typical survivor's. Past nine years in the league it never turns back up, so a thin group of 15-year veterans who happened to hold up can't make a 15-year player age slower than a 12-year one.

On the 5-year runway only, each future season is also weighted by the odds he is still in the league at all by then, measured from twenty years of careers at his experience level. This applies to every player outside the top 40 by current value. The aging curve alone cannot see this, because it is fitted only on players who played both seasons of a pair — so a career ending is invisible to it. The top 40 are exempt on purpose: established stars almost never leave mid-contract, and top-40 players with 14 to 20 years in the league played the next season close to 100% of the time.
Tested: pricing the odds a player is still in the league helps on a five-year runway, for everyone except established stars. Applied to stars as well, it made the top of the board worse — so it isn't.
The numbers
Walk-forward 2010–2020, 11 five-year windows, top-200 pools. Rank correlation with realized five-year production: +0.010 over no survival term, better in 10 of 11 windows, top-50 +0.012. Predicted rank by experience band (0–3, 4–7, 8–11, 12+ years) lands within about 3 board places of what happened. Applied to everyone, the same odds ranked the top 50 worse and under-priced 12+-year veterans by 6.4 spots, so that form was rejected. On the 2-year runway the same term measured +0.003, inside the noise, so that runway doesn't carry it. Refitting the curve as the expected change with a non-rising tail was worth another +0.011 on the same test, and left next-season rankings unchanged within noise.

Two honest caveats.Five-year windows starting in consecutive seasons share four years of data, so 10 of 11 is a consistency check, not 11 independent trials. And the "exempt the top 40" form was chosen after looking at diagnostics on these same seasons — so it rests on that consistency, on the shape across experience bands and on the rank calibration, not on a p-value. An earlier, stronger-looking version of this result was measured on a flawed base and has been withdrawn.

07

The 0–99

The rating you see is the value, stretched across everyone ranked.

ALGO = round( 99 · ( V′min ) ÷ ( maxmin ) )

In plain words: find where his value sits between the worst ranked player and the best, and put that on a 0 to 99 scale.

Three honest things about that number.

  • It's relative. The best player in the ranked pool is always exactly 99 and the worst exactly 0. The endpoints carry no information about quality.
  • It belongs to the pool, not your view. Filter down to centers and the best one on screen usually won't read 99, because the scale still stretches across everyone ranked.
  • It isn't rank. Spacing is real. The gap from #1 to #2 can be several ALGO points while ten places further down cost you one. Four ALGO points is the same amount of value wherever you read it. Four places is not.

Two boards with different settings are two different equations, and neither is wrong.

A known weakness of this scale
Because both ends are set by one player each, an unusually dominant season compresses everyone else. Today the board's top player is far enough clear that he alone defines a meaningful slice of the scale. Anchoring the scale on replacement level instead would be steadier across seasons. We haven't changed it because the ordering — which is what a draft board is for — is identical either way.

08

Points leagues — the other branch

If your league scores points, stages 3 and 4 are replaced by something genuinely simpler. We don't dress it up.

V = Σ stat · league weight

In plain words: every stat times what your league pays for it, added up. That's fantasy points per game.

No pool, no averages, no spreads, no compression, no punts, and no streakiness charge. The one subtlety worth knowing: double-doubles and triple-doubles are per-game rates. A player who double-doubles 40% of the time earns 0.4 of your double-double bonus every game, rather than a whole one some nights.

Stage 2 builds his line the same way, and stages 5, 6 and 7 are identical — the same expected games, the same blend toward replacement, the same 0–99. Only the grading changes.

WORKED EXAMPLE

All of it, on one real player: Alperen Sengun

Everything above, with his actual numbers — computed live by the same engine that ranks the board, not typed in by hand. He is HOU · F-C, currently #8 of 422 ranked players.

Stage 5 first — how many games we expect

This is the number people doubt most, so here is every step of it. His last five seasons, most recent weighted heaviest:

Availability by season
SeasonHe playedSeason lengthWeight
2021-227282×1
2022-237582×2
2023-246382×3
2024-257682×4
2025-267282×5
raw = 1075.0 ÷ 1230.0 = 0.874
shrunk = ( 0.874·410 + 0.525·123 ) ÷ ( 410 + 123 ) = 0.793
a = 0.793 0.006 = 0.78882 × 0.788 = 65 games

Read across: his own record says 0.874, but with 410 team games of history against a prior worth 123, it is pulled down toward the pool's 0.525 to land at 0.793. The age adjustment for a player 5 years into his career then marks it down to 0.788 — about 65 of 82 games.

Stages 2–3 — his line, graded

His projected per-game line, each stat against the 200-player curve. The last column is what actually entered the sum, after the extremes are compressed:

Category grades
CategoryHisPool avgSpreadGradeCounted
DD0.510.150.18+2.03+1.77
REB9.65.22.2+1.93+1.70
FGM8.25.61.7+1.51+1.39
AST5.93.71.8+1.23+1.17
PTS20.815.64.9+1.08+1.04
TD0.050.010.04+0.97+0.93
BLK0.90.60.4+0.80+0.78
STL1.21.00.3+0.57+0.57
3PM0.61.80.8−1.45−1.35
TO (lower is better)2.91.80.7+1.58−1.45
His total grade+6.56

Stages 4, 6 and 7 — the charge, the blend, the rating

V = +6.56 − 3·0.39 = +5.40
V′ = 0.788·+5.40 + 0.212·−4.41 = +3.32
ALGO = 99 · ( +3.32−13.28 ) ÷ ( +8.09−13.28 ) = 77

His streakiness charge is 1.16. Then the blend: he is expected for 65 games, so 79% of him is him and the rest is replacement level at −4.41 — the 157th-best player, the man you'd start instead. That lands him at +3.32, which against a board running from −13.28 to +8.09 is an ALGO of 77.

Check it yourself. Every number here is the engine's own — the grades, the pool averages, the replacement level and the availability trace all come from the same functions that rank the board, not from a second copy written for this page. If the arithmetic above ever stopped adding up to the rating, this section would disappear rather than show you something that doesn't reconcile.

ASIDE

The playoff schedule — beside the rating, on purpose

The board carries a block of playoff columns, and none of them touch the rating. That is a decision, not an oversight. It is also the one place on this page where the honest answer is that we measured the obvious version and it did not earn a place in the math.

PWplayoff-window games. How many games a player’s NBA team plays inside your fantasy playoff rounds. Pure calendar: teammates share the number, and only games that count for fantasy are counted.
xPWexpected playoff-window games. The same games, each weighted by his own chance of actually playing it — recent availability, role, back-to-back second nights, how late the game falls, and what his team is still playing for. A rotation player on a team already out of the race misses about half his scheduled final-weeks games. This is a window number, not the expected games of stage 5.

So why not fold it in? We tested exactly that — weighting a player's value by the games he's expected to give you in the window. At the window most leagues use, the last three weeks of the season, it measured flat. No reliable gain, no loss. A flat result doesn't get to move a number quietly, so the schedule sits in columns where you can see it and weigh it yourself.

Tested: the schedule genuinely helps only for leagues whose finals land well before the season ends — and it ships for exactly those, nowhere else.
The numbers
The expected-games model was fitted and validated walk-forward across twenty seasons. Weighting value by it gained 1–3% for leagues with early finals, and about nothing at the standard window. A placebo window in mid-January won by the same margins, which settles what the effect really is: a better forecast of production inside any window you choose, not a playoff edge. It ships only at three or more weeks of daylight, the position where the win was clearest.
Where the window comes from, and what ships
Connect a league and its bracket is read from the league itself and locked. Otherwise the PLAYOFF SCHEDULE control above the board opens on the common shape — two rounds and a finals, one week each, over the last three weeks of the regular season — tagged EST until you set your real dates. Rounds don't have to be whole weeks or run end to end, a two-week championship is just a finals with a fourteen-day range, and a league that plays no playoffs at all is a real answer that takes the columns off the board entirely.

The one arm that did not measure flat — leagues whose playoff window closes three or more weeks before the regular season ends — ships for exactly those leagues and no others. Connect one, and from four weeks before its window opens until that window closes, value on your league pages is weighted by expected window games. The public board you are reading about is untouched. Sorting by PW or xPW reorders the board and renumbers the # column, but nobody's rating moves.

09

The receipts

Every choice that changes what a player is worth gets backtested against real seasons before it ships. The tested tags on this page are those results. The rule cuts both ways — here is some of what we measured and rejected.

Kept, because it won
The replacement blend, worth about 5% and the biggest single fix here. Per-stat aging, −7.2% error overall and −22.5% for long careers. The per-minute projection basis, +1.2%. Recency-weighted availability, +0.3 to +0.5%. Grade compression, on the player-level test.
Rejected, because it lost
Multiplying value by availability. A role dimension on the aging curve. A "recovery bonus" for injury returners. Playoff-schedule weighting at the standard window. Career-survival odds applied to stars. Five market intuitions have now been measured and refuted here. A rejection is a result too, and it stays rejected.

How to read a win count on this page. Most of these results are small — a fraction of a percent in rank correlation — and the test seasons overlap, because the same players appear year after year. So "better in 14 of 16 seasons" means the improvement was consistent, not that we ran 16 independent experiments. Where a result was shaped after looking at the data, we say that too. The one genuinely large effect on this page is the replacement blend.

And where a number is a convention rather than a measurement — the 3 : 2 : 1 window weights, the 123-game pull, the charge coefficients — we say so instead of inventing a test that was never run.

Glossary

Every term on this page that isn't everyday fantasy vocabulary, defined once.

gradegrade point. The shared unit stages 3 to 6 work in. One grade point is one standard deviation of one category — roughly the gap between an average rotation player and a clearly above-average one in a single stat.
poolthe ranked pool. Everyone who clears the games and minutes floors — about 650–700 players. The 0–99 scale is stretched across them.
curvethe grading curve. The smaller group the averages and spreads are computed from: the top 200 by minutes, or your league's roster demand if you've connected one.
replreplacement level. The best player nobody rosters. In a 12-team league with 13 slots, about the 157th player. It is what you actually get on a night your man sits.
xGPexpected games. How many of a season's games we expect from him. Not last season's games played — an estimate built from five seasons, pulled toward the average, and age-adjusted.
wfwalk-forward. How every result here was tested. To score a season, the model may only use data from before it. Nothing is ever fitted on the season it is graded on.
ρrank correlation. How closely a ranking matches what actually happened, from 0 (random) to 1 (perfect). A change of +0.01 is small but real; the availability fix was worth about +0.037.
runwayrunway. How many future seasons a dynasty rating adds up: 1, 2 or 5. Longer runways produce bigger numbers, because they are sums.

Updates

The algorithm improves by measurement, and this page moves with it — last updated . Recent changes:

This page rewritten in plain English: a short version at the top, a real player near it, the arithmetic moved under expanders, and every measured result stated as what it means before what it measured. Three claims were corrected rather than reworded — the grade-compression result now reports the team-level test alongside the player-level one, the compression table had a rounding error, and the streakiness charge is now labelled as what it is, the one untested number in the default rating. The rating itself did not change.
The 5-year dynasty runway now weighs the measured odds a player is still in the league in each future season, for players outside the top 40 by current value — long-career role players stop being priced as if careers never end, while established stars, who almost never leave mid-contract, are left to the aging curve. Better in 10 of 11 backtested five-year windows; the gain on the 2-year runway was too small to call, so that runway is unchanged. The aging curve behind every horizon is now the expected year-over-year change rather than the typical survivor's, and it never turns back up past nine years in the league; redraft rankings measured unchanged within noise.
Projections re-based on per-minute production at today's minutes — a player who earned a bigger role stops being priced at his bench seasons. Better in 14 of 16 backtested seasons.
This walkthrough published.

The knobs are yours. Every blue tag on this page is an Algo Input — a control you can turn on the rankings board or in the Algo Lab, per profile and even per player. Gray steps are part of the algorithm. One control is deliberately neither: the playoff schedule columns are information beside the rating, and this board's rating never sees them.

Player data from the regular season only, play-in excluded. Ratings recompute as the season moves. A player's dossier shows this same walkthrough with his own numbers in every slot.