σμ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›الوحدة 1 · أساسيات Python للمحللين الكميين›الموضوع 1.29·~40 دمبتدئ

المشتقات بالشيفرة

الموضع في المسارالوحدة 1 من 11 · الموضوع 29 من 33
1.29 المشتقات بالشيفرة
—درجة المختبر— / 100إجمالي XP—التتابع—

ما سرعة تغيّره؟

المشتقة لدالة f عند x هي معدل تغيّرها اللحظي: ميل المنحنى عند تلك النقطة. وفي المالية تكاد كل حساسية تكون مشتقة. فـدلتا الخيار هي مقدار تحرك سعره لكل وحدة تحرك في الأصل الأساسي، وغاما هي سرعة تغيّر دلتا نفسها، ومدة السند مشتقة للسعر بالنسبة إلى العائد. يعطي التفاضل صيغًا دقيقة للدوال البسيطة (مشتقة x**2 هي 2*x)، لكن دوال التسعير الحقيقية كثيرًا ما تكون معقدة جدًا أو متاحة ككود فقط. عندها نقدّر المشتقة عدديًا.

# A function is just a Python function
def f(x):
    return x * x

# Slope between two nearby points approaches the true slope (2x = 6 at x = 3)
x = 3.0
for h in (1.0, 0.1, 0.001):
    slope = (f(x + h) - f(x)) / h
    print(h, round(slope, 4))
# 1.0 7.0
# 0.1 6.1
# 0.001 6.001

الفروق المنتهية: الأمامية والمركزية

تنظر الفروق الأمامية خطوة صغيرة h إلى الأمام: (f(x + h) - f(x)) / h. ويتناقص خطؤها بالتناسب مع h. وتنظر الفروق المركزية خطوة في كل اتجاه: (f(x + h) - f(x - h)) / (2 * h). فتتلاشى أخطاء الجانبين، ويتناقص خطؤها كمربع h وهي دقيقة تمامًا للدوال التربيعية. وتجمع المشتقة الثانية (غاما) ثلاث نقاط: (f(x + h) - 2 * f(x) + f(x - h)) / h**2. مرّر الدالة نفسها وسيطًا (f)، وهي مهارة من موضوعات الدوال.

import math

def forward_diff(f, x, h=1e-6):
    return (f(x + h) - f(x)) / h

def central_diff(f, x, h=1e-5):
    return (f(x + h) - f(x - h)) / (2 * h)

def second_derivative(f, x, h=1e-4):
    return (f(x + h) - 2 * f(x) + f(x - h)) / h**2

print(round(central_diff(math.sin, 0.0), 6))            # 1.0  (cos 0)
print(round(central_diff(lambda x: x**3, 2.0), 4))      # 12.0 (3 x^2)
print(round(second_derivative(lambda x: x**3, 2.0), 3)) # 12.0 (6 x)

# A quadratic: central is exact even for a big step, forward is not
print(central_diff(lambda x: x * x, 3.0, h=0.5))  # 6.0
print(forward_diff(lambda x: x * x, 3.0, h=0.5))  # 6.5

اختيار حجم الخطوة

يقلّل h الأصغر خطأ البتر في الصيغة، لكن طرح عددين متقاربين جدًا يُضيّع أرقامًا: ويكبر خطأ التقريب هذا كلما صغر h، وفي المشتقة الثانية يكبر أسرع لأننا نقسم أيضًا على h**2. وقد يعطي h صغير جدًا (مثل 1e-12) نتائج لا قيمة لها. التوفيق الجيد نحو 1e-5 للمشتقات الأولى بالفروق المركزية ونحو 1e-4 للثانية. وفي كود التسعير الفعلي، «ارفع وأعد التسعير» (bump and reprice) هو هذا بالضبط: أعد تشغيل المسعّر بسعر فوري مرفوع ومخفوض بمقدار صغير.

import math

def central_diff(f, x, h):
    return (f(x + h) - f(x - h)) / (2 * h)

# True derivative of exp at 0 is 1; watch the error as h shrinks
for h in (1e-1, 1e-3, 1e-5, 1e-8, 1e-12):
    error = abs(central_diff(math.exp, 0.0, h) - 1.0)
    print(f"h={h:g} error={error:.1e}")
# h=0.1 error=1.7e-03
# h=0.001 error=1.7e-07
# h=1e-05 error=1.2e-11
# h=1e-08 error=5.3e-10     (rounding error takes over)
# h=1e-12 error=3.3e-05     (much worse: too small)

استخدام المشتقات: طريقة نيوتن

تدلك المشتقة على الاتجاه الذي تتحرك فيه لبلوغ جذر، وهو نقطة f(x) = 0. تبدأ طريقة نيوتن من تخمين x وتستبدله مرارًا بـx - f(x) / f'(x) متتبعةً المماس نزولًا إلى الصفر. وتتقارب بسرعة كبيرة قرب الجذر، ولهذا تُستخدم لاستخلاص التقلب الضمني من سعر خيار. توقف حين تهبط abs(f(x)) دون تفاوت مسموح، واستسلم بعد عدد أقصى من التكرارات، وارفع خطأً إذا كانت المشتقة صفرًا أو لم تتقارب الحلقة بدل إرجاع رقم خاطئ.

def central_diff(f, x, h=1e-5):
    return (f(x + h) - f(x - h)) / (2 * h)

def newton_root(f, x0, tol=1e-10, max_iter=50):
    x = x0
    for _ in range(max_iter):
        if abs(f(x)) < tol:
            return x
        slope = central_diff(f, x)
        if slope == 0:
            raise ValueError("flat slope: Newton cannot continue")
        x = x - f(x) / slope
    raise ValueError("did not converge")

# The square root of 2 is the positive root of x^2 - 2
root = newton_root(lambda x: x * x - 2, 1.0)
print(round(root, 8))           # 1.41421356

# x^2 + 1 never reaches zero
try:
    newton_root(lambda x: x * x + 1, 1.0)
except ValueError:
    print("no root found")      # no root found
دقيق متى أمكن وعددي عند الضرورةإذا كنت تعرف صيغة المشتقة فاستخدمها: فهي أسرع وأدق. والمشتقات العددية للدوال التي لا تستطيع أو لا تريد اشتقاقها يدويًا، وهي دائمًا فيها قدر من الضجيج، فقارنها بحالة معروفة الجواب (مثل x**2 أو sin) قبل الاعتماد عليها في مسعّر. وتوفر مكتبات مثل numpy وscipy نسخًا مُختبَرة؛ ومعرفة كيف تعمل تخبرك متى تثق بها.
  • الأمامية (f(x+h) - f(x)) / h؛ المركزية (f(x+h) - f(x-h)) / (2h)؛ الثانية (f(x+h) - 2f(x) + f(x-h)) / h**2.
  • لا كبيرًا جدًا ولا صغيرًا جدًا: نحو 1e-5 للمشتقات الأولى و1e-4 للثانية.
  • نيوتن: x = x - f(x) / f'(x) حتى تصبح abs(f(x)) ضئيلة؛ وارفع خطأً إن لم تتقارب.

التالي: التكاملات في الكود، جمع شرائح رفيعة كثيرة لإيجاد المساحات والمجاميع والقيم المتوقعة.

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

  • قدّر ميلًا بالنظر إلى الأمام باستخدام forward_diff25 نقطة
  • قدّر ميلًا من الجانبين باستخدام central_diff25 نقطة
  • قدّر الانحناء (غاما) باستخدام second_derivative25 نقطة
  • اعثر على موضع انعدام دالة باستخدام newton_root25 نقطة
المستكشف · lab-29-1
▾ lab-29-1
…
bash · داخل المتصفح
learner@quantcraft:~/lab-29-1$
لم يتم تحميل Python بعدPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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