σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft Academyالمسارات
Ctrl K
AO
+1.2k متعلّم
تسجيل الدخولانضم ↗
المسارات
AO
+1.2k متعلّم
تسجيل الدخول
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
مسار Python›الوحدة 5 · تحسين المحافظ›الموضوع 5.4·~55 دمتوسط

تحسين المتوسط والتباين

الموضع في المسارالوحدة 5 من 11 · الموضوع 4 من 5
5.4 تحسين المتوسط والتباين
—درجة المختبر— / 100إجمالي XP—التتابع—

العائد والمخاطر في رقم واحد

التباين الأدنى يتجاهل العوائد. أما تحسين المتوسط والتباين (ماركوفيتز) فيستخدم الاثنين: يريد المستثمر عائدًا متوقعًا w @ mu مرتفعًا وتباينًا w @ cov @ w منخفضًا. وطريقة بسيطة للموازنة بينهما هي المنفعة w @ mu - 0.5 * lambda * w @ cov @ w حيث lambda هو النفور من المخاطر: كلما ارتفع كلفت وحدة التباين أكثر. ومستثمران بالتوقعات نفسها وبـlambda مختلف يختاران محفظتين مختلفتين، وأفضل محفظة لكل منهما هي قمة دالة ملساء مقعّرة.

import numpy as np

mu = np.array([0.08, 0.05, 0.10])                         # expected annual returns
cov = np.array([[0.0400, 0.0060, 0.0100],
                [0.0060, 0.0100, 0.0020],
                [0.0100, 0.0020, 0.0225]])

def utility(weights, mu, cov, risk_aversion):
    return weights @ mu - 0.5 * risk_aversion * weights @ cov @ weights

equal = np.full(3, 1 / 3)
print(round(float(equal @ mu), 4), round(float(equal @ cov @ equal), 4))      # 0.0767 0.0121
print(round(float(utility(equal, mu, cov, 4.0)), 4))                          # 0.0526

أفضل مركز لنفور معين من المخاطر

من دون قيد ميزانية (يربح باقي المال معدل الخالي من المخاطر، ويُعد هنا صفرًا بالزيادة) يكون أفضل مركز حيث ينعدم التدرج mu - lambda * cov @ w: w = cov^-1 * mu / lambda. وفي الكود np.linalg.solve(cov, mu) / lambda. وهو يتدرج كما يقتضي المنطق: ضعف النفور، نصف المركز. ومجموع الأوزان هو ما يلزم؛ والباقي، 1 - w.sum()، نقد.

# The best position for several risk aversions: more aversion, smaller bets
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]])

for aversion in (5.0, 10.0, 20.0):
    w = np.linalg.solve(cov, mu) / aversion
    print(aversion, np.round(w, 3), "invested", round(float(w.sum()), 3))

المحفظة المماسية

مع أصل خالٍ من المخاطر يحتفظ كل المستثمرين بالمزيج المخاطر نفسه بكميات مختلفة. وهذا المزيج هو صاحب أعلى نسبة شارب (w @ mu - rf) / sqrt(w @ cov @ w)، أي المحفظة المماسية: w متناسب مع cov^-1 * (mu - rf) ومُعاد تحجيمه ليجمع إلى 1. فالمستثمر الحذر يضع جزءًا من ماله فيها والباقي نقدًا؛ والجريء يقترض ليملك أكثر. وتقرير مقدار المخاطرة وتقرير الأصول المخاطرة مسألتان منفصلتان.

# The tangency portfolio: no other mix of the three assets has a higher Sharpe ratio
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

x = np.linalg.solve(cov, mu - rf)
best = x / x.sum()

def sharpe(w):
    return (w @ mu - rf) / np.sqrt(w @ cov @ w)

rng = np.random.default_rng(1)
trials = rng.normal(size=(2000, 3))
trials = trials / trials.sum(axis=1, keepdims=True)
print(np.round(best, 4), round(float(sharpe(best)), 4))
print(round(max(float(sharpe(w)) for w in trials), 4))      # the best of 2000 random mixes comes close, never above

بلوغ عائد مستهدف

طريقة أخرى لطرح السؤال: من بين كل المحافظ التي مجموعها 1 ولها عائد متوقع معين، أيها له أقل تباين؟ مع قيدين يكون الحل تركيبة من المتجهين المحلولين s1 = cov^-1 * 1 وsm = cov^-1 * mu بمعاملات من أربعة أعداد a, b, c, d تلخص السوق. وكل عائد مستهدف يعطي محفظة؛ ورسم مخاطر جميعها هو الحدود الكفؤة في الموضوع التالي.

# Minimum-variance portfolios for three target returns
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)
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

for target in (0.06, 0.08, 0.09):
    w = ((c - b * target) * s1 + (a * target - b) * sm) / d
    print(target, np.round(w, 3), round(float(w @ mu), 4), round(float(np.sqrt(w @ cov @ w)), 4))
المُحسِّن يعظّم أخطاءكأوزان المتوسط والتباين شديدة الحساسية لـmu: فتغير صغير في عائد متوقع واحد قد ينقل المحفظة من أصل إلى آخر. ويثق المُحسِّن بالمُدخلات ثقة تامة، فيتحول أي عائد مبالغ في تقديره إلى مركز كبير. وفي الواقع تُقلَّص العوائد وتُحدّ الأوزان وتأتي المُدخلات من نماذج أو آراء لا من متوسطات ماضية خام. المتوسط والتباين أداة جيدة للتفكير وخطرة عند الاستخدام الأعمى.
  • المنفعة هي w @ mu - 0.5 * lambda * w @ cov @ w؛ وأفضل مركز بلا ميزانية هو solve(cov, mu) / lambda، ومضاعفة lambda تنصّفه.
  • مع أصل خالٍ من المخاطر يكون أفضل مزيج مخاطر هو المحفظة المماسية solve(cov, mu - rf) بعد تحجيمها لتجمع إلى 1: أعلى نسبة شارب.
  • لعائد مستهدف تكون أوزان التباين الأدنى تركيبة من solve(cov, ones) وsolve(cov, mu)؛ ولا تزيد جودة النتيجة عن جودة mu المقدَّر.

التالي: الحدود الكفؤة، منحنى أفضل مخاطر لكل مستوى من العائد.

المختبر: ما الذي يُقيَّم

  • قيّم محفظة باستخدام utility25 نقطة
  • اعثر على أفضل مركز باستخدام utility_weights25 نقطة
  • عظّم نسبة شارب باستخدام tangency_weights25 نقطة
  • حقّق عائدًا مستهدفًا باستخدام target_return_weights25 نقطة
المستكشف · lab-85-1
▾ lab-85-1
…
bash · داخل المتصفح
learner@quantcraft:~/lab-85-1$
لم يتم تحميل Python بعدPythonLn 1, Col 1Spaces: 4UTF-8

هل تريد إعادة ضبط هذا الموضوع؟

سيعود كل ما في lab-85-1 إلى الملفات الابتدائية وستُمسح الطرفية. ستفقد حلّك الحالي ولا يمكن التراجع عن ذلك.

سيُعاد ضبطه
  • main.py ← الشيفرة الابتدائية
  • سجل الطرفية ومخرجات الاختبارات
  • التغييرات غير المُرسلة
سيُحتفظ به
  • أفضل درجة في المختبر
  • نقاط XP والتتابع
  • تقدّم المحاضرة والملاحظات

سجّل الدخول لتشغيل الكود الخاص بك.

قراءة كل المحاضرات مجانية. أنشئ حسابًا أو سجّل الدخول لتشغيل الكود وتنفيذ الاختبارات وتسليم هذا المختبر.

  • بيئة تطوير داخل المتصفح مع طرفية bash — لا حاجة لتثبيت أي شيء
  • تصحيح فوري ونقاط خبرة ومكانك في المسار
إنشاء حسابتسجيل الدخول
أو
المتابعة عبر GitHub