σμ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›الوحدة 11 · أنظمة الإنتاج والنماذج المتقدمة›الموضوع 11.7·~1 س 30 دخبير

نموذج هيستون

الموضع في المسارالوحدة 11 من 11 · الموضوع 7 من 13
11.7 نموذج هيستون
—درجة المختبر— / 100إجمالي XP—التتابع—

حين تتحرك التقلبات أيضًا

يفترض بلاك-شولز تقلبًا ثابتًا لكن التقلب الحقيقي يرتفع في الانهيارات ويخبو في الهدوء، وسوق الخيارات يُظهر ذلك: يختلف التقلب الضمني باختلاف سعر التنفيذ (الابتسامة أو الانحياز). ويُبقي نموذج هستون على عملية السعر الهندسية لكنه يجعل *التباين* v عشوائيًا أيضًا: يُسحب نحو مستوى طويل الأمد theta بسرعة kappa ويُهز بضجيج بحجم xi يتناسب مع sqrt(v)، ولصدمات السعر والتباين ارتباط rho. وارتباط سالب (ينخفض السعر حين يرتفع التقلب، أثر الرافعة) ينتج الانحياز الهابط الملاحَظ في خيارات الأسهم.

# The Heston equations, in words:  dS = mu S dt + sqrt(v) S dW      dv = kappa (theta - v) dt + xi sqrt(v) dZ      corr(dW, dZ) = rho
kappa, theta, xi = 2.0, 0.04, 0.3             # reversion speed, long-run variance (a 20% volatility), volatility of variance
print(round(theta ** 0.5, 2))                 # 0.2    the long-run volatility
print(2 * kappa * theta, xi ** 2)             # 0.16 0.09   the Feller condition 2 kappa theta >= xi^2 holds: the variance stays positive

محاكاته: القطع والارتباط

للمحاكاة نتقدم بفترات صغيرة dt. تحديث التباين هو v + kappa * (theta - v) * dt + xi * sqrt(v * dt) * dz لكن خطوة أويلر البسيطة قد تدفع v تحت الصفر حيث يفشل الجذر التربيعي. ويستعمل مخطط القطع الكامل القيمة max(v, 0) حيثما ظهر v في الطرف الأيمن (فالقيمة السالبة تعمل كصفر) ويحتفظ بالناتج الخام للخطوة التالية. وشرط فيلر 2 * kappa * theta >= xi^2 هو نظام المعاملات الذي لا تلمس فيه العملية الحقيقية الصفر؛ وإن لم يتحقق ازدادت أهمية القطع. ويجب أن تكون الصدمتان مرتبطتين: اسحب طبيعيَّين مستقلين z1 وz2 وضع dz = z1 وdw = rho * z1 + sqrt(1 - rho^2) * z2.

# One variance step with full truncation, and the correlated shocks for the price
import math

def variance_step(v, kappa, theta, xi, dz, dt):
    vp = max(v, 0.0)
    return v + kappa * (theta - vp) * dt + xi * math.sqrt(vp * dt) * dz

def correlated_normals(z1, z2, rho):
    return z1, rho * z1 + math.sqrt(1 - rho ** 2) * z2

print(round(variance_step(0.04, 2.0, 0.04, 0.3, 0.5, 1 / 252), 6))      # 0.04189   at the long-run level only the noise moves it
dz, dw = correlated_normals(1.0, 1.0, -0.7)
print(round(dz, 4), round(dw, 4))             # 1.0 0.0141   a negative rho: the price shock pulls against the variance shock
print(variance_step(-0.01, 2.0, 0.04, 0.3, 1.0, 1 / 252))               # -0.00968...   still negative, but it moved up by kappa * theta * dt: the negative value acted as 0

مسار كامل وفحص للصحة

تحدّث الخطوة الواحدة متغيّري الحالة معًا: يستعمل السعر التباين عند *بداية* الخطوة S * exp((mu - v/2) * dt + sqrt(v * dt) * dw) ثم يتحرك التباين. كرّر لعدد الخطوات في الأفق فيصير لديك مسار؛ وتعطي مسارات كثيرة توزيعًا لأسعار النهاية، ومتوسط عائد مخصوم عليها يسعّر خيارًا. وفحص صحة جيد: مع الانجراف mu ينبغي أن يقترب متوسط سعر النهاية من S0 * exp(mu * T) أيًّا كانت معاملات التقلب. وإلا ففي خطوة السعر خطأ. أما معايرة kappa, theta, xi, rho على أسعار الخيارات فتأتي في الموضوعات القادمة.

# A short Monte Carlo: simulate many paths, and check the average terminal price against S0 * exp(mu * T)
import math
import random

def simulate(s0, v0, mu, kappa, theta, xi, rho, steps, years, rng):
    dt = years / steps
    s, v = s0, v0
    for _ in range(steps):
        z1, z2 = rng.gauss(0, 1), rng.gauss(0, 1)
        dz, dw = z1, rho * z1 + math.sqrt(1 - rho ** 2) * z2
        vp = max(v, 0.0)
        s *= math.exp((mu - vp / 2) * dt + math.sqrt(vp * dt) * dw)
        v = v + kappa * (theta - vp) * dt + xi * math.sqrt(vp * dt) * dz
    return s

rng = random.Random(11)
finals = [simulate(100.0, 0.04, 0.05, 2.0, 0.04, 0.3, -0.7, 50, 1.0, rng) for _ in range(4000)]
mean = sum(finals) / len(finals)
print(abs(mean / (100.0 * math.exp(0.05)) - 1) < 0.02)       # True   the average terminal price follows S0 * exp(mu * T)
print(min(finals) > 0)                                       # True   prices stay positive
# A check that costs nothing: with xi = 0 and v0 = theta the variance never moves (Black-Scholes with volatility sqrt(theta))
import math

kappa, theta, xi = 2.0, 0.04, 0.0
v = theta
for z in (1.5, -2.0, 0.3, 0.9):
    vp = max(v, 0.0)
    v = v + kappa * (theta - vp) * (1 / 252) + xi * math.sqrt(vp / 252) * z
print(v == theta)                                    # True   no noise and already at the long-run level
print(round(math.sqrt(v), 2))                        # 0.2    a constant 20% volatility
أويلر بسيط لا دقيقتحمل مخططات أويلر خطأ تقطيع يتناقص مع dt، والشبكة الخشنة تُحيز أسعار الخيارات. استعمل خطوات كافية ومسارات كثيرة (يتناقص الخطأ المعياري كمقلوب جذر عدد المسارات). وتحقق من المحاكاة بجواب معروف: ضع xi = 0 فيؤول النموذج إلى بلاك-شولز بتقلب sqrt(theta). وفي الإنتاج يكون تسعير هستون شبه التحليلي عبر الدالة المميزة أسرع وأدق؛ والمحاكاة هي الأداة المرنة حين تعتمد العوائد على المسار.
  • يجعل هستون التباين عشوائيًا: يعود إلى theta بسرعة kappa وله ضجيج xi * sqrt(v) ويرتبط بالسعر بـ rho (سالب للأسهم).
  • حاكِ بالقطع الكامل (max(v, 0) في الطرف الأيمن) واربط الصدمات بـ dw = rho z1 + sqrt(1 - rho^2) z2 وافحص شرط فيلر 2 kappa theta >= xi^2.
  • تستعمل خطوة السعر التباين عند بداية الخطوة؛ تحقق من أن متوسط سعر النهاية يتبع S0 * exp(mu * T) وأن xi = 0 يعيد بلاك-شولز.

التالي: التقلب المحلي، سطح تقلب يعتمد على السعر والزمن.

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

  • أبقِ التباين موجبًا باستخدام feller_condition25 نقطة
  • حرّك التباين خطوة باستخدام variance_step25 نقطة
  • اربط الصدمات باستخدام correlated_normals25 نقطة
  • حرّك السعر والتباين باستخدام heston_step25 نقطة
المستكشف · lab-136-1
▾ lab-136-1
…
bash · داخل المتصفح
learner@quantcraft:~/lab-136-1$
لم يتم تحميل Python بعدPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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