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