So how are RotoValue auction prices computed anyway?
One way to think of them is as a sort of WAR for fantasy sports. Tom Tango has done a great job explaining WAR, emphasizing that it is a framework, and thus you can have many different implementations.
Ultimately that’s what RotoValue is – an implementation of a model to value fantasy players. Tango cites a list of key attributes for WAR:
a) WAR is wins above replacement.
b) WAR is a framework.
c) WAR presents the performance of a player into a single number.
d) WAR is limited to the data points it considers.
e) WAR is limited by the bias in the data.
f) WAR is not all-encompassing.
I think this is a great way to think about RotoValue pricing (and other fantasy sports pricing models, too). It’s “dollars”, not “wins”, but everything else in the description fits.
RotoValue is inherently based on the concept of replacement. A 12 team fantasy league needing 2 active catchers will need to start 24 catchers. While catchers usually don’t produce as good offensive stats as other positions, everyone needs two, and so players are valuable to the extent that they’re worth more than whoever is left over after all teams have picked somebody. That’s replacement level – you’re only as good as your replacement level.
So what do I do with RotoValue? Last fall I discussed it in the context of basketball, but the same basic model applies to all sports. First I need some measure of a player’s value, so I assign a normalized score to each player in each category. The best player in the league is given a score of 1, the worst is given 0, and everyone else is somewhere in between. Assuming equally weighted categories, I simply add up the category scores, and that’s the player’s raw value. Rate stats (like batting average or ERA) are a little more complex, but not too much: the “best” is impacted by how often you play. A batter who goes 1-3 may have a .333 average, but a .290 hitter in 600 AB helps your fantasy team a lot more. So I account for that.
And if you want to give categories different weights (either because that’s how your league scores, or because you want to emphasize or ignore particular categories because of how close teams are in the standings), I apply that here.
So this gives me a raw value for each player. Next I sort players by raw value, and find the “replacement” level for each position, which I define as the best player who shouldn’t be starting in the league. So in a 12 team league using 2 catchers per team, the 25th best catcher is the replacement level guy.
Once I know replacement level, I subtract the value of the replacement player from the raw value to get a net value for each player. I add up all the net value in the league (and the composite salary cap, minus any minimum bids required per roster spot), and I can create a ratio of dollars to “value”. So a player’s RotoValue price is just their net value times this ratio, plus the minimum bid.1
The whole point of a pricing model for fantasy sports is to distill a player’s expected contribution into a single number, the price. So in that sense, RotoValue is very much like a WAR implementation.
Like any pricing model, RotoValue is limited to the data points it considers. The model is designed to take in a set of statistics and output prices for players based on those statistics, and I’ve made it easy to use different sources: projections, actual data, and data from different time periods.
RotoValue is subject to constraints: the sum of positive RotoValue prices in a league must equal the total salary cap for that league. A player worth owning can’t have a price below the minimum bid. While WAR can never be all encompassing – you can’t quantify absolutely everything that goes into winning baseball games – a fantasy pricing model has an easier task, because the only thing that matters is the statistics players compile. And indeed the process of converting raw player statistics into prices is inherently a form of normalization, which can remove some biases in the input.
If, for example, a projection system is overly optimistic about league-wide batting average or ERA, that may make it seem “bad” in nominal comparison, but because prices are based on relative performance compared to a replacement level, and because the model is using as input a normalized score for each category, the raw numbers themselves can be “wrong” without impacting prices. If you doubled all the raw statistics for each player, the prices would be identical, because raw statistics are only meaningful in comparison to statistics of other players. But other biases in input will be reflected in computed prices: if your projections are overly optimistic for ground-ball pitchers, then they would as a group be overvalued compared to fly-ball pitchers.
Fantasy pricing will always be subjective, but it does help to have a consistent framework. RotoValue is one such framework. I first compute a raw normalized value for each player, summing their contributions in each category. After sorting by position, I find a replacement level for each player, and the player’s net value is just their raw value minus the appropriate replacement level.2 The remaining assumption is that an owner will pay the same rate for a unit of net value no matter where it comes from. So a player with a net value that is twice as big will have twice as large a price.3
RotoValue applies a consistent, reasonable set of assumptions to the problem of valuing players. When I bid in my own auctions, I use prices as a guide, but not as a hard-fast rule. And of course in bidding strategy you want to buy players below their theoretical prices, so I don’t always, or even usually, bid up to a player’s theoretical price for some input. Sometimes I may even bid beyond their price. But having a good model keeps me grounded.