σμ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.10·~40 دمبتدئ

النطاق والإغلاقات

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

أين يعيش الاسم

نطاق الاسم هو الجزء من البرنامج الذي يمكن استخدامه فيه. الاسم المُنشأ داخل دالة محلي: يوجد فقط أثناء عمل الدالة ولا يُرى خارجها. أما الاسم المُنشأ في المستوى الأعلى للملف فهو عام: تستطيع الدوال قراءته. عندما تصادف Python اسمًا تبحث أولًا في الدالة، ثم في أي دالة محيطة، ثم في الملف، ثم في الأسماء المدمجة.

rate = 0.001            # global: defined outside any function

def fee(notional):
    minimum = 1.0       # local: exists only during the call
    return max(minimum, notional * rate)

print(fee(36850.0))     # 36.85
# print(minimum)        # would raise NameError: minimum is not defined

الإسناد ينشئ اسمًا محليًا

قراءة اسم عام من داخل دالة أمر لا بأس به. لكن الإسناد إلى اسم داخل دالة ينشئ اسمًا محليًا جديدًا حتى لو وُجد اسم عام بالاسم نفسه: يبقى العام كما هو. هذا يحمي بياناتك، وهو أيضًا سبب أن تغيير حالة عامة من داخل دالة يتطلب كلمات إضافية (global) نادرًا ما تحتاجها. مرّر القيم كوسائط وأعد النتائج بـreturn.

# Assigning inside a function makes a new local name
balance = 1000

def deposit(amount):
    balance = amount     # a different, local balance
    return balance

print(deposit(50))  # 50
print(balance)      # 1000 (the global one is unchanged)

دوال تصنع دوال

يمكن لدالة أن تعرّف دالة أخرى داخلها وتُرجعها بـreturn. تحتفظ الدالة الداخلية بإمكانية الوصول إلى متغيرات الخارجية حتى بعد انتهاء الخارجية. هذه الحزمة المكوّنة من دالة والقيم التي تتذكرها هي الإغلاق (closure). وهي طريقة أنيقة لبناء أداة جاهزة من إعدادات: حاسبة للأسهم وأخرى للصناديق المتداولة.

# A closure remembers the variables of the function that made it
def make_fee_calculator(rate, minimum):
    def fee(notional):
        return max(minimum, notional * rate)
    return fee

stock_fee = make_fee_calculator(0.001, 1.0)
etf_fee = make_fee_calculator(0.0005, 0.5)
print(stock_fee(36850.0))  # 36.85
print(etf_fee(36850.0))    # 18.425

حالة تعيش بين الاستدعاءات: nonlocal

يمكن للإغلاق أيضًا تغيير ما يتذكره. ولأن الإسناد سينشئ اسمًا محليًا جديدًا، تعلن الدالة الداخلية أولًا nonlocal count: «هذا الاسم يتبع الدالة المحيطة». ينشئ كل استدعاء للدالة الخارجية ذاكرته المنفصلة، فلا يتداخل عدّادان أبدًا. بهذه الطريقة يحتفظ مولّد معرّفات الأوامر أو المتوسط المتحرك بحالته دون أي متغير عام.

# nonlocal lets the inner function rebind the outer variable
def make_counter():
    count = 0
    def next_id():
        nonlocal count
        count += 1
        return count
    return next_id

order_ids = make_counter()
print(order_ids(), order_ids(), order_ids())  # 1 2 3
other = make_counter()
print(other())                                # 1 (its own count)
# State between calls: an exponential moving average
def make_ema(alpha):
    value = None
    def update(price):
        nonlocal value
        value = price if value is None else alpha * price + (1 - alpha) * value
        return value
    return update

ema = make_ema(0.5)
print(ema(100.0), ema(110.0), ema(110.0))  # 100.0 105.0 107.5
الإغلاق يحتفظ بالمتغير لا بنسخة منهتبحث الدالة الداخلية عن المتغير حين تعمل، فترى آخر قيمة له. وهذا ما يجعل العدّاد والمتوسط يعملان، وهو أيضًا سبب أن إغلاقًا أُنشئ داخل حلقة يرى القيمة النهائية لمتغير الحلقة ما لم تمرّره كوسيطة أو قيمة افتراضية.
  • داخل الدالة تكون الأسماء التي تسندها محلية؛ مرّر البيانات للداخل وreturn للخارج.
  • الدالة التي تبني دالة وتُرجعها تحوّل الإعدادات إلى أداة.
  • استخدم nonlocal للحالة التي يجب أن تبقى بين الاستدعاءات، ذاكرة واحدة لكل إغلاق.

التالي: اشتقاقات القوائم لبناء قائمة جديدة من أخرى في سطر واحد مقروء.

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

  • ابنِ عدّادًا يتذكر عدّه باستخدام make_counter25 نقطة
  • اجمع إعدادات العمولة في دالة باستخدام make_fee_calculator25 نقطة
  • احتفظ بمتوسط متحرك بين الاستدعاءات باستخدام make_ema25 نقطة
  • أنشئ فحص سعر من حد معيّن باستخدام make_limit_checker25 نقطة
المستكشف · lab-10-1
▾ lab-10-1
…
bash · داخل المتصفح
learner@quantcraft:~/lab-10-1$
لم يتم تحميل Python بعدPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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