σμ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›الوحدة 4 · تسعير الدخل الثابت والخيارات›الموضوع 4.15·~55 دمتوسط

الأشجار ثنائية الحدين

الموضع في المسارالوحدة 4 من 11 · الموضوع 15 من 16
4.15 الأشجار ثنائية الحدين
—درجة المختبر— / 100إجمالي XP—التتابع—

سهم لا يستطيع إلا الصعود أو الهبوط

بلاك-شولز صيغة، أما الشجرة ثنائية الحدّ فإجراء، وتستطيع تسعير ما لا تستطيعه الصيغة. نقسم الزمن حتى الانتهاء إلى خطوات صغيرة. في كل خطوة يصعد السهم بعامل u أو يهبط بعامل d، لا غير. وبعد n خطوة توجد n + 1 أسعار ممكنة. المدفوعات معروفة عند الانتهاء، وقيمة كل عقدة سابقة هي المتوسط المخصوم للعقدتين اللتين تقودان إليهما، فنملأ الشجرة رجوعًا حتى الحاضر.

# One step: a stock at 100 goes to 110 or 90. What is a call with strike 100 worth?
import math

spot, strike, rate, dt = 100, 100, 0.05, 1.0
u, d = 1.10, 0.90
p = (math.exp(rate * dt) - d) / (u - d)             # the probability that makes the stock grow at the rate
up_value, down_value = max(spot * u - strike, 0), max(spot * d - strike, 0)
price = math.exp(-rate * dt) * (p * up_value + (1 - p) * down_value)
print(round(p, 4), round(up_value, 4), down_value)   # 0.7564 10.0 0
print(round(price, 4))                               # 7.1947

الاحتمال ليس توقعًا

يُختار العدد p ليكبر السهم في المتوسط بمعدل الفائدة الخالي من المخاطر: p * u + (1 - p) * d = exp(rate * dt)، فينتج p = (exp(rate * dt) - d) / (u - d). وهو الاحتمال المحايد للمخاطر: حيلة تجعل محفظة المحاكاة تساوي توقعها المخصوم، لا اعتقادًا عن وجهة السهم. ولمطابقة التقلب المرصود تستخدم شجرة كوكس-روس-روبنشتاين (CRR) u = exp(sigma * sqrt(dt)) وd = 1 / u، فيعيد الصعود يتبعه الهبوط السعر نفسه وتتحد الفروع: n خطوة لا تعطي إلا n + 1 عقدة نهائية.

# The CRR parameters and the prices at expiry of a 3-step tree
import math

def crr_parameters(rate, sigma, t, steps):
    dt = t / steps
    u = math.exp(sigma * math.sqrt(dt))
    d = 1 / u
    p = (math.exp(rate * dt) - d) / (u - d)
    return u, d, p

def terminal_prices(spot, u, d, steps):
    return [spot * u ** j * d ** (steps - j) for j in range(steps + 1)]

u, d, p = crr_parameters(0.05, 0.2, 1, 3)
print(round(u, 4), round(d, 4), round(p, 4))                     # 1.1224 0.8909 0.5438
print([round(price, 2) for price in terminal_prices(100, u, d, 3)])

العمل رجوعًا

عند الانتهاء كل عقدة هي المدفوع فقط، max(S - K, 0) للكول. وفي العمود الأسبق تكون كل قيمة exp(-rate * dt) * (p * value_up + (1 - p) * value_down) وينقص العمود عقدة. وبعد n مسحة تبقى قيمة واحدة هي سعر اليوم. وفي بايثون العمود قائمة، والمسحة قائمة اشتمال على أزواج الجيران. ومع ازدياد عدد الخطوات يتقارب السعر من سعر بلاك-شولز، فتعيد الشجرة ما تقوله الصيغة.

# The tree price of a European call approaches the Black-Scholes price as steps grow
import math

def norm_cdf(x):
    return 0.5 * (1 + math.erf(x / math.sqrt(2)))

def bs_call(spot, strike, rate, sigma, t):
    d1 = (math.log(spot / strike) + (rate + 0.5 * sigma ** 2) * t) / (sigma * math.sqrt(t))
    return spot * norm_cdf(d1) - strike * math.exp(-rate * t) * norm_cdf(d1 - sigma * math.sqrt(t))

def european_call_tree(spot, strike, rate, sigma, t, steps):
    dt = t / steps
    u = math.exp(sigma * math.sqrt(dt))
    d = 1 / u
    p = (math.exp(rate * dt) - d) / (u - d)
    disc = math.exp(-rate * dt)
    values = [max(spot * u ** j * d ** (steps - j) - strike, 0) for j in range(steps + 1)]
    for _ in range(steps):
        values = [disc * (p * values[j + 1] + (1 - p) * values[j]) for j in range(len(values) - 1)]
    return values[0]

print("Black-Scholes", round(bs_call(100, 100, 0.05, 0.2, 1), 4))
for steps in (1, 5, 25, 100, 400):
    print(steps, round(european_call_tree(100, 100, 0.05, 0.2, 1, steps), 4))

التنفيذ المبكر

القوة الحقيقية للشجرة هي الخيار الذي لا تسعّره الصيغة: الخيار الأمريكي يمكن تنفيذه في أي وقت. في كل عقدة يقارن حامله بين قيمتين، التوقع المخصوم للاحتفاظ ومدفوع التنفيذ الآن، ويأخذ الأكبر. هذا max الإضافي الوحيد في كل عقدة هو كل التغيير في الخوارزمية. ففي كول على سهم بلا توزيعات لا يفيد التنفيذ المبكر أبدًا، أما في البوت فقد يفيد: فالبوت العميق داخل النقود قيمته نقدًا اليوم أكبر، ولذلك يكلف البوت الأمريكي أكثر من الأوروبي.

# An American put against a European put: the early-exercise premium
import math

def tree(spot, strike, rate, sigma, t, steps, american):
    dt = t / steps
    u = math.exp(sigma * math.sqrt(dt))
    d = 1 / u
    p = (math.exp(rate * dt) - d) / (u - d)
    disc = math.exp(-rate * dt)
    values = [max(strike - spot * u ** j * d ** (steps - j), 0) for j in range(steps + 1)]
    for i in range(steps - 1, -1, -1):
        values = [disc * (p * values[j + 1] + (1 - p) * values[j]) for j in range(i + 1)]
        if american:
            values = [max(values[j], strike - spot * u ** j * d ** (i - j)) for j in range(i + 1)]
    return values[0]

for spot in (80, 100, 120):
    european = tree(spot, 100, 0.05, 0.2, 1, 200, False)
    american = tree(spot, 100, 0.05, 0.2, 1, 200, True)
    print(spot, round(european, 4), round(american, 4), "premium", round(american - european, 4))
البطيء العام أفضل من السريع الخاصفي الخيارات الأوروبية البسيطة تكون الصيغة المغلقة فورية ودقيقة فلا يُستخدم الشجرة أبدًا. وتستحق الشجرة مكانها حين يتضمن المدفوع قرارًا (تنفيذًا مبكرًا) أو حاجزًا أو توزيعًا منفصلًا: تُضاف القاعدة عند كل عقدة. والثمن هو الوقت: n خطوة تكلف نحو n**2 / 2 تحديثًا للعقد، والتقارب ليس سلسًا (يتذبذب الخطأ بحسب وقوع سعر التنفيذ بين العقد)، ولذلك تُفحص الأشجار بمقارنة عدة أعداد من الخطوات.
  • في كل خطوة يصعد السهم بـ u أو يهبط بـ d؛ واختيار CRR أي u = exp(sigma * sqrt(dt)) وd = 1 / u يجعل الشجرة تتحد، فتكون لـn خطوة n + 1 عقدة نهائية.
  • التسعير رجوعًا: المدفوعات عند الانتهاء ثم exp(-rate * dt) * (p * up + (1 - p) * down) لكل عقدة؛ وp احتمال محايد للمخاطر لا توقع.
  • الخطوات الكثيرة تتقارب مع بلاك-شولز؛ والخيار الأمريكي يضيف max(الاستمرار, التنفيذ) لكل عقدة، وهذا سبب وجود الأشجار.

التالي: طرق الفروق المنتهية، التسعير بحل المعادلة التفاضلية الجزئية للخيار على شبكة.

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

  • حدّد حركتي الصعود والهبوط باستخدام crr_parameters25 نقطة
  • اسرد الأسعار عند الانتهاء باستخدام terminal_prices25 نقطة
  • اعمل رجوعًا عبر الشجرة باستخدام european_call_tree25 نقطة
  • اسمح بالتنفيذ المبكر باستخدام american_put_tree25 نقطة
المستكشف · lab-80-1
▾ lab-80-1
…
bash · داخل المتصفح
learner@quantcraft:~/lab-80-1$
لم يتم تحميل Python بعدPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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