مثال على تطبيق قياسي في Python لتحسين محفظة الاستثمار باستخدام طريقة Markowitz. هناك العديد من تطبيقات هذه الطريقة. بما في ذلك لغة بايثون. تم التنفيذ مرة أخرى (انظر الرابط على GitHub ).
المصادر
لنأخذ بعض النظريات من هذه المصادر:
أفضل محفظة استثمارية من خلال محاكاة مونت كارلو في نظرية محفظة بايثون
ماركويتز (ويكيبيديا)
تحميل البيانات على عروض الأسعار
نستخدم البيانات من خدمة Yahoo.Finance
! pip install yfinance
import yfinance as yf
أخذنا عدة أسهم من السوق الأمريكية خلال الأشهر الثلاثة الماضية.
data = yf.download(['AAPL','GE','BAC','AMD','PLUG','F'],period='3mo')
معدلات الإغلاق
سوف نستخدم معدلات الإغلاق اليومية في حساباتنا
closeData = data.Close
closeData
مخططات الدورة
import matplotlib.pyplot as plt
for name in closeData.columns:
closeData[name].plot()
plt.grid()
plt.title(name)
plt.show()
تغيير الدورات
بعد ذلك ، تحتاج إلى تغييرات نسبية لليوم السابق.
dCloseData = closeData.pct_change()
dCloseData
الرسوم البيانية لتغييرات المعدل النسبي
for name in dCloseData.columns:
dCloseData[name].plot()
plt.title(name)
plt.grid()
plt.show()
متوسط العائد
متوسط العائد اليومي لكل سهم لحساب عائد المحفظة.
dohMean = dCloseData.mean()
dohMean
التغاير
لحساب مخاطر المحفظة ، يلزم وجود مصفوفة التغاير.
cov = dCloseData.cov()
cov
محفظة عشوائية
سنقوم بإنشاء محافظ عشوائية. في نفوسهم ، مجموع الأسهم يساوي 1 (واحد).
import numpy as np
cnt = len(dCloseData.columns)
def randPortf():
res = np.exp(np.random.randn(cnt))
res = res / res.sum()
return res
r = randPortf()
print(r)
print(r.sum())
[0.07519908 0.07594622 0.20932539 0.40973202 0.1234458 0.10635148]
1.0
عودة المحفظة
يتم حساب عائد المحفظة على أنه مجموع حصص العوائد لكل سهم في المحفظة.
def dohPortf(r):
return np.matmul(dohMean.values,r)
r = randPortf()
print(r)
d = dohPortf(r)
print(d)
[0.0789135 0.13031559 0.25977124 0.21157419 0.13506695 0.18435853]
0.006588795350151513
مخاطر المحفظة
نحسب مخاطر المحفظة من خلال منتجات مصفوفة لأسهم المحفظة ومصفوفات التغاير.
def riskPortf(r):
return np.sqrt(np.matmul(np.matmul(r,cov.values),r))
r = randPortf()
print(r)
rs = riskPortf(r)
print(rs)
[0.10999361 0.13739338 0.20412889 0.13648828 0.24021123 0.17178461]
0.02483674110724784
سحابة المحفظة
دعونا ننشئ مجموعة من المحافظ ونعرض النتيجة على مخطط عائد المخاطرة. دعنا نجد معلمات المحفظة المثلى للحد الأدنى من المخاطر والحد الأقصى لنسبة شارب. دعنا نقارن مع بيانات المحفظة المتوسطة.
risk = np.zeros(N)
doh = np.zeros(N)
portf = np.zeros((N,cnt))
for n in range(N):
r = randPortf()
portf[n,:] = r
risk[n] = riskPortf(r)
doh[n] = dohPortf(r)
plt.figure(figsize=(10,8))
plt.scatter(risk*100,doh*100,c='y',marker='.')
plt.xlabel(', %')
plt.ylabel(', %')
plt.title(" ")
min_risk = np.argmin(risk)
plt.scatter([(risk[min_risk])*100],[(doh[min_risk])*100],c='r',marker='*',label=' ')
maxSharpKoef = np.argmax(doh/risk)
plt.scatter([risk[maxSharpKoef]*100],[doh[maxSharpKoef]*100],c='g',marker='o',label=' - ')
r_mean = np.ones(cnt)/cnt
risk_mean = riskPortf(r_mean)
doh_mean = dohPortf(r_mean)
plt.scatter([risk_mean*100],[doh_mean*100],c='b',marker='x',label=' ')
plt.legend()
plt.show()
دعنا نعرض بيانات المحافظ التي تم العثور عليها.
import pandas as pd
print('---------- ----------')
print()
print(" = %1.2f%%" % (float(risk[min_risk])*100.))
print(" = %1.2f%%" % (float(doh[min_risk])*100.))
print()
print(pd.DataFrame([portf[min_risk]*100],columns=dCloseData.columns,index=[', %']).T)
print()
print('---------- ----------')
print()
print(" = %1.2f%%" % (float(risk[maxSharpKoef])*100.))
print(" = %1.2f%%" % (float(doh[maxSharpKoef])*100.))
print()
print(pd.DataFrame([portf[maxSharpKoef]*100],columns=dCloseData.columns,index=[', %']).T)
print()
print('---------- ----------')
print()
print(" = %1.2f%%" % (float(risk_mean)*100.))
print(" = %1.2f%%" % (float(doh_mean)*100.))
print()
print(pd.DataFrame([r_mean*100],columns=dCloseData.columns,index=[', %']).T)
print()
---------- ----------
= 1.80%
= 0.59%
, %
AAPL 53.890706
AMD 12.793389
BAC 4.117541
F 16.547201
GE 10.945462
PLUG 1.705701
---------- ----------
= 2.17%
= 0.88%
, %
AAPL 59.257114
AMD 8.317192
BAC 2.049882
F 8.689935
GE 4.772159
PLUG 16.913719
---------- ----------
= 2.33%
= 0.68%
, %
AAPL 16.666667
AMD 16.666667
BAC 16.666667
F 16.666667
GE 16.666667
PLUG 16.666667
الاستنتاجات
كررنا الطريقة الكلاسيكية لحساب أسهم محفظة استثمارية. لقد حصلنا على نتائج محددة للغاية.
يفترض تحسين المحفظة باستخدام طريقة Markowitz مسبقًا الحفاظ على المعلمات في المستقبل (الارتباطات بين الأدوات الفردية ومستوى ربحيتها). لكن هذا غير مضمون. هذا ليتم التحقق منها في الأعمال التالية.
من الواضح أنه لا ينبغي للمرء أن يتوقع نتيجة إيجابية من الاختيار أعلاه. ولكن بعد ذلك يمكنك البحث عن كيفية تعديل طريقة Markowitz للحصول على دخل مضمون أكثر في المستقبل. هذا موضوع لدراسة أخرى.