风险平价模型
风险平价模型是一种投资组合优化模型,其基本思想是将资产配置权重分配为每种资产的风险贡献相等,以此最大限度地平衡整个投资组合的风险。
在风险平价模型中,每种资产的权重是根据它们的风险贡献来分配的,而不是按照它们的预期收益率。风险贡献是指每种资产对整个投资组合风险的贡献程度,它的计算通常基于资产的历史波动率或协方差矩阵。通常情况下,高波动性的资产将被分配更低的权重,低波动性的资产将被分配更高的权重,以达到风险平衡的效果。
风险平价模型的优点在于,它能够有效地平衡整个投资组合的风险,并降低整个投资组合的风险波动性。然而,它也有一些缺点,例如在市场波动性较高的时期,模型可能会将更多的资产配置到低波动性的资产上,从而可能会错过一些高收益机会。此外,风险平价模型的计算较为复杂,需要考虑资产之间的相关性和不同的风险贡献计算方法。
首先得了解组合资产风险贡献.具体来说,假设我们有个资产,投资组合的权重为,协方差矩阵为,投资组合的波动率为,则每个资产的风险贡献可以通过以下公式计算:
其中,代表第个资产的波动率。
将上述公式转换成矩阵形式,可以得到:
其中,是维向量,表示每个资产的风险贡献,是维向量,表示投资组合的权重,是的协方差矩阵,表示投资组合的波动率。
因此,公式就是上述公式的numpy实现,用于计算每个资产的风险贡献。
weights * np.dot(cov_matrix, weights) / portfolio_volatility
完整代码为
import numpy as np
from scipy.optimize import minimize
def risk_parity(weights, cov_matrix):
"""
计算给定资产权重下的风险平价组合的方差
"""
"""
计算投资组合的波动率,使用了投资组合的权重向量weights和协方差矩阵cov_matrix,
按照风险平价模型的思想,投资组合的波动率应该等于各资产的风险贡献之和,
因此接下来需要计算各资产的风险贡献。
"""
portfolio_volatility = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
"""
计算各资产的风险贡献,使用了权重向量、协方差矩阵和投资组合波动率。
每个资产的风险贡献等于该资产在投资组合中的权重乘以该资产的风险暴露,
其中风险暴露等于该资产在投资组合中的权重乘以协方差矩阵中该资产与其
他资产的协方差之和再除以投资组合波动率。这个计算公式可以使得每个资产的风险贡献都相等,
即实现了风险平价的目的。
"""
asset_contributions = weights * np.dot(cov_matrix, weights) / portfolio_volatility
"""
将各资产的风险贡献除以总的风险贡献之和,得到各资产的风险贡献占比,
即每个资产在投资组合中的风险权重。
这个步骤是为了后续计算资产收益的加权平均值提供依据。
"""
risk_contribution = asset_contributions / np.sum(asset_contributions)
return np.sum((risk_contribution - 1 / len(weights)) ** 2)
def calculate_portfolio_weights(cov_matrix, init_weights=None):
"""
给定协方差矩阵和初始权重,返回风险平价组合的资产权重
"""
num_assets = len(cov_matrix)
if not init_weights:
# 如果未提供初始权重,则使用等权重
init_weights = np.ones(num_assets) / num_assets
# 定义约束条件和优化器选项
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
options = {'ftol': 1e-20, 'maxiter': 1000}
# 使用约束最小化器求解权重
optimized_results = minimize(fun=risk_parity, x0=init_weights, args=cov_matrix,
method='SLSQP', constraints=constraints, options=options)
return optimized_results.x
def portfolio_return(weights, returns):
expected_return = np.dot(weights, returns)
return expected_return
def portfolio_volatility(weights, covariance_matrix):
volatility = np.sqrt(np.dot(weights.T, np.dot(covariance_matrix, weights)))
return volatility
if __name__ == '__main__':
# 定义协方差矩阵
# cov_matrix = np.array([[0.0400, 0.0238, 0.0264],
# [0.0238, 0.0625, 0.0380],
# [0.0264, 0.0380, 0.0900]])
returns = np.array([0.1, 0.2, 0.15, 0.18])
cov_matrix = np.array([[0.01, 0.005, 0.003, 0.004],
[0.005, 0.02, 0.007, 0.008],
[0.003, 0.007, 0.015, 0.005],
[0.004, 0.008, 0.005, 0.02]])
# 计算风险平价组合的资产权重
weights = calculate_portfolio_weights(cov_matrix)
# Compute portfolio expected return and volatility
expected_return = portfolio_return(weights, returns)
volatility = portfolio_volatility(weights, cov_matrix)
print(weights,expected_return,volatility)