I wanted to share an article I wrote on a better way to analyze trades for 9cat fantasy basketball. If you want to read it in the format with images you can see it here:
https://ratball.ca/articles/how-to-analyze-fantasy-basketball-trades
A great way to analyze a trade in a head-to-head category league is to measure what it does to your team's chance of winning each category. This may seem obvious, but many trade analysis tools measure trades by who wins more "Z-scores", which is a very flawed way to see if you should make a trade.
This superior method evaluates the trade by representing each team with a probability distribution for each category. The probability distribution for each team is made of the probability distributions of all players on that team. You can easily compare the team level distributions to get a win % for that category.
Then, you swap the distributions of each player being traded to the teams they are being traded to, and recalculate the win %. The difference is the win % impact the trade has on your team.
The common alternative, adding up Z-scores for each side, gets this wrong in a predictable way. A Z-score total gives a player one fixed value, no matter which team he's on. But the same production is worth a lot in a category where your team is in the middle of the pack, and very little in a category you already win almost every week. Where your team stands decides what a player is worth to you, and it gets ignored by Z-scores.
A trade where both teams win
Because a player's value depends on the team, a trade between two teams isn't zero-sum. Each side can give up production it doesn't need for production it does, and both teams can come out ahead.
To find an example, I searched the same rosters for one-for-one trades between players of nearly identical overall value. One of the clearest win-wins was Alperen Sengun for Jalen Brunson. By Z-scores, the two were very even: Sengun at +1.35, Brunson at +1.36, ranked 30th and 29th (this was mid last season). When traded, according to category win%, both teams improved: +6.2% for the team that gets Sengun and +4.7% for the team that gets Brunson.
https://imgur.com/a/jCycxCc
The team that gets Sengun shows exactly why. It was winning threes 89% of the time and points 79% of the time, so giving up Brunson's scoring and shooting cost it only 10 and 8 points of win%. In return it gained 16 points in rebounds (from 49%) and 12 in blocks (from 33%). The team that gets Brunson gains in categories where it was behind: threes (from 22%), free throws (from 39%) and points (from 39%).
A Z-score total would call this trade a wash for both sides. Instead, it's a win for both.
A player's value to different teams
To demonstrate how each player gives different value to each team, I took one player, Josh Giddey, and added him to every roster in a sample league, then calculated how much each team's win% went up in each category.
Some teams gained a lot and some gained very little. For a team that was already winning points, rebounds and assists most weeks, he added +9.5% in total category win%. For a team that was behind in those categories, he added +51.7% across all categories.
https://imgur.com/a/iukx33N
Your category strengths decides what a player is worth
I repeated the same test in eight leagues, adding him to every roster. Here are some of the results:
In a category a team was already winning more than 80% of the time, he was worth less than half of his usual gain. In a category the team was winning 20% to 40% of the time, he was worth the most.
The teams' probability distributions show why; a team that already wins a category is ahead of almost everyone, so extra production helps them pass fewer teams. A team in the middle of the pack has opponents close by, and extra production moves it past many of them.
https://imgur.com/a/gFGilDB
Real matchups show the same effect
To confirm the effect holds in real matchups, I went back to 500 real head-to-head matchups from the 2025-26 season in eight leagues: 4,315 weekly category results. For each one, I calculated how many Z-scores one team was projected to be ahead in that category, using averages based on only games played before that week, and recorded who actually won.
The lead is measured in Z-scores: the projected gap between the two teams' weekly totals, divided by the category's per-game standard deviation (Z-scores). In points, one standard deviation is about 6 points, so a team projected to score 100 more points than its opponent that week leads by about 17 Z-scores.
https://imgur.com/a/mlDuAHc
When the projected lead was under 4 Z-scores, the team with the lead won only 53% of the time. With a 16 to 20 Z-score lead it won 75% of the time, and with a 36 to 40 Z-score lead, 88.5%. One more Z-score of projected lead added 1.4% to a team's chance of winning an even category, 1.0% at a 20 Z-score lead, and 0.5% at a 40 Z-score lead, about a third as much. In real results, as in the model, production is worth the most where the matchup is close.
All the data comes from eight public ESPN head-to-head category leagues from the 2025-26 season: five 9-category leagues and three 8-category leagues without turnovers.
ESPN league IDs: 312218237, 10287961, 1482931495, 1801165221, 832393914, 1382487116, 1609319867, 150
How probability distribution-based trade analysis works
This is the calculation RatBall's Trade Analyzer runs for your league.
1. Each player's single-game distributions
Every player gets a probability mass function (PMF) for each category, built from his (2025-2026) game logs: how often he scored each possible number of points, blocks, threes and so on in a single game. FG% and FT% use makes and attempts together, so a high-volume shooter moves a team's percentage more than a low-volume one.
https://imgur.com/a/AGqXi8e
2. Each team's week
A player's single-game distribution is combined with itself over the games he plays in a week. Then every player's weekly distribution on a roster is combined (convolved) into one weekly distribution per category for the whole team.
3. Win% in every category
The team's weekly distribution in each category is compared with every other team's, giving its chance of beating each one in a matchup week, with a tie counting as half a win. Averaged over every opponent, that's the team's win% in the category. It already reflects where the team stands: a team far ahead of most of the league in a category has a high win% there, and little left to gain.
4. Swap the players and compare
The traded players switch teams, both rosters are rebuilt, and the win% in every category is calculated again. The change in each category, added up across the categories your league scores, is the trade's Total Win% Change. Because each team is measured against the whole league, both teams can come out ahead.
Analyze your trades
A trade doesn't have a value of its own. It has a value to your team, in your league, and the best way to measure it is the way your matchups are decided: category win percentage. Comparing Z-score misses what's really important, and can lead to trades that make your team worse.
RatBall's Trade Analyzer runs this calculation on your own league. Connect your league, pick the players on each side, and it builds every team's weekly distributions from the rosters, swaps the players, and shows how the trade changes your win% in every category. It shows the same for the other team, and puts the Z-score comparison next to it, so you can see exactly where the two disagree.