باستخدام طريقة مونت كارلو لإنشاء محفظة

غالبًا ما يتساءل المستثمرون المبتدئون (وليس فقط) عن كيفية اختيار النسبة المثالية للأصول المدرجة في المحفظة. في كثير من الأحيان (أو ليس كثيرًا ، لكني أعرف حوالي اثنين بالتأكيد) لبعض الوسطاء ، يتم تنفيذ هذه الوظيفة بواسطة روبوت التداول. ولكن لم يتم الكشف عن الخوارزميات المضمنة فيها.

سيغطي هذا المنشور كيفية تحسين المحفظة باستخدام محاكاة Python و Monte Carlo. يُفهم تحسين المحفظة على أنها نسبة من الأوزان تفي بأحد الشروط:

  • محفظة ذات مستوى أدنى من المخاطر مع الربحية المرجوة ؛
  • محفظة ذات ربحية قصوى بمخاطر مثبتة ؛
  • محفظة بأقصى عائد

للحساب ، سنأخذ تسعة أسهم موصى بها من قبل روبوت التداول لأحد الوسطاء في بداية يناير 2020 ونحدد أيضًا الأوزان المثالية لهم في المحفظة: "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) 

صورة

محاكاة مونت كارلو


في البداية ، مقدمة صغيرة لكيفية استخدام طريقة مونت كارلو لتحسين المحفظة

، أولاً ، يتم إعطاء أوزان عشوائية للأسهم ، وبعد ذلك يتم حساب العائد والانحراف المعياري. يتم حفظ القيم الناتجة. الخطوة التالية هي تغيير الأوزان بشكل عشوائي (الشيء الرئيسي هو ألا ننسى أن مجموعهم يجب أن يكون واحدًا) ويتكرر كل شيء - حساب القيمة التي تم الحصول عليها وحفظها. يعتمد عدد التكرارات على الوقت وقدرات الكمبيوتر في الحساب والمخاطر التي يكون المستثمر على استعداد لقبولها. هذه المرة سنحاول إجراء 10000 عملية حسابية لتحديد محفظة ذات الحد الأدنى من الخسارة ونسبة شارب القصوى.

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

صورة

يتم عرض المحفظة التي تحتوي على الحد الأقصى لنسبة شارب من نجمة حمراء ، زرقاء - مع الحد الأدنى من الانحراف المعياري والأخضر - التي اقترحها الروبوت. كما ترى ، لا تتوافق المحفظة التي يقترحها الروبوت مع هذه المؤشرات ، ولكن يترك المستثمر لاختيار المحفظة. وسأحاول في نهاية العام العودة إلى مقارنة الحقائب. والآن جميع المحافظ الثلاث في حالة تراجع.

All Articles