Verwenden der Monte-Carlo-Methode zum Erstellen eines Portfolios

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) 

Bild

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):
        #    ,    1
        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]

#     DataFrame     .
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.

#   Sharpe Ratio
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)

Bild

Bild

Nun, die wichtigste Idee kann erhalten werden, wenn Sie die Daten visualisieren:

fig, ax = plt.subplots(figsize=(10, 10))

#    scatter plot        x      y

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

Bild

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.

All Articles