-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path2024马科维兹投资组合时间探索.py
More file actions
220 lines (147 loc) · 5.15 KB
/
Copy path2024马科维兹投资组合时间探索.py
File metadata and controls
220 lines (147 loc) · 5.15 KB
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
##################################################################
#
# 马科维兹投资组合实践探索
#
####################################################################
#
import tushare as ts
import pandas as pd
import numpy as np
import statsmodels.api as sm
import scipy.stats as scs
import matplotlib.pyplot as plt
data = pd.DataFrame
data1= ts.get_hist_data('600000.SH,'20240101','20250101')
data1= data1['close']
data1=data1[:,-1]
data['600000.SH']=data1
data2= ts.get_hist_data('600000.SH,'20240101','20250101')
data2= data2['close']
data2=data2[:,-1]
data['600001.SH']=data2
data3= ts.get_hist_data('600000.SH,'20240101','20250101')
data3= data3['close']
data3=data3[:,-1]
data['600002.SH']=data3
data=data.dropna()
data.head()
##可视化后的时序数据为
data.plot(figsize=(8,4))
## 2 计算不同证券的均值,协方差和相关系数
returns = np.log(data/data.shift(1))
returns.mean() * 252
returns.cov()
returns.corr()
## 3 给不同资产随机分配初始权重;
noa = 3
weights = np.random.random(noa)
weights /= np.sum(weights)
weights
array([0.288,0.103,0.608])
## 4 计算组合预期收益率,组合方差,和组合标准差
np.sum(returns.mean()*weights)
np.dot(weights.T,np.dot(returns.cov(),weights))
np.sqrt(np.dot(weights.T,np.dot(returns.cov(),weights)))
## 5 用蒙特卡洛模拟产生大量随机组合;
port_returns=[ ]
port_variance=[ ]
for p in range(5000):
weights=np.random.random(noa)
weights /= np.sum(weights)
port_returns.append(np.sum(returns.mean()*252*weights))
port_variance.append(np.sqrt(np.dot(weights.T,np.dot(returns.cov()*252,weights))))
port_returns = np.array(port_returns)
port_variance = np.array(port_variance)
#无风险利率设定为1.5%
risk_free=0.015
plt.figure(figsize=(8,4))
plt.scatter(port_variance,port_returns,c=(port_returns-risk_free)/port_variace,marker="o")
plt.grid(True)
plt.xlabel('volatility')
plt.ylabel('expected return')
plt.colorbar(label="Sharpe ratio")
plt.legend()
plt.show()
# 6 夏普比最大的最优资产组合;
def statistics(weights):
weights = np.array(weights)
port_returns = np.sum(returns.mean()*weights)*252
port_variance=np.sqrt(np.dot(weights.T,np.dot(returns.cov()*252,weights)))
return np.array([port_returns,port_variance,(port_return-risk_free)/port_variance])
# 最优组合的推倒是一个约束条件下最优问题,引入optimize 函数;
import scipy.optimize as sco
# 最小化夏普比的负值;
def min_sharpe(weights):
return-statistics(weights)[2]
# 约束所有参数总和为1
cons=({'type':'eq','fun';lambda x; np.sum(x) - 1})
# 参数的权重限制在0~1之间;
bnds = tuple((0,1) for x in range(noa))
# 优化函数调用中忽略的唯一输入是起始参数列表
opts = sco.minimize(min_sharpe,noa*[1./noa,],method='SLSQP',bounds=bnds,constraints=cons)
opts
opts['x'].round(3)
statistics(opts['x'].round(4))
# 7 方差最小的最优资产组合
def min_variance(weights):
return statistics(weights)[1]
optv= sco.minimize(min_variance,noa*[1./noa,],method='SLSQP',bounds=bnds,consttraints=cons)
optv
optv['x'].round(4)
statistics(optv['x']).round(4)
# 8 资产组合的有效边界
def min_variance(weights):
return statistics(weights)[1]
# 在不同目标收益水平 target_returns循环时,最优化的一个约束条件会变化;
target_returns = np.linspace(0.0,0.5,50)
target_variance = [ ]
for tar in target_returns:
cons = ({'type':'eq','fun':lambda x:statistics(x)[0] - tar},{'type':'eq','fun':lambda x:np.sum(x) - 1})
res = sco.minizime(min_variance,noa*[1./noa,],method='SLSQP',bounds=bnds,constraints=cons)
target_variance.append(res['fun'])
target_variance= np.array(target_variace)
## 下面是最优化结果的战士。深色星:夏普比最大的投资组合; 浅色星:方差最小的投资组合;
plt.figure(figsize=(8,4))
plt.scatter(port_variance,port_returns,c=port_returns/port_variance,marker='o')
plt.scatter(target_variance,target_returns,c=target_returns/target_variance,marker='x')
plt.plot(statistics(opts['x'])[1],statistics(opts['x'])[0],'r*',markersize=15.0)
plt.plot(statistics(opts['x'])[1],statistics(opts['x'])[0],'y*',markersize=15.0)
plt.grid(True)
plt.xlabel('volatility')
plt.ylabel('expected return')
plt.colorbar(label='Sharpe ratio')
plt.legend()
plt.show()
## 单项资产的期望收益和风险的估计量及Python应用;
from pandas import Series,DataFrame
import pandas as pd
import numpy as np
df = Series([])
np.mean(df)
np.var(df)
np.std(df)
# r均值与标准差差*2
## 单资产之间的协方差与相关系数及Python应用
df.var()
var(df)
df.cov()
df.corr()
## 多资产组合的期望与风险;
def portvar(x,y)
return x.T*v*x
## 资产组合均值方差模型;
import pandas as pd
from numpy as *
import matplot.pyplot as plt
r1 = 0.06
sigma1 = 0.12
r2 = 0.11
sigma2 = 0.22
rho = 0.19
covar = rho*sigma1*sigma2
x= pd.Series([0,.1,.2,.3,.4,.5,.6,.7,.8,1])
variance = x * 2 * sigma1 * *2 +(1-x)* * 2*sigma2* * 2 + 2 * x*(1-x)*covar
sigma = sqrt(variance)
ret = x*r1 + (1-r)*r2
print(x;sigma;ret)
plt.plot(sigma,ret,"k-o")