AnfĂ€nger (und nicht nur) fragen sich oft, wie sie das ideale VerhĂ€ltnis der im Portfolio enthaltenen Vermögenswerte wĂ€hlen sollen. Bei einigen Brokern wird diese Funktion hĂ€ufig (oder nicht sehr, aber ich kenne sicher zwei) von einem Handelsroboter ausgefĂŒhrt. Die darin eingebetteten Algorithmen werden jedoch nicht offenbart.In diesem Beitrag erfahren Sie, wie Sie ein Portfolio mithilfe von Python- und Monte-Carlo-Simulationen optimieren. Unter Portfoliooptimierung wird ein solches VerhĂ€ltnis von Gewichten verstanden, das eine der folgenden Bedingungen erfĂŒllt:- Ein Portfolio mit einem Mindestrisiko und der gewĂŒnschten RentabilitĂ€t;
- Portfolio mit maximaler RentabilitÀt bei etabliertem Risiko;
- Portfolio mit maximaler Rendite
Zur Berechnung nehmen wir neun Aktien, die vom Handelsroboter eines der Broker Anfang Januar 2020 empfohlen wurden, und legen auch die optimalen Gewichte fĂŒr sie im Portfolio fest: 'ATVI', 'BA', 'CNP', 'CMA', 'STZ', 'GPN', 'MPC', 'NEM' und 'PKI'. Zur Analyse werden Bestandsdaten der letzten drei Jahre herangezogen.
import pandas as pd
import yfinance as yf
import numpy as np
import matplotlib.pyplot as plt
ticker = ['ATVI','BA','CNP','CMA', 'STZ','GPN','MPC','NEM', 'PKI']
stock = yf.download(ticker,'2017-01-01', '2019-01-31')
Wenn Sie den Anteil aller im Portfolio enthaltenen Aktien addieren, sollte der Betrag zu eins tendieren (oder eher gleich sein). Dann bereiten wir wie gewohnt die Daten fĂŒr die Berechnungen vor:
all_adj_close = stock[['Adj Close']]
all_returns = all_adj_close.pct_change()
mean_returns = all_returns.mean()
cov_matrix = all_returns.cov()
Jetzt können Sie die vom Handelsroboter angebotenen Gewichte berechnen und die RentabilitĂ€t dieses Portfolios fĂŒr die letzten drei Jahre sowie die Standardabweichung ermitteln.
robot = np.array([0.0441, 0.1030, 0.1086, 0.2070, 0.1525, 0.0714, 0.0647, 0.1828, 0.0661])
portfolio_return_robot = np.sum(mean_returns * robot)
portfolio_std_dev_robot = np.sqrt(np.dot(robot.T,np.dot(cov_matrix, robot)))
sharpo_robot = portfolio_return_robot/portfolio_std_dev_robot
robot_result = np.array([portfolio_return_robot, portfolio_std_dev_robot, sharpo_robot])
robot_result = np.array([portfolio_return_robot, portfolio_std_dev_robot, sharpo_robot])
robot_result = np.concatenate((robot_result, robot), axis=0)
robot_sim_result = pd.DataFrame(robot_result, columns=['Robot'], index=['ret','stdev','sharpe',ticker[0],ticker[1],ticker[2],ticker[3],ticker[4],ticker[5],ticker[6],ticker[7],ticker[8]])
print(robot_sim_result)

Monte-Carlo-Simulation
ZunĂ€chst eine kleine EinfĂŒhrung in die Verwendung der Monte-Carlo-Methode zur Optimierung des Portfolios.ZunĂ€chst werden die Aktien nach dem Zufallsprinzip gewichtet, wonach Rendite und Standardabweichung berechnet werden. Die resultierenden Werte werden gespeichert. Der nĂ€chste Schritt besteht darin, die Gewichte zufĂ€llig zu Ă€ndern (die Hauptsache ist nicht zu vergessen, dass ihre Summe eins sein sollte) und alles wiederholt sich - Berechnen und Speichern des erhaltenen Werts. Die Anzahl der Iterationen hĂ€ngt von der Zeit, den ComputerkapazitĂ€ten fĂŒr die Berechnung und den Risiken ab, die der Anleger zu akzeptieren bereit ist. Dieses Mal werden wir versuchen, 10.000 Berechnungen durchzufĂŒhren, um ein Portfolio mit einem minimalen Verlust und einer maximalen Sharpe Ratio zu identifizieren.
num_iterations = 10000
simulation_res = np.zeros((4+len(ticker)-1,num_iterations))
for i in range(num_iterations):
weights = np.array(np.random.random(9))
weights /= np.sum(weights)
portfolio_return = np.sum(mean_returns * weights)
portfolio_std_dev = np.sqrt(np.dot(weights.T,np.dot(cov_matrix, weights)))
simulation_res[0,i] = portfolio_return
simulation_res[1,i] = portfolio_std_dev
simulation_res[2,i] = simulation_res[0,i] / simulation_res[1,i]
for j in range(len(weights)):
simulation_res[j+3,i] = weights[j]
sim_frame = pd.DataFrame(simulation_res.T,columns=['ret','stdev','sharpe',ticker[0],ticker[1],ticker[2],ticker[3],ticker[4],ticker[5],ticker[6],ticker[7],ticker[8]])
Jetzt können Sie das Portfolio mit der maximalen Sharpe Ratio oder dem minimalen Risiko berechnen.
max_sharpe = sim_frame.iloc[sim_frame['sharpe'].idxmax()]
min_std = sim_frame.iloc[sim_frame['stdev'].idxmin()]
print ("The portfolio for max Sharpe Ratio:\n", max_sharpe)
print ("The portfolio for min risk:\n", min_std)

Nun, die wichtigste Idee kann erhalten werden, wenn Sie die Daten visualisieren:fig, ax = plt.subplots(figsize=(10, 10))
plt.scatter(sim_frame.stdev,sim_frame.ret,c=sim_frame.sharpe,cmap='RdYlBu')
plt.xlabel('Standard Deviation')
plt.ylabel('Returns')
plt.ylim(0,.0015)
plt.xlim(0.007,0.012)
plt.scatter(max_sharpe[1],max_sharpe[0],marker=(5,1,0),color='r',s=600)
plt.scatter(min_std[1],min_std[0],marker=(5,1,0),color='b',s=600)
plt.scatter(portfolio_std_dev_robot, portfolio_return_robot,marker=(5,1,0),color='g',s=600)
plt.show()
Das Portfolio mit dem maximalen Sharpe-VerhĂ€ltnis wird durch einen roten Stern angezeigt, blau - mit einer minimalen Standardabweichung und grĂŒn - vom Roboter vorgeschlagen. Wie Sie sehen, stimmt das vom Roboter vorgeschlagene Portfolio nicht mit diesen Indikatoren ĂŒberein, aber der Investor hat die Wahl des Portfolios. Und ich werde Ende des Jahres versuchen, wieder Portfolios zu vergleichen. Und jetzt sind alle drei Portfolios im Drawdown.