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
- We work out what a player will do per game next season — not what he already did.
- We grade every stat against real rotation players, so rebounds and blocks can be added together.
- We add those grades up. That total is his value.
- We charge him for the games we expect him to miss, by mixing in the player you'd start instead.
- 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.
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.
| We expect him to play | 65 of 82 games | stage 5 |
| His stats grade out at | +6.56 | stage 3 |
| Minus the streakiness charge | −1.16 | stage 4 |
| Mixed with the man you'd start instead | +3.32 | stage 6 |
| Stretched onto the 0–99 scale | 77 | stage 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.
| One category, from average to best in the league | about 3 grade points |
| The streakiness charge | 1.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 point | 0.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.
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
The numbers
The numbers
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
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.
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?
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.
| raw grade z | +1 | +2 | +3 | +4 | +6 |
|---|---|---|---|---|---|
| counted ẑ | +0.96 | +1.75 | +2.28 | +2.61 | +2.89 |
The numbers
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.
Two known quirks of adding grades up
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
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.
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.
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.
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.
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.
The numbers
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
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.
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.
The numbers
What happens on a dynasty runway
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.
The numbers
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.
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
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.
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:
| Season | He played | Season length | Weight |
|---|---|---|---|
| 2021-22 | 72 | 82 | ×1 |
| 2022-23 | 75 | 82 | ×2 |
| 2023-24 | 63 | 82 | ×3 |
| 2024-25 | 76 | 82 | ×4 |
| 2025-26 | 72 | 82 | ×5 |
shrunk = ( 0.874·410 + 0.525·123 ) ÷ ( 410 + 123 ) = 0.793
a = 0.793 − 0.006 = 0.788 → 82 × 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 | His | Pool avg | Spread | Grade | Counted |
|---|---|---|---|---|---|
| DD | 0.51 | 0.15 | 0.18 | +2.03 | +1.77 |
| REB | 9.6 | 5.2 | 2.2 | +1.93 | +1.70 |
| FGM | 8.2 | 5.6 | 1.7 | +1.51 | +1.39 |
| AST | 5.9 | 3.7 | 1.8 | +1.23 | +1.17 |
| PTS | 20.8 | 15.6 | 4.9 | +1.08 | +1.04 |
| TD | 0.05 | 0.01 | 0.04 | +0.97 | +0.93 |
| BLK | 0.9 | 0.6 | 0.4 | +0.80 | +0.78 |
| STL | 1.2 | 1.0 | 0.3 | +0.57 | +0.57 |
| 3PM | 0.6 | 1.8 | 0.8 | −1.45 | −1.35 |
| TO (lower is better) | 2.9 | 1.8 | 0.7 | +1.58 | −1.45 |
| His total grade | +6.56 | ||||
Stages 4, 6 and 7 — the charge, the blend, the rating
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.
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.
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.
The numbers
Where the window comes from, and what ships
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.
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.
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.
Updates
The algorithm improves by measurement, and this page moves with it — last updated —. Recent changes:
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.