تخطٍّ إلى المحتوى
الجمعة، 7 أغسطس 2026 · لندنENع
ريان الأزهري.الاستدامة · الطاقة · الكربون · البيئة المبنيةومنعطفات عابرة إلى الفلسفة أو الدين أو البرمجة، حيثما قاد الفضول
التداول الكمي الإنتاجي

سهم واحد يُرسم مرة واحدة: العمارة التي تُبقي البحث خارج الإنتاج

أخطر شيفرة في أي مستودع تداول هي دفتر الملاحظات الاستكشافي الذي لا يجب أن يقترب أبداً من رأس المال الفعلي. قاعدة بنيوية واحدة، هي أن تسري التبعيات في اتجاه واحد فقط، تُبقيه خارج الإنتاج وتحوّل الاقتران الخفي إلى رقم يمكنك أن تراه بأمر واحد من grep.

ريان الأزهريأخصائي بيئي معتمد · 9 دقيقة قراءة
بطاقة عنوان لمقال سهم واحد يُرسم مرة واحدة، تُظهر مجلدي research وscripts وهما يستوردان كلاهما نحو الداخل باتجاه المكتبة، التي لا تستورد بدورها من أي شيء فوقها.

أخطر شيفرة برمجية في أي نظام تداول هي دفتر الملاحظات (Notebook) المؤقت الذي اكتُشفت فيه الفرصة (Edge). فهو سريع ومتساهل تحديداً لأنه مسموح له أن يخطئ، ومسموح له أن يرى مجموعة البيانات كاملة دفعة واحدة، وهذه بالضبط هي الشيفرة التي لا تريدها أبداً على مقربة من رأس المال الفعلي. ومع ذلك فإن المسار الافتراضي لكل نظام تقريباً يسير بها إلى هناك مباشرة: يكتشف أحدهم إشارة داخل دفتر ملاحظات، فينبت للدفتر اتصال بوسيط، ثم ينبت لذلك الاتصال مُحجِّم مراكز (Position-sizer)، وفي أحد أيام الثلاثاء يجد الدفتر نفسه يتداول مالاً حقيقياً، حاملاً معه كل اختصار استكشافي ارتُكب في طريقه.

وثمة قرار بنيوي واحد يمنع معظم هذا، وهو ليس إطار عمل ولا نمط تصميم (Design Pattern)، بل قاعدة واحدة تحدد الاتجاه المسموح لجمل import أن تشير إليه.

رتّب الشيفرة بحسب ما يُسمح لها أن تفترضه

نظام التداول ليس برنامجاً واحداً، بل هو أربعة برامج على الأقل، لكل منها عمر افتراضي مختلف تماماً ونطاق ضرر مختلف تماماً. والطريقة المفيدة للتمييز بينها ليست "ماذا تفعل هذه الشيفرة" بل "بماذا يُسمح لها أن تفترض؟"

Figure

The four-layer arrow

Sort code by what it is allowed to assume. Everything points inward at the library; the library points at nothing above it.

Discovery

disposable · research/

May assume it sees the whole dataset. Notebooks, sweeps, audits. It may import the library; nothing may import it.

Intent

versioned · config/

States what runs and with which parameters. It is data, read at runtime, never imported. Diff it to see a deployment change.

Library

the asset · titan/

The tested implementation that touches capital. It imports only itself and depends on nothing above it. This is the sink every arrow points at.

Entry points

glue · scripts/

Wire the library to a broker and press go. Inert until called; the only place a broker connection is ever constructed.

Invert one arrow and the most reckless code in the repo is suddenly load-bearing.

Source: Building a Production Quant Trading System (Titan)
  • الاكتشاف (Discovery) يُسمح له أن يفترض أنه يرى المستقبل: السلسلة الزمنية كاملة دفعة واحدة، ومُطبِّع (Normaliser) مضبوط على كامل التاريخ، وفائز يُختار وفق المعيار نفسه الذي سيُقيَّم به لاحقاً. دفاتر الملاحظات، والمسوح (Sweeps)، والتدقيقات (Audits). قابلة للتخلص منها بحكم التصميم.
  • النية (Intent) هي الإعدادات (Configuration) المُدارة بإصدارات (Versioned) التي تحدد ماذا يعمل وبأي معاملات. إنها بيانات تُقرأ وقت التشغيل، لا شيفرة تستوردها.
  • المكتبة (Library) لا تفترض المستقبل ولا وجود وسيط؛ لا تفترض شيئاً سوى مدخلاتها واختباراتها الخاصة. هذا هو التطبيق المُختبَر والمُغلَّف (Packaged) الذي يتداول فعلياً. إنه الأصل (Asset).
  • نقاط الدخول (Entry Points) يُسمح لها أن تفترض وجود اتصال بوسيط. فهي تربط المكتبة بساعة وبمكان تنفيذ (Venue)، ثم تضغط زر البدء.

أما الشيفرة التي تريد أن تفترض المستقبل والاتصال بالوسيط معاً، فهي في الحقيقة ملفان يتقنّعان في ثوب واحد. واختبار الطبقات يفصل بينهما قبل أن يندمجا.

سهم واحد، لا يشير إلا في اتجاه واحد

والآن القاعدة: التبعيات تسري في اتجاه واحد فقط لا غير: الاكتشاف ونقاط الدخول كلاهما يشير إلى الداخل نحو المكتبة، والمكتبة لا تشير إلى شيء فوقها. يجوز للبحث أن يستورد الشيفرة المُختبَرة؛ ولا يجوز أبداً للشيفرة المُختبَرة أن تستورد من البحث. يجوز لنقاط الدخول أن تستورد من المكتبة؛ ولا يجوز للمكتبة أبداً أن تحتوي على نقطة دخول. ومرسوماً كرسم بياني، يكون النظام بأكمله خالياً من أي حلقة، والمكتبة فيه هي نقطة المصب.

لماذا يكون اتجاه السهم هو الركيزة الحاملة هنا، لا مجرد وجود المجلدات بحد ذاته؟ لثلاثة أسباب، يُسقط كل واحد منها فئة كاملة من الأخطاء:

  1. يحصر نطاق الضرر. فالتبعية عقد: غيّرني، وقد أكسر كل ما يشير إليّ. ولأن المكتبة لا تشير إلى شيء فوقها، تستطيع أن تعيد كتابة دفتر ملاحظات، أو تحذف مسحاً، أو تُعيد تسمية مفتاح في الإعدادات دون أي خطر على الشيفرة التي تتداول فعلياً. أما إن عكستَ سهماً واحداً، وتركتَ المكتبة تستورد دالة مساعدة من البحث، فإن أكثر ملف تهوراً في المستودع يصبح فجأة على المسار الحرج المؤدي إلى حسابك.
  2. يجعل تسريب التحيز التطلعي (Look-ahead bias) إلى الإنتاج أصعب بنيوياً. فشيفرة الاكتشاف يُسمح لها أن تضبط درجة معيارية (Z-score) على السلسلة كاملة، بينما تعيش المكتبة في عالم شمعة واحدة في كل مرة: القرار قبل العائد. وحين يكون الحد الفاصل أحادي الاتجاه، لا يستطيع ذلك التسرب أن يركب جملة import من الطبقة المتساهلة إلى الطبقة الصارمة، لأن الطبقة الصارمة لا يمكنها أصلاً أن تستورد من المتساهلة. ولنكن دقيقين بشأن ما تشتريه هذه القاعدة: إنها تُغلق مساراً واحداً فقط أمام التحيز التطلعي، لا كل المسارات. فمُطبِّع سببي البنية لكنه خاطئ المضمون، كتبتَه أنت داخل المكتبة، لا يزال يحتاج إلى أن يُمسَك لاحقاً عبر الاختبار المستمر (Walk-forward) ومجموعة المقاييس (Metric Suite). فالطبقات والتحقق، كل منهما يُغلق باباً مختلفاً.
  3. يفصل النية عن التنفيذ. فترات الاسترجاع (Lookbacks)، والعتبات (Thresholds)، وقوائم الأدوات المالية التي تُشكِّل فرصتك ينبغي أن تعيش في إعدادات مُدارة بإصدارات، تُقرأ كبيانات، لا أن تُدرَج داخل الشيفرة كقيم ثابتة (Literals) مكتوبة يدوياً. فالمراجع يقارن (Diff) مجلد الإعدادات ويرى بالضبط ما تغيّر في عملية الإطلاق دون أن يقرأ سطراً واحداً من Python.

المكسب الحقيقي: اقتران يمكنك عدّه

وهذا هو الجزء الذي تغفل عنه معظم مقالات العمارة البرمجية، وهو السبب الذي يجعل هذه القاعدة تستحق مكانها حتى حين تخرقها.

قاعدة التبعية أحادية الاتجاه لا تمنع الاقتران (Coupling) بمعجزة. ما تفعله هو أنها تجعل الاقتران قابلاً للقراءة. فكل تبعية غير مشروعة تتحول إلى عملية grep واحدة. وتتوقف تنازلات عمارتك البرمجية عن كونها شعوراً غامضاً، لتصبح قائمة قابلة للعدّ، تضع عليها رقماً وتراقب اتجاهه.

Figure

A 30-second architecture audit

Four greps tell you whether the arrow holds. No deep reading required.

from scripts in titan/

must be EMPTY

A library that imports an entry point has inverted itself completely. This should return nothing, ever.

from research in titan/

your debt ledger

Library coupling to disposable code. A countable number you drive toward zero, wired into CI as a budget that only ever lowers.

from titan in research/

expect MANY

Research reusing the exact tested code the live system runs. If this is empty, you have copy-paste, not architecture.

from titan in scripts/

expect MANY

Entry points composing the same asset. Reuse-inward is the point: one implementation, not two that drift apart.

The rule does not prevent coupling. It makes coupling countable.

Source: Building a Production Quant Trading System (Titan)

يمكنك أن تدقق نظاماً مُصنَّفاً بطبقات في نحو ثلاثين ثانية، دون حاجة إلى قراءة متعمقة. فمكتبة تستورد من نقطة دخول (from scripts داخل المكتبة) يجب ألا تُعيد أي نتيجة أبداً: مكتبة تستورد مُشغِّلها (Runner) الخاص بها قد انقلبت على نفسها تماماً. ومكتبة تستورد من شيفرة الاكتشاف (from research داخل المكتبة) هي دَين الاقتران لديك، مُعدَّداً، رقم تدفعه نحو الصفر. أما حين يستورد البحث ونقاط الدخول من المكتبة، فينبغي أن يُعيد كل منهما عدداً كبيراً من النتائج، لأن إعادة الاستخدام نحو الداخل هي بيت القصيد كله: فالبحث والعمليات التشغيلية يُركِّبان التطبيق المُختبَر نفسه بدل أن يُعيدا اشتقاقه من جديد. فإذا عادت هذه النتائج فارغة، فأنت لا تملك عمارة برمجية، بل نسخاً ولصقاً، تطبيقين لفرصتك سينجرفان بعيداً حتى لا يعود الفعلي مطابقاً للبحث.

وهذه هي القوة الهادئة لهذه القاعدة. فالنظام الذي يفتقر إليها يحمل الاقتران نفسه تماماً؛ لكنه لا يملك ببساطة أي وسيلة لأن يراه، لأن كل شيء يستورد كل شيء، ولم يكن أي سهم مطالباً أصلاً بالإشارة إلى اتجاه بعينه.

قصة حرب: الحافة العكسية التي التهمت عملية البناء

ما من نظام لديّ يحمل سهماً نظيفاً تماماً بلا استثناء، والتظاهر بعكس ذلك يُعلِّم الدرس الخاطئ. رُقِّيت استراتيجية ذات مرة إلى التداول الفعلي بأن جعلتُ غلاف مكتبتها (Wrapper) يستورد دالة الإشارة الأصلية مباشرة من حزمة البحث، بدلاً من أن أنقل تلك الدالة إلى داخل المكتبة. ونجح الأمر. واجتاز المراجعة، لأن جملة import عملت دون مشكلة ولأن كل الاختبارات كانت ناجحة.

وظهرت الكلفة في لحظة إطلاق صورة الإنتاج (Production Image): لم تعد صورة الإنتاج تُبنى من المكتبة وحدها، بل باتت مضطرة إلى تضمين شجرة البحث بأكملها، وصار فحص الاستيراد وقت البناء يعني أن تعديلاً لا علاقة له بالموضوع في ملف بحثي استكشافي قادر على كسر بناء الإنتاج. وشكل هذا الخطأ اقتران يشير في الاتجاه الخاطئ: الأصل يعتمد على ما هو قابل للتخلص منه. أما القاعدة التي دفعتُ ثمنها في هذه الحادثة فتستحق أن تُحفَظ: الترقية تعني نقل الشيفرة عبر الحد الفاصل، لا استيرادها عبره. وأي import research داخل المكتبة هو TODO، لا تصميم.

ولاحظ كيف اكتُشف الخطأ: ليس بإعادة قراءة أي شيء، بل بعملية grep واحدة قادرة على عدّ الحواف العكسية. فالقاعدة هي التي جعلت الدَين مرئياً في اللحظة ذاتها التي نشأ فيها.

الإلزام لا العُرف

إن عملية grep تُشغِّلها يدوياً ليست إلا عرفاً، وأي عرف كهذا سينجرف أول مرة يضغط فيها موعد نهائي (فقصة الحرب أعلاه اجتازت المراجعة تحديداً لأن الجميع كان يثق بالعرف السائد). ولتحويل السهم إلى قيد حقيقي، ادمجه ضمن CI:

  • عقد (Contract) في import-linter يُعلن أن المكتبة لا يجوز لها أن تستورد من research أو scripts، ويُفشل عملية البناء عند أي خرق. وهذه هي النسخة الأقوى: المُصرّف (Compiler) يتولى مراجعة الشيفرة (Code Review) نيابة عنك.
  • أو، كضابط أخف لا يعمل إلا في اتجاه واحد، اختبار يشترط ألا يتجاوز عدد الحواف العكسية حداً N، وهو حد لا تفعل به إلا أن تُخفِّضه. فعملية البناء، لا ذاكرتك، هي التي تُبقي الحد قائماً، وتتحول عبارة "راقب الرقم حتى يقترب من الصفر" إلى شيء لن يسمح CI بارتفاعه أبداً.

وفي الحالتين كلتيهما، يتوقف الحد الفاصل عن أن يكون وعداً، ليصبح خاصية ثابتة في عملية البناء.

الخلاصة

لا تحتاج إلى إطار عمل ذكي لإبقاء البحث خارج الإنتاج. تحتاج إلى سهم واحد، يُرسم مرة واحدة ويُفرَض إلى الأبد: الاكتشاف ونقاط الدخول يشيران إلى الداخل نحو المكتبة؛ والمكتبة لا تعتمد على شيء فوقها. رتّب شيفرتك بحسب ما يُسمح لها أن تفترضه، وأبقِ النية داخل الإعدادات كبيانات، وادمج اتجاه السهم ضمن CI ليصمد تحت ضغط المواعيد النهائية. لن تجعل هذه القاعدة اقترانك صفراً، بل ستجعله رقماً، وهذا أول خطوة نحو خفضه.

وهذا هو الفصل الثاني في أساسيات النظام الذي تنبع منه هذه المقالات. والمعالجة الكاملة، العمارة وقاعدة التبعية أحادية الاتجاه، متاحة للقراءة مجاناً، وتضم جدول الطبقات، والتعقيد الصادق حيث ينحني السهم أحياناً في الواقع، والبوابة الدوارة التي تُبقي النية بياناتٍ لا شيفرة. ويمكنك أن ترى المخطط نفسه في إطار العمل المرافق المُنقَّح على GitHub، المرخّص بموجب Apache-2.0. وهذا الفصل يفتتح كتاب Building a Production Quant Trading System؛ والكتاب الكامل، نسخة رقمية حيّة على Leanpub ونسخة ورقية مطبوعة على Amazon، هو حيث يُعالَج التحجيم وبناء المحفظة والتشغيل الفعلي من البداية إلى النهاية.

هذا مقال هندسي، وليس نصيحة استثمارية، ولا يحتوي على أي استراتيجية قابلة للتداول.

Figure

The four-layer arrow

Sort code by what it is allowed to assume. Everything points inward at the library; the library points at nothing above it.

Discovery

disposable · research/

May assume it sees the whole dataset. Notebooks, sweeps, audits. It may import the library; nothing may import it.

Intent

versioned · config/

States what runs and with which parameters. It is data, read at runtime, never imported. Diff it to see a deployment change.

Library

the asset · titan/

The tested implementation that touches capital. It imports only itself and depends on nothing above it. This is the sink every arrow points at.

Entry points

glue · scripts/

Wire the library to a broker and press go. Inert until called; the only place a broker connection is ever constructed.

Invert one arrow and the most reckless code in the repo is suddenly load-bearing.

Source: Building a Production Quant Trading System (Titan)

Figure

A 30-second architecture audit

Four greps tell you whether the arrow holds. No deep reading required.

from scripts in titan/

must be EMPTY

A library that imports an entry point has inverted itself completely. This should return nothing, ever.

from research in titan/

your debt ledger

Library coupling to disposable code. A countable number you drive toward zero, wired into CI as a budget that only ever lowers.

from titan in research/

expect MANY

Research reusing the exact tested code the live system runs. If this is empty, you have copy-paste, not architecture.

from titan in scripts/

expect MANY

Entry points composing the same asset. Reuse-inward is the point: one implementation, not two that drift apart.

The rule does not prevent coupling. It makes coupling countable.

Source: Building a Production Quant Trading System (Titan)

قراءات إضافية

طاقة المكاتب، الجزء 4 من 25

مقالات ذات صلة

اشترِ المحرك، وابنِ فرصتك: الخاصية الوحيدة التي تحسم اختيار محرك التداول الكمي

اختيار محرك للتداول الكمي ليس مقارنة سمات بين NautilusTrader وbacktrader وحلقة أحداث تُكتب منزلياً. الأمر يُحسم بخاصية واحدة، ومعيار تقييم يمكن تطبيقه على أي محرك: هل يُشغّل اختبار المحاكاة لديك الشيفرة نفسها التي يعمل بها نظامك الفعلي؟

· 9 min

اختبارك التاريخي ليس دليلاً: لماذا تموت أنظمة التداول الكمي قبل أن تتداول

منحنى الأسهم الجميل هو النتيجة الافتراضية لأي اختبار محاكاة تاريخية، وليس إنجازاً. إليك لماذا تنحاز كل أنماط الفشل في التداول الكمي نحو التفاؤل، والعادة الوحيدة التي تصمد أمام السوق الحقيقي: الشك قبل الاحتفال.

· 9 min

دليل شامل للهجرة من ووردبريس إلى Next.js

دليل عملي شامل للانتقال بموقع محتوى من ووردبريس إلى Next.js دون فقدان ترتيبك في محركات البحث: قاعدة الحفاظ على الروابط التي تحكم كل شيء، وبنية محتوى قادرة على الصمود أثناء الانتقال، والتعامل مع اللغتين العربية والإنجليزية، ومتطلبات السيو والأمان، وعملية الانتقال التي يمكنك التراجع عنها في أي وقت.

· 20 min

مقالات إلى بريدك

كتابات جديدة عن سوريا والاستدامة والتمويل، بضع مرات في الشهر.

يمكنك إلغاء الاشتراك في أي وقت. يقرأها أكثر من ٤٢٠٠ متخصّص.