Calculating Pitcher WAR, A Complete Example
One of the hallmark statistics available at FanGraphs is Wins Above Replacement (WAR) and we’ve just rolled out an updated Library entry that spells out the precise calculations for pitchers in more detail than ever before. There’s always been a clear sense of the the kinds of things that go into our WAR calculation, but until this point finding the specific formula for pitcher WAR has been a little complicated.
As of today, we’ve resolved that and I encourage you to go check out our basic primer on WAR and our detailed breakdown of how we calculate it for pitchers. If you’re a hands-on learner, grab a pen and paper or spreadsheet and follow along. I’m going to walk you through a complete example of how to calculate WAR for pitchers. Let’s use the 2016 version of Marcus Stroman as our exemplar. Please note that I will being rounding off certain numbers in the example to keep the page as neat as possible, so if you wind up being off by 0.1 WAR or so, don’t sweat it.
See also: Position Player Formula | Position Player Example
Overview
Calculating WAR for pitchers is conceptually straightforward, but there are many steps and a lot of notation to follow. Generally speaking, the first thing you need is some estimate of a pitcher’s value relative to league average. There are all sorts of different approaches to selecting this number. FanGraphs uses Fielding Independent Pitching (FIP), with a few adjustments, but you could use RA9, DRA, or any other metric related to pitcher performance.
Once you have a number that you can compare to league average, you need to convert that from runs per game to wins per game. To do that, you need to divide by runs per win. This gets more complicated for pitchers than hitters because pitchers directly influence their run environment in a way that hitters do not. So instead of using the league average runs per win value, we calculate it specifically for each pitcher.
Then we need to add in replacement level, which is different for starters and relievers. After that we scale the number based on innings pitched. For relievers, we also add a leverage component. Finally, we make a small uniform adjustment at the end so that the league-wide WAR value matches our target.
Here’s the basic construction:
WAR = [[([(League “FIP” – “FIP”) / Pitcher Specific Runs Per Win] + Replacement Level) * (IP/9)] * Leverage Multiplier for Relievers] + League Correction
Fielding Independent Pitching (with Infield Flies!)
The first thing you need to do to calculate Stroman’s WAR is to calculate his FIP. Unfortunately for those of you playing along at home, you can’t simply take Stroman’s FIP from his player page because we treat infield fly balls (IFFB) as strikeouts for the purposes of WAR but not for the general FIP calculation found on the player pages. We’ll call this ifFIP to avoid confusion. Keep in mind that you also need to calculate a special ifFIP constant and can’t just grab “cFIP” from our guts page.
Here is the formula for the ifFIP constant, all values are MLB wide:
ifFIP Constant = lgERA – (((13*lgHR)+(3*(lgBB+lgHBP))-(2*(lgK+lgIFFB)))/lgIP)
ifFIP Constant = 4.19 – (((13*5610)+(3*(15088+1651))-(2*(38982+4234)))/43306.33)
ifFIP Constant = 3.34
Now that we have the ifFIP constant, we use the standard FIP formula with IFFB added in as strikeouts pulling from Stroman’s 2016 stats.
ifFIP = ((13*HR)+(3*(BB+HBP))-(2*(K+IFFB)))/IP + ifFIP constant
ifFIP = ((13*21)+(3*(54+4))-(2*(166+7)))/204 + 3.34
ifFIP = 3.84
Scaling ifFIP to RA9
When we’re working with FIP in general, we know that it’s on the ERA scale. That is, league average ERA and league average FIP are equal. For the purposes of WAR, we want to put FIP on the same scale as RA9. Making this adjustment is simple, just find the difference between MLB average RA9 and ERA, and then add it to Stroman’s ifFIP.
Adjustment = lgRA9 – lgERA
Adjustment = 4.52 – 4.19
Adjustment = 0.33
FIPR9 = ifFIP + Adjustment
FIPR9 = 3.84 + 0.33
FIPR9 = 4.17
Now we have a new metric that we have called FIPR9. This is FIP, with infield flies, on an RA9 scale.
Park Adjustment
Now that we have FIPR9, we need to adjust it for the pitcher’s home park. On our park factors page, you will see a park factor labeled “FIP,” which is the park factored designed specifically based on the FIP components. To park adjust, simply divide FIPR9 by the FIP park factor over 100. In this case, the Jays park factor is 101.
pFIPR9 = FIPR9 / (PF/100)
pFIPR9 = 4.17 / (101/100)
pFIPR9 = 4.12
pFIPR9 is the number we’re going to use as our measure of Stroman’s value. It’s FIP with infield flies adjusted for park and scaled to RA9.
Compare to AL/NL Average
The next step is to determine how Stroman compares to his league’s average. To do this, you need to calculate the FIPR9 for that specific league (i.e., AL or NL) based on the process above. You can skip the park factor because it will be 100. He’s in the AL, so it goes like this:
AL ifFIP = ((13*AL HR)+(3*(AL BB+ AL HBP))-(2*(AL K+AL IFFB)))/ AL IP + ifFIP constant
AL ifFIP = ((13*2934)+(3*(7280+771))-(2*(19244+2320)))/21611 + 3.34
AL ifFIP = 4.23
AL FIPR9 = AL ifFIP + Adjustment
AL FIPR9 = 4.23 + 0.33
AL FIPR9 = 4.56
Once you have that, subtract Stroman from the league:
Runs Above Average Per 9 (RAAP9) = AL or NL FIPR9 – pFIPR9
Runs Above Average Per 9 (RAAP9) = 4.56 – 4.12
RAAP9 = 0.44
This gives you the number of runs above average per nine innings that Stroman is relative to his league. I have invented the abbreviation RAAP9 so that we can keep the notation straight.
Dynamic Runs Per Win
As noted above, pitchers directly influence their run environment based on how well they pitch. As a result, we don’t simply use the league average Runs Per Win (RPW) value, we use a dynamic equation that creates a unique RPW value based on Stroman’s innings per game and pFIPR9. Here’s how it works:
Dynamic RPW (dRPW) = ([([(18 – IP/G)*(AL or NL FIPR9)] + [(IP/G)*pFIPR9]) / 18] + 2)*1.5
I recognize this looks like a disaster, but I tried to alternate the parenthesis format to give you a chance to get the order of operations right. Let’s focus on what’s inside the bold red brackets first. Inside those brackets we are calculating the average run environment for games Stroman pitched in. There are 18 pitcher innings in a typical MLB game but Stroman only impacts the run environment directly in a portion of those innings. Let’s pull out the part of the equation inside the red brackets:
([(18 – IP/G)*(AL or NL FIPR9)] + [(IP/G)*pFIPR9]) / 18
The bold terms are setting up a weighted average. On the left it’s the innings per game Stroman is not on the mound and on the right it’s the innings per game Stroman is on the mound. We multiply the left term by the league average and the right term by Stroman’s pFIPR9. Then we divide by 18 to re-scale it to runs per nine scale.
You’ll note that we also need to add that value to 2 and multiply it by 1.5. You’re probably wondering why we’re doing that, and the simple answer is that it’s a straightforward way to convert Runs Per Game into Runs Per Win. You could use a more complex process known as Pythagpat, but the values will almost the same. This is equivalent to how we handle the conversion for position players. The big difference for pitchers is inside the bold red brackets.
So let’s actually do it for Stroman. He pithed 204 innings over 32 starts. That’s 6.375 IP/G.
Dynamic RPW (dRPW) = ([([(18 – IP/G)*(AL or NL FIPR9)] + [(IP/G)*pFIPR9]) / 18] + 2)*1.5
Dynamic RPW (dRPW) = ([([(18 – 6.375)*(4.56)] + [(6.375)*4.12]) / 18] + 2)*1.5
Dynamic RPW (dRPW) = 9.61
Converting to Wins Per Game
So far we have RAAP9 which is a runs per game metric. We also have dRPW which is a runs per win metric. If we divide RAAP9 by dRPW, we can create a metric that is on the scale of wins per game above average.
Wins Per Game Above Average (WPGAA) = RAAP9 / dRPW
Wins Per Game Above Average (WPGAA) = 0.44 / 9.61
Wins Per Game Above Average (WPGAA) = 0.046
Replacement Level
So far we have the Stroman’s performance relative to AL average. But we’re shooting for wins above replacement, so we need to know the difference between an average pitcher and a replacement level pitcher. The formula looks complicated, but that’s only because it’s designed to handle relievers and starters at once.
Replacement Level = 0.03*(1 – GS/G) + 0.12*(GS/G)
In other words, you want 0.03 times the share of your games that took place as a reliever plus 0.12 times the share of your games that took place as a starter. If the pitcher was a reliever only, replacement level is 0.03. If the pitcher was a starter only, the replacement level is 0.12. You only need the formula if they split time between both roles, and even then, it makes more sense to calculate their WAR separately as a reliever and starter and add them together at the end. We’ll do the entire thing just so you can see it work:
Replacement Level = 0.03*(1 – GS/G) + 0.12*(GS/G)
Replacement Level = 0.03*(1 – 32/32) + 0.12*(32/32)
Replacement Level = 0.12
Scaling to Innings Pitched
We have wins per game above average (WPGAA) and replacement level on a wins per game scale, so our next step is to add them together.
Wins Per Game Above Replacement (WPGAR) = WPGAA + Replacement Level
Wins Per Game Above Replacement (WPGAR) = 0.046 + 0.12
Wins Per Game Above Replacement (WPGAR) = 0.166
That leaves us with wins per game above replacement (WPGAR). The next step is to get rid of the “per game” because we’re interested in wins above replacement (WAR). To do that, we need to multiply by IP/9.
“WAR” = WPGAR * (IP/9)
“WAR” = 0.166 * (204/9)
“WAR” = 3.76
You’ll notice “WAR” in quotes because we have to make a couple of minor tweaks before we are completely finished.
Leverage
We want to give relievers who pitch in higher leverage spots more credit, but we have to make an adjustment to their leverage index first. The idea behind WAR is that we are comparing a player to a replacement level player. For a starting pitcher, that’s easy enough to do. If you get hurt, you’re replaced by someone from Triple-A. But relief pitchers have a hierarchy. If the closer gets hurt, a Triple-A player doesn’t slot into the closer’s role. Rather, everyone in the pen moves up a slot and the Triple-A arm takes the lowest rung on the ladder. As a result, we want to account for this by considering the reliever’s role in the WAR calculation. You may hear this referred to as “chaining.”
LI Multiplier = (1 + gmLI) / 2
Essentially, we’re regressing the pitcher’s average leverage index halfway toward average to account for the chaining effect. Once you have the LI Multiplier, multiply it by “WAR” for relievers. You can ignore this step for starters, so we won’t apply it to Stroman.
Final Adjustments
There is one final step to take in order to ensure that MLB league-wide pitcher WAR sums to 430 each season. That value is based on our assumption that there are 1,000 WAR per season (i.e., that replacement level is a 0.294 winning percentage) and that the position player/pitcher split is 57%/43%. These assumptions are subject to debate, but even if you change the values to something else, this final correction is necessary, just with different values.
Essentially what we need to do is make a uniform adjustment per IP. For 2016, that adjustment was -0.000682902 per IP (called WARIP). We multiply that by the Stroman’s IP to get the correction.
Correction = WARIP * IP
Correction = -0.000682902* 204
Correction = -0.14
The number changes year to year, but it’s generally in the range of -0.0007 and -0.0012. I’ll post more about how to get that WARIP over on the Library page if anyone is curious.
Finally, you take your “WAR” value and add the correction and you’re done.
WAR = “WAR” + Correction
WAR = 3.76 – 0.14
WAR = 3.6
You’ll notice that on his player page it says 3.6 WAR! While you aren’t typically going to want to calculate a pitcher’s WAR by hand during your daily routine, this offers you a framework to construct your own version of WAR based on your own preferences. For example, if you don’t like FIP you can start with some other statistic like RA9, SIERA, xFIP, etc. If you don’t like our park factors you can use a different one. If you want to control for strength of opponent, you can do that as well.
As I noted at the beginning, I don’t think any of this is conceptually that complicated, but there are a lot of steps and notation between the beginning and the end. If you have questions, feel free to post them in the comments or to find me on Twitter @NeilWeinberg44.
Neil Weinberg is the Site Educator at FanGraphs and can be found writing enthusiastically about the Detroit Tigers at New English D. Follow and interact with him on Twitter @NeilWeinberg44.