使用Markowitz方法优化投资组合的Python标准实现示例。此方法有许多实现。包括Python。再次实现(请参阅GitHub上的链接)。
资料来源
让我们从这些来源中获取一些理论:
Python中的蒙特卡罗模拟获得最佳投资组合
Markowitz组合理论(Wikipedia)
下载报价数据
我们使用Yahoo.Finance服务中的数据
! pip install yfinance
import yfinance as yf
在过去的3个月中,我们在美国市场上占有一些份额。
data = yf.download(['AAPL','GE','BAC','AMD','PLUG','F'],period='3mo')
收盘价
我们将在计算中使用每日收盘价
closeData = data.Close
closeData
课程表
import matplotlib.pyplot as plt
for name in closeData.columns:
closeData[name].plot()
plt.grid()
plt.title(name)
plt.show()
换班
接下来,您需要对前一天进行相对更改。
dCloseData = closeData.pct_change()
dCloseData
相对汇率变化图
for name in dCloseData.columns:
dCloseData[name].plot()
plt.title(name)
plt.grid()
plt.show()
平均产量
每股平均每日收益以计算投资组合收益。
dohMean = dCloseData.mean()
dohMean
协方差
为了计算投资组合风险,需要协方差矩阵。
cov = dCloseData.cov()
cov
随机组合
我们将生成随机投资组合。在它们中,份额之和等于1(一)。
import numpy as np
cnt = len(dCloseData.columns)
def randPortf():
res = np.exp(np.random.randn(cnt))
res = res / res.sum()
return res
r = randPortf()
print(r)
print(r.sum())
[0.07519908 0.07594622 0.20932539 0.40973202 0.1234458 0.10635148]
1.0
投资组合收益
投资组合收益计算为投资组合中每只股票的收益份额之和。
def dohPortf(r):
return np.matmul(dohMean.values,r)
r = randPortf()
print(r)
d = dohPortf(r)
print(d)
[0.0789135 0.13031559 0.25977124 0.21157419 0.13506695 0.18435853]
0.006588795350151513
投资组合风险
我们通过投资组合份额和协方差矩阵的乘积来计算投资组合风险。
def riskPortf(r):
return np.sqrt(np.matmul(np.matmul(r,cov.values),r))
r = randPortf()
print(r)
rs = riskPortf(r)
print(rs)
[0.10999361 0.13739338 0.20412889 0.13648828 0.24021123 0.17178461]
0.02483674110724784
投资组合云
让我们生成一组投资组合,并将结果显示在风险收益图表上。让我们找到最小风险和最大夏普比率的最佳投资组合的参数。让我们与平均投资组合的数据进行比较。
risk = np.zeros(N)
doh = np.zeros(N)
portf = np.zeros((N,cnt))
for n in range(N):
r = randPortf()
portf[n,:] = r
risk[n] = riskPortf(r)
doh[n] = dohPortf(r)
plt.figure(figsize=(10,8))
plt.scatter(risk*100,doh*100,c='y',marker='.')
plt.xlabel(', %')
plt.ylabel(', %')
plt.title(" ")
min_risk = np.argmin(risk)
plt.scatter([(risk[min_risk])*100],[(doh[min_risk])*100],c='r',marker='*',label=' ')
maxSharpKoef = np.argmax(doh/risk)
plt.scatter([risk[maxSharpKoef]*100],[doh[maxSharpKoef]*100],c='g',marker='o',label=' - ')
r_mean = np.ones(cnt)/cnt
risk_mean = riskPortf(r_mean)
doh_mean = dohPortf(r_mean)
plt.scatter([risk_mean*100],[doh_mean*100],c='b',marker='x',label=' ')
plt.legend()
plt.show()
让我们显示找到的投资组合的数据。
import pandas as pd
print('---------- ----------')
print()
print(" = %1.2f%%" % (float(risk[min_risk])*100.))
print(" = %1.2f%%" % (float(doh[min_risk])*100.))
print()
print(pd.DataFrame([portf[min_risk]*100],columns=dCloseData.columns,index=[', %']).T)
print()
print('---------- ----------')
print()
print(" = %1.2f%%" % (float(risk[maxSharpKoef])*100.))
print(" = %1.2f%%" % (float(doh[maxSharpKoef])*100.))
print()
print(pd.DataFrame([portf[maxSharpKoef]*100],columns=dCloseData.columns,index=[', %']).T)
print()
print('---------- ----------')
print()
print(" = %1.2f%%" % (float(risk_mean)*100.))
print(" = %1.2f%%" % (float(doh_mean)*100.))
print()
print(pd.DataFrame([r_mean*100],columns=dCloseData.columns,index=[', %']).T)
print()
---------- ----------
= 1.80%
= 0.59%
, %
AAPL 53.890706
AMD 12.793389
BAC 4.117541
F 16.547201
GE 10.945462
PLUG 1.705701
---------- ----------
= 2.17%
= 0.88%
, %
AAPL 59.257114
AMD 8.317192
BAC 2.049882
F 8.689935
GE 4.772159
PLUG 16.913719
---------- ----------
= 2.33%
= 0.68%
, %
AAPL 16.666667
AMD 16.666667
BAC 16.666667
F 16.666667
GE 16.666667
PLUG 16.666667
结论
我们重复了计算投资组合份额的经典方法。我们得到了非常具体的结果。
使用Markowitz方法进行投资组合优化的前提是将来保留参数(各个工具之间的相关性及其获利水平)。但这不能保证。这将在以下工作中得到验证。
显然,不应期望以上检查会带来积极的结果。但是,然后您可以寻找如何修改Markowitz方法以在将来获得更多保证收入的方法。这是另一个研究的主题。