Markowitzメソッドによる投資ポートフォリオの最適化





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()




























平均収量



ポートフォリオの収益を計算するための、各株の1日の平均収益。



dohMean = dCloseData.mean()
dohMean








共分散





ポートフォリオリスクを計算するには、共分散行列が必要です。



cov = dCloseData.cov()
cov








ランダムポートフォリオ



ランダムなポートフォリオを生成します。それらでは、シェアの合計は1(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メソッドを変更して、将来、より保証された収入を得る方法を探すことができます。これが別の研究のトピックです。



All Articles