قواطع حماية روبوتات التداول
تعرّف إلى قواطع التداول التي توقف الروبوت قبل تفاقم الخسائر، وكيف يُفعّل حد الخسارة اليومية وما الذي يغيّره ضبط التقلب في حجم المركز، مع أمثلة عملية.
قواطع التداول الآلية هي قواعد توقف الاستراتيجية المؤتمتة عن إرسال الأوامر عند بلوغ حد محدد. تعمل هذه القواطع ضمن طبقة لإدارة المخاطر بين الاستراتيجية والوسيط، وتُطبَّق على كل أمر، سواء وافقت الاستراتيجية أم لا. تحدد الاستراتيجية ما الذي سيجري تداوله. أما طبقة المخاطر فتحدد ما إذا كان التداول سيجري أصلاً.
هذا الفصل هو جوهر التصميم. فالاستراتيجية التي تراقب نفسها لا تخضع لفحص مستقل عندما تنهار افتراضاتها، مع أن تلك هي اللحظة التي تصبح فيها الحاجة إلى الفحص أكبر.
ما الذي يفعله قاطع الخسائر في روبوت التداول
تتألف طبقة إدارة المخاطر من أربعة أجزاء، ويهدف كل جزء منها إلى منع إخفاق محدد ورتيب.
- حدود قصوى صارمة لحجم المركز، والتعرض الاسمي لكل رمز، ومعدل إرسال الأوامر. وهي تحد من الخسائر التي قد يتسبب فيها خلل كان سيجعلها بلا سقف.
- قاطع خسائر للسحب يوقف إرسال الأوامر الجديدة عندما ينخفض رصيد الحساب بمقدار محدد خلال الجلسة، أو عندما يتراجع بمقدار محدد عن ذروة حقوق الملكية.
- تحديد حجم الأوامر بصورة متدرجة استناداً إلى التقلبات الأخيرة أو إلى جزء من رهان Kelly، بدلاً من اعتماد عدد ثابت من الأسهم. ويحافظ ذلك على ثبات مخاطر الصفقة تقريباً بينما يتغير نطاق حركة السوق.
- سجل تدقيق للإضافة فقط يوثّق كل قرار، بما في ذلك الأوامر التي رفضتها طبقة إدارة المخاطر. وهو السجل الوحيد الذي يميز بين «كانت الاستراتيجية خاطئة» و«لم يُنفَّذ الفحص أصلاً».
كل ما يرد أدناه هو تطبيق عملي لأحد هذه الأجزاء الأربعة.
ما الحد اليومي المعقول للخسارة في روبوت تداول؟
يوقف حد الخسارة اليومي إرسال أوامر جديدة بمجرد تجاوز خسارة الجلسة عتبةً محددة. اختيار الرقم هو عملية معايرة، وليس مسألة ذوق: إذا حددته داخل نطاق الضوضاء المعتادة للسوق، فسيظل الروبوت متوقفاً معظم الأسابيع؛ وإذا حددته بعيداً جداً عن هذا النطاق، فلن يُفعَّل أبداً. وتبدأ العملية بتحديد مدى تكرار تسجيل السوق نفسه يوماً هابطاً بحجم معين.
استعلام SQL الدقيق وراء كل رقم
WITH daily AS (
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d,
argMax(toFloat64(close), window_start) AS close_px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2017-12-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY d
),
with_prev AS (
SELECT d,
close_px,
any(close_px) OVER (ORDER BY d ASC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS prev_close
FROM daily
)
SELECT toYear(d) AS year,
countIf(close_px / prev_close - 1 <= -0.01) AS down_1pct_days,
countIf(close_px / prev_close - 1 <= -0.02) AS down_2pct_days,
countIf(close_px / prev_close - 1 <= -0.03) AS down_3pct_days
FROM with_prev
WHERE prev_close > 0
AND d >= toDate('2018-01-01')
GROUP BY year
ORDER BY yearبلغ عدد الجلسات التي هبطت فيها السوق بنسبة 1% أو أكثر 15 جلسة في 2019، و45 جلسة في 2020، من أصل نحو 250 يوم تداول سنوياً. أما عدد الجلسات التي هبطت فيها بنسبة 3% أو أكثر فكان مختلفاً تماماً: 0 في 2019 مقابل 16 في 2020. ويغطي الصف الأخير من 9 الجلسات حتى 31 يوليو 2026 فقط.
لا يتحرك الخط بوتيرة منتظمة، بل يأتي على شكل تكتلات، وهذه هي النقطة الأساسية في التصميم. فالأيام الصعبة تصل في مجموعات متقاربة. وإذا أوقف الروبوت التداول في أول يوم من إحدى هذه المجموعات ثم استأنفه في اليوم الثاني، فهو لم يتوقف فعلياً.
يؤدي كل حد من حدَّين وظيفتين مختلفتين. ينهي حد الخسارة اليومي، الذي يبلغ عادةً 2% من حقوق ملكية الحساب، التداول في الجلسة. أما حد التراجع المتحرك، المقاس من أعلى مستوى لحقوق الملكية، والذي يبلغ عادةً نحو 10%، فينهي عمل الاستراتيجية إلى حين إجراء مراجعة بشرية. الأول إجراء اعتيادي، أما الثاني فمن المفترض أن يكون نادراً. والروبوت الذي لا يملك سوى الحد الأول قد يستنزف الحساب بنسبة 2% في كل مرة من دون أن يتوقف أي شيء على الإطلاق.
كيف يغيّر تحجيم المراكز وفق التقلب حجمَ المركز؟
يحدد استهداف التقلب حجم المركز عكسياً بالنسبة إلى التقلب المحقق مؤخراً: فعندما يتضاعف النطاق اليومي، ينخفض حجم المركز إلى النصف تقريباً، مع إبقاء المخاطر بالدولار لكل صفقة قريبة من مستوى ثابت. ويُقصد بالتقلب المحقق هنا الانحراف المعياري السنوي للعوائد اليومية، وهو يتغير بدرجة أكبر مما يتوقعه معظم المتداولين.
استعلام SQL الدقيق وراء كل رقم
WITH daily AS (
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d,
argMax(toFloat64(close), window_start) AS close_px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2023-12-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY d
),
rets AS (
SELECT d,
close_px / any(close_px) OVER (ORDER BY d ASC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) - 1 AS ret
FROM daily
)
SELECT formatDateTime(toStartOfMonth(d), '%Y-%m') AS month,
round(stddevSamp(ret) * sqrt(252) * 100, 1) AS realized_vol_pct,
round(least(100.0, 1200.0 / (stddevSamp(ret) * sqrt(252) * 100)), 1) AS vol_target_size_pct
FROM rets
WHERE d >= toDate('2024-01-01')
AND isFinite(ret)
GROUP BY toStartOfMonth(d)
HAVING count() >= 15
ORDER BY toStartOfMonth(d)قيس التقلب المحقق 11.1% على أساس سنوي في 2024-01 و12% في 2026-07، على مدى 31 شهراً. يحوّل العمود الثاني كل قراءة إلى حجم المركز الذي يستهدف تقلباً قدره 12%، مع وضع حد أقصى عند المركز الكامل: 100% في 2024-01 مقابل 99.7% في 2026-07. الاستراتيجية نفسها، والقناعة نفسها، لكن عدد الأسهم مختلف تماماً.
يتناول معيار Kelly المشكلة نفسها من الجانب الآخر، إذ يحدد حجم المركز استناداً إلى الميزة المقدّرة والتباين، بدلاً من التقلب وحده. ويستخدم معظم المتداولين المنهجيين جزءاً من هذا الحجم، مثل نصف Kelly أو ربعه، لأن كلا المدخلين تقديران مبنيان على عينة محدودة. يشرح تحجيم المراكز وفق معيار Kelly هذه الحسابات.
لماذا يعاود روبوت التداول الدخول بعد تفعيل وقف الخسارة؟
يتفعّل وقف الخسارة. يُغلق المركز. وبعد تسعين ثانية، يتحقق شرط الدخول مجدداً، فيعاود الروبوت الدخول، ويتكبد الخسارة نفسها، ثم يكرر العملية. لا يوجد مكوّن واحد معطّل. فقد نفّذت الاستراتيجية ما كُتبت لتنفيذه، ونفّذ وقف الخسارة ما كُتب له، ومع ذلك يستمر الحساب في النزيف عبر رحلات دخول وخروج متتالية.
ينبع التكرار مباشرةً من مسار السعر. تحسب هذه اللوحة، لكل جلسة، عدد المرات التي انتقل فيها SPY من أكثر من 0.1% فوق سعر افتتاحه إلى أكثر من 0.1% دونه، أو عاد في الاتجاه المعاكس.
استعلام SQL الدقيق وراء كل رقم
WITH mins AS (
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d,
window_start AS ts,
toFloat64(close) AS px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2025-08-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
),
opens AS (
SELECT d, argMin(px, ts) AS open_px
FROM mins
GROUP BY d
),
zoned AS (
SELECT m.d AS d,
m.ts AS ts,
multiIf(m.px >= o.open_px * 1.001, 1,
m.px <= o.open_px * 0.999, -1,
0) AS zone
FROM mins AS m
INNER JOIN opens AS o ON m.d = o.d
),
flips AS (
SELECT d,
zone,
any(zone) OVER (PARTITION BY d ORDER BY ts ASC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS prev_zone
FROM zoned
WHERE zone != 0
),
per_day AS (
SELECT d, countIf(prev_zone != 0 AND zone != prev_zone) AS crossings
FROM flips
GROUP BY d
)
SELECT formatDateTime(toStartOfMonth(d), '%Y-%m') AS month,
round(avg(crossings), 1) AS avg_crossings_per_session,
max(crossings) AS max_crossings_in_a_session
FROM per_day
GROUP BY toStartOfMonth(d)
ORDER BY toStartOfMonth(d)تجاوز SPY هذا النطاق بمتوسط 0.7 مرة في الجلسة خلال 2025-08، و1.5 مرة خلال 2026-07، فيما سجلت إحدى الجلسات في 2026-07 عدد 5 من حالات التجاوز. وأي قاعدة تفتح مركزاً على جانب من مستوى وتضع وقفاً على الجانب الآخر تملك هذا العدد من فرص التفعيل خلال يوم واحد.
تحدّ أربعة آليات من ذلك.
- فترة تهدئة بعد كل تفعيل لوقف الخسارة، تُقاس بالدقائق أو بالشموع، ولا يمر خلالها أي أمر جديد لذلك الرمز عبر طبقة إدارة المخاطر.
- حد يومي لعدد الصفقات لكل رمز، يحوّل الحلقة غير المحدودة إلى حلقة ذات نطاق محدد.
- علامة إيقاف تظل مفعّلة. وعند بلوغ حد الخسارة اليومي، تبقى مفعّلة إلى أن يقوم شخص بإلغائها.
- حفظ هذه العلامة خارج ذاكرة العملية. فالمشرف الذي يعيد تشغيل روبوت متعطل يمنحه حالة بداية نظيفة، وهذه الحالة النظيفة هي بالضبط ما وُجدت العلامة لمنعه.
وهذه هي النقطة التي تفوت من اتخذوا جميع الإجراءات الأخرى بصورة صحيحة. تضع روبوتات تداول الشبكة سلالم من الأوامر بحكم تصميمها، ما يجعل حد عدد الصفقات عنصراً أساسياً لا إجراءً شكلياً.
ماذا يحدث عندما يتداول روبوت على أساس مصدر أسعار قديم؟
يظل السعر الذي توقف عن التحديث يبدو رقماً صالحاً. يقرأه الروبوت، ويسعّر أمراً بناءً عليه، ثم يرسل الأمر إلى سوق تحرك بالفعل. يكون الإخفاق صامتاً: لا يظهر أي استثناء، ولا يُسجَّل أي خطأ، ولا تبدو التنفيذات غريبة إلا بعد ذلك.
تتمثل الصورة القابلة للقياس بوضوح في الفجوة السعرية بين الإغلاق والافتتاح، إذ يظل سعر معروف ثابتاً لساعات بينما يتحرك السعر القابل للتداول.
استعلام SQL الدقيق وراء كل رقم
WITH daily AS (
SELECT ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS d,
argMin(toFloat64(open), window_start) AS open_px,
argMax(toFloat64(close), window_start) AS close_px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('SPY', 'KO', 'MSFT', 'AAPL', 'NVDA', 'TSLA')
AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2024-01-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY ticker, d
),
gaps AS (
SELECT ticker,
d,
open_px,
any(close_px) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS prev_close
FROM daily
)
SELECT ticker,
round(quantileDeterministic(0.5)(abs(open_px / prev_close - 1) * 100, cityHash64(ticker, d)), 2) AS median_gap_pct,
round(quantileDeterministic(0.95)(abs(open_px / prev_close - 1) * 100, cityHash64(ticker, d)), 2) AS p95_gap_pct,
round(max(abs(open_px / prev_close - 1) * 100), 2) AS max_gap_pct
FROM gaps
WHERE prev_close > 0
GROUP BY ticker
ORDER BY p95_gap_pct DESCكان السهم صاحب أوسع فجوة عند المئين الخامس والتسعين هو TSLA عند 4.41%، مقارنةً بـ 1% لدى KO. وكانت الليالي المعتادة أكثر هدوءاً بكثير، إذ بلغت الفجوات الوسيطة 1.01% و0.24% على التوالي. وتستهدف طبقة إدارة المخاطر هذه الحالات الطرفية، فيما بلغت أكبر فجوة منفردة في TSLA خلال الفترة المقاسة 14.57%. وهذه هي المسافات التي قد يقطعها السعر بينما يتصرف الروبوت بناءً على سعر قرأه قبل وقت من ذلك. يشرح لماذا تتشكل الفجوات السعرية في الأسهم بين الإغلاق والافتتاح الآلية.
إجراءات الحماية بسيطة وغير مكلفة. حدّد عمراً أقصى لكل سعر ستعتمد عليه طبقة إدارة المخاطر في التسعير، ويكون عادةً بضع ثوانٍ لاستراتيجية تتداول خلال اليوم. واستقبل إشارة نبض من مصدر البيانات بصورة منفصلة عن البيانات نفسها، لتميّز بين انقطاع صامت في الاتصال وسوق هادئ. وتعامل مع البيانات المفقودة باعتبارها توقفاً في التداول، لا سعراً ثابتاً، لأن الروبوت الذي لا يملك أسعاراً لا يستطيع تقييم أوامر الخروج أيضاً.
ما الحدود الصارمة التي يجب أن تندرج ضمن طبقة المخاطر؟
- الحد الأقصى للقيمة الاسمية لكل رمز كنسبة من حقوق ملكية الحساب. يحول سقف بنسبة 10% دون أن يتسبب رمز واحد سيئ الأداء في الإضرار بالحساب بأكمله.
- الحد الأقصى للقيمة الاسمية الإجمالية لجميع المراكز المفتوحة. يعني تحديده عند 100% من حقوق الملكية عدم استخدام الرافعة المالية، وهو قرار يستحق اتخاذه صراحةً بدلاً من تركه لإعداد افتراضي لدى الوسيط.
- الحد الأقصى لمعدل الأوامر، لكل دقيقة ولكل يوم. يُعد إرسال عشرة أوامر في الدقيقة معدلاً مرتفعاً لمعظم استراتيجيات المستثمرين الأفراد، لكنه يظل كافياً لتقييد حلقة تنفيذ خارجة عن السيطرة خلال دقيقة واحدة.
- الحد الأقصى لحجم الأمر كنسبة من متوسط الحجم اليومي للرمز. يحد سقف بنسبة 1% من قدرة الروبوت على تحريك السعر الذي يحاول التداول عليه، ويشكّل متوسط الحجم اليومي المقام المستخدم في الحساب.
ينبغي أن يندرج كل حد من هذه الحدود ضمن طبقة المخاطر، لا ضمن الاستراتيجية، وينبغي أن تُطبَّق جميعها عبر مسار الشيفرة نفسه في الاختبار التاريخي، والتداول الورقي، والتداول الفعلي. فالحد الذي لا يوجد إلا في التداول الفعلي هو حد لم يختبره أحد.
ما الذي يحتاجه سجل تدقيق روبوت التداول؟
يكتب السجل المُلحق فقط سجلاً واحداً لكل قرار، ولا يعدّل السجلات أو يحذفها. يتضمن كل سجل الطابع الزمني، وسعر العرض المستخدم وعمره، وكل فحص للحدود نُفّذ مع نتيجته، والأمر المُرسل، ورد الوسيط. وتُسجّل الأوامر المرفوضة بالأهمية نفسها التي تُسجّل بها الأوامر المنفذة.
إعادة بناء القرار هي الغاية. بعد ستة أسابيع من جلسة سيئة، لا يكون السؤال هو قيمة الربح والخسارة. بل يكون السؤال: أي فحص اجتاز النظام، وبناءً على أي مدخلات؟ من دون تسجيل المدخلات، ستنتهي إلى إعادة اشتقاق حالة الروبوت من حالة السوق، وهذا هو الخطأ نفسه الذي تمثله مشكلة الانحياز الاستباقي في الاختبار الخلفي: استخدام معلومات لم يكن النظام يحتفظ بها لحظة اتخاذ القرار.
يمثل مشروع riskguard أحد التطبيقات مفتوحة المصدر لهذا الفصل، إذ توجد فحوص الحدود في مكوّن تستدعيه الاستراتيجية، بدلاً من توزيع المنطق داخل الاستراتيجية نفسها. وهو تصميم من بين عدة تصاميم، ويستحق القراءة لا الاعتماد عليه فوراً. أياً تكن الأداة التي تعتمد عليها، ثبّت إصداراً موسوماً بدلاً من الاعتماد على الفرع الافتراضي. فقد يتغير الفرع بين تشغيلين للاختبار الخلفي نفسه، وتكون طبقة المخاطر التي تغيّرت بصمت أسوأ من عدم وجودها.
لماذا يُجرى التشغيل الأول عبر وسيط للتداول الورقي
تكون إعدادات محوّل الوسيط مضبوطةً افتراضياً على التداول الورقي، ولا يُفعَّل التداول الفعلي إلا عبر خيار صريح، وهذا مقصود. فهو يمنع خطأً شائعاً: أن يرسل ملف إعدادات منسوخ، أو متغير بيئي لم يُستبدل، أوامر حقيقية بأموال حقيقية.
كما ينتج التشغيل الورقي السجل الأهم: سجل قرارات صادر عن طبقة المخاطر نفسها، باستخدام أسعار حية، ويوضح أي حدود فُعِّلت وأيها لم يُفعَّل. وهذا دليل على أداء طبقة المخاطر، وهو سؤال منفصل عن مدى تحقيق الاستراتيجية للأرباح. يوضح التداول الورقي قبل استخدام أموال حقيقية ما الذي يثبته السجل الورقي وما الذي لا يثبته، بينما يشرح أنظمة التداول بالذكاء الاصطناعي متعددة الوكلاء سبب ضرورة وضع صلاحية الإيقاف خارج نطاق كل وكيل، بمجرد أن يصبح بوسع عدة وكلاء إرسال الأوامر.
الأسئلة الشائعة حول قاطع الدائرة في روبوت التداول
ما المقصود بقاطع الدائرة في روبوت التداول؟
هو قاعدة في طبقة إدارة المخاطر توقف الروبوت عن إرسال أوامر جديدة عند بلوغ حد محدد، وغالباً ما يكون هذا الحد عتبة خسارة يومية أو تراجعاً من أعلى مستوى لحقوق الملكية في الحساب. تعمل القاعدة بصورة مستقلة عن الاستراتيجية مع كل أمر، وتظل مفعّلة إلى أن يجري إلغاء تفعيلها.
كم مرة يسجل السوق يوماً ينخفض فيه بنسبة 2%؟
سجّل SPY 5 جلسة بانخفاض نسبته 2% أو أكثر في 2019، و25 في 2020، من أصل نحو 250 يوم تداول في كل سنة. ويوضح هذا الفارق بين سنة هادئة وأخرى مضطربة سبب معايرة حد الخسارة بالاستناد إلى البيانات التاريخية لا إلى الحدس.
كيف تمنع الروبوت من إعادة الدخول بعد إيقافه؟
تؤدي فترة تهدئة بعد كل إيقاف، إلى جانب حد يومي لعدد الصفقات لكل رمز، إلى تحويل الحلقة غير المحدودة إلى حلقة ذات حد أقصى. كما يجب أن تكون إشارة الإيقاف ثابتة ومخزنة خارج ذاكرة العملية، لأن المشرف الذي يعيد تشغيل روبوت متعطل سيمنحه بخلاف ذلك حالة جديدة غير موقوفة.
كيف يعرف الروبوت أن موجز الأسعار أصبح قديماً؟
يفحص عمر كل عرض سعري قبل تسعير أمر بالاستناد إليه، ويراقب أيضاً إشارة نبض من موجز البيانات بصورة منفصلة عن البيانات نفسها. وتوضح الفجوات الليلية حجم ما قد يخفيه السعر القديم: فقد بلغ التحرك الليلي عند المئين 95 نسبة 4.41% في TSLA خلال الفترة بين يناير 2024 ويوليو 2026.
هل يحتاج روبوت تداول صغير فعلاً إلى سجل تدقيق؟
يسجل سجل التنفيذ ما حدث. أما سجل القرارات فيسجل ما اعتقد الروبوت أنه مخوّل بفعله، وهذه هي الطريقة الوحيدة للتمييز بين استراتيجية خاطئة وفحص مخاطر لم يُنفّذ قط. ويُعد السجل الذي يسمح بالإضافة فقط، ويشمل حالات الرفض، الحد الأدنى المفيد.
تأتي كل الأرقام الواردة أعلاه من استعلام مخزّن على بيانات الشموع ذات الفواصل الدقيقة، وتفتح كل لوحة الاستعلام SQL الذي يقف وراءها. وجّه الاستعلامات نفسها إلى قائمة الرموز الخاصة بك على منصة Strasmore.