المؤشرات في الكود: مؤشرات SMA وEMA وRSI وATR ونطاقات بولينجر بصيغة متّجهة، مع التحقق منها مقابل منصة رسوم بيانية
اكتب دوال pandas متّجهة للمؤشرات الخمسة الأكثر استخدامًا، وتعلّم لماذا قد تختلف قيمها عن منصة الرسوم البيانية وكيف توفّق بينها.
ما الذي ستتعلمه
- كيف تنفّذ
rollingوewmكلًّا من SMA وEMA وتنعيم وايلدر وATR ونطاقات بولينجر في بضعة أسطر لكل منها. - أي المعاملات (
adjustوalphaوddof) تغيّر الأرقام بصمت. - لماذا يختلف مؤشر RSI أو EMA لديك عن منصة الرسوم البيانية في الشموع الأولى، وكيف تقارن بينهما بشكل صحيح.
- كيف تنظّم المؤشرات في صورة دوال نقية داخل
src/indicators.pyلإعادة استخدامها واختبارها.
الشرح
شرحت دورة «التحليل الفني المتعمّق» معنى هذه المؤشرات؛ أما الهدف هنا فهو كود صحيح وسريع وقابل للاختبار. تأخذ كل دالة سلسلة Series وتعيد سلسلة Series على الفهرس نفسه.
SMA (المتوسط المتحرك البسيط): def sma(s, n): return s.rolling(n).mean().
EMA (المتوسط المتحرك الأسي): def ema(s, n): return s.ewm(span=n, adjust=False).mean(). مع span=n يكون ثابت التنعيم α = 2 ÷ (n + 1)؛ فلـ n = 20 تكون α = 0.0952. يعطي adjust=False الصيغة التكرارية EMAt = α × Pt + (1 − α) × EMAt−1 التي تستخدمها المنصات؛ أما القيمة الافتراضية adjust=True فتوزّع الأوزان بشكل مختلف في بضع عشرات من الشموع الأولى. يبدأ pandas بأول سعر كقيمة ابتدائية؛ بينما تبدأ معظم المنصات بمتوسط SMA لأول n شمعة. وكلتا القيمتين الابتدائيتين يتلاشى أثرهما؛ فبعد نحو 3n شمعة تتقارب السلسلتان كثيرًا.
RSI (مؤشر القوة النسبية)، نسخة وايلدر:
delta = s.diff()
gain = delta.clip(lower=0); loss = -delta.clip(upper=0)
avg_gain = gain.ewm(alpha=1/n, adjust=False).mean()
avg_loss = loss.ewm(alpha=1/n, adjust=False).mean()
rsi = 100 - 100 / (1 + avg_gain / avg_loss)
تنعيم وايلدر متوسط أسي بقيمة α = 1 ÷ n، لا 2 ÷ (n + 1)؛ واستخدام span=14 هنا هو أشيع أخطاء RSI. وعندما يكون avg_loss صفرًا، يصبح RSI عن حق مساويًا لـ 100.
ATR (متوسط المدى الحقيقي): المدى الحقيقي هو الأكبر بين الأعلى − الأدنى، و|الأعلى − الإغلاق السابق|، و|الأدنى − الإغلاق السابق|:
pc = close.shift(1)
tr = pd.concat([high - low, (high - pc).abs(), (low - pc).abs()], axis=1).max(axis=1)
atr = tr.ewm(alpha=1/n, adjust=False).mean()
تعرض بعض المنصات بدلًا من ذلك ATR قائمًا على SMA؛ تحقّق من ذلك قبل المقارنة. يستخدم الدرس 8 مؤشر ATR لأوامر الوقف وتحديد الحجم.
نطاقات بولينجر: الأوسط = SMA(n)، والعلوي والسفلي = الأوسط ± k × الانحراف المعياري على الشموع n نفسها، وعادةً n = 20 وk = 2. الفخّ هنا هو ddof: إذ يقسم rolling(n).std() في pandas على n − 1 (العيّنة)، بينما تقسم المنصات عادةً على n (المجتمع الإحصائي). اكتب std(ddof=0) للمطابقة. قيمة العيّنة أكبر، بما يكفي لتحويل «ملامسة» النطاق إلى «عدم ملامسة».
التحقق مقابل منصة. استخدم السلسلة المعدّلة نفسها التي تستخدمها المنصة، واحسب مؤشرك، وقارن آخر 100 قيمة، لأن فروق القيم الابتدائية تتلاشى. استخدم np.allclose مع هامش تسامح صغير. وتنشأ الفروق المستمرة من خمسة مصادر معتادة: البيانات المعدّلة مقابل غير المعدّلة، أو القيمة الابتدائية، أو span مقابل alpha، أو ddof، أو سعر مدخل مختلف. أصلح عدم التطابق أو وثّقه؛ ولا «تضبط» أي معامل أبدًا حتى تتفق الأرقام.
مثال محلول
مثال افتراضي: عشرة أسعار إغلاق يومية باليورو: 20.00، 20.50، 21.00، 20.80، 21.40، 21.00، 21.60، 22.00، 21.80، 22.40.
SMA(5) على الشمعة الأخيرة: (21.00 + 21.60 + 22.00 + 21.80 + 22.40) ÷ 5 = 108.80 ÷ 5 = €21.76.
بولينجر(5، 2) على الشمعة الأخيرة. الانحرافات عن 21.76: −0.76، −0.16، 0.24، 0.04، 0.64؛ ومجموع مربعاتها 1.0720. تباين المجتمع = 1.0720 ÷ 5 = 0.2144، والانحراف المعياري 0.4630، والعلوي = 21.76 + 2 × 0.4630 = €22.69، والسفلي €20.83. صيغة العيّنة: 1.0720 ÷ 4 = 0.2680، والانحراف المعياري 0.5177، والعلوي €22.80، والسفلي €20.72.
EMA(5) مع α = 2 ÷ 6 = 0.3333 وadjust=False: EMA1 = 20.00 (القيمة الابتدائية)، EMA2 = 0.3333 × 20.50 + 0.6667 × 20.00 = 20.1667، EMA3 = 0.3333 × 21.00 + 0.6667 × 20.1667 = 20.4444، وهكذا حتى 21.8310 على الشمعة الأخيرة.
المدى الحقيقي لشمعة أعلاها €21.20 وأدناها €20.60 وإغلاقها السابق €20.80: max(0.60, |21.20 − 20.80| = 0.40, |20.60 − 20.80| = 0.20) = €0.60.
خطأ شائع
ewm(span=14) القيمة α = 2 ÷ 15 = 0.133، بينما يحتاج RSI وATR وفق وايلدر إلى ewm(alpha=1/14)، أي α = 0.0714. تتفاعل نسخة span بسرعة تقارب الضعف، ولن تطابق أي منصة معيارية. اكتب قيمة α التي تقصدها صراحةً وسجّلها في سلسلة توثيق الدالة.نشاط تطبيقي
على الورق، باستخدام RSI وايلدر لثلاث فترات لأغراض التوضيح فقط (الاستخدام الفعلي 14): أسعار الإغلاق 50.00، 50.50، 51.00، 50.80. (أ) اذكر المكاسب والخسائر لكل شمعة. (ب) يبدأ ewm(alpha=1/3, adjust=False) في pandas بالمشاهدة الأولى كقيمة ابتدائية؛ احسب avg_gain وavg_loss على الشمعة الأخيرة ثم RSI. (ج) اشرح في جملة واحدة لماذا قد تُظهر منصةٌ تبدأ بالمتوسط البسيط لأول ثلاثة تغيرات قيمةً مختلفة هنا، وما الذي ستفعله قبل أن تستنتج أن كودك خاطئ.
عرض الحل
(أ) التغيرات: +0.50، +0.50، −0.20. المكاسب: 0.50، 0.50، 0.00. الخسائر: 0.00، 0.00، 0.20.
(ب) α = 1/3. avg_gain: 0.50 (القيمة الابتدائية) ← (1/3)(0.50) + (2/3)(0.50) = 0.50 ← (1/3)(0) + (2/3)(0.50) = 0.3333. avg_loss: 0 ← 0 ← (1/3)(0.20) + (2/3)(0) = 0.0667. RS = 0.3333 ÷ 0.0667 = 5.0؛ RSI = 100 − 100 ÷ (1 + 5) = 83.33.
(ج) هنا تصادف أن القيمة الابتدائية بالمتوسط البسيط (مكاسب 0.3333، وخسائر 0.0667) تعطي القيمة نفسها 83.33، لكن القيمتين الابتدائيتين تختلفان عمومًا في بضع عشرات من الشموع الأولى، لذا قارن آخر 100 قيمة من سلسلة طويلة قبل أن تمسّ الكود.
القيود: مؤشر RSI لثلاث فترات أداة تعليمية؛ وأربع شموع لا يمكنها إظهار سلوك التقارب الذي يهمّ في الممارسة العملية.
أهم النقاط
- SMA هو
rolling(n).mean()؛ وEMA هوewm(span=n, adjust=False)؛ وتنعيم وايلدر لمؤشري RSI وATR هوewm(alpha=1/n, adjust=False). - تستخدم نطاقات بولينجر في معظم المنصات الانحراف المعياري للمجتمع: مرّر
ddof=0. - تتلاشى فروق القيم الابتدائية؛ قارن آخر 100 شمعة مع هامش تسامح، وابحث عن الأسباب الخمسة المعتادة لعدم التطابق قبل تغيير الكود.
- احتفظ بالمؤشرات في صورة دوال نقية موثّقة كي يمكن كتابة اختبارات وحدة لها وإعادة استخدامها في كل اختبار رجعي.
الخطوة التالية
يجمع الدرس 7 القطع في اختبار رجعي متّجه: الإشارات والمراكز والإزاحة التي تمنع انحياز الاستباق وتكاليف المعاملات ومنحنى رأس المال.
تقييم ذاتي
أجب عن الأسئلة، ثم تحقّق من إجاباتك. يمكنك إعادة المحاولة بقدر ما تشاء.
تقييم ذاتي تلقائي لمراجعتك الشخصية. تُفحَص إجاباتك في متصفحك ولا نطّلع عليها ولا نقيّمها. هذا ليس امتحانًا ولا مؤهّلًا.
تقدّمك
«مكتمل» يعني فقط أنك علّمت الدرس كمنتهٍ. وهو ليس اختبارًا لفهمك. يُحفظ التقدّم والملاحظات فقط في هذا المتصفح على هذا الجهاز — وليس في حساب.