使用蒙特卡洛方法创建投资组合

新手(不仅是)投资者经常想知道如何选择投资组合中包含的理想资产比率。对于某些经纪人来说,通常(或者不是很清楚,但是我肯定知道两个)是由交易机器人执行的。但是没有公开嵌入其中的算法。

这篇文章将介绍如何使用Python和Monte Carlo模拟来优化投资组合。投资组合优化应理解为满足以下条件之一的权重比:

  • 具有最低风险水平并具有预期获利能力的投资组合;
  • 在确定风险下具有最大获利能力的投资组合;
  • 最高收益的投资组合

为了进行计算,我们将采用其中一位经纪人的交易机器人在2020年1月开始推荐的9只股票,并在投资组合中为它们设置最佳权重:“ ATVI”,“ BA”,“ CNP”,“ CMA”,“ STZ”, “ GPN”,“ MPC”,“ NEM”和“ PKI”。为了进行分析,我们将获取最近三年的库存数据。

# 

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


如果将投资组合中包含的所有股份的份额加起来,则金额应趋向于一个(或相等)。然后,像往常一样,我们将为计算准备数据:

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

#  
all_returns = all_adj_close.pct_change()

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

现在,您可以计算交易机器人提供的权重,并找出最近三年该投资组合的盈利能力和标准差。

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

图片

蒙特卡洛模拟


最初,简要介绍了如何使用蒙特卡洛方法优化投资组合:

首先,对股票进行随机加权,然后计算收益率和标准差。结果值已保存。下一步是随机更改权重(最主要的是不要忘记权重之和应该为一个),然后一切重复—计算并保存获得的值。迭代次数取决于时间,计算机计算能力以及投资者准备接受的风险。这次,我们将尝试进行10,000次计算,以找出损失最小,夏普比率最大的投资组合。

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

现在,您可以计算最大夏普比率或最小风险的投资组合。

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

图片

图片

好了,当您可视化数据时,可以获得最重要的想法:

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

图片

机器人建议的最大Sharpe比率的组合由红色星形,蓝色(具有最小标准偏差)和绿色表示。如您所见,机器人提出的投资组合与这些指标不一致,但是投资者可以选择投资组合。我将在年底尝试返回比较投资组合。现在所有三个投资组合都处于亏损状态。

All Articles