风险平价投资组合是一种资产配置,其重点是**配置风险**,而不是配置资产。例如,典型的债券40%、股票60%投资组合中,股票风险很大。风险平价(等同风险)是这样一种投资组合:**单个资产(在这种情况下为债券和股票)对整体投资组合总风险具有相同的风险贡献**。该理论在过去几十年中得到普及和发展,基于风险的资产配置理念已被用于许多策略,如管理期货策略和着名的桥水全天候基金。有研究表明,这种资产配置策略比基于资产的配置策略提供更好的风险调整回报。
我将讨论风险平价的一个非常基本的例子,以及如何构建简单的风险平价(相等风险)投资组合,并将其扩展到风险预算组合(目标风险分配)的具体实现。
首先将资产j的**边际风险贡献($MRC_j$)**定义为:
$$MRC_j = \frac{\partial \sigma_p}{\partial w_j} = \frac{(V*w)_j}{\sigma_p}$$
其中:
$w_j$表示第j个资产的权重
$V$表示资产的协方差矩阵
$\sigma_p = \sqrt{w*V*w^T}$ 表示组合风险
然后,资产j对总投资组合的**风险贡献($RC_j$)**为:
$$RC_j = w*MRC_j = \frac{{w_j(V*w)}_j}{\sigma_p}$$
风险平价投资组合是所有资产中每个资产的$RC$相等的投资组合。
计算风险平价组合的权重,本质上属于一个**二次优化**问题。
让投资组合资产$RC$的平方误差的总和为(优化问题的目标函数):
$$J(x)=(\sum_{i=1}^n\sum_{j=1}^n(w_i(V*w))_i-w_j(V*w)_j)^2$$
优化问题的约束条件为:
$$minJ(x)$$
$$s.t.\sum_iw_i = 1 $$
$$1 \geq wi \geq 0$$
# 协方差矩阵和收益率向量
from scipy.optimize import minimize
V = np.matrix('123 37.5 70 30; 37.5 122 72 13.5; 70 72 321 -32; 30 13.5 -32 52')/100 # covariance
R = np.matrix('14; 12; 15; 7')/100 # return
# 风险预算优化
def calculate_portfolio_var(w,V):
# 计算组合风险的函数
w = np.matrix(w)
return (w*V*w.T)[0,0]
def calculate_risk_contribution(w,V):
# 计算单个资产对总体风险贡献度的函数
w = np.matrix(w)
sigma = np.sqrt(calculate_portfolio_var(w,V))
# 边际风险贡献
MRC = V*w.T
# 风险贡献
RC = np.multiply(MRC,w.T)/sigma
return RC
def risk_budget_objective(x,pars):
# 计算组合风险
V = pars[0]# 协方差矩阵
x_t = pars[1] # 组合中资产预期风险贡献度的目标向量
sig_p = np.sqrt(calculate_portfolio_var(x,V)) # portfolio sigma
risk_target = np.asmatrix(np.multiply(sig_p,x_t))
asset_RC = calculate_risk_contribution(x,V)
J = sum(np.square(asset_RC-risk_target.T))[0,0] # sum of squared error
return J
def total_weight_constraint(x):
return np.sum(x)-1.0
def long_only_constraint(x):
return x
# 根据资产预期目标风险贡献度来计算各资产的权重
def calcu_w(x):
w0 = [0.2, 0.2, 0.2, 0.6]
# x_t = [0.25, 0.25, 0.25, 0.25] # 目标是让四个资产风险贡献度相等,即都为25%
x_t = x
cons = ({'type': 'eq', 'fun': total_weight_constraint},
{'type': 'ineq', 'fun': long_only_constraint})
res= minimize(risk_budget_objective, w0, args=[V,x_t], method='SLSQP',constraints=cons, options={'disp': True})
w_rb = np.asmatrix(res.x)
return w_rb
# 将各资产风险贡献度绘制成柱状图
def plot_rc(w):
rc = calculate_risk_contribution(w, V)
rc = rc.tolist()
rc = [i[0] for i in rc]
rc = pd.DataFrame(rc,columns=['rick contribution'],index=[1,2,3,4])
T.plot(rc, chart_type='column', title = 'Contribution to risk')
# 假设四个资产的风险贡献度相等
w_rb = calcu_w([0.25, 0.25, 0.25, 0.25])
print('各资产权重:', w_rb)
plot_rc(w_rb)
# 假设风险贡献度依次为0.3,0.3,0.1,0.3
w = calcu_w([0.3, 0.3 ,0.1,0.3])
print('各资产权重:', w)
plot_rc(w)