المخاطر لكل مستوى من العائد
وجد الموضوع السابق، لعائد مستهدف واحد، الأوزان ذات أقل تباين. افعل ذلك لكل هدف وارسم التقلب على المحور الأفقي والعائد على الرأسي: تشكل النقاط منحنى هو الحدود الكفؤة. وكل محفظة من هذه الأصول تقع عليه أو داخله إلى اليمين. والمحفظة داخل المنحنى مهدرة، إذ توجد أخرى بالعائد نفسه وبمخاطر أقل، أو بعائد أكبر وبالمخاطر نفسها. وفكرة ماركوفيتز أن على المستثمرين أن ينظروا إلى المنحنى وحده.
import numpy as np
mu = np.array([0.08, 0.05, 0.10])
cov = np.array([[0.0400, 0.0060, 0.0100],
[0.0060, 0.0100, 0.0020],
[0.0100, 0.0020, 0.0225]])
def target_return_weights(mu, cov, target):
ones = np.ones(len(mu))
s1, sm = np.linalg.solve(cov, ones), np.linalg.solve(cov, mu)
a, b, c = ones @ s1, ones @ sm, mu @ sm
d = a * c - b ** 2
return ((c - b * target) * s1 + (a * target - b) * sm) / d
for target in (0.05, 0.06, 0.07, 0.08, 0.09, 0.10):
w = target_return_weights(mu, cov, target)
print(target, round(float(np.sqrt(w @ cov @ w)), 4))شكلها ورأسها
الحدود قطع مكافئ في المستوى (العائد، التباين)، وقطع زائد إن رسمنا التقلب. والتباين عند العائد المستهدف t هو (a * t**2 - 2 * b * t + c) / (a * c - b**2) بالأعداد a, b, c الأربعة نفسها كما قبل. وأدنى نقطة فيه هي محفظة التباين الأدنى الكلي عند العائد b / a: رأس المنحنى وهي محفظة التباين الأدنى من قبل موضوعين. والجزء من الرأس صعودًا وحده هو الحدود الكفؤة؛ أما الفرع السفلي فصورة معكوسة بعائد أقل لنفس المخاطر.
# The tip of the curve: the minimum-variance portfolio and its return
import numpy as np
mu = np.array([0.08, 0.05, 0.10])
cov = np.array([[0.0400, 0.0060, 0.0100],
[0.0060, 0.0100, 0.0020],
[0.0100, 0.0020, 0.0225]])
ones = np.ones(3)
x = np.linalg.solve(cov, ones)
w = x / x.sum()
print(np.round(w, 4), round(float(w @ mu), 4), round(float(np.sqrt(w @ cov @ w)), 4)) # the tip: return, volatility
def closed_form_vol(target):
s1, sm = x, np.linalg.solve(cov, mu)
a, b, c = ones @ s1, ones @ sm, mu @ sm
return float(np.sqrt((a * target ** 2 - 2 * b * target + c) / (a * c - b ** 2)))
for target in (0.05, 0.0642, 0.07):
print(target, round(closed_form_vol(target), 4))النقاط الكفؤة وغير الكفؤة
يظهر المخاطر نفسها عند عائدين على المنحنى، أحدهما على كل فرع، والأعلى وحده يستحق الاحتفاظ به. فيكون الهدف كفؤًا تمامًا عندما يساوي عائد التباين الأدنى أو يفوقه. والاختبار مقارنة واحدة لكنه يحدد الأهداف التي تنتمي إلى رسم الخيارات. ويصبح البحث عن أفضل موازنة على الحدود مسألة اختيار نقطة، والإجابة الشائعة هي التي تحقق أكبر عائد لكل وحدة مخاطر فوق المعدل الخالي من المخاطر.
# The point with the highest Sharpe ratio among candidate targets
import numpy as np
mu = np.array([0.08, 0.05, 0.10])
cov = np.array([[0.0400, 0.0060, 0.0100],
[0.0060, 0.0100, 0.0020],
[0.0100, 0.0020, 0.0225]])
rf = 0.02
ones = np.ones(3)
s1, sm = np.linalg.solve(cov, ones), np.linalg.solve(cov, mu)
a, b, c = ones @ s1, ones @ sm, mu @ sm
d = a * c - b ** 2
targets = np.linspace(0.05, 0.10, 11)
vols = np.sqrt((a * targets ** 2 - 2 * b * targets + c) / d)
sharpe = (targets - rf) / vols
for t, v, s in zip(targets, vols, sharpe):
print(round(float(t), 3), round(float(v), 4), round(float(s), 4))
print("best target:", round(float(targets[np.argmax(sharpe)]), 3))# Efficient or not: compare a target with the return of the minimum-variance portfolio
import numpy as np
mu = np.array([0.08, 0.05, 0.10])
cov = np.array([[0.0400, 0.0060, 0.0100],
[0.0060, 0.0100, 0.0020],
[0.0100, 0.0020, 0.0225]])
x = np.linalg.solve(cov, np.ones(3))
tip = float((x / x.sum()) @ mu)
for target in (0.05, 0.06, 0.07, 0.08):
print(target, "efficient" if target >= tip else "inefficient")mu وcov وكلاهما مقدَّر، فهو نفسه تقدير، ومبالغ فيه: فقد اختار المُحسِّن من بين كل المزائج ما تصادف أن عوائده المقدَّرة مرتفعة ومخاطره منخفضة. والنتائج الحقيقية تقع إلى يمين الخط المرئي وتحته. وإعادة أخذ العينات، أو مقارنة حدود النصف الأول من العينة بأدائها في النصف الثاني، تُظهر كم من المنحنى كان حظًّا. فاعتبر الحدود خريطة للموازنات لا وعدًا.- تعطي الحدود الكفؤة لكل عائد مستهدف أقل تقلب:
sqrt(w @ cov @ w)معw = target_return_weights(...)؛ والمحافظ داخلها مهدرة. - رأسها هو محفظة التباين الأدنى الكلي عند العائد
b / a؛ والأهداف التي تساوي هذا العائد أو تفوقه فقط كفؤة. - اختر نقطة بمعيار مثل أعلى نسبة شارب
(target - rf) / volatility؛ وتذكّر أن المنحنى مبني من تقديرات وهو متفائل.
التالي: اختبار رجعي متجه، اختبار قاعدة تداول على أسعار تاريخية.
المختبر: ما الذي يُقيَّم
- ارسم الحدود باستخدام
frontier_vols25 نقطة - اعثر على رأس المنحنى باستخدام
min_variance_return25 نقطة - ميّز النصف الجيد من السيئ باستخدام
is_efficient25 نقطة - اختر أفضل نقطة باستخدام
max_sharpe_target25 نقطة