37 min read

Soccer is a team sport, and while individual brilliance can decide moments, sustained success emerges from collective performance. The greatest players in history have occasionally failed to lift mediocre squads, while well-drilled teams with fewer...

Learning Objectives

  • Build multidimensional team style profiles using event-level data
  • Construct expected points models and regression-adjusted league tables
  • Quantify squad balance, depth, and positional coverage
  • Measure team chemistry through passing network cohesion and lineup stability
  • Analyze performance under varying match conditions (home/away, score state, fatigue)
  • Implement fixture difficulty ratings using Elo-based strength estimates
  • Run Monte Carlo season simulations to produce probabilistic league table forecasts
  • Understand the relationship between spending and performance
  • Build a team performance dashboard integrating multiple analytical views

Chapter 16: Team Performance Analysis

Introduction

Soccer is a team sport, and while individual brilliance can decide moments, sustained success emerges from collective performance. The greatest players in history have occasionally failed to lift mediocre squads, while well-drilled teams with fewer star names have overachieved season after season. Understanding why requires tools that operate at the team level---tools that capture style, balance, cohesion, and adaptability.

This chapter builds on the player-level metrics developed in Chapters 12 and 13 and the match event frameworks from Chapters 7--11 to construct a comprehensive team analysis toolkit. We move from describing what teams do (style identification) to evaluating how well they do it (expected points), understanding why they succeed or struggle (chemistry, balance, conditions), and projecting where they will finish (season simulations).

By the end of this chapter, you will be able to produce a full analytical profile of any team in a league season---the kind of work that informs recruitment strategy, opposition scouting reports, and broadcast analytics packages at the highest level of the professional game.


16.1 Team Style Identification

Every team has a tactical identity---a characteristic way of building attacks, defending, transitioning, and using set pieces. While coaches articulate this identity in qualitative terms ("we want to dominate possession," "we press high and fast"), analytics allows us to quantify style and compare teams on a common scale.

16.1.1 Defining Style Dimensions

A team's style can be decomposed along several orthogonal (or near-orthogonal) dimensions. The most commonly used dimensions in professional analytics are:

  1. Possession Orientation: How much of the ball does the team seek to hold? Measured by possession percentage, passes per defensive action (PPDA inverted), and average sequence length.

  2. Pressing Intensity: How aggressively does the team press in the opposition half? Measured by PPDA (passes allowed per defensive action in the attacking 40%), high turnovers won, and counterpressure actions within 5 seconds of losing the ball.

  3. Directness: How quickly does the team move the ball toward goal? Measured by direct speed of attacks (meters per second toward goal), long ball percentage, and progressive pass/carry ratio.

  4. Width: How much of the pitch does the team use laterally? Measured by the standard deviation of x-coordinates in the final third, touchline-zone actions, and cross frequency.

  5. Defensive Line Height: Where does the team defend? Measured by average defensive action height, offside trap frequency, and the distance between the defensive and attacking lines (team compactness).

  6. Set-Piece Reliance: What proportion of the team's goal threat comes from dead-ball situations? Measured by set-piece xG share, corner routines per match, and free-kick shot conversion.

Mathematically, we represent a team's style as a vector in $\mathbb{R}^d$ where $d$ is the number of style dimensions:

$$\mathbf{s}_i = \begin{pmatrix} s_{i,1} \\ s_{i,2} \\ \vdots \\ s_{i,d} \end{pmatrix}$$

where $s_{i,j}$ is the standardized score (z-score) of team $i$ on dimension $j$.

Intuition: Think of a team's style fingerprint like a person's fingerprint. No two are identical, but you can group similar ones. Manchester City under Guardiola and Barcelona under Xavi would have similar fingerprints---high possession, high press, moderate directness---while Burnley under Dyche and Atletico Madrid under Simeone would cluster together at the opposite end of most dimensions.

16.1.2 Building Style Fingerprints from Event Data

To construct style fingerprints, we aggregate event-level data to the team-match level, then average across matches. The process follows these steps:

  1. Feature Engineering: For each match, compute raw metrics (e.g., total passes, passes in final third, PPDA, progressive carries, defensive action height).

  2. Normalization: Convert raw counts to per-90-minute rates where appropriate. Adjust for possession share---a team with 70% possession will naturally have more passes, so we normalize defensive metrics by opposition possession time.

  3. Standardization: Compute z-scores across all teams in the league:

$$z_{i,j} = \frac{x_{i,j} - \bar{x}_j}{\sigma_j}$$

  1. Dimensionality Reduction (optional): Apply PCA or factor analysis if the raw feature space is large (>15 features). The first 5--7 principal components typically capture 80%+ of variance.

  2. Visualization: Radar charts (spider plots) are the standard visualization for style fingerprints. Each axis represents one dimension, and the filled polygon shows the team's profile at a glance.

import numpy as np
import matplotlib.pyplot as plt

def plot_style_radar(team_name: str, dimensions: list[str],
                     values: np.ndarray, ax=None) -> None:
    """Plot a radar chart for a team's style fingerprint.

    Args:
        team_name: Name of the team.
        dimensions: List of dimension labels.
        values: Array of z-scores for each dimension.
        ax: Optional matplotlib axes.
    """
    angles = np.linspace(0, 2 * np.pi, len(dimensions), endpoint=False).tolist()
    values_plot = np.concatenate([values, [values[0]]])
    angles += angles[:1]

    if ax is None:
        fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True))
    ax.fill(angles, values_plot, alpha=0.25)
    ax.plot(angles, values_plot, linewidth=2)
    ax.set_xticks(angles[:-1])
    ax.set_xticklabels(dimensions, size=10)
    ax.set_title(f"{team_name} Style Fingerprint", size=14, fontweight="bold")

Common Pitfall: Raw possession percentage is a poor proxy for "possession style" in isolation. A team that presses high and wins the ball back quickly may have relatively low possession percentage (because they concede it to press) but still play a possession-based buildup when they have the ball. Always combine possession with pass sequence length, buildup speed, and defensive metrics.

16.1.3 Clustering Teams by Style

Once we have style vectors for every team, we can apply clustering algorithms from Chapter 15 to identify groups of tactically similar teams. The most common approaches are:

  • K-Means Clustering: Partition teams into $k$ groups by minimizing within-cluster variance. Works well for 3--5 clusters in a league of 20 teams.

  • Hierarchical Clustering: Produces a dendrogram showing the similarity tree. Useful for understanding gradations of similarity rather than hard boundaries.

  • Gaussian Mixture Models (GMM): Allow soft assignment---a team can belong partially to multiple style clusters, which better reflects the reality that many teams blend elements of different styles.

The silhouette score and gap statistic help choose the optimal number of clusters. In practice, major European leagues typically yield 3--5 natural style clusters: (1) possession-dominant, (2) pressing/transition, (3) direct/physical, (4) defensive/compact, and occasionally (5) set-piece specialists.

Real-World Application: Recruitment departments use style clustering to identify target teams for scouting. If you want a player who will adapt to your high-press system, prioritize scouts watching teams in the same style cluster---players from tactically similar environments tend to adapt faster.

16.1.4 Tracking Style Evolution Over Time

Team style is not static. Managerial changes, key injuries, transfer windows, and tactical adjustments all cause style to evolve within and across seasons. We can track this by computing style vectors over rolling windows (e.g., 6-match rolling averages) and plotting trajectories in style space.

A useful metric for style stability is the style drift measure:

$$D_t = \|\mathbf{s}_t - \mathbf{s}_{t-1}\| = \sqrt{\sum_{j=1}^{d} (s_{t,j} - s_{t-1,j})^2}$$

where $\mathbf{s}_t$ is the style vector at time window $t$. Large values of $D_t$ indicate significant tactical shifts.

Callout --- Detecting Managerial Impact Through Style Drift: One of the most compelling applications of style tracking is measuring the impact of a new manager. When Thomas Tuchel replaced Frank Lampard at Chelsea in January 2021, the style drift scores spiked dramatically in the first six matches as Tuchel implemented a back-three system with different pressing triggers. Within 10 matches, the drift stabilized as the players internalized the new system. This pattern---a sharp spike followed by stabilization---is characteristic of successful managerial transitions. When the spike is followed by continued high drift, it often indicates a manager struggling to impose their ideas.

16.1.5 Style Matchups and Tactical Advantages

Not all style matchups are neutral. Certain styles have structural advantages against others---a phenomenon familiar from rock-paper-scissors. A high-pressing team may struggle against a team that bypasses the press with accurate long balls. A possession-dominant team may be vulnerable to a fast counter-attacking side that concedes territory deliberately.

We can quantify these matchup effects by computing the average xG differential when teams of each style cluster play against each other:

$$ \text{Matchup Effect}_{k,l} = \overline{\text{xG}}_{k \text{ vs } l} - \overline{\text{xG}}_{k \text{ overall}} $$

where $k$ and $l$ are style clusters. A positive value indicates that cluster $k$ teams overperform their average when facing cluster $l$ teams. This matchup analysis informs both tactical preparation (how to set up against a specific opponent) and squad building (ensuring the squad can execute multiple stylistic approaches).


16.2 Expected Points and League Tables

16.2.1 The Problem with Actual Points

The actual league table is a noisy indicator of team quality. Over a 38-match Premier League season, the standard deviation due to randomness alone is approximately 6--8 points. Teams can over- or under-perform their underlying quality by a full European qualification place.

The sources of noise include:

  • Shot quality variance: A team creating 2.0 xG might score 0 or 4 in a given match.
  • Goalkeeper and finishing variance: Some teams systematically over- or under-convert xG due to finishing quality, but much of the deviation is random.
  • Individual errors and red cards: Low-probability events with outsized impact.
  • Penalty decisions: xG models assign ~0.76 xG to penalties, but whether a penalty is awarded is itself stochastic.

16.2.2 Building an Expected Points (xPts) Model

The expected points model converts match-level xG into a points expectation using simulation or analytical methods.

Method 1: Poisson Simulation

For a match where the home team has $xG_H$ and the away team has $xG_A$, we model the number of goals as independent Poisson random variables:

$$G_H \sim \text{Poisson}(\lambda = xG_H), \quad G_A \sim \text{Poisson}(\lambda = xG_A)$$

We simulate $N = 10{,}000$ match outcomes and compute the fraction of simulations that result in home win, draw, or away loss:

$$\text{xPts}_H = 3 \cdot P(G_H > G_A) + 1 \cdot P(G_H = G_A)$$

Method 2: Analytical Poisson (Skellam Distribution)

The difference $D = G_H - G_A$ follows a Skellam distribution:

$$P(D = k) = e^{-(\lambda_H + \lambda_A)} \left(\frac{\lambda_H}{\lambda_A}\right)^{k/2} I_{|k|}(2\sqrt{\lambda_H \lambda_A})$$

where $I_{|k|}$ is the modified Bessel function of the first kind. This allows exact computation without simulation.

from scipy.stats import skellam

def expected_points(xg_for: float, xg_against: float) -> float:
    """Compute expected points from match xG totals.

    Args:
        xg_for: Expected goals scored by the team.
        xg_against: Expected goals conceded by the team.

    Returns:
        Expected points (0 to 3 scale).
    """
    p_win = 1 - skellam.cdf(0, xg_for, xg_against)
    p_draw = skellam.pmf(0, xg_for, xg_against)
    return 3 * p_win + 1 * p_draw

Intuition: A team with 1.5 xG vs. an opponent with 1.0 xG might feel like a comfortable expected win, but the expected points are only about 1.85---not even two thirds of a maximum 3 points. This reflects the fundamental uncertainty of low-scoring sports. Football is far more random than basketball or baseball on a per-game basis.

16.2.3 Expected Points Tables

An xPts league table replaces actual points with cumulative expected points across the season. The difference between actual points and xPts reveals which teams have been "lucky" (positive residual) or "unlucky" (negative residual):

$$\text{Luck Index}_i = \text{Pts}_i - \text{xPts}_i$$

Teams with large positive Luck Index values are candidates for regression---they are likely to perform worse in future matches. Conversely, teams with large negative values are likely to improve.

Common Pitfall: Do not assume that all deviation from xPts is "luck." Some teams systematically over-perform xG due to elite finishing (e.g., a squad with multiple top-tier strikers) or elite goalkeeping. The key is to separate repeatable skill from random variance. A useful heuristic: finishing over-performance that persists across 2+ seasons is likely partly skill; single-season spikes are mostly noise.

16.2.3a How Expected Points Models Differ from Actual Points

The divergence between expected points and actual points is not merely a curiosity---it reveals fundamental truths about team quality and sustainability. To understand why xPts models are more informative than the raw league table, it helps to examine the specific mechanisms that drive the gap.

Shot-by-shot vs. match-level xG. The simplest xPts models use match-level xG totals (team A created 1.8 xG, team B created 0.9 xG), but more sophisticated approaches aggregate at the shot level. A match where one team takes ten 0.1 xG shots (total 1.0 xG) differs fundamentally from a match where they take two 0.5 xG shots (also total 1.0 xG). The Poisson model treats both identically, but the underlying chance quality is different. Shot-level models that simulate each shot independently capture this distinction and produce more accurate xPts estimates.

Non-shot xG contributions. Modern expected points models are beginning to incorporate expected goals from non-shot situations---penalties won (separate from the penalty shot itself), dangerous situations that did not result in a shot, and pre-shot expected threat. These refinements address a known limitation: some teams consistently create situations that are dangerous but do not always produce shots, perhaps because the final pass is slightly overhit or the attacker chooses to dribble instead. Traditional xG-based xPts models undervalue these teams.

Regression toward the mean in practice. One of the most practically useful properties of xPts is its predictive power. Teams whose actual points significantly exceed their xPts tend to regress in subsequent stretches of matches. Empirical studies across multiple seasons of the Premier League show that mid-season xPts is a better predictor of second-half-of-season points than actual mid-season points. The correlation between first-half xPts and second-half actual points is typically $r \approx 0.70$, compared to $r \approx 0.55$ for first-half actual points.

Intuition: Think of expected points like a credit score for football performance. Your actual bank balance (real points) might look healthy because you had some lucky windfalls (opposition errors, deflected goals), but your credit score (xPts) reflects your underlying financial habits. A team spending beyond their xPts means is living on borrowed time---eventually the bank balance will correct to reflect the underlying reality.

Callout --- The xPts Table as a Diagnostic Tool: The gap between actual points and xPts is most valuable not as a prediction of future performance but as a diagnostic tool. When a team significantly underperforms their xPts, it prompts investigation: Are they missing key chances? Is the goalkeeper underperforming? Are they conceding goals from individual errors? When a team overperforms, it prompts caution: Is this level sustainable, or should we expect regression? Analytics departments present xPts tables alongside actual tables in board reports to provide a more nuanced view of where the team truly stands.

16.2.4 The Dixon-Coles Model

The basic Poisson model assumes independence between home and away goals, which is unrealistic---low-scoring draws (0-0, 1-1) are more common than independence predicts. The Dixon-Coles (1997) model adds a correction factor $\tau$ for scores where both teams score 0 or 1:

$$P(G_H = x, G_A = y) = \tau_{\lambda_H, \lambda_A}(x, y) \cdot \frac{e^{-\lambda_H} \lambda_H^x}{x!} \cdot \frac{e^{-\lambda_A} \lambda_A^y}{y!}$$

where the correction factor is:

$$\tau_{\lambda_H, \lambda_A}(x, y) = \begin{cases} 1 - \lambda_H \lambda_A \rho & \text{if } x = 0, y = 0 \\ 1 + \lambda_H \rho & \text{if } x = 0, y = 1 \\ 1 + \lambda_A \rho & \text{if } x = 1, y = 0 \\ 1 - \rho & \text{if } x = 1, y = 1 \\ 1 & \text{otherwise} \end{cases}$$

The parameter $\rho$ (typically small and negative, around $-0.03$ to $-0.10$) captures the positive correlation in low-scoring outcomes. The model also decomposes team strength into attack ($\alpha_i$) and defense ($\beta_i$) ratings with a home advantage parameter $\gamma$:

$$\lambda_H = \alpha_H \cdot \beta_A \cdot \gamma, \quad \lambda_A = \alpha_A \cdot \beta_H$$

Advanced: The Dixon-Coles model parameters are estimated by maximum likelihood, typically with a time-decay weighting function $\phi(t) = e^{-\xi t}$ where $t$ is the number of days since the match and $\xi$ controls the half-life of information. A half-life of about 1 year ($\xi \approx 0.0019$) works well for most leagues.


16.3 Squad Balance and Depth Analysis

16.3.1 Why Balance Matters

A team's first XI might be elite, but injuries, suspensions, rotation, and fixture congestion mean that squad depth determines season-long performance. The 2015-16 Leicester City title win was partly enabled by extraordinary injury luck---their core XI started together in 23 of 38 matches, compared to a league average of around 12--15 for title contenders.

16.3.2 Measuring Squad Depth

We define the Squad Depth Index (SDI) for each position group $p$ (goalkeeper, center-back, full-back, central midfield, wide midfield, striker) as:

$$\text{SDI}_p = \frac{\sum_{i \in P_p} q_i \cdot \min(m_i, M_p)}{M_p \cdot q_{\max, p}}$$

where: - $P_p$ is the set of players in position group $p$ - $q_i$ is the quality rating of player $i$ (from Chapter 14 player ratings) - $m_i$ is the expected availability (minutes) of player $i$ - $M_p$ is the total minutes available for position group $p$ - $q_{\max, p}$ is the quality of the best player in position group $p$

An SDI of 1.0 means the team has depth that perfectly replicates first-choice quality. Values below 0.7 indicate significant drop-off when the first-choice player is unavailable.

16.3.3 Positional Coverage Matrix

A more granular view is the positional coverage matrix, which shows how many players in the squad can competently play each position. We define competency as having played at least 450 minutes (5 full matches) in a position over the past two seasons with above-median performance ratings.

import pandas as pd
import numpy as np

def compute_coverage_matrix(
    squad: pd.DataFrame,
    positions: list[str],
    min_minutes: int = 450,
    min_rating: float = 8.5
) -> pd.DataFrame:
    """Compute positional coverage matrix for a squad.

    Args:
        squad: DataFrame with columns ['player', 'position', 'minutes', 'rating'].
        positions: List of positions to evaluate.
        min_minutes: Minimum minutes to qualify as competent.
        min_rating: Minimum rating to qualify as competent.

    Returns:
        DataFrame showing number of competent players per position.
    """
    coverage = {}
    for pos in positions:
        pos_data = squad[squad["position"] == pos]
        competent = pos_data[
            (pos_data["minutes"] >= min_minutes) &
            (pos_data["rating"] >= min_rating)
        ]
        coverage[pos] = len(competent)
    return pd.DataFrame.from_dict(coverage, orient="index", columns=["competent_players"])

16.3.4 Balance Metrics

Beyond depth, balance measures whether resources are appropriately distributed across the squad. We compute:

  • Wage Gini Coefficient: The Gini coefficient of the wage distribution. Higher values indicate concentration of spending on a few star players. Values above 0.55 are associated with dressing-room tension and underperformance relative to total wage bill.

  • Age Balance Score: The standard deviation of ages in the regular XI. Teams with very low age SD may lack experience or may face a cliff when the cohort ages out simultaneously. Teams with very high age SD may lack tactical coherence.

$$\text{Age Balance} = 1 - \frac{|\sigma_{\text{age}} - \sigma^*|}{\sigma^*}$$

where $\sigma^* \approx 3.5$ years is the empirically optimal age spread.

  • Left-Right Footedness Ratio: Particularly important for center-back pairings, central midfield triangles, and wing play. A team with no natural left-footed center-back has a structural weakness in left-sided buildups.

  • Physical Profile Distribution: The balance of physical archetypes across the squad---speed players, aerial threats, press-resistant technical players, and high-endurance runners. Teams that are one-dimensional physically (e.g., lacking any aerial presence) can be exploited by opponents who adjust their approach accordingly. Computing the centroid and spread of player physical profiles in a multidimensional physical attribute space reveals whether the squad can adapt to different physical demands:

$$\text{Physical Balance} = 1 - \frac{\|\bar{\mathbf{p}} - \mathbf{p}^*\|}{\|\mathbf{p}^*\|}$$

where $\bar{\mathbf{p}}$ is the squad's average physical profile vector and $\mathbf{p}^*$ is the ideal balanced profile estimated from historically successful squads.

  • Contract Expiry Profile: While not a performance metric per se, the distribution of contract expiry dates across the squad affects negotiating leverage, long-term planning, and the risk of losing multiple key players simultaneously. A squad where five or more starters have contracts expiring in the same summer faces significant roster instability.

Common Pitfall: Squad balance analysis can be misleading if it treats all positions as equally important. Research consistently shows that the marginal value of upgrading certain positions (e.g., center-forward, center-back, goalkeeper) has a greater impact on team performance than upgrading others (e.g., backup full-back). Weight your balance metrics by positional importance, which can be estimated from the regression coefficients when modeling team performance as a function of positional quality.

Real-World Application: Liverpool's recruitment team under Michael Edwards was renowned for squad balance analysis. Their 2019-20 title-winning squad had exceptional depth at full-back (Trent Alexander-Arnold, Andrew Robertson, James Milner, Joe Gomez) and center-back (van Dijk, Matip, Lovren, Gomez), which enabled consistency through fixture congestion. The one position where depth was thin---attacking midfield---was masked by Firmino's extraordinary durability.

16.3.5 Squad Rotation Optimization

Managing a squad across multiple competitions requires strategic rotation. The goal is to balance three competing objectives: (1) winning the current match, (2) preserving player fitness for future matches, and (3) developing younger players.

A rotation optimization model can be formulated as:

$$ \max_{\mathbf{x}} \sum_{t=1}^{T} \left[ w_{\text{match}} \cdot q(\mathbf{x}_t) - w_{\text{fatigue}} \cdot f(\mathbf{x}_t, \mathbf{x}_{t-1}, \ldots) + w_{\text{dev}} \cdot d(\mathbf{x}_t) \right] $$

where: - $\mathbf{x}_t$ is the starting lineup for match $t$ - $q(\mathbf{x}_t)$ is the expected team quality given the lineup - $f(\cdot)$ is the cumulative fatigue cost - $d(\mathbf{x}_t)$ is the development value from giving young players minutes

Subject to constraints such as minimum rest between starts, squad registration rules, and injury availability.

Callout --- The Rotation Paradox: Research consistently shows that heavy rotation (changing 4+ players between matches) reduces team performance in the short term due to disrupted chemistry and unfamiliarity between combinations. Yet insufficient rotation leads to fatigue-related injuries and late-season collapses. The optimal balance, suggested by multiple studies of Premier League and Champions League schedules, is rotating 2-3 players per match during congested periods, with a focus on rotating the most physically demanding positions (full-backs, box-to-box midfielders) while maintaining the spine of the team (goalkeeper, centre-backs, central midfielder, striker).


16.4 Team Chemistry Metrics

16.4.1 What Is Team Chemistry?

Team chemistry is the degree to which a group of players functions as a cohesive unit rather than a collection of individuals. It encompasses tactical understanding (knowing where teammates will be), passing rapport (the quality and speed of combination play between specific player pairs), and defensive coordination (pressing triggers, cover-shadow alignment).

While chemistry is often dismissed as an intangible, several quantifiable proxies exist.

16.4.2 Lineup Stability Index

The simplest chemistry proxy is lineup stability. Teams that field consistent lineups develop better understanding. We measure this with the Lineup Stability Index (LSI):

$$\text{LSI} = \frac{1}{N-1} \sum_{t=2}^{N} \frac{|S_t \cap S_{t-1}|}{11}$$

where $S_t$ is the set of starting eleven players in match $t$ and $N$ is the number of matches. An LSI of 1.0 means the same XI started every match; the typical Premier League LSI is around 0.65--0.75.

16.4.3 Pairwise Passing Chemistry

From Chapter 10 (Passing Networks), we have tools to measure the quality of passing connections between player pairs. We extend this to a chemistry score for each pair $(i, j)$:

$$C_{ij} = w_1 \cdot \text{pass\_accuracy}_{ij} + w_2 \cdot \text{pass\_frequency}_{ij} + w_3 \cdot \text{progressive\_share}_{ij} + w_4 \cdot \text{xT\_added}_{ij}$$

where $\text{xT\_added}_{ij}$ is the expected threat generated by passes from player $i$ to player $j$. The weights $w_k$ can be estimated by regressing pairwise chemistry scores against team performance outcomes.

The overall Team Chemistry Score (TCS) aggregates pairwise chemistry:

$$\text{TCS} = \frac{2}{n(n-1)} \sum_{i < j} C_{ij}$$

where $n$ is the number of regular starters.

16.4.4 Combination Play Metrics

Beyond individual passing connections, the quality of combination play---quick passing sequences involving three or more players---is a strong indicator of team chemistry. Key metrics include:

  • Third-man combinations per 90: Sequences where Player A passes to Player B, who plays a first-time pass to Player C. These require anticipation and mutual understanding.
  • One-two (wall pass) frequency: The classic give-and-go requires precise timing between two players. Teams with high one-two frequency in the final third tend to create higher-quality chances.
  • Average passing speed in the final third: The speed (in seconds) between receiving and releasing the ball in the attacking third. Lower values indicate better anticipation and quicker decision-making, which are hallmarks of a well-drilled unit.
def compute_combination_play_metrics(
    pass_events: pd.DataFrame,
    min_sequence_length: int = 3,
    max_time_between_passes: float = 3.0,
) -> dict:
    """Compute combination play metrics from pass event data.

    Args:
        pass_events: DataFrame with columns ['match_id', 'team', 'player',
            'timestamp', 'x_start', 'y_start', 'x_end', 'y_end', 'success'].
        min_sequence_length: Minimum passes in a combination.
        max_time_between_passes: Maximum seconds between consecutive passes.

    Returns:
        Dictionary of combination play metrics.
    """
    combinations = []
    for match_id, group in pass_events.groupby("match_id"):
        team_passes = group.sort_values("timestamp")
        current_seq = [team_passes.iloc[0]]

        for i in range(1, len(team_passes)):
            row = team_passes.iloc[i]
            prev = current_seq[-1]
            time_diff = row["timestamp"] - prev["timestamp"]

            if time_diff <= max_time_between_passes and row["success"]:
                current_seq.append(row)
            else:
                if len(current_seq) >= min_sequence_length:
                    combinations.append(current_seq)
                current_seq = [row]

    return {
        "total_combinations": len(combinations),
        "avg_sequence_length": np.mean([len(c) for c in combinations]) if combinations else 0,
        "max_sequence_length": max([len(c) for c in combinations]) if combinations else 0,
    }

16.4.5 Pressing Coordination

A well-coordinated press is one of the strongest indicators of team chemistry. We measure pressing coordination through:

  • Press Trigger Alignment: The percentage of pressing sequences where the designated trigger player initiates and at least two teammates join within 2 seconds. Teams with high values (>60%) show coached, synchronized pressing.

  • Cover Shadow Efficiency: The percentage of opposition passing lanes blocked during pressing sequences. Computed using Voronoi tessellations and passing angle analysis.

  • Recovery Time After Losing Possession: The time from loss of possession to the first defensive action. Well-drilled teams average under 3 seconds; disorganized teams exceed 5 seconds.

Intuition: Watch a team like Klopp's Liverpool at their peak pressing---when one player presses, the entire front line moves as a unit, cutting passing lanes simultaneously. This coordination is measurable. The time between the first player pressing and the last player closing space is a direct measure of how "in sync" the team is. New signings often take 8--12 matches to fully integrate into a pressing system, which is visible in these metrics.

16.4.6 Integration Time for New Signings

When a new player joins, their individual quality is known, but their chemistry with teammates is zero. We can track the integration curve---the trajectory of a new player's pairwise chemistry scores over their first $N$ matches:

$$C_{ij}(t) = C_{ij}^{\infty} \left(1 - e^{-\kappa t}\right)$$

where $C_{ij}^{\infty}$ is the asymptotic chemistry level and $\kappa$ is the integration rate. Players with prior experience in similar tactical systems (identified through style clustering in Section 16.1) tend to have higher $\kappa$ values.

Callout --- Quantifying the "New Manager Bounce": When a new manager is appointed, teams often experience a short-term performance boost followed by a settling period. This pattern can be tracked through chemistry metrics: the LSI drops sharply (the new manager experiments with lineups), pressing coordination initially improves (the intensity effect of a new voice), but pairwise passing chemistry may decline as new patterns are established. The "bounce" typically lasts 6-10 matches, after which performance reflects the true quality of the manager-player fit.


16.5 Performance Under Different Conditions

16.5.1 Home and Away Splits

Home advantage in soccer has been extensively studied (see Chapter 4). At the team level, we decompose home advantage into components:

$$\text{HA}_i = \underbrace{(\text{xG}_{H,i} - \text{xG}_{A,i})}_{\text{attacking boost}} + \underbrace{(\text{xGA}_{A,i} - \text{xGA}_{H,i})}_{\text{defensive boost}}$$

Some teams derive their home advantage primarily from attacking improvement (e.g., crowd-energized pressing leading to more turnovers in dangerous areas), while others benefit defensively (e.g., opposition teams are more cautious away from home).

The magnitude of home advantage also varies by team characteristics. Research has shown that teams with smaller stadiums and louder crowds per square meter tend to have larger home advantages. Teams that depend heavily on pressing benefit more from home support because the crowd energizes the physical effort required to press for 90 minutes.

Callout --- The COVID-19 Natural Experiment: The pandemic-era empty-stadium matches of 2020-21 provided a natural experiment for studying home advantage. Across Europe's top five leagues, home win rates dropped from approximately 46% to 36% during matches played without fans. Interestingly, the decline was not uniform: teams that derived most of their home advantage from attacking intensity (high pressing, aggressive forward play) saw larger declines than teams whose home advantage was primarily defensive. This supports the theory that crowd support primarily affects the effort-intensive attacking aspects of play.

16.5.2 Score-State Analysis

Team behavior changes dramatically with the scoreline. We define three score states:

  • Winning: The team is ahead by 1+ goals
  • Drawing: The score is level
  • Losing: The team is behind by 1+ goals

For each score state, we compute style metrics (possession, PPDA, directness, xG per minute). The differences reveal tactical flexibility:

$$\Delta_{\text{flex}} = \|\mathbf{s}_{\text{winning}} - \mathbf{s}_{\text{losing}}\|$$

Teams with high $\Delta_{\text{flex}}$ are tactically adaptable---they change approach based on the game state. Teams with low $\Delta_{\text{flex}}$ are rigid, playing the same way regardless of the score.

Common Pitfall: Score-state analysis requires careful handling of time. A team that is losing for only 5 minutes in a match contributes very little data in the "losing" state for that match. Always weight by minutes spent in each state, and aggregate across many matches before drawing conclusions. A minimum of 500 minutes in each state is recommended for stable estimates.

16.5.3 Fatigue and Fixture Congestion

Teams playing multiple competitions face fixture congestion, particularly during the October-December and February-April periods. We measure congestion as:

$$\text{Congestion}_t = \frac{1}{\text{days since last match}_t}$$

and analyze performance metrics as a function of congestion. Key findings from the literature:

  • Teams with fewer than 4 days of recovery show a 5--8% decline in high-intensity running distance.
  • xG creation drops by approximately 0.1--0.15 per match when congestion is high.
  • Squad depth (Section 16.3) moderates the congestion effect: deep squads can rotate and maintain performance.

16.5.4 Weather and Pitch Conditions

While less studied in the analytics literature, weather conditions measurably affect style:

  • Rain: Pass completion rates drop by 2--4 percentage points; long balls become relatively more effective.
  • Wind: Strong winds (>20 mph) reduce crossing accuracy and increase aerial duel frequency.
  • Temperature: Extreme heat (>30C) reduces total distance covered by 3--5%, favoring compact, low-pressing teams.
  • Pitch size: Larger pitches favor possession-based teams; smaller pitches favor direct, physical play.

Advanced: To properly isolate the effect of conditions, use a regression framework that controls for team quality, opponent quality, home/away, and other confounders:

$$\text{xG}_i = \beta_0 + \beta_1 \text{Quality}_i + \beta_2 \text{Opp\_Quality}_i + \beta_3 \text{Home}_i + \beta_4 \text{Congestion}_i + \beta_5 \text{Rain}_i + \epsilon_i$$

The coefficients $\beta_4$ and $\beta_5$ then represent the causal effect of conditions, controlling for confounders.


16.6 Fixture Difficulty Adjustments

16.6.1 Why Raw Metrics Are Misleading

A team that creates 2.0 xG per match sounds impressive---but not if they played the bottom 5 teams in the league. Conversely, a team creating 1.2 xG per match against the top 6 is performing well. Fixture difficulty adjustment is essential for fair comparison, especially mid-season when teams have played different schedules.

16.6.2 Elo Ratings for Opponent Strength

The Elo rating system provides a continuously updated measure of team strength. The basic update rule after a match is:

$$R_i' = R_i + K \cdot (S_i - E_i)$$

where: - $R_i$ is the pre-match Elo rating of team $i$ - $K$ is the update factor (typically 20--40 for soccer) - $S_i$ is the actual result (1 for win, 0.5 for draw, 0 for loss) - $E_i$ is the expected result: $E_i = \frac{1}{1 + 10^{(R_j - R_i)/400}}$

For soccer, modifications include: - Home advantage offset: Add ~65 Elo points to the home team's rating for expectation calculations. - Goal difference scaling: Scale $K$ by a goal-difference multiplier: $K_{\text{adj}} = K \cdot \ln(|\Delta G| + 1)$ where $\Delta G$ is the goal difference. - Mean reversion between seasons: Regress ratings toward the league mean by 25--33% at the start of each season.

16.6.3 Fixture Difficulty Rating (FDR)

The FDR for a team's upcoming $n$ matches is:

$$\text{FDR}_i = \frac{1}{n} \sum_{t=1}^{n} \left( R_{\text{opp}(i,t)} + H_{i,t} \right)$$

where $R_{\text{opp}(i,t)}$ is the Elo rating of the opponent in match $t$ and $H_{i,t}$ is the home advantage adjustment (positive if away, zero if home).

This can be normalized to a 1--5 scale for communication to non-technical stakeholders:

$$\text{FDR}_{\text{scaled}} = 1 + 4 \cdot \frac{\text{FDR} - \text{FDR}_{\min}}{\text{FDR}_{\max} - \text{FDR}_{\min}}$$

16.6.4 Strength of Schedule Adjustments

To adjust team metrics for schedule strength, we use a regression approach. For any metric $Y_i$ (e.g., xG per match), we fit:

$$Y_{i,t} = \mu + \alpha_i + \beta \cdot R_{\text{opp}(i,t)} + \gamma \cdot \text{Home}_{i,t} + \epsilon_{i,t}$$

The team effect $\alpha_i$ represents the schedule-adjusted metric, which can be compared fairly across teams regardless of opponents faced so far.

Real-World Application: Fantasy Premier League (FPL) uses a simplified version of FDR to help players plan transfers. Professional clubs use more sophisticated versions---incorporating recent form, injury status of key opposition players, and tactical matchup analysis---to plan rotation and squad selection across congested periods.

Callout --- Mid-Season Schedule Asymmetry: In the early weeks of a season, schedule asymmetry can create wildly misleading impressions. A team that has faced three of the top six teams in its first five matches may sit mid-table with 7 points, while a team that has faced the bottom three may sit top with 13 points. Without fixture difficulty adjustment, the first team appears mediocre and the second appears dominant. Schedule-adjusted metrics correct this distortion and provide a more honest mid-season assessment. This is particularly important for managerial evaluation: firing a manager after a difficult early-season schedule is a well-documented failure mode of impatient club ownership.


16.7 Season Projections and Simulations

16.7.1 Monte Carlo Season Simulation

The most powerful tool for season projection is Monte Carlo simulation. The process:

  1. Estimate team strengths: Use the Dixon-Coles model (Section 16.2.4) to estimate attack ($\alpha_i$) and defense ($\beta_i$) parameters for each team.

  2. For each remaining match: Generate a scoreline by sampling from the bivariate Poisson model (with Dixon-Coles correction).

  3. Compute the league table: Assign points based on simulated results.

  4. Repeat $N$ times: Typically $N = 10{,}000$ to $100{,}000$ iterations.

  5. Aggregate results: For each team, compute the distribution of final points, finishing positions, and probabilities of key outcomes (title, top 4, relegation).

import numpy as np
from scipy.stats import poisson

def simulate_season(
    attack: np.ndarray,
    defense: np.ndarray,
    home_adv: float,
    fixtures: list[tuple[int, int]],
    n_sims: int = 10_000,
    rho: float = -0.04
) -> np.ndarray:
    """Simulate remaining season using Dixon-Coles model.

    Args:
        attack: Array of team attack strengths.
        defense: Array of team defense strengths.
        home_adv: Home advantage multiplier.
        fixtures: List of (home_team_idx, away_team_idx) tuples.
        n_sims: Number of simulations.
        rho: Dixon-Coles correlation parameter.

    Returns:
        Array of shape (n_sims, n_teams) with simulated points.
    """
    n_teams = len(attack)
    points = np.zeros((n_sims, n_teams))

    for sim in range(n_sims):
        for home, away in fixtures:
            lambda_h = attack[home] * defense[away] * home_adv
            lambda_a = attack[away] * defense[home]
            goals_h = poisson.rvs(lambda_h)
            goals_a = poisson.rvs(lambda_a)
            if goals_h > goals_a:
                points[sim, home] += 3
            elif goals_h == goals_a:
                points[sim, home] += 1
                points[sim, away] += 1
            else:
                points[sim, away] += 3
    return points

16.7.2 Incorporating Form and Momentum

Static team strength parameters assume constant quality throughout the season, which is unrealistic. To incorporate form:

  • Exponential decay weighting: Weight recent matches more heavily when estimating parameters. A half-life of 30--40 matches balances responsiveness and stability.

  • Dynamic Elo: Update Elo ratings after each match and use the current rating for future match projections.

  • State-space models: Use a Kalman filter or particle filter to model team strength as a latent variable that evolves over time:

$$\alpha_{i,t} = \alpha_{i,t-1} + \eta_{i,t}, \quad \eta_{i,t} \sim \mathcal{N}(0, \sigma_\eta^2)$$

This allows strength to drift smoothly, capturing managerial changes, injury crises, and confidence spirals.

16.7.3 Interpreting Simulation Outputs

The key outputs from season simulation are:

  • Win probability: The fraction of simulations where a team finishes first.
  • Top-4 probability: Critical for Champions League qualification.
  • Relegation probability: The fraction of simulations where a team finishes in the bottom 3.
  • Points distribution: The full distribution of final points, often displayed as a box plot or violin plot.
  • Position distribution: A heatmap showing the probability of each team finishing in each position.

$$P(\text{Team } i \text{ finishes position } k) = \frac{1}{N} \sum_{s=1}^{N} \mathbb{1}[\text{position}_{i,s} = k]$$

Intuition: Early in the season, simulation outputs are wide and uncertain---most teams have a non-trivial chance of finishing anywhere in the table. As the season progresses and more matches are played, the distributions narrow. A useful way to communicate this is "the title race is effectively over when the leader's win probability exceeds 95%," which typically happens with 5--8 matches remaining in most seasons.

16.7.4 Validation and Calibration

A good simulation model should be calibrated: events predicted to happen with probability $p$ should actually happen with frequency $p$. We validate calibration by:

  1. Collecting historical predictions: Run the model retrospectively on past seasons.
  2. Binning predictions: Group predictions into probability bins (0--10%, 10--20%, etc.).
  3. Comparing actual frequencies: Plot predicted probability vs. observed frequency. A well-calibrated model lies on the diagonal.

The Brier score provides a single-number summary of calibration:

$$\text{Brier} = \frac{1}{N} \sum_{i=1}^{N} (p_i - o_i)^2$$

where $p_i$ is the predicted probability and $o_i$ is the outcome (0 or 1). Lower is better; a Brier score below 0.20 for match outcomes is considered good for soccer.

Common Pitfall: Simulation models that do not account for correlation between matches will underestimate the probability of extreme outcomes (historically great seasons, dramatic collapses). Sources of correlation include: shared weather/pitch conditions in a given week, referee assignments, and momentum/confidence effects. More advanced models use copulas or correlated random effects to capture these dependencies.

16.7.5 Decision Support from Simulations

Season simulations are not just academic exercises. They support concrete decisions:

  • Transfer deadline day: "We have a 35% chance of top 4. Adding a striker with $+0.15$ xG per match raises it to 52%. Is that worth $30M?"
  • Rotation policy: "Resting 3 starters for the midweek cup match reduces our league win probability from 62% to 58%, but increases our cup win probability from 20% to 28%."
  • Managerial evaluation: "Under the current manager, our projected points total is 58. Under the candidate replacement (using their historical team performance data), the projection rises to 65."

Real-World Application: Major betting markets and prediction sites like FiveThirtyEight (now ABC News), Opta's predictions platform, and academic models like the Euro Club Index all use variants of the simulation framework described here. The key differentiator between models is the sophistication of the team strength estimation (static vs. dynamic, match-level vs. shot-level xG) and the treatment of correlations.


16.8 The Relationship Between Spending and Performance

16.8.1 Wage Bills as Predictors

One of the most robust findings in soccer analytics is that wage expenditure is a far better predictor of league position than transfer spending. Research by Stefan Szymanski and others has consistently shown that wage bills explain approximately 60-80% of the variance in league position across seasons, while net transfer spend explains only 20-30%.

The relationship is well-modeled by a log-linear regression:

$$ \text{League Position}_i = \beta_0 + \beta_1 \cdot \log(\text{Wage Bill}_i) + \epsilon_i $$

The logarithmic specification captures the diminishing returns of spending: going from the 15th-highest wage bill to the 10th-highest makes a bigger difference than going from the 5th-highest to the 1st-highest.

16.8.2 Overperformance and Underperformance Relative to Spending

The residuals from the wage-performance regression are deeply informative. Teams with large negative residuals (performing better than their spending would predict) are the "overachievers"---clubs like Leicester City (2015-16), Atalanta, and Brighton under Roberto De Zerbi. Teams with large positive residuals are "underachievers"---clubs spending heavily but failing to convert that spending into results.

$$ \text{Efficiency}_i = \text{Predicted Position}_i - \text{Actual Position}_i $$

A positive efficiency score means the team finished higher than their spending predicted (overachieving); a negative score means they finished lower (underachieving).

Callout --- The Transfer Market Efficiency Myth: Many fans and pundits assume that transfer spending is the primary driver of success. The data tells a different story. Net transfer spend is weakly correlated with single-season league performance because: (1) expensive signings need integration time, (2) selling key players can be worse than the replacement quality suggests because of chemistry disruption, and (3) the transfer market is highly inefficient---clubs regularly overpay for players who do not fit their system. Wage bills, by contrast, represent the accumulated quality of the entire squad and correlate strongly with points because they reflect the ongoing investment in retaining and attracting talent.

16.8.3 Parachute Payments and Financial Fairness

The financial landscape of soccer creates structural advantages and disadvantages. In the English system, relegated Premier League clubs receive "parachute payments" that give them significant financial advantages in the Championship. Financial Fair Play (FFP) rules in UEFA competitions and domestic leagues create constraints that limit the ability of ambitious clubs to spend beyond their revenue.

Analytics departments increasingly model the financial constraints alongside the sporting constraints. A simulation that projects a team's points also needs to account for the financial feasibility of maintaining or improving the squad within FFP guidelines. This integration of financial and sporting analytics is one of the frontiers of modern club management.


16.9 Benchmarking Against Historical Teams

16.9.1 Historical Performance Databases

To contextualize a current team's performance, analysts compare against historical benchmarks. Questions such as "Is this the best defensive season in Premier League history?" or "How does this team's pressing intensity compare to Guardiola's Barcelona?" require historical data.

Key historical benchmarks include:

Achievement Team Season Metric
Most points Manchester City 2017-18 100 points
Best goal difference Manchester City 2017-18 +79
Fewest goals conceded Chelsea 2004-05 15
Highest xG differential Liverpool 2019-20 +1.52 xG per match
Most points from losing positions Newcastle 2001-02 28 points recovered

16.9.2 Era-Adjusted Comparisons

Comparing across eras requires normalization because the statistical environment changes over time. Defensive metrics have shifted as tactics have evolved; pressing data was not collected before the 2010s; xG models were not applied before the late 2000s.

The most defensible approach is to measure a team's dominance relative to their league in that season:

$$ \text{Dominance}_{i,s} = \frac{x_{i,s} - \bar{x}_s}{\sigma_s} $$

where $x_{i,s}$ is the team's metric in season $s$, and $\bar{x}_s$ and $\sigma_s$ are the league mean and standard deviation in that season. This z-score-based approach allows comparison across eras on a common scale.

Advanced: For the richest historical comparisons, analysts reconstruct xG models retroactively using shot location data from older seasons. While the models are necessarily simpler (lacking information like shot body part and build-up type for older data), they provide reasonable estimates of underlying quality that can be compared to modern teams. Projects like FBref's historical xG estimates enable analysis stretching back to the mid-2000s for top European leagues.

16.9.3 Building a Historical Benchmarking Framework

A robust benchmarking framework goes beyond individual record comparisons to provide a systematic way of placing any team-season in historical context. The process involves three steps.

First, select a set of core metrics that are available across the historical periods you wish to compare. For the Premier League era (1992--present), reliable metrics include points, goal difference, goals scored, goals conceded, win percentage, and clean sheet percentage. For the advanced analytics era (roughly 2010--present), xG, xGA, PPDA, and possession percentage become available.

Second, compute era-adjusted percentile ranks for each metric. Rather than comparing raw values, rank each team-season against all other team-seasons in the database. A team that finishes in the 95th percentile for goals conceded has historically elite defensive numbers, regardless of whether the raw total is 15 or 25---the league environment determines what constitutes elite.

Third, construct a composite historical score by averaging percentile ranks across metrics, optionally weighting by importance:

$$\text{Historical Score}_i = \sum_{j=1}^{M} w_j \cdot \text{Percentile}_{i,j}$$

This single number allows ranking of team-seasons on a common scale. For instance, Manchester City 2017-18, Arsenal 2003-04, and Chelsea 2004-05 consistently rank in the top five by composite historical score, but they dominate for different reasons: City for attacking output, Arsenal for consistency (unbeaten), and Chelsea for defensive solidity.

Real-World Application: Several data journalism outlets and analytics platforms maintain historical benchmarking databases that are updated in real time during a season. When a team is on pace for a historically notable achievement (fewest goals conceded, most consecutive wins, highest possession average), these databases provide immediate context. This powers both broadcast storytelling and internal club analytics---a manager can see, for example, that their team's pressing intensity places them in the 98th percentile historically, validating a tactical approach even if results have not yet caught up.


16.10 Building a Team Performance Dashboard

16.10.1 Dashboard Design Principles

A team performance dashboard synthesizes the analyses from this chapter into a single, interactive interface. Effective dashboards follow several design principles:

  1. Hierarchy of information: Place the most important metrics (league position, xPts, goal difference) prominently at the top. Detailed breakdowns (score-state analysis, pairwise chemistry) are available through drill-down navigation.

  2. Context over raw numbers: Every metric should be accompanied by a benchmark (league average, historical comparison, or expected value). A raw xG of 1.5 per match is meaningless without knowing whether the league average is 1.2 or 1.8.

  3. Temporal dimension: Include time-series views showing how key metrics have evolved across the season. A team's current xG per match matters less than the trend---are they improving or declining?

  4. Uncertainty quantification: Where possible, display confidence intervals, probability distributions, or ranges rather than point estimates. A projected final points total of "68-76 (90% interval)" is more honest and useful than a single number of "72."

16.10.2 Core Dashboard Components

A comprehensive team performance dashboard includes:

  • Overview panel: League position, xPts position, points per match, xG and xGA per match, form rating (last 5 matches)
  • Style fingerprint: Radar chart of the team's style dimensions with league average overlay
  • xPts tracking: Time series of cumulative actual points vs. xPts, with the gap highlighted
  • Squad health: Availability tracker, fatigue indicators, upcoming rotation recommendations
  • Upcoming fixtures: FDR-rated fixture list with per-match win probability estimates
  • Season projection: Monte Carlo simulation outputs including probability of finishing in each position
  • Chemistry monitor: Lineup stability index, top passing partnerships, pressing coordination score
def build_dashboard_data(
    team_id: str,
    season: str,
    match_data: pd.DataFrame,
    player_data: pd.DataFrame,
    simulation_results: np.ndarray,
) -> dict:
    """Assemble all data needed for a team performance dashboard.

    Args:
        team_id: Identifier for the team.
        season: Season identifier (e.g., "2024-25").
        match_data: DataFrame with match-level metrics.
        player_data: DataFrame with player-level metrics.
        simulation_results: Array from Monte Carlo season simulation.

    Returns:
        Dictionary of dashboard components.
    """
    team_matches = match_data[match_data["team_id"] == team_id]

    dashboard = {
        "overview": {
            "matches_played": len(team_matches),
            "points": team_matches["points"].sum(),
            "xpts": team_matches["xpts"].sum(),
            "xg_per_match": team_matches["xg"].mean(),
            "xga_per_match": team_matches["xga"].mean(),
        },
        "form": {
            "last_5_ppg": team_matches.tail(5)["points"].mean(),
            "last_5_xg": team_matches.tail(5)["xg"].mean(),
        },
        "simulation": {
            "median_final_points": np.median(simulation_results),
            "p_title": np.mean(simulation_results == simulation_results.max(axis=1, keepdims=True)),
            "p_top4": np.mean(np.argsort(-simulation_results, axis=1)[:, :4]),
        },
    }
    return dashboard

Callout --- The One-Page Report: While dashboards are powerful tools for ongoing monitoring, many stakeholders (particularly owners, directors, and non-technical board members) prefer condensed summaries. The "one-page report" distills the dashboard into a single printable page with 5-7 key numbers, one visualization (typically the style radar or the xPts tracking chart), and 2-3 bullet-point narratives. Learning to compress complex analysis into accessible summaries is as important as the analysis itself.


Summary

This chapter has provided a complete framework for team performance analysis:

  1. Style Identification (16.1): Quantify what teams do tactically through multidimensional style fingerprints, cluster similar teams, track style evolution over time, and analyze tactical matchup advantages.

  2. Expected Points (16.2): Move beyond noisy actual results to xPts-based evaluation using Poisson and Dixon-Coles models, revealing luck and regression candidates.

  3. Squad Balance and Depth (16.3): Measure whether a squad can sustain performance through injury, suspension, and fixture congestion using depth indices, coverage matrices, and rotation optimization.

  4. Team Chemistry (16.4): Quantify the intangible through lineup stability, pairwise passing chemistry, combination play metrics, pressing coordination, and integration curves for new signings.

  5. Situational Performance (16.5): Decompose performance by home/away, score state, fixture congestion, and weather conditions to understand when and why teams excel or struggle.

  6. Fixture Difficulty (16.6): Adjust all metrics for opponent strength using Elo-based ratings, enabling fair mid-season comparisons.

  7. Season Simulations (16.7): Bring everything together in Monte Carlo simulations that produce probabilistic league table forecasts and support strategic decision-making.

  8. Spending and Performance (16.8): Understand the relationship between financial resources and results, identify overachieving and underachieving clubs, and integrate financial constraints with sporting projections.

  9. Historical Benchmarking (16.9): Place current performance in historical context using era-adjusted comparisons.

  10. Dashboard Construction (16.10): Synthesize all analyses into an actionable, accessible team performance dashboard.

Together, these tools provide the analytical backbone for a modern football club's performance analysis department. The next chapter extends this framework to the spatial dimension, examining how teams and players use space on the pitch through Voronoi diagrams, pitch control models, and spatial value surfaces.