Notice
Recent Posts
Recent Comments
Link
반응형
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

To Be Develop

Implementing Hierarchical Risk Parity for Diversified Portfolios 본문

study

Implementing Hierarchical Risk Parity for Diversified Portfolios

infobeste 2024. 11. 26. 22:47
반응형

Overview

Traditional Risk Parity (RP) methods allocate portfolio weights to equalize risk contributions from assets. While effective, these methods can overlook correlation structures between assets, leading to suboptimal diversification. Hierarchical Risk Parity (HRP), introduced by Lopez de Prado (2016), improves on traditional RP by using hierarchical clustering to group assets with similar risk characteristics and allocate weights accordingly.

This blog introduces the concept of HRP and demonstrates how to:

  1. Use hierarchical clustering to identify asset groups.
  2. Allocate portfolio weights based on risk contributions within and between clusters.
  3. Implement HRP using Python for real-world portfolio diversification.

1. What is Hierarchical Risk Parity?

HRP combines hierarchical clustering with risk parity principles to address the limitations of traditional approaches, such as the need for inverting a covariance matrix (which can be unstable for large or highly correlated datasets).

Key Steps in HRP:

  1. Hierarchical Clustering: Group assets based on their correlation structure.
  2. Recursive Bisection: Allocate weights hierarchically, starting with clusters and moving down to individual assets.
  3. Risk Allocation: Ensure that weights within each group are proportional to risk contributions.

2. Why Use Hierarchical Risk Parity?

2.1 Advantages Over Traditional Risk Parity

  • Robust to Noise: HRP avoids matrix inversion, making it more stable for noisy data.
  • Better Diversification: By considering correlation structures, HRP ensures that assets are grouped meaningfully for diversification.
  • Scalability: Suitable for portfolios with many assets.

2.2 Real-World Applications

  • Asset allocation for mutual funds and ETFs.
  • Diversified risk management for multi-asset portfolios.
  • Enhanced performance for quantitative trading strategies.

3. Hierarchical Risk Parity Methodology

3.1 Step 1: Calculate the Correlation Matrix

The first step is to compute the correlation matrix for the portfolio assets. This matrix is used for hierarchical clustering.

import pandas as pd
import numpy as np

# Sample returns data
np.random.seed(42)
data = pd.DataFrame(np.random.randn(100, 5), columns=['Asset1', 'Asset2', 'Asset3', 'Asset4', 'Asset5'])

# Calculate correlation matrix
corr_matrix = data.corr()

print(corr_matrix)

3.2 Step 2: Perform Hierarchical Clustering

Using the correlation matrix, we perform hierarchical clustering to group assets based on their similarity.

from scipy.cluster.hierarchy import linkage, dendrogram

# Convert correlation matrix to distance matrix
dist_matrix = np.sqrt(0.5 * (1 - corr_matrix))

# Perform hierarchical clustering
linkage_matrix = linkage(dist_matrix, method='ward')

# Plot dendrogram
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 5))
dendrogram(linkage_matrix, labels=corr_matrix.columns, leaf_rotation=90)
plt.title("Hierarchical Clustering Dendrogram")
plt.show()

3.3 Step 3: Recursive Bisection

Risk Allocation Algorithm

  1. Group Weights: Divide assets into clusters based on the hierarchical tree.
  2. Within-Group Risk Allocation: Assign weights to assets in each cluster to equalize their risk contributions.
  3. Between-Group Allocation: Allocate weights to clusters based on their aggregated risks.

3.4 Implementing HRP in Python

Function: Inverse Variance Portfolio

The inverse variance portfolio allocates weights inversely proportional to an asset's variance.

def inverse_variance_weights(cov_matrix):
iv_weights = 1 / np.diag(cov_matrix)
iv_weights /= iv_weights.sum()
return iv_weights

Function: Hierarchical Risk Parity

def hrp_weights(cov_matrix, linkage_matrix):
# Extract the number of assets
n = len(cov_matrix)

# Initialize weights
weights = pd.Series(1, index=cov_matrix.index)

# Recursive bisection
clusters = [(0, n)]  # Start with the entire portfolio
while clusters:
# Split the cluster
cluster = clusters.pop(0)
if cluster[1] - cluster[0] > 1:  # More than one asset in the cluster
sub_clusters = [linkage_matrix[i] for i in range(cluster[0], cluster[1])]
left_cluster = [x[0] for x in sub_clusters if x[2] == 'left']
right_cluster = [x[0] for x in sub_clusters if x[2] == 'right']

# Compute variances

Continuing from the Hierarchical Risk Parity (HRP) implementation, let's complete the recursive bisection process.


Recursive Bisection in HRP

The goal is to recursively divide clusters and compute weights based on their risk contributions.

Complete hrp_weights Function

```python
def hrp_weights(cov_matrix, linkage_matrix):
"""
Compute Hierarchical Risk Parity weights.
:param cov_matrix: Covariance matrix of asset returns.
:param linkage_matrix: Linkage matrix from hierarchical clustering.
:return: Portfolio weights.
"""

Initialize weights

weights = pd.Series(1, index=cov_matrix.index)

Recursive bisection

def get_cluster_variance(cov, cluster_indices):
sub_cov = cov.iloc[cluster_indices, cluster_indices]
iv_weights = inverse_variance_weights(sub_cov)
return np.dot(iv_weights, np.dot(sub_cov, iv_weights.T)) # Portfolio variance

Start with the entire portfolio

clusters = [(0, len(cov_matrix))]
while clusters:
start, end = clusters.pop(0)
if end - start > 1: # More than one asset in the cluster

Split into two sub-clusters

left = linkage_matrix[start, 0]
right = linkage_matrix[start, 1]

Assign indices to clusters

left_indices = list(map(int, linkage_matrix[:start + 1, 0])) if left < len(cov_matrix else +mapping logic


weights=

반응형