Interdependence of returns across multiple strategies

Posted on Mon 03 March 2025 in Portfolio construction


In portfolio diversification, it's common to rely on low pairwise correlations between trading strategies (often around 0.2) as a sign of effective risk management. However, this approach can underestimate systemic risk, especially when strategies are sensitive to the same market conditions. In this article, I explore why non-linear correlations and shared exposure to market regimes can lead to hidden interdependence among strategies, and how that impacts risk management in trading.

Hidden Systemic Risk from Shared Market Exposure

Even if day-to-day return correlations appear modest, strategies might still be exposed to the same market regime. When the regime shifts, strategies may suffer simultaneously, even if their daily movements do not appear to be in lockstep. In essence, they are interdependent in terms of their underlying risk factors.

Why Correlation Alone Falls Short in Risk Management

Correlation primarily measures linear relationships and can miss nuances such as tail dependencies (simultaneous large losses) or regime-specific behaviors. In markets characterized by heavy whipsaws and reversals, the distribution of returns can be non-Gaussian, which means that a simple Pearson correlation might understate the true risk of simultaneous losses.

How Market Regimes Trigger Non-Linear Correlation Spikes

Strategies with low average correlation might become correlated when the underlying market regime changes. In other words, they become correlated at the worst possible time (during adverse market conditions). This phenomenon underscores the importance of looking beyond correlations to understand the true interdependence among strategies.

Alternative Measures

To capture these dependencies more accurately, consider the following alternative measures:

Co-Movement Measures: Dynamic correlations, rolling correlations, and cointegration provide insight into how relationships change over time and under different market conditions.

In the code snippets, returns_df is a pandas DataFrame where each column represents a different strategy and each row corresponds to the return over a given time period, such as daily or weekly. This format allows us to easily compute various correlation metrics between strategies.

overall_corr = returns_df.corr().loc["StrategyA", "StrategyB"]
rolling_corr = returns_df["StrategyA"].rolling(window=10).corr(returns_df["StrategyB"]

Correlation Analysis

The overall correlation between StrategyA and StrategyB is 0.28. However, when we look at the 10-day rolling correlation, we see that their relationship can be considerably stronger or weaker in the short term.

Tail Dependence: Focuses on the joint behavior in the extremes, which is critical for understanding the risk of simultaneous large losses.

def tail_dependency(returns_df, quantile=0.1):
    """
    Compute the tail dependency between pairs of strategies.
    """

    thresholds = returns_df.quantile(quantile)

    # Find tail events (big losses)
    tail_events = returns_df.lt(thresholds, axis=1).astype(float)
    tail_counts = tail_events.sum(axis=0)

    # Compute pairwise simultaneous tail events
    both = tail_events.T.dot(tail_events)

    # P(strategy1 in tail | strategy1 or strategy2 in tail)
    row_counts = tail_counts.values.reshape(-1, 1)
    col_counts = tail_counts.values.reshape(1, -1)
    tail_dep_matrix = 0.5 * (both.values / row_counts + both.values / col_counts)

    # Set the diagonal values to 1.0
    np.fill_diagonal(tail_dep_matrix, 1.0)

    return pd.DataFrame(tail_dep_matrix, index=returns_df.columns, columns=returns_df.columns)

Factor Analysis: Decomposes strategy returns into common underlying factors, helping to identify whether strategies are truly diversified or merely different manifestations of the same risk exposure.

Conditional Loss Probability: This metric measures the likelihood that strategy A loses money on a given day, given that strategy B loses money on that same day. By focusing on downside risk, it provides a clearer picture of how often two strategies experience losses simultaneously.

Below is an example of how to calculate conditional loss probability:

def conditional_loss_probability(returns_df):
    """
    Compute the conditional loss probability between pairs of strategies.
    """

    loss = (returns_df < 0).astype(float)

    # Number of loss days for each strategy
    total_losses = loss.sum(axis=0)
    total_losses = total_losses.replace(0, np.nan)

    # Pairwise simultaneous losses
    both_losses = loss.T.dot(loss)

    # Convert total_losses to numpy arrays
    row_losses = total_losses.values.reshape(-1, 1)
    col_losses = total_losses.values.reshape(1, -1)

    cond_matrix = 0.5 * (both_losses.values / row_losses + both_losses.values / col_losses)

    # Set the diagonal values to 1.0
    np.fill_diagonal(cond_matrix, 1.0)

    return pd.DataFrame(cond_matrix, index=returns_df.columns, columns=returns_df.columns)

Conclusion

When building a diversified trading portfolio, it's not enough to rely on low correlations. Systemic risk often hides in plain sight, especially during market regime shifts. Understanding non-linear relationships and the limitations of traditional correlation analysis is key to improving risk management in trading.