Who Gives a Hoot’s exclusive League 1 Elo Rankings are created by local wizard and Union Omaha fan, Jon Ryan. We will be releasing updated rankings each Monday as part of the Data Dump column or when Union Omaha doesn’t play as a standalone. What follows is a full explanation of the work he is doing in his own words.
The Elo rating system (named after its developer, Arpad Elo) was originally designed to determine the skill levels of individual players in what are known as zero-sum games, in this case chess was the game Elo was most interested in. However this formula can be adapted to consider other games and sports, soccer of course being one of them. While not officially used by FIFA, Elo ratings are still calculated to this day in international soccer. As of the writing of this document (August 12, 2020) Belgium is currently the highest rated team, and have been since November 16, 2019.
The “zero-sum” aspect of an Elo rating system is still respected regarding soccer in that at the conclusion of a match, one team’s rating will increase a specific amount and their opponent’s will decrease by the exact same amount. Numerous variables go into calculating a team’s rating after the result of a particular match:
- Their rating prior to the match
- The rating of their opponent prior to the match
- The location of the match (home vs. away vs. neutral)
- The result of the match (including goal difference)
- The importance of the match (friendly, tournament, final, etc.)
Using the elements above, a formula can be calculated to determine the adjustment to a rating from the results of an individual match. The basic formula used is:
Ro + P = Rn
The variables above are defined as:
Rn = New team rating
Ro = Old team rating
P = Change in points
The “P” variable has a formula of its own: P = KG (W – We)
The variables above are defined as:
K = Weight applied based on the match importance (see table below)
G = Number from an index applied based on goal difference (see table below)
W = Match result (1 for a win, 0.5 for a draw)
We = Expected result (see formula below)
How to determine “K”
Table for variable labeled “K”:
| Match Type | K |
| Regular Season | 30 |
| Postseason | 40 |
| League Final | 50 |
How to determine “G”
The variable listed as “G” will simply have a value of 1 if a match ends in a draw or a one goal difference. If the result of a match is a two goal difference, the value of “G” is 1.5. For all other results, the following formula is used, where “N” is the goal difference of the match:
G = (11 + N) / 8
Using the above formula, the index that determines “G” looks like this:
| Goal Difference | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| G | 1 | 1 | 1.5 | 1.75 | 1.875 | 2 | 2.125 | 2.25 |
How to determine “We“
Finally, we need to determine win expectancy. This formula looks complicated, but when you have a spreadsheet to do all of the work for you it’s not so bad:
We = 1 / (10 -dr/400 + 1)
“dr” is the difference between the two team’s ratings. If the match is not at a neutral location, add 100 points to the home team’s rating before calculating.
It’s as simple as that!
A team with an Elo rating of 1500 is considered to be an average team, so in order to calculate these ratings each team started with an equal rating of 1500 at the beginning of the 2019 season. Here is an example of how the match on March 30, 2019 between Orlando City B and FC Tucson (both club’s season openers) was calculated, a match won by FC Tucson 3-1:
Orlando City B (Home)
We = 1 / (10 -dr/400 + 1)
We = 1 / (10-((1500+100)-1500))/400 + 1)
We = 1 / (10-(100/400) + 1)
We = 1 / (10-.25 + 1)
We = 1 / 1.562
We = .6401 (64.01%)
P = KG (W – We)
P = 30 (1.5) (0 – .6401)
P = -28.8029
Rn = Ro + P
Rn = 1500 – 28.8029
Rn = 1471.1971
FC Tucson (Away)
We = 1 / (10 -dr/400 + 1)
We = 1 / (10-(1500-(1500+100))/400 + 1)
We = 1 / (10-(-100/400) + 1)
We = 1 / (10.25 + 1)
We = 1 / 2.778279
We = .3599 (35.99%)
P = KG (W – We)
P = 30 (1.5) (1 – .3599)
P = 28.8029
Rn = Ro + P
Rn = 1500 + 28.8029
Rn = 1528.8029
As you can see above, everything that is not a constant is in direct relation to the opponent due to the zero sum nature of Elo rankings. For example, each team’s chances of winning the match are combined to equal 1, and the winning team gains the same number of points that the defeated team loses. Naturally these ratings fluctuate over the course of the season, leading to the following ratings right before the 2019 USL League One final played between North Texas and Greenville Triumph (rounded to the nearest point):
| Team | Rating |
| North Texas | 1635 |
| Greenville Triumph | 1576 |
| Lansing Ignite | 1562 |
| Forward Madison | 1556 |
| Chattanooga Red Wolves | 1503 |
| South Georgia Tormenta | 1475 |
| Toronto FC II | 1471 |
| FC Tucson | 1453 |
| Richmond Kickers | 1450 |
| Orlando City B | 1318 |
Let’s look at an example from one more match from last season, the 2019 USL League One Cup Final (for the sake of simplicity, ratings are rounded to the nearest whole number for display purposes only, results below are from the calculation of the actual ratings):
North Texas Soccer Club
We = 1 / (10 -dr/400 + 1)
We = 1 / (10-((1635+100)-1576))/400 + 1)
We = 1 / (10-(159/400) + 1)
We = 1 / (10-.3975 + 1)
We = 1 / 1.4004
We = .7141 (71.41%)
P = KG (W – We)
P = 50 (1) (1 – .7141)
P = 14.2907
Rn = Ro + P
Rn = 1635 + 14.2907
Rn = 1649.2907
Greenville Triumph
We = 1 / (10 -dr/400 + 1)
We = 1 / (10-(1576-(1635+100))/400 + 1)
We = 1 / (10-(-159/400) + 1)
We = 1 / (10.3975 + 1)
We = 1 / 3.49747
We = .2859 (28.59%)
P = KG (W – We)
P = 50 (1) (0 – .2859)
P = 14.2907
Rn = Ro + P
Rn = 1576 – 14.2907Rn = 1561.7093
So, that’s the 2019 season in a nutshell. Now, how do we handle the start of the 2020 season?
Should roster churn account for anything? What about new teams? So, obviously, just because 2020 is Union Omaha’s first season doesn’t mean we should pretend 2019 didn’t happen. That’s why in order to begin tracking how Union Omaha compares to the rest of the league, the 2019 season needed to be calculated first. Then, I arbitrarily decided to reduce all team’s gains/losses over the course of the previous season by 50% to account for roster churn, venue changes, and coaching changes. So, each team moved closer to 1500 (that base position representing an average team) while all new teams were assigned a new value of 1500 to start the 2020 season. These adjustments can be seen below:
| Team | 2019 final rating | 2020 opening rating |
| North Texas | 1650 | 1575 |
| Greenville Triumph | 1562 | 1531 |
| Lansing Ignite | 1562 | R.I.P. |
| Forward Madison | 1556 | 1528 |
| Chattanooga Red Wolves | 1503 | 1502 |
| South Georgia Tormenta | 1475 | 1488 |
| Toronto FC II | 1471 | ¯\_(ツ)_/¯ |
| FC Tucson | 1453 | 1477 |
| Richmond Kickers | 1450 | 1475 |
| Orlando City B | 1318 | 1409 |
| Fort Lauderdale CDF | — | 1500 |
| New England II | — | 1500 |
| Union Omaha | — | 1500 |
With this as the baseline we’ve been testing our model each week and are ready to go live at the end of Matchweek 5.
5 thoughts on “League 1 Elo Explainer”