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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import numpy as np
import pandas as pd
from scipy.optimize import minimize
# 风险预算优化
def calculate_portfolio_var(w, S):
# 计算组合风险的函数
w = np.mat(w)
return w * S * w.T
def calculate_risk_contribution(w, S):
# 计算单个资产对总体风险贡献度的函数
w = np.mat(w)
sigma = np.sqrt(calculate_portfolio_var(w, S))
# 边际风险贡献
MRC = S * w.T / sigma
# 风险贡献
RC = np.multiply(MRC, w.T)
return RC
def risk_budget_objective(w, pars):
# 计算组合风险
S = pars[0] # 协方差矩阵
risk_target = pars[1] # 组合中资产预期风险贡献度的目标向量
sig_p = np.sqrt(calculate_portfolio_var(w, S)) # portfolio sigma
risk_target = np.asmatrix(np.multiply(sig_p, risk_target))
asset_RC = calculate_risk_contribution(w, S)
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(w_origin, S, risk_target):
# w0 = [0.2, 0.2, 0.2, 0.6]
# x_t = [0.25, 0.25, 0.25, 0.25] # 目标是让四个资产风险贡献度相等,即都为25%
cons = ({'type': 'eq', 'fun': total_weight_constraint},)
# {'type': 'ineq', 'fun': long_only_constraint})
res = minimize(risk_budget_objective, w_origin, args=[S, risk_target], method='SLSQP',
bounds=[[0,1]] * len(w_origin),
constraints=cons, options={'disp': True})
w_rb = np.asmatrix(res.x)
return w_rb
# return res.x
# 将各资产风险贡献度绘制成柱状图
def plot_rc(w, S):
rc = calculate_risk_contribution(w, S)
print(rc)
if __name__ == '__main__':
P = pd.read_csv("tests/resources/stock_prices.csv", parse_dates=True, index_col="date")
w_origin, S, mu = optim_drawdown(P, 0.6, [0.001, 1])
S = np.asmatrix(S)
w_origin = np.asarray([i for i in w_origin.values()])
risk_target = np.asarray([1/len(w_origin)] * len(w_origin))
print(risk_target)
w_rb = calcu_w(w_origin, S, risk_target)
print('各资产权重:', w_rb)
print(w_rb @ mu)
plot_rc(w_rb)