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:

  1. Compute correlation matrix
  2. Convert to distance matrix (√(0.5 × (1 - corr)))
  3. Hierarchical clustering (single linkage)
  4. Quasi-diagonalize the covariance matrix
  5. 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

Next