إنتقل إلى المحتوى الرئيسي

FakeTradingSession_—_عقد_الولاء_لـ_cTrader_Open_API

tests/UnitTests/CopyTrading/FakeTradingSession.cs=IOpenApiTradingSession في_الذاكرة_التي_تُشغَّل_عليها_جميع_اختبارات_وحدة_نسخ_التداول.المهمة: تقليد خادم_cTrader_Open_API_الحقيقي بدرجة_كافية_لأن_اختبارات الوحدة_تغطي_السلوك_الذي_كان_فقط_المستوى_المباشر_يستطيع_التقاطه.هذا التوثيق_=_عقد_الولاء:_ماذا_ينمذئ_الأصلي،_بأي_ولاء،والقاعدة التي_تحافظ_على_الأصلي.

قاعدة_ملزمة_(CLAUDE.md): الأصلي_يبقى_مؤمناً_بـ_cTrader. مدّده،_ولاتُضعفه _لتمرير_اختبار.كل_سلوك_حقيقي_جديد تعتمد_عليه_يتم_نمذجته_هنا، _مُثبّت_باختبار_الولاء.

مصفوفة_الولاء_(F1–F13)​

تتتبع_خطة_plans/copy-trading-overhaul.md §7.6.الأسطورة:✅نمذأ·◑جزئي (opt-in/تمديد)·_⬜_لم_يُنمذأ_بعد.

#سلوك_Open_API_الحقيقيحالة_الأصليكيف_يتم_نمذجته
F1أمر_السوق_يمكنه ملء_جزئي◑PartialFillFractionForCtid[ctid]_=_f ملء_فقطf×volume؛المصادقة
تُظهر_الفجوة_ Phase-1 true-up (G5) _يُغلق._قبول→زوج_الملء_لا_يزال_قادماً.
F2الحجم_يُطبع_إلى step،_مرفوض_أقل_من min /_أكثر_من max✅VolumeBoundsForCtid[ctid]_=_(Step,_Min,_Max) يُطبع_إلى_الأقل_إلى
step،يُلقيCtraderRejectException(VolumeTooLow/High).
F3SL/TP_غير_صالح مرفوض_(الجانب_+_الأرقام)⬜مخطط_في_ Phase 0a/1 (أزواج_مع_M6 _تطبيع_دقة_SL/TP).
F4الأسعار مُوسَّعة_صحيحياً_بالأرقام؛_pipPosition◑SymbolDetails الآن_تحملDigits(و_MaxVolume)_،مُعبأة_من_الرمز
الحقيقي؛_PipPosition تدفع_تحمل_نطاق_السوق،Digits تدفع
تطبيع_دقة_SL/TP_(M6)._توسع_السعر_الصحيح_العدد_لا_يزال_معلقاً.
F5نطاق_السوق الملء_فقط_إذا_كانت_الأسعار_الفورية_ضمنbase_±_slippage،
وإلا_مرفوض✅IsMarketRangeRejected يقارن_السعر_الفوري(SetSpot)إلى
baseSlippagePrice_±_slippageInPoints.علامةRejectMarketRangeForCtid_
القديمة_تstill_تُجبر_الرفض.
F6مُحرّك_معلق_→_ملء حدث_ثنائي(الأمر_يحمل_positionId_+موضع OPEN)◑PushOpen(...,_orderId:) يُعيد_إنتاج_حدث_الملء_المعلق؛
FX-Blue/cMAM_إلغاء_النسخ_المزدوج_مغطى_في_
CopyEngineHostTests.Filled_pending_does_not_double_open.
F7إقفال_مُحرّك_بالخادم (SL/TP_أُصيب،_إيقاف_الخسارة)⬜اليوم_اختبار_مدفوع_(PushClose)؛SL/TP_المُحرّك_بالسعر+_
إقفالات_ stop-out_مخططة.
F8لكل_حساب _جداول/تفاصيل_الرموز◑أسماء/معرفات_الرموز_لكل_أصلي؛الجداول_المتباينة_لكل_حساب
(cross-broker)_معلقة.
F9حالة_الحساب_الكاملة (الرصيد،_الحقبة،_الهامش،_الرصيد_الحر)◑Balance=LoadPositionValuationsAsync(entry/swap/عمولة_عبر
SetPositionValuation)+SetSpot تغذي_الحقبة_الفعلية_إلى
تحديد_الحجم_النسبي_للحسابات_(G2،اختبار_بالوحدة_في
CopyEquitySizingTests).الهامش_المستخدم_لا_يعرضه_واجهة_البرمجة
للمصادقة_،_لذا_الرصيد_الحر_يُبلغ_كـ_الحقبة.
F10الأحداث_تحمل طوابع_الوقت_للخادم✅ExecutionEvent.ServerTimestamp(unix_ms)—الجلسة_الحقيقية_تقرأ
من_deal's_ExecutionTimestamp؛PushOpen/PushPending ت acceptserverTimestamp:
ل drive_FakeTimeProvider-_الاختبار_يقود_زمن_الlatency_النسخ_الحقيقي_(G1).
F11وضع_التداول_/_الجدول (معطل_/close-only/_مغلق)⬜Phase 2b_مخطط.
F12تصنيف_الأخطاء_المكتوبة (ProtoOAErrorRes أكواد)✅RejectReasonForCtid[ctid]_=_CtraderRejectReason.X تُلقي
CtraderRejectException(reason)_(NotEnoughMoney،_MarketClosed،
PositionNotFound،_…).
F13إلغاء_الرمز —رمز_قديم→خطأ auth✅InvalidateToken(ctid) يُعلم_الرمز_المُرفق_قديم؛
استدعاءات_التداول_تُلقي حقيقي OpenApiException مع
OpenApiErrorKind.TokenInvalid(رمزCH_ACCESS_TOKEN_INVALID)_،
تماماً_مثل_الخادم_الحقيقي_،حتىSwapAccessTokenAsync يثبت
رمزاً_حديثاً._يُغذي_اختبار_متانة_الرمز_M1.

اختبارات_الولاء_تعيش_في_ tests/UnitTests/CopyTrading/FakeTradingSessionFidelityTests.cs.

opt-in،_الافتراضيات_تحافظ_على_السلوك_القديم​

كل_مقبض_ولاء معطل_افتراضياً لذا_الأصلي_يحافظ_على_سلوك_ملء_بسيط للاختبارات_التي_لا_تهتم._الاختبار_يختار_لكل_حساب:

session.VolumeBoundsForCtid[slave] = (Step: 10, Min: 10, Max: 1000); // F2
session.PartialFillFractionForCtid[slave] = 0.6; // F1 / G5
session.RejectReasonForCtid[slave] = CtraderRejectReason.NotEnoughMoney; // F12 (one-shot)
session.InvalidateToken(slave); // F13

التوصيف_والمطابقة_(مخطط،يحافظ_على_الأصلي≡_الحقيقي)​

آليتان_تحافظان_على_الأصلي_مقابل_الخادم_الحقيقي_المتحرك_(مُتتبع،تهبط عبر_ Phase 0a):

  1. توصيف_مباشر (LiveApiCharacterization،_حسابات_demo،_محصور_بالأسرار، Inconclusive عند_السوق_المغلق):تقود_Open_API_الحقيقي، تسجل_الحقيقة_السلكية_الفعلي(تسلسلات_الأحداث،_التوسع،أكواد الرفض)في_ثوابت_ذهبية_مُفحصة_في_مشروع_الاختبار.لا_أسرار_في الثوابت—_فقط_الأشكال_المُراقَبة.
  2. harness_المطابقة:تشغل_مجموعة_السيناريو_نفسه_مرتين—مرة ضد_FakeTradingSession،ومرة_ضد_الجلسة_الحقيقية(عندما_الأسرار_ موجودة)_—تؤكد_نتائج_ملاحظة_متطابقة.الخادم_الحقيقي_يتغير→ الساق_الحية_تفشل→تحديث_الأصلي.هذا_يجعل"اختبارات الوحدة_تغطي_كل_شيء"_موثوقاً.

الأسرار_الحية:secrets/dev-credentials.local.json(أو_الملفات_المنقسمة_ القديمة)_—انظرdocs/testing/dev-credentials.md.