Menggunakan Metode Monte Carlo untuk Membuat Portofolio

Investor pemula (dan tidak hanya) sering bertanya-tanya bagaimana cara memilih rasio aset ideal yang termasuk dalam portofolio. Seringkali (atau tidak terlalu, tapi saya tahu dua pasti) untuk beberapa broker, fungsi ini dilakukan oleh robot perdagangan. Tetapi algoritma yang tertanam di dalamnya tidak diungkapkan.

Posting ini akan membahas cara mengoptimalkan portofolio menggunakan simulasi Python dan Monte Carlo. Optimalisasi portofolio dipahami sebagai rasio bobot yang akan memenuhi salah satu syarat:

  • Portofolio dengan tingkat risiko minimum dengan profitabilitas yang diinginkan;
  • Portofolio dengan profitabilitas maksimum dengan risiko yang ditetapkan;
  • Portofolio dengan hasil maksimal

Untuk perhitungan, kami akan mengambil sembilan saham yang direkomendasikan oleh robot perdagangan salah satu broker pada awal Januari 2020 dan juga menetapkan bobot optimal untuk mereka dalam portofolio: 'ATVI', 'BA', 'CNP', 'CMA', 'STZ', 'GPN', 'MPC', 'NEM' dan 'PKI'. Untuk analisis, kami akan mengambil data stok selama tiga tahun terakhir.

# 

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


Jika Anda menambahkan bagian dari semua saham yang termasuk dalam portofolio, maka jumlahnya harus cenderung satu (atau lebih tepatnya sama). Kemudian, seperti biasa, kami akan menyiapkan data untuk perhitungan:

#    
all_adj_close = stock[['Adj Close']]

#  
all_returns = all_adj_close.pct_change()

#       
mean_returns = all_returns.mean()
cov_matrix = all_returns.cov()

Sekarang Anda dapat menghitung untuk bobot yang ditawarkan oleh robot perdagangan dan mengetahui profitabilitas portofolio ini selama tiga tahun terakhir dan standar deviasi.

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

gambar

Simulasi Monte Carlo


Awalnya, pengantar kecil tentang bagaimana metode Monte Carlo digunakan untuk mengoptimalkan portofolio.Pertama

, bobot acak diberikan kepada saham, setelah itu hasil dan standar deviasi dihitung. Nilai yang dihasilkan disimpan. Langkah selanjutnya adalah mengubah bobot secara acak (yang terpenting adalah jangan lupa bahwa jumlahnya harus satu) dan semuanya berulang - menghitung dan menyimpan nilai yang diperoleh. Jumlah iterasi tergantung pada waktu, kapasitas komputer untuk perhitungan, dan risiko yang siap diterima investor. Kali ini kami akan mencoba melakukan 10.000 perhitungan untuk mengidentifikasi portofolio dengan kerugian minimum dan rasio Sharpe maksimum.

#   
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]])

Sekarang Anda dapat menghitung portofolio dengan rasio Sharpe maksimum atau risiko minimum.

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

gambar

gambar

Nah, ide paling penting dapat diperoleh saat Anda memvisualisasikan data:

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

gambar

Portofolio dengan rasio Sharpe maksimum ditunjukkan oleh bintang merah, biru - dengan standar deviasi minimum dan hijau - yang diajukan oleh robot. Seperti yang Anda lihat, portofolio yang diajukan oleh robot tidak sesuai dengan indikator ini, tetapi investor dibiarkan dengan pilihan portofolio. Dan saya akan mencoba pada akhir tahun untuk kembali membandingkan portofolio. Dan sekarang ketiga portofolio tersebut dalam drawdown.

All Articles