Optimierung des Anlageportfolios nach der Markowitz-Methode





Ein Beispiel für eine Standardimplementierung in Python zur Optimierung eines Anlageportfolios nach der Markowitz-Methode. Es gibt viele Implementierungen dieser Methode. Einschließlich Python. Erneut implementiert (siehe Link auf GitHub ).



Quellen



Nehmen wir ein bisschen Theorie aus diesen Quellen:

Bestes Anlageportfolio durch Monte-Carlo-Simulation in Python

Markowitz Portfolio Theory (Wikipedia)



Herunterladen von Daten zu Angeboten



Wir verwenden Daten aus dem Yahoo.Finance- Dienst



! pip install yfinance
import yfinance as yf




Wir haben in den letzten 3 Monaten mehrere Aktien des amerikanischen Marktes übernommen.



data = yf.download(['AAPL','GE','BAC','AMD','PLUG','F'],period='3mo')




Schlusskurse



Wir werden die täglichen Schlusskurse für unsere Berechnungen verwenden



closeData = data.Close
closeData








Kursdiagramme



import matplotlib.pyplot as plt

for name in closeData.columns:
    closeData[name].plot()
    plt.grid()
    plt.title(name)
    plt.show()




























Kurse wechseln



Als nächstes benötigen Sie relative Änderungen zum vorherigen Tag.



dCloseData = closeData.pct_change()
dCloseData








Diagramme der relativen Ratenänderungen





for name in dCloseData.columns:
    dCloseData[name].plot()
    plt.title(name)
    plt.grid()
    plt.show()




























Durchschnittsertrag



Durchschnittliche tägliche Rendite für jede Aktie zur Berechnung der Portfoliorendite.



dohMean = dCloseData.mean()
dohMean








Kovarianz





Zur Berechnung des Portfoliorisikos ist eine Kovarianzmatrix erforderlich.



cov = dCloseData.cov()
cov








Zufälliges Portfolio



Wir werden zufällige Portfolios erstellen. In ihnen ist die Summe der Aktien gleich 1 (eins).



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




Portfoliorendite



Die Portfoliorendite wird als Summe der Aktien der Renditen für jede Aktie im Portfolio berechnet.



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




Portfoliorisiko



Wir berechnen das Portfoliorisiko anhand von Matrixprodukten aus Portfolioaktien und Kovarianzmatrizen.



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




Portfolio Cloud



Lassen Sie uns eine Reihe von Portfolios erstellen und das Ergebnis in einem Risiko-Rendite-Diagramm anzeigen. Lassen Sie uns die Parameter des optimalen Portfolios für das minimale Risiko und die maximale Sharpe Ratio finden. Vergleichen wir mit den Daten des gemittelten Portfolios.




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








Lassen Sie uns die Daten der gefundenen Portfolios anzeigen.



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




Schlussfolgerungen



Wir haben die klassische Methode zur Berechnung der Aktien eines Anlageportfolios wiederholt. Wir haben sehr spezifische Ergebnisse erzielt.



Die Portfoliooptimierung nach der Markowitz-Methode setzt die Beibehaltung von Parametern in der Zukunft voraus (Korrelationen zwischen einzelnen Instrumenten und deren Rentabilität). Dies ist jedoch nicht garantiert. Dies wird in den nächsten Arbeiten überprüft.



Es ist klar, dass man von der obigen Prüfung kein positives Ergebnis erwarten sollte. Aber dann können Sie nach Möglichkeiten suchen, die Markowitz-Methode zu ändern, um in Zukunft ein garantierteres Einkommen zu erzielen. Hier ist ein Thema für eine andere Studie.



All Articles