عينات كود المؤشرات
توفر هذه الصفحة العديد من أمثلة الكود بلغتي Python و C# لإنشاء مؤشرات فنية تستخدم للتداول اليدوي أو الخوارزمي.
مستودعات عينات المؤشرات
تتوفر عينات كود شاملة للمؤشرات، بما في ذلك قوالب جاهزة للتشغيل لأنواع مختلفة من المؤشرات وأدوات التحليل الفني، في مستودعات منفصلة لـ Python و C# في GitHub.
المؤشرات البسيطة
يقوم مؤشر الفرق بين الأعلى والأدنى بحساب الفرق بين أسعار الأعلى والأدنى للشمعة الحالية ويعرضه في سلسلة النتائج. يتم رسم السلسلة على الرسم البياني كخط يربط بين القيم الناتجة في كل شمعة.
1 2 3 4 5 6 7 8 9 10 11 | |
ملاحظة
تستخدم مؤشرات Python معلمات قابلة للتخصيص معلنة في ملفات .cs الخاصة بها.
1 2 3 4 5 6 7 | |
يتضمن إعلان [Indicator...] العديد من المعلمات المحددة على النحو التالي:
IsOverlay- قيمة منطقية تحدد ما إذا كان سيتم تراكب الخط على الرسم البياني أو عرضه في لوحة واجهة مستخدم منفصلة.TimeZone- حقل من فئةTimeZonesيحدد المنطقة الزمنية لبيانات المؤشر ووقت الخادم.AccessRights- حقل من فئةAccessRightsيحدد حقوق الوصول المخصصة لمؤشرك.ScalePrecision- عدد صحيح يحدد دقة مقياس مخرجات المؤشر.
كما تعلمت سابقًا عند تحرير كود المؤشر، يتم إعلان السمة Output لتمييز خاصية كمخرج للمؤشر. يجب أن تكون هذه الخاصية public حتى يمكن الإشارة إليها من قبل الفئات الأخرى.
يجب أن يكون مخرج المؤشر دائمًا من نوع البيانات IndicatorDataSeries وهو قائمة من الأرقام المزدوجة التي يمكن فهرستها مثل المصفوفة. لذلك، يمكن تعيين القيمة في كل [index] في القائمة Result في طريقة Calculate على النحو التالي.
1 2 3 4 | |
1 2 | |
المؤشرات ذات المعلمات
في معظم الحالات، يمكن أن تختلف مخرجات المؤشرات اعتمادًا على مدخلات المستخدم. طريقة إعداد المعلمات القابلة للتخصيص للمؤشرات مشابهة لكيفية القيام بذلك لـ cBots.
تم تصميم مؤشر المتوسط المتحرك البسيط أدناه لقبول مصدر السعر وفترة كمعلمات قابلة للتخصيص. يجب أن تسبق هذه المعلمات (Source و Periods في هذا المثال المحدد) السمة Parameter.
على غرار السمات [Indicator()] و [Output()] التي نوقشت سابقًا، يمكن للسمة [Parameter()] تحديد خصائص معينة تطبق على مدخلات المستخدم.
1 | |
ملاحظة
تستخدم مؤشرات Python معلمات قابلة للتخصيص معلنة في ملفات .cs الخاصة بها.
أعلاه، نحدد الخصائص التالية:
- الاسم المعروض للإشارة إلى هذه المعلمة في واجهة مستخدم cTrader (
"MA Periods"). - القيمة الافتراضية للمعلمة؛ يمكن للمستخدم تغييرها عند تخصيص نسخة (
DefaultValue = 14) - الحد الأدنى والأقصى لقيم المعلمات (
MinValue = 1, MaxValue = 20)
في المقتطف التالي، نوضح كيف يمكن دمج المعلمات القابلة للتخصيص في كود المؤشر.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
ملاحظة
تستخدم مؤشرات Python معلمات قابلة للتخصيص معلنة في ملفات .cs الخاصة بها.
1 2 3 4 5 6 7 8 | |
المؤشرات المتداخلة
المؤشرات المتداخلة هي المؤشرات التي تعتمد قيمتها على نتائج الحسابات التي تجريها المؤشرات الأخرى. وهي مفيدة عند كتابة أنواع معينة من الإضافات مثل مؤشر DeMark 9. انظر إلى نموذج الكود التالي:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | |
ملاحظة
تستخدم مؤشرات Python معلمات قابلة للتخصيص معلنة في ملفات .cs الخاصة بها.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
في المثال أعلاه، deMinMA و deMaxMA هما متغيران يستخدمان لحساب قيمة مؤشر DeMarker الخاص بنا.
يجب تعريف المؤشرات المتداخلة في طريقة Initialize(). على سبيل المثال، يتم تعريف deMinMA كمتوسط متحرك بسيط للسلسلة deMin.
1 | |
1 | |
يتم تعريف deMin بدوره في طريقة Calculate() كحد أقصى لآخر قيمتين لسعر الأدنى.
1 | |
1 | |
لتبسيط العمل مع المؤشرات المتداخلة، يقوم IntelliSense تلقائيًا بملء قائمة جميع المؤشرات المدمجة عندما تكتب Indicators متبوعة بنقطة في محرر الكود. كما سيعرض جميع معلمات الإدخال ذات الصلة بمجرد اختيارك لمؤشر معين من هذه القائمة.

التحميل الكسول
يستخدم cTrader Algo التحميل الكسول عند استخدام المؤشرات المرجعية. لا يتم حساب القيم التي يوفرها المؤشر المرجعي حتى يبدأ الكود الخاص بك في استخدامها بنشاط.
إذا قمت بالوصول إلى بيانات Outputs لمؤشر مرجعي، سيبدأ cTrader في تحميل بيانات المؤشر عن طريق استدعاء طريقة Calculate() الخاصة به على الشموع السابقة والمستقبلية. في أي حالة أخرى، سيظل المؤشر المرجعي خاملاً وبالتالي لن يستهلك أي موارد نظام.
هذا يعني أيضًا أنه إذا لم يكن لمؤشرك أي Output أو إذا حاولت الوصول إلى أي من خصائصه العامة، ستحصل على القيمة الافتراضية للخاصية المعنية. لحل هذه المشكلة، قم باستدعاء طريقة Calculate() لمؤشرك المخصص من طريقة Calculate() للمؤشر الحالي.
المذبذبات وسمة المستويات
يشمل مصطلح "المذبذبات" جميع المؤشرات التي تتذبذب حول متغير ثابت معين.
عند إنشاء المذبذبات، من المفيد أولاً رسم خط أفقي أو "مستوى" عند تلك القيمة الثابتة؛ سيتذبذب المؤشر بعد ذلك حول هذا الخط. في كثير من الحالات، تساوي القيمة الثابتة صفرًا.
في المثال أدناه، نحدد مذبذب الزخم. عادة ما يتذبذب حول القيمة 100. نضيف خط مستوى عند هذه القيمة باستخدام السمة Levels التي يتم إعلانها قبل سمات المؤشر.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
ملاحظة
تستخدم مؤشرات Python معلمات قابلة للتخصيص معلنة في ملفات .cs الخاصة بها.
1 2 3 4 | |
لاحظ أنه يمكن استخدام السمة Levels فقط إذا لم يتم تراكب المؤشر على الرسم البياني، مما يعني أن خاصية IsOverlay لم يتم تعيينها إلى true. بشكل افتراضي، تكون قيمة IsOverlay هي false. إذا تم حذف هذه السمة من الكود الخاص بك، يجب أن تعمل Levels بشكل صحيح.
إذا كنت بحاجة إلى إنشاء خطوط "مستوى" متعددة، أضف قائمة قيم مفصولة بفواصل داخل الأقواس كما هو موضح أدناه.
1 | |
1 | |
1 | |
المستويات في مؤشرات Python
في Python، تقوم بإعلان المستويات في ملف C# الخاص بمؤشرك بنفس طريقة مؤشرات C#.
خاصية IsLastBar
في بعض الحالات، قد ترغب في إنشاء مؤشر يجب حسابه فقط للشمعة الأخيرة في الرسم البياني للتداول. لتبسيط ذلك، يمكن استخدام خاصية IsLastBar للتحقق مما إذا كان معلمة الفهرس لطريقة Calculate() هي للشمعة الأخيرة.
يعتمد المؤشر أدناه على توقيت UTC؛ ومع ذلك، يمكنه عرض آخر وقت افتتاح في نيويورك وطوكيو.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
دمج المؤشرات
يسمح cTrader بدمج مؤشرات متعددة في نفس اللوحة أو داخل نفس الرسم البياني.
يجمع المؤشر التالي بين مؤشرات Aroon و RSI ونظام الحركة الاتجاهية في واحد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | |
ملاحظة
تستخدم مؤشرات Python معلمات قابلة للتخصيص معلنة في ملفات .cs الخاصة بها.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
الأطر الزمنية المتعددة
-
استخدام الأطر الزمنية المتعددة
يعرض المثال التالي مؤشر المتوسط المتحرك على أطر زمنية مختلفة.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)] public class MultiTF_MA : Indicator { [Parameter(DefaultValue = 50)] public int Period { get; set; } [Output("MA", LineColor = "Yellow")] public IndicatorDataSeries MA { get; set; } [Output("MA5", LineColor = "Orange")] public IndicatorDataSeries MA5 { get; set; } [Output("MA10", LineColor = "Red")] public IndicatorDataSeries MA10 { get; set; } private Bars bars5; private Bars bars10; private MovingAverage ma; private MovingAverage ma5; private MovingAverage ma10; protected override void Initialize() { bars5 = MarketData.GetBars(TimeFrame.Minute5); bars10 = MarketData.GetBars(TimeFrame.Minute10); ma = Indicators.MovingAverage(Bars.ClosePrices, Period, MovingAverageType.Triangular); ma5 = Indicators.MovingAverage(bars5.ClosePrices, Period, MovingAverageType.Triangular); ma10 = Indicators.MovingAverage(bars10.ClosePrices, Period, MovingAverageType.Triangular); } public override void Calculate(int index) { MA[index] = ma.Result[index]; var index5 = bars5.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]); if (index5 != -1) MA5[index] = ma5.Result[index5]; var index10 = bars10.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]); if (index10 != -1) MA10[index] = ma10.Result[index10]; } }ملاحظة
تستخدم مؤشرات Python معلمات قابلة للتخصيص معلنة في ملفات
.csالخاصة بها.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
class MultiTF_MA(): def initialize(self): self.bars5 = api.MarketData.GetBars(TimeFrame.Minute5) self.bars10 = api.MarketData.GetBars(TimeFrame.Minute10) # Period is declared as a parameter in the C# file # We use indicator time frame bars for this moving average self.ma = Indicators.MovingAverage(api.Bars.ClosePrices, api.Period, MovingAverageType.Triangular) # We use other two time frame bars that we created previously # for these two moving averages self.ma5 = Indicators.MovingAverage(self.bars5.ClosePrices, api.Period, MovingAverageType.Triangular) self.ma10 = Indicators.MovingAverage(self.bars10.ClosePrices, api.Period, MovingAverageType.Triangular) def calculate(self, index): # MA, MA5, and MA10 are outputs we declared in the C# file api.MA[index] = self.ma.Result[index] index5 = self.bars5.OpenTimes.GetIndexByTime(api.Bars.OpenTimes[index]) if index5 > -1: api.MA5[index] = self.ma5.Result[index5] index10 = self.bars10.OpenTimes.GetIndexByTime(api.Bars.OpenTimes[index]) if index10 > -1: api.MA10[index] = self.ma10.Result[index10] -
استخدام أطر زمنية ورموز متعددة
يعرض المثال التالي مؤشر المتوسط المتحرك على أطر زمنية ورموز متعددة.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)] public class MultiSymbolMA : Indicator { private MovingAverage ma1, ma2, ma3; private Bars bars2, bars3; private Symbol symbol2, symbol3; [Parameter(DefaultValue = "EURCHF")] public string Symbol2 { get; set; } [Parameter(DefaultValue = "EURCAD")] public string Symbol3 { get; set; } [Parameter(DefaultValue = 14)] public int Period { get; set; } [Parameter(DefaultValue = MovingAverageType.Simple)] public MovingAverageType MaType { get; set; } [Output("MA Symbol 1", LineColor = "Magenta")] public IndicatorDataSeries Result1 { get; set; } [Output("MA Symbol 2", LineColor = "Magenta")] public IndicatorDataSeries Result2 { get; set; } [Output("MA Symbol 3", LineColor = "Magenta")] public IndicatorDataSeries Result3 { get; set; } protected override void Initialize() { symbol2 = Symbols.GetSymbol(Symbol2); symbol3 = Symbols.GetSymbol(Symbol3); bars2 = MarketData.GetBars(TimeFrame, symbol2.Name); bars3 = MarketData.GetBars(TimeFrame, symbol3.Name); ma1 = Indicators.MovingAverage(Bars.ClosePrices, Period, MaType); ma2 = Indicators.MovingAverage(bars2.ClosePrices, Period, MaType); ma3 = Indicators.MovingAverage(bars3.ClosePrices, Period, MaType); } public override void Calculate(int index) { ShowOutput(Symbol, Result1, ma1, Bars, index); ShowOutput(symbol2, Result2, ma2, bars2, index); ShowOutput(symbol3, Result3, ma3, bars3, index); } private void ShowOutput(Symbol symbol, IndicatorDataSeries result, MovingAverage movingAverage, Bars bars, int index) { var index2 = bars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]); result[index] = movingAverage.Result[index2]; string text = string.Format("{0} {1}", symbol.Name, Math.Round(result[index], symbol.Digits)); Chart.DrawStaticText(symbol.Name, text, VerticalAlignment.Top, HorizontalAlignment.Right, Color.Yellow); } }ملاحظة
تستخدم مؤشرات Python معلمات قابلة للتخصيص معلنة في ملفات
.csالخاصة بها.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
class MultiSymbolMA(): def initialize(self): # Symbol2 and Symbol3 are declared as parameters in the C# file self.symbol2 = api.Symbols.GetSymbol(api.Symbol2) self.symbol3 = api.Symbols.GetSymbol(api.Symbol3) self.bars2 = api.MarketData.GetBars(api.TimeFrame, self.symbol2.Name) self.bars3 = api.MarketData.GetBars(api.TimeFrame, self.symbol3.Name) self.ma1 = api.Indicators.MovingAverage(api.Bars.ClosePrices, api.Period, api.MaType) self.ma2 = api.Indicators.MovingAverage(self.bars2.ClosePrices, api.Period, api.MaType) self.ma3 = api.Indicators.MovingAverage(self.bars3.ClosePrices, api.Period, api.MaType) def calculate(self, index): # Result1, Result2, and Result3 are declared as outputs in the C# file self.show_output(api.Symbol, api.Result1, self.ma1, api.Bars, index) self.show_output(self.symbol2, api.Result2, self.ma2, self.bars2, index) self.show_output(self.symbol3, api.Result3, self.ma3, self.bars3, index) def show_output(self, symbol, result, movingAverage, bars, index): index2 = bars.OpenTimes.GetIndexByTime(api.Bars.OpenTimes[index]) result[index] = movingAverage.Result[index2] text = f"{symbol.Name} {round(result[index], symbol.Digits)}" api.Chart.DrawStaticText(symbol.Name, text, VerticalAlignment.Top, HorizontalAlignment.Right, Color.Yellow)
