HRP & Denoising
Hierarchical Risk Parity and Marcenko-Pastur covariance denoising
Mean-variance optimization inverts the covariance matrix, which is numerically unstable when assets are correlated. Small estimation errors produce wildly different weights. HRP avoids this entirely by using a tree-based allocation that never inverts a matrix.
From AFML Chapter 16.
HRP weights
python
import horizon as hz
# returns_matrix: list of lists, each inner list is one asset's return series
weights = hz.hrp_weights(returns_matrix)
# Returns a list of portfolio weights that sum to 1.0
The algorithm:
- Compute correlation matrix
- Convert to distance matrix (
√(0.5 × (1 - corr))) - Hierarchical clustering (single linkage)
- Quasi-diagonalize the covariance matrix
- Recursive bisection with inverse-variance weighting
Covariance denoising
Before using any covariance-based method, denoise the matrix using random matrix theory:
python
denoised_cov = hz.denoise_covariance(
cov_matrix,
n_observations=252,
bandwidth=0.01,
)
Uses the Marcenko-Pastur law to identify which eigenvalues are signal vs noise, then shrinks the noise eigenvalues.
When to use
- HRP: portfolio allocation when you have many correlated assets and don’t trust mean-variance stability
- Denoising: any time you estimate a covariance matrix from limited data (which is always)
- The combination (denoise then HRP) is more robust than either alone