σμ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›الوحدة 8 · النماذج العشوائية والتعلم الآلي›الموضوع 8.4·~55 دمتقدم

الخيارات الآسيوية

الموضع في المسارالوحدة 8 من 11 · الموضوع 4 من 10
8.4 الخيارات الآسيوية
—درجة المختبر— / 100إجمالي XP—التتابع—

الدفع على المتوسط

يعتمد الكول العادي على سعر يوم واحد هو الأخير. أما الخيار الآسيوي فيعتمد على متوسط السعر عبر مجموعة تواريخ: الكول الآسيوي يدفع max(المتوسط - K, 0). وتستخدمه الشركات لتحوط كلفة تتحملها باستمرار، كشراء النفط شهريًا، ويصعب التلاعب به عند الانتهاء. وهو *معتمد على المسار* فلا توجد صيغة بلاك-شولز بسيطة للمتوسط الحسابي، والأداة المعتادة هي محاكاة مونت كارلو.

import numpy as np

# Two simulated paths: the starting price, then monthly prices; the last column is expiry
paths = np.array([[100.0, 90.0, 110.0, 130.0],
                  [100.0, 70.0,  80.0,  90.0]])
average = paths[:, 1:].mean(axis=1)                      # the monitoring dates only, not the starting price
print(average)                                           # [110.  80.]
print(np.maximum(average - 100.0, 0.0))                  # Asian call payoffs: [10.  0.]
print(np.maximum(paths[:, -1] - 100.0, 0.0))             # European call payoffs on the same paths: [30.  0.]

محاكاة المسارات

تأتي المسارات من الحركة البراونية الهندسية بانجراف محايد للمخاطر: يحل المعدل r محل mu. نسحب مصفوفة طبيعية معيارية بصف لكل مسار وعمود لكل تاريخ رصد، ونحولها إلى حركات لوغاريتم السعر، ونجري مجموعًا تراكميًا على كل صف. فيحمل مصفوف واحد كل المسارات، وكل خطوة لاحقة (المتوسطات والمدفوعات) عملية متجهة على الصفوف بلا حلقة على المسارات.

import numpy as np

def simulate_paths(s0, rate, sigma, t, steps, n_paths, rng):
    dt = t / steps
    z = rng.standard_normal((n_paths, steps))
    log_moves = (rate - 0.5 * sigma ** 2) * dt + sigma * np.sqrt(dt) * z
    return s0 * np.exp(np.hstack([np.zeros((n_paths, 1)), np.cumsum(log_moves, axis=1)]))

rng = np.random.default_rng(1)
paths = simulate_paths(100.0, 0.05, 0.2, 1.0, 12, 50000, rng)       # monthly monitoring for a year
print(paths.shape)                                                   # (50000, 13)
print(round(float(paths[:, -1].mean()), 2), round(100 * np.exp(0.05), 2))      # the risk-neutral mean of the final price

السعر وهامش خطئه

سعر الخيار هو متوسط المدفوع المخصوم: exp(-r * T) * mean(payoffs). وسعر مونت كارلو تقدير، فأبلغ دائمًا عن خطئه المعياري std(payoffs) / sqrt(عدد المسارات) (مخصومًا)، وهو يبين مدى بعد الرقم عن الحقيقة: أربعة أضعاف المسارات تنصّفه. والكول الآسيوي أرخص من الأوروبي على السهم نفسه لأن المتوسط يملّس السعر ويخفض التقلب الفعلي.

import numpy as np

def simulate_paths(s0, rate, sigma, t, steps, n_paths, rng):
    dt = t / steps
    z = rng.standard_normal((n_paths, steps))
    log_moves = (rate - 0.5 * sigma ** 2) * dt + sigma * np.sqrt(dt) * z
    return s0 * np.exp(np.hstack([np.zeros((n_paths, 1)), np.cumsum(log_moves, axis=1)]))

def asian_price(paths, strike, rate, t):
    payoff = np.maximum(paths[:, 1:].mean(axis=1) - strike, 0.0)
    discount = np.exp(-rate * t)
    return discount * payoff.mean(), discount * payoff.std(ddof=1) / np.sqrt(len(payoff))

rng = np.random.default_rng(1)
paths = simulate_paths(100.0, 0.05, 0.2, 1.0, 12, 100000, rng)
price, error = asian_price(paths, 100.0, 0.05, 1.0)
european = np.exp(-0.05) * np.maximum(paths[:, -1] - 100.0, 0.0).mean()
print(round(float(price), 3), "+/-", round(float(error), 3))
print(round(float(european), 3), "European call on the same paths")
# Geometric and arithmetic averages of the same monitoring prices
import numpy as np

prices = np.array([90.0, 110.0, 130.0])
arithmetic = prices.mean()
geometric = np.exp(np.log(prices).mean())
print(round(float(arithmetic), 3), round(float(geometric), 3))        # 110.0 108.774: the geometric average is never larger
للمتوسط الهندسي صيغةحاصل ضرب لوغاريتميات طبيعية لوغاريتمي طبيعي، فيمكن تسعير خيار آسيوي على المتوسط الهندسي بصيغة من نوع بلاك-شولز. وهذا يجعله مفيدًا للتحقق، وأكثر من ذلك متغيرًا ضابطًا للحسابي: فالمدفوعان شديدا الارتباط، فيستطيع السعر الدقيق المعروف للخيار الهندسي إلغاء جزء كبير من ضجيج مونت كارلو. وموضوع لاحق هو المتغيرات الضابطة يستخدم هذه الفكرة بعينها.
  • يدفع الخيار الآسيوي على متوسط تواريخ الرصد: max(المتوسط - K, 0)؛ معتمد على المسار فلا صيغة بسيطة ومونت كارلو هي الأداة.
  • حاكِ كل المسارات في مصفوفة واحدة (الصفوف = مسارات والأعمدة = تواريخ) بانجراف محايد للمخاطر؛ والمتوسطات والمدفوعات متجهة على الصفوف.
  • السعر = exp(-r * T) * mean(payoffs) بخطأ معياري std / sqrt(paths)؛ والتوسيط يجعله أرخص من الكول الأوروبي، والنسخة الهندسية متغير ضابط.

التالي: الخيارات ذات الحاجز، التي تُولد أو تموت عندما يلمس السعر مستوى معينًا.

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

  • احسب المتوسط على طول كل مسار باستخدام average_price25 نقطة
  • جرّب المتوسط الهندسي باستخدام geometric_average25 نقطة
  • ادفع على المتوسط باستخدام asian_call_payoff25 نقطة
  • سعّرها مع هامش الخطأ باستخدام asian_price25 نقطة
المستكشف · lab-105-1
▾ lab-105-1
…
bash · داخل المتصفح
learner@quantcraft:~/lab-105-1$
لم يتم تحميل Python بعدPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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