العوائد في الكود: العوائد البسيطة مقابل اللوغاريتمية والعوائد التراكمية والعائد والتقلب السنويان والنوافذ المتحركة
احسب العوائد البسيطة واللوغاريتمية في pandas، وركّبها بشكل صحيح، وحوّل العائد والتقلب إلى قيم سنوية، وابنِ إحصاءات متحركة.
ما الذي ستتعلمه
- كيف تحسب العوائد البسيطة واللوغاريتمية من سلسلة أسعار الإغلاق، ومتى تكون كل منها الأداة المناسبة.
- لماذا يجب تركيب العوائد البسيطة بحاصل الضرب بينما تُجمع العوائد اللوغاريتمية ببساطة.
- كيف تحوّل متوسط العائد اليومي والانحراف المعياري اليومي إلى قيم سنوية، وما الذي تفترضه قاعدة الجذر التربيعي للزمن.
- كيف تُنتج النوافذ المتحركة إحصاءات متغيرة بمرور الوقت مثل التقلب لمدة 20 يومًا، ولماذا تكون الصفوف الأولى فارغة.
الشرح
العائد البسيط هو التغيّر النسبي المئوي في السعر، rt = (Pt − Pt−1) ÷ Pt−1، وفي pandas: r = df["close"].pct_change(). أما العائد اللوغاريتمي فهو اللوغاريتم الطبيعي لنسبة السعرين، ℓt = ln(Pt ÷ Pt−1)، وفي الكود: np.log(df["close"]).diff(). وكلاهما يبدأ بقيمة NaN. في التحركات الصغيرة يكاد الاثنان يتطابقان؛ أما في التحركات الكبيرة فيتباعدان (العائد البسيط −50% يساوي عائدًا لوغاريتميًا قدره −69.3%).
التركيب. عبر عدة فترات، تُضرب العوائد البسيطة: الإجمالي = (1 + r1)(1 + r2)…(1 + rn) − 1. أما العوائد اللوغاريتمية فتُجمع: إجمالي العائد اللوغاريتمي = ℓ1 + ℓ2 + … + ℓn، والتحويل العكسي يعطي إجمالي العائد البسيط = exp(المجموع) − 1. جمع العوائد البسيطة خطأ، ويكبر الخطأ مع التقلب: فـ +10% تليها −10% مجموعهما 0%، لكنهما في الواقع تتركان −1%. سلسلة العائد التراكمي هي (1 + r).cumprod() − 1؛ ومنحنى رأس المال انطلاقًا من €10,000 هو 10_000 * (1 + r).cumprod()؛ ومع العوائد اللوغاريتمية: np.exp(lr.cumsum()).
متى تستخدم أيًّا منهما. العوائد اللوغاريتمية للتجميع عبر الزمن وللإحصاءات؛ والعوائد البسيطة كلما انتقل المال من يد إلى يد أو جُمعت الأصول معًا، لأن عائد المحفظة مجموع مرجّح للعوائد البسيطة. وعند عرض النتائج على الناس استخدم النسب المئوية البسيطة.
التحويل إلى قيم سنوية. يفترض العُرف وجود 252 يوم تداول في السنة للأسهم (يختلف العدد الحقيقي قليلًا حسب البورصة والسنة؛ اذكر العُرف الذي تستخدمه). متوسط العائد اليومي × 252 هو العائد السنوي الحسابي، وCAGR (معدل النمو السنوي المركب، المعرَّف في دورة «التداول المنهجي والاختبار الرجعي») هو (النهائي ÷ الابتدائي)1 ÷ السنوات − 1، وهو ما ينبغي أن تذكره لأي اختبار رجعي. أما التقلب فهو الانحراف المعياري للعوائد؛ ويتناسب مع الجذر التربيعي للزمن، لذا فإن التقلب السنوي ≈ الانحراف المعياري اليومي × √252 ≈ اليومي × 15.87. وللبيانات الشهرية استخدم 12 و√12، وللأسبوعية 52 و√52. تفترض قاعدة الجذر التربيعي استقلال العوائد، وهو ما تخالفه السلاسل ذات الاتجاه؛ فتعامل معها بوصفها عُرفًا.
النوافذ المتحركة. يعطي r.rolling(20).std() * np.sqrt(252) التقلب السنوي لآخر 20 يومًا، ويُعاد حسابه في كل صف. تكون أول 19 صفًا NaN لأن النافذة لم تكتمل بعد (يمكن لـ min_periods تخفيف ذلك). ويستخدم expanding() جميع البيانات حتى كل صف (الحد الأقصى الجاري لرأس المال لحساب التراجع في الدرس 9). وكلاهما ينظر إلى الخلف فقط، لذا فهما خاليان من انحياز الاستباق بحكم بنائهما.
مثال محلول
مثال افتراضي: أربعة أسعار إغلاق لسهم، €100.00 و€105.00 و€100.80 و€105.84؛ دون تكاليف أو توزيعات أو ضرائب.
العوائد البسيطة: (105 − 100) ÷ 100 = +5.00%؛ (100.80 − 105) ÷ 105 = −4.00%؛ (105.84 − 100.80) ÷ 100.80 = +5.00%.
العوائد اللوغاريتمية: ln(1.05) = 0.04879؛ ln(0.96) = −0.04082؛ ln(1.05) = 0.04879. المجموع = 0.05676. exp(0.05676) − 1 = 0.0584، أي +5.84%.
التحقق: 1.05 × 0.96 × 1.05 = 1.0584 ← +5.84%، و105.84 ÷ 100 − 1 = 5.84%. أما جمع العوائد البسيطة فسيعطي 6.00%، أي مبالغة بمقدار 0.16 نقطة في ثلاثة أيام: تصبح €10,000 مبلغ €10,584 لا €10,600.
الكود: يعيد r = c.pct_change(); total = (1 + r.dropna()).prod() - 1 القيمة 0.0584. ويضع r.rolling(3).mean() القيمة (0.05 − 0.04 + 0.05) ÷ 3 = 2.00% في الصف الأخير وNaN قبله.
تحويل عيّنة افتراضية أطول إلى قيم سنوية: إذا كان متوسط العوائد اليومية 0.04% وانحرافها المعياري 1.2%، فإن العائد السنوي الحسابي هو 0.0004 × 252 = 10.08%، والتقلب السنوي هو 0.012 × 15.87 = 19.05%.
خطأ شائع
r.sum() بوصفه عائد الفترة. وهذا يتجاهل التركيب ويبالغ في النتائج في السلاسل المتقلبة، وبصورة هائلة في المنتجات ذات الرافعة المالية. استخدم (1 + r).prod() − 1 للعوائد البسيطة، أو اجمع العوائد اللوغاريتمية ثم طبّق الدالة الأسية.نشاط تطبيقي
على الورق: أسعار إغلاق €50.00 و€48.00 و€50.40 و€49.392 (افتراضية). (أ) احسب العوائد البسيطة الثلاثة. (ب) احسب العوائد اللوغاريتمية الثلاثة باستخدام ln(0.96) = −0.04082 وln(1.05) = 0.04879 وln(0.98) = −0.02020. (ج) أعطِ العائد الإجمالي بالتركيب وبجمع اللوغاريتمات، وقارنه بالجمع الساذج للعوائد البسيطة. (د) إذا أظهرت سلسلة أخرى انحرافًا معياريًا يوميًا قدره 1.5%، فاذكر تقلبها السنوي باستخدام 252 يومًا، واشرح لماذا يكون الضرب في 252 خطأً.
عرض الحل
(أ) 48 ÷ 50 − 1 = −4.00%؛ 50.40 ÷ 48 − 1 = +5.00%؛ 49.392 ÷ 50.40 − 1 = −2.00%.
(ب) −0.04082، +0.04879، −0.02020؛ المجموع = −0.01223.
(ج) بالتركيب: 0.96 × 1.05 × 0.98 = 0.98784 ← −1.216%. ومن اللوغاريتمات: exp(−0.01223) − 1 = −1.216%، ويؤكّد ذلك 49.392 ÷ 50 − 1 = −1.216%. أما الجمع الساذج فيعطي −4 + 5 − 2 = −1.00%، وهو ما يقلّل من حجم الخسارة.
(د) التقلب السنوي = 1.5% × √252 = 1.5% × 15.87 = 23.8%. أما الضرب في 252 فسيعطي 378%، وهذا خلط بين قاعدة تحجيم المتوسطات (خطية مع الزمن) وقاعدة تحجيم الانحرافات المعيارية (الجذر التربيعي للزمن).
القيود: تفترض قاعدة √252 استقلال العوائد اليومية؛ أما السلاسل الحقيقية ذات الارتباط الذاتي فلها تقلب سنوي حقيقي مختلف.
أهم النقاط
- يعطي
pct_change()العوائد البسيطة، ويعطيnp.log(c).diff()العوائد اللوغاريتمية؛ وكلاهما يتركNaNفي الصف الأول. - ركّب العوائد البسيطة بحاصل الضرب؛ واجمع العوائد اللوغاريتمية ثم طبّق الدالة الأسية؛ ولا تجمع العوائد البسيطة أبدًا.
- حوّل المتوسطات إلى قيم سنوية بـ × 252 والانحرافات المعيارية بـ × √252، واذكر العُرف المستخدم، واعرض CAGR في الاختبارات الرجعية.
- النوافذ المتحركة والمتوسّعة تنظر إلى الخلف فقط، وتُنتج
NaNحتى تكتمل، وتستخدم الانحراف المعياري للعيّنة افتراضيًا.
الخطوة التالية
يبرمج الدرس 6 المؤشرات المعيارية في صورة دوال متّجهة، وهي SMA وEMA وRSI وATR ونطاقات بولينجر، ويبيّن كيف تتحقق منها مقابل منصة رسوم بيانية.
تقييم ذاتي
أجب عن الأسئلة، ثم تحقّق من إجاباتك. يمكنك إعادة المحاولة بقدر ما تشاء.
تقييم ذاتي تلقائي لمراجعتك الشخصية. تُفحَص إجاباتك في متصفحك ولا نطّلع عليها ولا نقيّمها. هذا ليس امتحانًا ولا مؤهّلًا.
تقدّمك
«مكتمل» يعني فقط أنك علّمت الدرس كمنتهٍ. وهو ليس اختبارًا لفهمك. يُحفظ التقدّم والملاحظات فقط في هذا المتصفح على هذا الجهاز — وليس في حساب.