Cross-Impact Matrix
Multi-market price impact estimation and contagion channels
Cross-impact quantifies how trading in one market moves prices in correlated markets. When you buy heavily in market A, you affect not just A’s price but also markets B and C if they share common risk factors. Horizon estimates an N-by-N impact matrix separating self-impact (diagonal) from cross-impact (off-diagonal).
API
Estimate from historical data
python
import numpy as np
# returns: (T, N) matrix of N market returns over T periods
# volumes: (T, N) matrix of signed trade volumes (positive = buy)
returns = np.array([...])
volumes = np.array([...])
impact = hz.estimate_cross_impact(returns, volumes)
impact.matrix # (N, N) impact matrix G
impact.self_impact # diagonal entries [G_11, G_22, ...]
impact.cross_impact # off-diagonal entries as dict {(i,j): G_ij}
impact.eigenvalues # eigenvalues of G (check for stability)
impact.condition_num # condition number (high = fragile estimate)
Estimator with rolling updates
python
estimator = hz.CrossImpactEstimator(
n_markets=4,
window=500, # rolling estimation window
regularization=0.01, # shrinkage toward diagonal
)
# Incremental updates
estimator.update(returns_row, volumes_row)
# Current estimate
G = estimator.matrix()
# Predict impact of a trade vector on all markets
trade = [100, 0, -50, 0] # buy 100 of market 0, sell 50 of market 2
predicted_moves = estimator.predict_impact(trade)
Interpretation
The impact matrix G maps a trade vector q to expected price changes dp:
dp = G @ q
G[i][i](diagonal): self-impact. How much trading marketimoves its own price.G[i][j](off-diagonal): cross-impact. How much trading marketjmoves marketi’s price.
Large off-diagonal entries indicate contagion channels. If G[BTC][ETH] is large, heavy ETH selling will drag BTC down.
Example: prediction market contagion
python
# Three correlated election markets
returns = np.column_stack([pres_returns, senate_returns, house_returns])
volumes = np.column_stack([pres_volume, senate_volume, house_volume])
impact = hz.estimate_cross_impact(returns, volumes)
# Check: does trading the presidential market move senate odds?
print(f"Pres -> Senate impact: {impact.cross_impact[(1, 0)]:.4f}")
print(f"Pres self-impact: {impact.self_impact[0]:.4f}")
When to use
- Execution optimization: if you need to trade two correlated markets, sequence trades to minimize total impact (trade the less-impactful one first).
- Portfolio rebalancing: estimate total market impact of a multi-leg rebalance before executing.
- Contagion detection: monitor off-diagonal entries over time. Spikes indicate increased market coupling, often before a volatility event.
- Market making: adjust quotes in market B when you see large flow in correlated market A.
python
# Optimal execution: minimize total impact across two markets
trade_a, trade_b = 200, -150
total_impact = (
G[0][0] * trade_a + G[0][1] * trade_b, # impact on A
G[1][0] * trade_a + G[1][1] * trade_b, # impact on B
)