انتقل إلى المحتوى

كيفية إضافة طرق إلى API cTrader

طرق التوسيع هي أداة حاسمة إذا كنت ترغب في إضافة وظائف جديدة إلى API cTrader. باستخدام بناء جملة بسيط نسبيًا، يمكنك إضافة سلوكيات جديدة إلى أي فئة API محددة مسبقًا، مثل Symbol أو Position. بعد تعريف طريقة التوسيع، يمكنك استدعاؤها من أي كائن من الفئة التي قمت بتوسيعها.

حالة استخدام لطرق التوسيع

أولاً، سنقوم بإجراء عرض توضيحي سريع لسبب رغبتك في استخدام طرق التوسيع.

باستخدام cBot، نريد أن نتمكن من الوصول إلى حجم مركز معين باللوت حيث تؤثر هذه المعلومات مباشرة على إستراتيجية التداول المفضلة لدينا. للقيام بذلك، يمكننا محاولة تهيئة متغير من فئة Position ثم محاولة الوصول إلى طريقة Lots() الخاصة به.

1
2
Position position = Positions.Last();
Print(position.Lots());

إذا كتبنا الكود كما هو، سنتلقى خطأ يشير إلى أن الوصول إلى Lots() غير موجود في واجهة برمجة التطبيقات. ولكن ماذا لو كانت هناك طريقة لإضافة طريقة جديدة إلى عضو واجهة برمجة التطبيقات الحالية دون التأثير على أي وظائف أخرى؟

بافتراض وجود هذه الطريقة، كان بإمكاننا إنشاء cBot بسيط يقوم، في كل شمعة، بالتكرار على قائمة جميع المراكز الحالية وطباعة حجمها باللوت في السجل. كنا سنحدد طريقة OnBar() على النحو التالي.

1
2
3
4
5
6
protected override void OnBar()
{
    foreach (var position in Positions) {
        Print(position.Lots());
    }
}

تسمح لنا طرق التوسيع بإضافة وظيفة Lots() في بضعة أسطر من الكود ثم إعادة استخدامها متى أردنا على أي كائن من فئة Position. فيما يلي، نشرح كيف يمكنك إنشاء واحدة ونقدم عدة أمثلة على الخوارزميات التي تستخدمها.

كيف تعمل طرق التوسيع

عند العمل مع طرق التوسيع، ضع في اعتبارك القواعد التالية.

  • طرق التوسيع دائمًا ثابتة.

للإعلان عن طريقة ثابتة، كل ما عليك فعله هو استخدام الكلمة الأساسية static. فيما يلي، نعلن عن طريقة Lots() بجسم فارغ.

1
2
3
4
public static class MyExtensions {
    public static double Lots() {}

}
  • يمكن أن تحتوي طرق التوسيع على أي عدد من الوسائط ولكن يجب أن تكون الوسيطة الأولى دائمًا هي نوع البيانات/الفئة التي من المفترض استدعاء الطريقة لها مسبوقة بالكلمة الأساسية this.

سنضيف كائنًا من فئة Position كأول وسيطة ووحيدة لطريقة Lots(). نظرًا لأن كائن Position يحتوي أيضًا على معلومات حول الرمز الذي تم فتح المركز له، فإننا لا نحتاج إلى أي وسائط أخرى.

1
2
3
public static class MyExtensions {
    public static double Lots(this Position position) {}
}
  • يمكن أن تحتوي طرق التوسيع على أي منطق مناسب للوسائط المقدمة.

لا حاجة لاستخدام بناء جملة خاص عند تحديد جسم طريقة التوسيع. يمكننا التعامل معها كأي طريقة أخرى، وبالتالي، يمكننا تحديد جسمها على النحو التالي.

1
2
3
4
5
public static class MyExtensions {
    public static double Lots(this Position position) {
        return position.VolumeInUnits / position.Symbol.LotSize;
    }
}
  • يمكن استدعاء طرق التوسيع كطرق مثيل أو طرق ثابتة.

هناك طريقتان ممكنتان لاستدعاء طريقة التوسيع الخاصة بنا في كود cBot.

عند استخدام بناء جملة طريقة المثيل، نستدعي الطريقة من أي كائن مناسب من نوع Position.

1
2
var position = Positions.Last();
Print(position.Lots());

عند استخدام بناء جملة الطريقة الثابتة، يمكننا استدعاء طريقة التوسيع الخاصة بنا بعد تحديد فئتها الثابتة المقابلة بالكامل.

1
2
var position = Positions.Last();
Print(MyExtensions.Lots(position));

الأمر متروك لك لتحديد أي طريقة لاستدعاء طرق التوسيع هي الأكثر ملاءمة.

توقيعات الطرق

عند استخدام بناء جملة المثيل، تجنب الحالات التي يكون فيها لطرق التوسيع الخاصة بك نفس التوقيعات مثل أي من طرق واجهة برمجة التطبيقات المدمجة (مثل Position.Close()). في هذه الحالات، سيتم استدعاء طريقة مدمجة في كل مرة تحاول فيها استدعاء طريقة توسيع بالتوقيع المطابق.

IntelliSense

عندما نحاول استدعاء طريقة توسيع، يستخدم IntelliSense أيقونة خاصة لتمييزها عن أعضاء واجهة برمجة التطبيقات المدمجة.

لإظهار طريقتنا الجديدة قيد العمل، يمكننا إنشاء cBot يضع ثلاثة أوامر عند البدء، كل منها بحجم مختلف. في كل شمعة، يقوم cBot بطباعة حجم جميع المراكز المفتوحة حاليًا باللوت.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
protected override void OnStart()
{
    ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000);
    ExecuteMarketOrder(TradeType.Buy, SymbolName, 100000);
    ExecuteMarketOrder(TradeType.Buy, SymbolName, 50000);
}

protected override void OnBar()
{
    foreach (var position in Positions) {
        Print(position.Lots());
    }
}

بعد بناء وإطلاق cBot الخاص بنا، يجب أن نرى القيم الصحيحة يتم طباعتها في السجل.

استخدام طرق التوسيع في cBots

سنحاول الآن إنشاء cBot أكثر تعقيدًا. في كل شمعة، ستقوم الخوارزمية الخاصة بنا بمراجعة قائمة المراكز المفتوحة حاليًا وتعديل مستويات إيقاف الخسارة الخاصة بها بحيث تكون عند نقطة التعادل. للقيام بذلك، سنحتاج إلى إنشاء طريقة توسيع BreakEven() لفئة Position.

نقوم بإنشاء cBot جديد وإعادة تسميته. بعد ذلك، نحذف كل الكود الذي لا نحتاجه ونضيف فئة MyExtensions.

1
2
3
public static class MyExtensions {

}

الكود الخاص بنا لطريقة BreakEven() بسيط نسبيًا. نتحقق مما إذا كان للمركز إيقاف خسارة، وما إذا كان إجمالي ربحه أكبر من الصفر وما إذا كان إيقاف الخسارة المعين حاليًا لا يساوي سعر دخول المركز. إذا كانت جميع هذه الشروط صحيحة، فإننا نعدل إيقاف الخسارة للمركز بحيث يساوي سعر دخول المركز.

1
2
3
4
5
6
7
public static class MyExtensions {
    public static void BreakEven(this Position position) {
        if (position.StopLoss is not null && position.GrossProfit > 0 && position.StopLoss != position.EntryPrice) {
            position.ModifyStopLossPrice(position.EntryPrice);
        }
    }
}

في cBot نفسه، لا نحتاج إلى استخدام أي طريقة غير OnBar(). في كل شمعة نطلب من cBot تنفيذ عملية بسيطة، وهي التكرار على مجموعة Positions واستدعاء طريقة BreakEven() الجديدة لكل عنصر فيها.

1
2
3
4
5
6
protected override void OnBar() 
{
    foreach (var position in Positions) {
        position.BreakEven();
    }
}

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

استخدام طرق التوسيع في المؤشرات

سننشئ أيضًا مؤشرًا مفيدًا يعتمد على طرق التوسيع. سيقيس المؤشر التقلب من خلال رسم النسبة المئوية التي تغير بها سعر الرمز في كل شمعة مقارنة بسعر الافتتاح لتلك الشمعة.

للقيام بذلك، سننشئ مؤشرًا جديدًا ونعيد تسميته. في نافذة محرر الكود، سننشئ فئة MyExtensions لتوسيع فئة Bar.

1
2
3
public static class MyExtensions {

}

سنضيف أيضًا طريقة PercentageChange(). في المتغير priceChange، نطرح سعر إغلاق الشمعة من سعر افتتاحها. تعيد الطريقة تغير السعر الخاص بنا مقسومًا على سعر الافتتاح ومضروبًا في 100.

1
2
3
4
5
6
7
8
public static class MyExtensions 
{
    public static double PercentageChange(this Bar bar) 
    {
        var priceChange = bar.Open - bar.Close;
        return priceChange / bar.Open * 100;
    }
}

في كود المؤشر نفسه، ليس لدينا حاجة لطريقة Initialize() والمعلمات غير الضرورية. في جسم طريقة Calculate()، نستدعي ببساطة طريقة PercentageChange() الجديدة الخاصة بنا على كل شمعة.

1
2
3
4
5
6
7
8
[Output("Main")]
public IndicatorDataSeries Result { get; set; }


public override void Calculate(int index)
{
    Result[index] = Bars[index].PercentageChange();
}

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

الملخص

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