اختبار رجعي قائم على الأحداث: محرّك حلقي مع أوامر وقف مبنية على ATR وتحديد لحجم المركز وقائمة صفقات بمضاعفات R
ابنِ في بايثون حلقة اختبار رجعي تمرّ شمعةً شمعة، تحدّد حجم المراكز حسب المخاطرة المبنية على ATR، وتلتزم بأوامر الوقف بما في ذلك الفجوات السعرية، وتسجّل كل صفقة بمضاعفات R.
ما الذي ستتعلمه
- لماذا لا يستطيع الاختبار الرجعي المتّجه نمذجة أوامر الوقف أو التنفيذ الجزئي أو تحديد الحجم القائم على المخاطرة، ومتى تحتاج إلى محرّك حلقي.
- الحالة التي يجب أن يحملها المحرّك القائم على الأحداث من شمعة إلى أخرى: النقد والمركز وسعر الدخول ومستوى الوقف والصفقة المفتوحة.
- كيف تحدّد حجم كل مركز انطلاقًا من مخاطرة الحساب ومؤشر ATR، وكيف تسجّل النتيجة بوصفها مضاعف R.
- كيف تُعالَج الفجوات السعرية التي تتخطى الوقف بنزاهة في الكود.
الشرح
يحسب الاختبار الرجعي المتّجه في الدرس 7 مركز كل شمعة من السلسلة كلها دفعة واحدة. وهو سريع، لكنه لا يستطيع التعبير عن القواعد التي تعتمد على المسار: فالوقف الواقع على بُعد 2 ATR تحت سعر الدخول يعتمد على المكان الذي دخلت منه، والحجم يعتمد على قيمة الحساب في تلك اللحظة. أما الاختبار الرجعي القائم على الأحداث فيمرّ على الشموع واحدة تلو الأخرى، ولا يستخدم إلا المعلومات المتاحة حتى تلك الشمعة، ويحدّث حالته تمامًا كما يفعل المتداول.
الحالة وترتيب الأحداث
يحتفظ المحرّك بمجموعة صغيرة من المتغيرات: cash وposition (عدد الأسهم، 0 عند البقاء خارج السوق) وentry وstop وrisk_per_share وقائمة trades. وفي كل شمعة يكون لترتيب الفحوص أهمية، ويجب تدوينه مرة واحدة والالتزام به:
- الخروج أولًا. إذا كان هناك مركز مفتوح وكان أدنى سعر اليوم عند الوقف أو دونه، فاخرج. سعر التنفيذ هو الوقف، ما لم يكن الافتتاح دون الوقف أصلًا (فجوة سعرية)، وفي هذه الحالة يكون التنفيذ عند الافتتاح. وهنا قد تتحوّل خسارة مخطّطة قدرها 1R إلى 1.4R أو أكثر.
- حدّث أوامر الوقف المتحركة باستخدام إغلاق اليوم ومؤشر ATR.
- الدخول أخيرًا، وفقط عند افتتاح الشمعة التالية، لأن الإشارة المحسوبة من إغلاق اليوم لا يمكن التداول عليها عند إغلاق اليوم. وفي الكود يعني هذا: الإشارة في الشمعة t ترفع علامة، ويحدث التنفيذ عند
open[t+1].
تحديد حجم المركز داخل الحلقة
جرى تدريس تحديد الحجم القائم على المخاطرة في دورة «إدارة المخاطر والصفقات» (الدرس 2) ودورة «التداول المنهجي والاختبار الرجعي» (الدرس 9). وفي الكود هو سطر واحد: size = floor(equity * risk_pct / (entry - stop))، حيث المقام هو المخاطرة لكل سهم (2 * ATR هنا). أضف حدًا أقصى مثل size * entry <= 0.25 * equity كي لا يُنشئ ATR ضئيل جدًا مركزًا لا يستطيع الحساب تحمّله.
تسجيل الصفقات بوحدات R
تُضاف كل صفقة مغلقة في صورة قاموس يتضمن التواريخ والأسعار والحجم والربح باليورو ومضاعف R = الربح / (الحجم × المخاطرة لكل سهم). يحوّل pd.DataFrame(trades) القائمة إلى جدول صفقات لدوال المقاييس في الدرس 9 ولحساب القيمة المتوقعة من دورة «إدارة المخاطر والصفقات» (الدرس 1).
محرّك بالحد الأدنى
def run(df, risk_pct=0.01, atr_mult=2.0, start_cash=20_000):cash, pos, entry, stop, rps = start_cash, 0, None, None, Nonetrades, equity, pending = [], [], Falsefor i in range(1, len(df)):o, h, l, cl, atr = df.open[i], df.high[i], df.low[i], df.close[i], df.atr[i]if pos > 0 and l <= stop: # الخروج: وقف أو فجوة سعريةfill = min(o, stop)pnl = pos * (fill - entry)trades.append(dict(exit=df.index[i], pnl=pnl, R=pnl / (pos * rps)))cash += pos * fill; pos = 0if pending and pos == 0: # الدخول عند افتتاح هذه الشمعةentry, rps = o, atr_mult * df.atr[i-1]pos = int(cash * risk_pct // rps)stop = entry - rps; cash -= pos * entry; pending = Falseif pos == 0 and df.signal[i]:pending = True # التداول عند الافتتاح التاليequity.append(cash + pos * cl)return pd.DataFrame(trades), pd.Series(equity, index=df.index[1:])
تفصيلتان: قيمة ATR المستخدمة لتحديد الحجم هي df.atr[i-1]، أي القيمة المعروفة مساء اليوم السابق للدخول، ويُفحص الوقف مقابل الأدنى لا الإغلاق. والوقف المتحرك سطر إضافي واحد، stop = max(stop, cl - rps)، بعد كتلة الخروج. ويمكن طرح التكاليف من pnl كما في الدرس 7؛ وقد حُذفت هنا من أجل الوضوح.
مثال محلول
مثال افتراضي: رأس المال الابتدائي €20,000، والمخاطرة 1 % لكل صفقة (€200)، والوقف عند 2 × ATR. الأسعار وقيم ATR أرقام مقرّبة مختلَقة؛ والرسوم والفارق السعري والضرائب مستبعدة.
- الصفقة 1. إشارة يوم الاثنين؛ افتتاح الثلاثاء €50.00، وATR السابق €2.50. المخاطرة لكل سهم = 2 × 2.50 = €5.00؛ والوقف = €45.00. الحجم = floor(200 / 5) = 40 سهمًا (انكشاف قدره €2,000، أي 10 % من رأس المال، ضمن حد أقصى قدره 25 %). الخروج لاحقًا بإشارة عند €58.00: الربح = 40 × 8 = €320 = 320 / 200 = +1.6R.
- الصفقة 2. الإعداد نفسه، الدخول €50.00، والوقف €45.00، و40 سهمًا. أخبار خلال الليل: يفتتح السهم عند €43.00. ينفّذ المحرّك عند min(الافتتاح، الوقف) = €43.00. الخسارة = 40 × 7 = €280 = −1.4R، لا −1.0R المخطّطة. كان الاختبار المتّجه سيُظهر −1.0R أو لا شيء على الإطلاق.
- الصفقة 3. الدخول €50.00 مع وقف متحرك؛ وقد ارتفع الوقف إلى €47.50 حين لامسه الأدنى. الخسارة = 40 × 2.50 = €100 = −0.5R.
- قائمة الصفقات. مضاعفات R هي +1.6 و−1.4 و−0.5: المجموع −0.3R، والمتوسط −0.1R. ثلاث صفقات لا تُثبت شيئًا، لكن الجدول له الشكل الصحيح لمئات الصفقات.
أداة ثانية سعرها €120 وATR لها €6 تعطي حجمًا قدره floor(200 / 12) = 16 سهمًا: المخاطرة نفسها البالغة €200، لكن بعدد أسهم أقل لأن التقلب أعلى.
خطأ شائع
if l <= stop: fill = stop يفترض بصمت أن السوق تداول عند وقفك. وفي حالة الفجوة لم يحدث ذلك. استخدم دائمًا min(open, stop) للخروج من مراكز الشراء (وmax(open, stop) لمراكز البيع على المكشوف). وينطبق المنطق نفسه على الدخول بأمر وقف: أمر شراء بالوقف عند €52 يُنفَّذ عند الافتتاح إذا كان الافتتاح €54.نشاط تطبيقي
تتبّع على الورق عمل المحرّك في صفقة واحدة: رأس المال €15,000، والمخاطرة 1.5 %، وATR مساء اليوم السابق للدخول €1.80، ومضاعف الوقف 2.5، والدخول عند الافتتاح التالي €36.00. (أ) احسب المخاطرة لكل سهم ومستوى الوقف وحجم المركز (مقرّبًا إلى الأسفل). (ب) يفتتح يوم الخروج عند €37.00، وينخفض التداول إلى أدنى سعر عند €31.00 ويغلق عند €32.00. ما سعر التنفيذ والربح باليورو ومضاعف R؟ (ج) هل ستختلف النتيجة لو فحصت الوقف مقابل الإغلاق بدلًا من الأدنى؟
عرض الحل
(أ) المخاطرة لكل صفقة = 0.015 × 15,000 = €225. المخاطرة لكل سهم = 2.5 × 1.80 = €4.50. الوقف = 36.00 − 4.50 = €31.50. الحجم = floor(225 / 4.50) = 50 سهمًا.
(ب) الافتتاح €37.00 أعلى من الوقف، فلا توجد فجوة؛ والأدنى €31.00 عند €31.50 أو دونه، لذا يكون التنفيذ عند min(37.00, 31.50) = €31.50. الخسارة = 50 × (31.50 − 36.00) = −€225 = −1.0R.
(ج) فحص الإغلاق (€32.00) كان سيُطلق الخروج هنا أيضًا، لكن عند €32.00 بدلًا من €31.50، فتكون الخسارة €200 (−0.89R) وتبدو أفضل من الواقع. وفي شموع أخرى قد يلامس الأدنى الوقف بينما يتعافى الإغلاق فوقه؛ وعندئذ سيفوّت الفحص القائم على الإغلاق خروجًا حقيقيًا كليًا.
القيود: ترتيب الأعلى والأدنى خلال اليوم مجهول في الشموع اليومية؛ وعندما يقع الوقف والهدف كلاهما داخل شمعة واحدة، افترض النتيجة الأسوأ.
أهم النقاط
- استخدم محرّكًا حلقيًا عندما تعتمد القواعد على المسار: أوامر الوقف، والوقف المتحرك، وتحديد الحجم القائم على المخاطرة، والخروج الجزئي.
- ثبّت ترتيب الأحداث في كل شمعة: الخروج، ثم تحديث أوامر الوقف، ثم الدخول عند الافتتاح التالي.
- حدّد الحجم بقسمة رأس المال × نسبة المخاطرة على المخاطرة لكل سهم، مع حد أقصى للانكشاف؛ وخزّن كل صفقة مع مضاعف R الخاص بها.
- نفّذ الخروج عند الفجوات السعرية بسعر الافتتاح لا بسعر الوقف؛ فمن هنا تأتي الخسائر التي تتجاوز 1R.
الخطوة التالية
يحوّل الدرس 9 منحنى رأس المال وقائمة الصفقات اللذين تنتجهما الآن إلى دوال أداء قابلة لإعادة الاستخدام ومُختبَرة: CAGR والتراجع ونسبة شارب ونسبة سورتينو ومعامل الربح.
تقييم ذاتي
أجب عن الأسئلة، ثم تحقّق من إجاباتك. يمكنك إعادة المحاولة بقدر ما تشاء.
تقييم ذاتي تلقائي لمراجعتك الشخصية. تُفحَص إجاباتك في متصفحك ولا نطّلع عليها ولا نقيّمها. هذا ليس امتحانًا ولا مؤهّلًا.
تقدّمك
«مكتمل» يعني فقط أنك علّمت الدرس كمنتهٍ. وهو ليس اختبارًا لفهمك. يُحفظ التقدّم والملاحظات فقط في هذا المتصفح على هذا الجهاز — وليس في حساب.