股票组合投资的风险平价策略
导入每只股票的净值数据:
import pandas as pd import numpy as np from scipy.optimize import minimize StockPrices = pd.DataFrame() StockPrices = pd.read_excel('zuhe.xlsx',index_col=[0]) StockPrices.index.name = '日期' StockPrices.head()
提取每只股票的名称:
codes=StockPrices.columns.tolist()
codes
计算股票的每日收益率:
StockReturns = StockPrices.pct_change().dropna()
StockReturns
计算他们的协方差:
R_cov = StockReturns.cov()
cov= np.array(R_cov)
构建风险平价组合:
def risk_budget_objective(weights,cov): weights = np.array(weights) sigma = np.sqrt(np.dot(weights, np.dot(cov, weights))) MRC = np.dot(cov,weights)/sigma TRC = weights * MRC delta_TRC = [sum((i - TRC)**2) for i in TRC] return sum(delta_TRC) def total_weight_constraint(x): return np.sum(x)-1.0 x0 = np.ones(cov.shape[0]) / cov.shape[0] bnds = tuple((0,None) for x in x0) cons = ({'type': 'eq', 'fun': total_weight_constraint}) options={'disp':False, 'maxiter':1000, 'ftol':1e-20} solution = minimize(risk_budget_objective, x0,args=(cov), bounds=bnds, constraints=cons, method='SLSQP', options=options) final_weights = solution.x for i in range(len(final_weights)): print(f'{final_weights[i]:.1%}投资于{R_cov.columns[i]}')
代码注释:
weights = np.array(weights)
: 将传入的weights
参数转换为NumPy数组,以便后续计算。sigma = np.sqrt(np.dot(weights, np.dot(cov, weights)))
: 计算投资组合的标准差(风险),使用了传入的协方差矩阵cov
和权重数组weights
。首先通过np.dot(cov, weights)
计算协方差矩阵与权重的乘积,然后再与权重的乘积再次进行点乘,最后使用np.sqrt
计算标准差。MRC = np.dot(cov,weights)/sigma
: 计算风险贡献(Marginal Risk Contribution,MRC)的数组。通过将协方差矩阵与权重的乘积除以标准差,得到每个资产的风险贡献。TRC = weights * MRC
: 计算总风险贡献(Total Risk Contribution,TRC)的数组。将权重数组与风险贡献数组相乘,得到每个资产对总体风险的贡献。delta_TRC = [sum((i - TRC)**2) for i in TRC]
: 计算风险贡献差异的数组。对于每个资产的风险贡献,计算其与总体风险贡献之间的差异,并将差异的平方求和。return sum(delta_TRC)
: 返回风险贡献差异的总和作为目标函数值。
risk_budget_objective(weights, cov)
: 这是之前提到的风险预算优化的目标函数,用于衡量投资组合的风险分配是否符合预期的风险预算。total_weight_constraint(x)
: 这个函数用于设置投资组合权重的约束条件,要求所有权重之和等于1。x0 = np.ones(cov.shape[0]) / cov.shape[0]
: 初始化投资组合的权重,将其设置为均匀分配。bnds = tuple((0, None) for x in x0)
: 设置权重的边界条件,限制权重的取值范围为非负数。cons = {'type': 'eq', 'fun': total_weight_constraint}
: 定义了约束条件字典,表示约束条件是总权重之和等于1。options = {'disp': False, 'maxiter': 1000, 'ftol': 1e-20}
: 设置了优化算法的参数,如显示优化过程、最大迭代次数和收敛容差等。solution = minimize(risk_budget_objective, x0, args=(cov), bounds=bnds, constraints=cons, method='SLSQP', options=options)
: 使用minimize
函数进行优化,传入目标函数、初始权重、约束条件、边界条件、优化方法和参数等。final_weights = solution.x
: 从优化结果中获取最优的资产权重。for i in range(len(final_weights)):
: 遍历最优权重列表。print(f'{final_weights[i]:.1%}投资于{R_cov.columns[i]}')
: 输出每个资产的最终权重,以百分比形式显示,并显示对应的资产名称。