Introduction

In this article I am going to consider the topic of adjusting team ratings for schedule strength.  All fans will know that teams will on average perform better against opposition that is ranked lower in the table and worse against opposition ranked higher.  This blog is all about the predictive and we don’t want our measure of a team’s performance to be skewed by their opposition. 

My team ratings are nearly always in the style of a performance delta for each game (as opposed to a percentage/ratio).  E.g. if the home team has 10 shots in a game and the away team has 5, the home teams rating for that game is +5.  If a team has 6.25 xG for and 10.1 xG against over 5 games then the team’s rating for that sample of games is the xG difference (6.25 – 10.1 = -3.85) divided by the number of games (5) to give -0.77 (xG) per game.

How to apply a fixture adjustment

Let’s make a mock 10 team league and assign the ability of each team as follows:

Table 1

Let’s consider how I would make 2 different schedule adjustments.

Example a):

If Team D (a league average team1) plays teams A and C (one home and one away so it balances out) – we’d expect their performance for those 2 games to average -2.4 xG, or -1.2xG per game.

Table 1 (team ratings based on a large sample of games) tells us team D is an average team.  We want their rating to show as 0 for whatever sample of games they play.  This means our fixture adjustment for team D for these 2 games is going to be +1.2 (-1.2xG (rating)+ 1.2xG (fixture adjustment) = 0

Example b):

Team B plays teams F and I, one home and one away.  Again we consider the performance of an average team against teams F and I and conclude the fixture adjustment for Team B will be -0.6 (sum the strength of the two opponents and divide by 2). 

Seems simple enough but I believe the 2nd example is missing something.  Do you know what it is?

Special Adjustment

In order to explain what extra adjustment is missing here, let’s play out a season in this mock league where each teams plays each team once (or more, it doesn’t matter too much but we assume home/away ties aren’t a factor).  The schedule adjustment I calculate for each team is as follows.

Table 2

Even though every team has played every team, it appears as though Team A has had an easy schedule (their opponents had an average performance of -0.24 xG per game) and team J a hard one. This comes about because if we average our performance rating for every team in a league will get 0 (it’s a zero sum situation, every xG produced is an xG conceded). Now when we consider all opponents team A have had, we are effectively removing team A and averaging the rating of every other team. This will not equal zero (and only would if we were considering the league average side, team D).

This all means we need an extra adjustment. No one would say a league is unfair because the better teams played an easier schedule than the lowly ranked teams did.  The opponents of the highly ranked teams only appear ‘bad’ as a function of the highly ranked teams own performance. We don’t want the schedule adjustment for each team to be a function of the teams own performance!

The adjustment we require for calculating the scheduled adjustment for a team is then:

Special adjustment = (Team rating) / (total teams in the league – 1)

where Team Rating is the rating of the team we are calculating the schedule adjustment for.

In example a) above the factor is zero as team rating is 0 in that case (0/11 = 0).  Using the formula for example b) we calculate 1.4 / 9 = 0.16.  This means we add a factor of 0.16 to the team rating of all the teams that Team B plays.  This means the fixture adjustment for team B would be -0.44 after playing team F and team I (-0.6 + 0.16).

The fixture adjustment of each team once the league is finished would now be zero – exactly what we want. The formula above is equal to the values in table 2 but with the opposite sign. When I recalculate table 2 with the special adjustment each value equals zero. This is what we want – in a completed league the schedule adjustment for every team is zero.

I would define a fixture adjustment for any Team ‘X’ as ‘the performance of a league average side against Team X’s opponents in an otherwise similar league without Team X’.

Summary

We now have a complete adjustment to add to the rating of a team.  For Team A this is

Fixture adjusted rating  =

Raw rating + Average level of Team A’s opponents + (rating of Team A / (total league teams – 1))

Remember the rating should be in the format of +3 shots per game or +0.5 xG per game or +1 goal per game e.t.c.

Quiz

Calculate the fixture adjusted rating for the following team.

The team in question have a rating of +0.3 xG after 5 games and they have played teams we estimate are of levels -0.1 xG, -0.05 xG, +0.2 xG, +0.5 xG, and +1.0 xG in a 20 team league. 

Circular Issues

In order to calculate the fixture adjustment we need the true performance level of the opponents.  The method is somewhat counterintuitive because we are trying to calculate the true performance level of every team but we need the performance levels of the teams as an input to adjust for schedule.  With smaller samples I recommend estimating the level of each opponent rather than inputting their raw performance.  If the adjusted ratings significantly change your estimated ratings it would be reasonable to recalculate the schedule adjustment with the new ratings.

Edit: Back from the future, I did a little study on how many iterations are optimal for a fixture here: https://syzygyanalytics.co.uk/2025/10/25/grab-bag-25th-october-2025/

If you would like to get in touch about anything or tweet me blow at https://x.com/SamH112358.

Also you could consider subscribing using the white box on my home page!

Glossary

1 It’s interesting to note there could be different definitions of ‘league average’.  In this case average to us means total attacking output is equal to the total attacking output of their opponents (i.e. their goal difference equals 0).  However it’s also not unreasonable to argue that the average side is the middle team of the league, e.g. 10th in a 20-team league.  If a league is skewed towards either having some very dominant teams or very weak teams then the middle team (10th in a 20 team league) would not be expected to have a goal difference of zero.  For all analytical purposes our ‘league average’ team is going to be the one with a goal difference of zero, an xG difference of zero, a shot ratio of 0.5 e.t.c.    

Posted in

6 responses to “Soccer Team Ratings II – Fixture Adjustments”

  1. Jay D Avatar
    Jay D

    Hey. Really enjoy your content.
    Can you confirm how you get to the figure of -0.44 in the below paragraph?
    ‘This means we add a factor of 0.16 to the team rating of all the teams that Team B plays. This means the fixture adjustment for team B would be -0.44 after playing team F and team I.’

    Sorry if it’s obvious, I’m not very au fait with maths/statistics!

  2. syzygy112358 Avatar

    Hi thanks for the comment!!
    Geez sorry I didn’t label part a) and part b) very well did I. I will edit the article a bit.
    Also I’ve screwed this part up, it does get a bit confusing with the signs. I’ll get back to you tomorrow

    1. Jay D Avatar
      Jay D

      Thanks. Appreciate this. I’m slowly making my way through all your articles!

      1. syzygy112358 Avatar

        Hi Jay I’ve re-wrote some of this now.
        See if it is any clearer? I don’t think it was clear I think it was a bit hard to read (and might still be). I think I did have the -0.44 correct though.

        Team B had a fixture adjustment of -0.6 (average level of the 2 listed opponents) + 0.16 (1.4/11 from the special adjustment formula) = -0.44

        Appreciate your comment it’s useful for me. Some of the material does require a bit of prior understanding I think

  3. Jay D Avatar
    Jay D

    Hey – sorry – I’ve only just had a chance to read this and respond.
    Thank you so much – it’s much clearer now.

    I have started creating my own tissue prices for asian handicap lines based off npxg supremacy weighted between whole season and last 5 games, before adding in home/away adjustments.
    I have not added in team ratings adjustment into my prices yet – I guess this is more pertinent when you have less data to go off earlier in the season? Although I can seen that a lot of professional punters use team ratings as part of their models.
    I have been trading football in-play for a few years now and predominantly rely on reacting to what I see happening in front of me to try and find value opportunities.
    However, I would like to try and add in this more bottom-up approach I suppose. Does it seem like I am on the right track?
    Thanks again – I really have found your blog posts insightful

    1. syzygy112358 Avatar

      hi glad it helped a bit, I’m never sure how easy it is for people to follow some things I write.

      “I have started creating my own tissue prices for asian handicap lines based off npxg supremacy weighted between whole season and last 5 games, before adding in home/away adjustments.”
      5 games is very few with raw xg but still useful to do I think. I’m working on a post(s) with on a similar topic.

      “I have not added in team ratings adjustment into my prices yet – I guess this is more pertinent when you have less data to go off earlier in the season?”
      Do you mean schedule adjustments here? If so you’re right schedules are definitely a bit more skewed for smaller samples and equalise over a larger period. In terms of other adjustments it varies

      “Does it seem like I am on the right track?”
      Yes sounds like a good track to me. I don’t really do anything in-play but sounds interesting for sure
      I’m perpetually trying to improve my procedures but in a way the finish line doesn’t seem to get any closer

Leave a Reply