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.