Metrx Factory

FREEMIUM
By MetrxPulse | Updated 3 days ago | Sports
Popularity

9.2 / 10

Latency

667ms

Service Level

97%

Health Check

N/A

Back to All Tutorials (3)

Performance trends and peaks

_

Evaluating the strength of sports teams becomes a difficult task when coequal opponents compete and it is often overlaid by subjective perception. Whether a team performs well on the pitch does not only depend on its basic strength and tactic alignment but also if it is currently on form and not at least favored by fortune. When various of these factors add up either on the positive or negative side this can lead to winning or losing streaks and surprising results.

Everybody knows there is no team in the world that always wins or loses. This is simply due to the fact that one day even the strongest will not be able to confirm its rocket conversion rate and misses all its sitters in a game while the weakest benefits from a last minute penalty or an unfair referee decision.

Unsteady process

More than 80% of match actions in a football game underlie randomness. No surprise the final result of a single game can be quite random as well, especially in lower scoring sports like football (soccer). This single result can be seen as one tiny part in a process shaped when observing a sequence of results. Applying an objective rating to such a sequence reveals similarities to other natural unsteadiness processes existing out there. Those measuring time-varying quantities have one thing in common: they underlie a wave signal that fluctuates more or less and tends to reverse its direction when reaching a peak (a domain specific minimum or maximum value). These findings can be translated to performance in sports quite well since it’s subject to regular ups and downs.

_

For this exercise the Metrx Index being a long-term performance rating of team strength is a suitable measure. It is comparable to the widely known ELO rating but with more elaborate dependencies in points calculation. It draws the performance of all the teams on a single scale no matter what competition level, country or continent and brings them into relation.

When we plot the history of a team index we will recognize how much it naturally varies. Let’s try and evaluate the last three years of the Dutch top team PSV Eindhoven who showed a strong increase in team performance after the appointment of Roger Schmidt as their manager in 2020.

Step 1

We define the basic procedure which includes searching for the team in question, getting the history of its performance index and bringing the data into a convenient output format.

The team info is easily fetched from the API using the Get Teams endpoint. The operation requires at least four characters for a team name. The team’s identifier is then used to fetch historical data using the Get Team Performance Index History endpoint. We provide date threshold parameters which will return all the team’s performance index values within the desired time span.
Furthermore, we request the relative index format for a smoother representation, i.e. index values will be returned in percent and relation to other team indices.


BASE_URL = 'https://metrx-factory.p.rapidapi.com/v1';
HEADERS = {
  x-rapidapi-host: 'metrx-factory.p.rapidapi.com'
  x-rapidapi-key: 'your-app-key'
}

START
   team = get_team('psv e')
   pfms = get_performance_history(team['id'], DATE('20190301'), DATE('20220301'))
   plot_performance_history(pfms)
END

FUNCTION get_team(nameLike)
  uri = HTTP.uri(BASE_URL, '/teams', '?nameLike=', nameLike)
  json = PARSER.json(HTTP.request('GET', uri, HEADERS))
  IF json['success']
    return json['result'][0]
  ELSE
    PRINTER.error('Failed to get team: ', json['error'])
    return
  ENDIF
END

FUNCTION get_performance_history(teamId, minDate)
  uri = HTTP.uri(BASE_URL, '/performance-index/team-history', '?teamId=', teamId, '&minDate=', FORMAT(minDate), '&maxDate=', FORMAT(maxDate), '&format=REL')
  json = PARSER.json(HTTP.request('GET', uri, HEADERS))
  IF json['success']
    return json['result']['entries']
  ELSE
    PRINTER.error('Failed to get team performance history: ', json['error'])
    return
  ENDIF
END

Every history entry in the response is the result of an index change following from the preceding match performance.
What remains is to transform the entries into a data structure understandable by a plotting component of your choice.


FUNCTION plot_performance_history(entries)
  size = SIZE(entries)
  dataX = ARRAY[size] of DATE
  dataY = ARRAY[1][size] of FLOAT
  FOR i = 0 TO size
    dataX[i] = entries[i]['date']
    dataY[0][i] = entries[i]['index']
  ENDFOR
  PRINTER.plot(dataX, dataY, 'YYYY', '%', '', 'Performance index')
END

Performance Index History (1)

Step 2

The above chart might be perceived as a promise of PSV’s way towards Europe’s elite. Whether this trend will progress depends, of course, on too many factors to make a reliable statement. What we can do is look for potential turnarounds based on the underlying signal which can be a valuable approach when assessing team vitality or trying to find market niches.

Fortunately, the API provides us with trend information i.e. a measure how well the team performed during certain time frames. Precisely, we get a short-run average (ten matches) and a long-run average (one year) of index changes. We’ll see unexpected match performance has much more impact on the former hence makes it vary more intensively.

In order to fetch trend data we need to call the API operation with an additional projection. A projection represents a filter that gives control which data should be returned by the endpoint.
For this purpose we request the IT (=index trend) projection in addition to the I (=main index, default) projection and extend our history chart by the averages showing the relationship between short-run and long-run trends. The trends give a good impression to what extent the team’s performance meets the expectation at a certain point in time. They visualize the signal we’re interested in which is calculated as the difference between the trends. We plot the signal as a separate line and can recognize the cycles similar to a sinusoidal curve.


FUNCTION get_performance_history(teamId, minDate, maxDate)
  uri = HTTP.uri(BASE_URL, '/performance-index/team-history',
	                '?teamId=', teamId, '&minDate=', FORMAT(minDate), '&maxDate=', FORMAT(maxDate), '&format=REL', '&projections=I,IT')
  ...
END

FUNCTION plot_performance_history(entries)
  size = SIZE(entries)
  dataX = ARRAY[size] of DATE
  dataY = ARRAY[4][size] of FLOAT
  FOR i = 0 TO size
    dataX[i] = entries[i]['date']
    dataY[0][i] = entries[i]['index']
    dataY[1][i] = entries[i]['trend']['shortRun']['averageChange']
    dataY[2][i] = entries[i]['trend']['longRun']['averageChange']
    dataY[3][i] = dataY[1][i] - dataY[2][i]
  ENDFOR
  PRINTER.plot(dataX, dataY, 'YYYY', '%', '', 'Performance index')
END

Performance Index History (2)

_

The signal (green line) represents the over and under performance of the team. In our case this is expressed in percent of the overall teams index range and it shows the extent by which the latest ten index changes outperform the team’s long-run (annual) expectation.

We find that the smoother the signal the more likely a performance will shift in either direction. We can further await increased probability for performance trend reversals when the signal tends to reach minima or maxima. All natural time-varying processes have this characteristic in common.
The more we study signals this way the more we’ll come to the conclusion that the difficulty with trends in sports is the unclear threshold which triggers the unexpected to happen. A piece of advice here is not only rely on one-sided information but always confirm through as many factors as possible.

_

Contextualizing trends

Finally, we want to demonstrate how to use trend information in the context of team building and potential performance turnarounds.

In order to support rational decision-making in the appointment of team managers we joined historical team performance with manager chronology. To be fair, dates of appointments are not an API feature yet so this example involved some manual work. Anyway, evaluating the underlying signal gives a good indicator about the right time to consider changes in management or when the numbers already promise a forthcoming performance change.


Performance Index History (3)