σμ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›الوحدة 2 · NumPy وpandas لبيانات السوق›الموضوع 2.11·~35 دمتوسط

العوائد اللوغاريتمية

الموضع في المسارالوحدة 2 من 11 · الموضوع 11 من 20
2.11 العوائد اللوغاريتمية
—درجة المختبر— / 100إجمالي XP—التتابع—

لوغاريتم نسبة السعرين

العائد اللوغاريتمي هو اللوغاريتم الطبيعي لنسبة سعرين. وبدل P_t / P_{t-1} - 1 تحسب ln(P_t / P_{t-1}). وفي الحركات الصغيرة يتقارب الاثنان (ارتفاع 2% يساوي 0.0198 باللوغاريتم)، لكن للنسخة اللوغاريتمية خصائص تجعلها الخيار المعياري في الإحصاء والنمذجة. في pandas خذ لوغاريتم سلسلة الأسعار كلها بـ np.log ثم طبّق diff: فطرح اللوغاريتمات هو قسمة الأسعار.

r_t = ln(P_t / P_{t-1}) = ln(P_t) - ln(P_{t-1})
import numpy as np
import pandas as pd

prices = pd.Series([100.0, 102.0, 100.98, 103.0], index=["Mon", "Tue", "Wed", "Thu"])

log_ret = np.log(prices).diff()
print(log_ret.round(4))
# Mon       NaN
# Tue    0.0198
# Wed   -0.0101
# Thu    0.0198
# dtype: float64

print(prices.pct_change().round(4).tolist())   # [nan, 0.02, -0.01, 0.02]   the simple returns, for comparison

العوائد اللوغاريتمية تُجمع عبر الزمن

هذا هو السبب الرئيسي لاستخدامها. فبما أن ln(a) - ln(c) = (ln(a) - ln(b)) + (ln(b) - ln(c)) فإن العائد اللوغاريتمي على عدة فترات هو ببساطة مجموع عوائد الفترات دون تراكب. عائد اليومين مجموع عائدين يوميين، والعائد الشهري مجموع اليوميّ منها، ويعيد exp(total) - 1 النتيجة إلى عائد بسيط. والعوائد اللوغاريتمية متماثلة أيضًا: سعر يتضاعف ثم ينصّف عائداه اللوغاريتميان +0.6931 و-0.6931 فيتلاشيان، بينما كانت العوائد البسيطة +100% و-50%.

# The sum of the daily log returns is the log return over the whole period
print(round(log_ret.sum(), 6))                         # 0.029559
print(round(np.log(prices.iloc[-1] / prices.iloc[0]), 6))   # 0.029559   end price over start price

# exp(total) - 1 is the simple return of the whole period
print(round(np.exp(log_ret.sum()) - 1, 6))             # 0.03
# Symmetry: the price doubles, then halves
doubling = pd.Series([100.0, 200.0, 100.0])
print(doubling.pct_change().tolist())               # [nan, 1.0, -0.5]
print(np.log(doubling).diff().round(4).tolist())    # [nan, 0.6931, -0.6931]

التحويل والحركات على عدة أيام

للعودة إلى عائد بسيط استخدم np.exp(r) - 1 (أو np.expm1(r) الأدق مع القيم الصغيرة جدًا). يتفق الاثنان في الحركات الصغيرة ويتباعدان في الكبيرة: عائد بسيط +50% يساوي 0.4055 باللوغاريتم. وتعمل np.log وnp.exp على Series كاملة فلا حاجة إلى حلقة. ولقياس حركة على عدة أيام يقبل diff عدد الفترات: np.log(prices).diff(5) هو العائد اللوغاريتمي على خمسة أيام، ويساوي مجموع خمسة عوائد لوغاريتمية يومية.

# Small moves agree with the simple return, big moves do not
for simple in [0.01, 0.1, 0.5, -0.5]:
    print(simple, round(np.log1p(simple), 4))   # log1p(r) is ln(1 + r)
# 0.01 0.01
# 0.1 0.0953
# 0.5 0.4055
# -0.5 -0.6931

# Back to simple returns, on the whole Series at once
print((np.exp(log_ret) - 1).round(4).tolist())   # [nan, 0.02, -0.01, 0.02]

# The log return over 2 days: diff takes a number of periods
print(np.log(prices).diff(2).round(4).tolist())   # [nan, nan, 0.0098, 0.0098]
اجمعها عبر الزمن لا عبر الأصولتُجمع العوائد اللوغاريتمية عبر الفترات، لكن عائد المحفظة هو المجموع المرجّح لعوائد أصولها البسيطة. مركزان متساويان بعائدين لوغاريتميين +10% و-10% لا يعطيان محفظة بعائد 0%: فبالقيم البسيطة هما +10.5% و-9.5% فتربح المحفظة +0.5%. حوّل أولًا إلى عوائد بسيطة ثم رجّحها ثم أعد التحويل إن أردت اللوغاريتم.
  • العائد اللوغاريتمي هو ln(السعر / السعر السابق): np.log(prices).diff()؛ والعنصر الأول NaN.
  • عبر الزمن تُجمع ببساطة: log_ret.sum()، ويعطي np.exp(total) - 1 العائد البسيط.
  • يعطي diff(k) الحركة على k فترة؛ وعبر الأصول رجّح العوائد البسيطة لا اللوغاريتمية.

التالي: DatetimeIndex والفهرسة الزمنية، لإعطاء سلسلة الأسعار تواريخ حقيقية وتقطيعها حسب الشهر أو يوم الأسبوع.

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

  • حوّل الأسعار إلى عوائد لوغاريتمية باستخدام log_returns25 نقطة
  • حوّل العوائد اللوغاريتمية إلى بسيطة باستخدام simple_from_log25 نقطة
  • اجمع العوائد اللوغاريتمية للفترات باستخدام total_log_return25 نقطة
  • قِس الحركة على عدة أيام باستخدام multi_day_log_return25 نقطة
المستكشف · lab-44-1
▾ lab-44-1
…
bash · داخل المتصفح
learner@quantcraft:~/lab-44-1$
لم يتم تحميل Python بعدPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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