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

العمليات المتقدمة مع المؤشرات

تكمل هذه المقالة قائمتنا الشاملة من عينات كود المؤشرات. نتوسع في بعض المفاهيم المذكورة في عينات الكود هذه ونناقش العديد من الميزات المتقدمة التي يمكنك تنفيذها عند إنشاء مؤشرات جديدة.

سمة السحابة

من المحتمل أنك رأيت سحابًا شفافة على مخططات التداول.

Image title

يمكنك إضافة سحب إلى مخرجات المؤشر الخاص بك باستخدام سمة الفئة CloudAttribute كما هو موضح في المثال أدناه:

 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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using cAlgo.API;
using cAlgo.API.Indicators;
using System;

namespace cAlgo
{
    /// <summary>
    /// This indicator shows how to make a built-in cTrader indicator multi time frame and how to use cloud attribute
    /// </summary>
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None), Cloud("Top", "Bottom", Opacity = 0.2)]
    public class BollingerBandsMTFCloudSample : Indicator
    {
        private BollingerBands _bollingerBands;

        private Bars _baseBars;

        [Parameter("Base TimeFrame", DefaultValue = "Daily")]
        public TimeFrame BaseTimeFrame { get; set; }

        [Parameter("Source", DefaultValue = DataSeriesType.Close)]
        public DataSeriesType DataSeriesType { get; set; }

        [Parameter("Periods", DefaultValue = 14, MinValue = 0)]
        public int Periods { get; set; }

        [Parameter("Standard Deviation", DefaultValue = 2, MinValue = 0)]
        public double StandardDeviation { get; set; }

        [Parameter("MA Type", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { get; set; }

        [Output("Main", LineColor = "Yellow", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries Main { get; set; }

        [Output("Top", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries Top { get; set; }

        [Output("Bottom", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries Bottom { get; set; }

        protected override void Initialize()
        {
            _baseBars = MarketData.GetBars(BaseTimeFrame);

            var baseSeries = GetBaseSeries();

            _bollingerBands = Indicators.BollingerBands(baseSeries, Periods, StandardDeviation, MaType);
        }

        public override void Calculate(int index)
        {
            var baseIndex = _baseBars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);

            Main[index] = _bollingerBands.Main[baseIndex];
            Top[index] = _bollingerBands.Top[baseIndex];
            Bottom[index] = _bollingerBands.Bottom[baseIndex];
        }

        private DataSeries GetBaseSeries()
        {
            switch (DataSeriesType)
            {
                case DataSeriesType.Open:
                    return _baseBars.OpenPrices;

                case DataSeriesType.High:
                    return _baseBars.HighPrices;

                case DataSeriesType.Low:
                    return _baseBars.LowPrices;

                case DataSeriesType.Close:
                    return _baseBars.ClosePrices;
                default:

                    throw new ArgumentOutOfRangeException("DataSeriesType");
            }
        }
    }

    public enum DataSeriesType
    {
        Open,
        High,
        Low,
        Close
    }
}

يأخذ منشئ CloudAttribute اسمين لخطي الإخراج. بعد ذلك، يقوم تلقائيًا برسم السحابة لتتطابق مع المساحة بين هذين المخرجين.

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

العمل مع الألوان

تتضمن واجهة برمجة التطبيقات Algo enum Color التي يمكن استخدامها لتكوين الألوان لكائنات Chart، وعناصر التحكم في المخطط والمخرجات.

تمثل قيم enum Color الألوان شائعة الاستخدام. يمكنك استخدامها دون الحاجة إلى التعامل مع رموز الألوان السداسية عشرية أو ARGB.

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

1
2
3
4
_ = Chart.DrawStaticText("NamedColor", "This is text using Color class color name properties", VerticalAlignment.Center, HorizontalAlignment.Center, Color.Red);
_ = Chart.DrawStaticText("HexadecimalColor", "This is text using Hexadecimal color", VerticalAlignment.Bottom, HorizontalAlignment.Center, Color.FromHex("#FF5733"));
_ = Chart.DrawStaticText("ARGBColor", "This is text using ARGB color", VerticalAlignment.Top, HorizontalAlignment.Center, Color.FromArgb(255, 200, 100, 60));
_ = Chart.DrawStaticText("ParsedNameColor", "This is text using color name by parsing it from string", VerticalAlignment.Center, HorizontalAlignment.Left, Color.FromName("Yellow"));
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
var stackPanel = new StackPanel
{
    Orientation = Orientation.Vertical,
    HorizontalAlignment = HorizontalAlignment.Center,
    VerticalAlignment = VerticalAlignment.Center
};

stackPanel.AddChild(new TextBlock { Text = "Red Color property", BackgroundColor = Color.Red });
stackPanel.AddChild(new TextBlock { Text = "Hexadecimal Color code", BackgroundColor = Color.FromHex("#FF5733") });
stackPanel.AddChild(new TextBlock { Text = "ARGB Color", BackgroundColor = Color.FromArgb(200, 100, 40, 80) });
stackPanel.AddChild(new TextBlock { Text = "Color Name", BackgroundColor = Color.FromName("Green") });

Chart.AddControl(stackPanel);
1
2
3
4
5
[Output("Hexadecimal", LineColor = "#FF5733", PlotType = PlotType.Line, Thickness = 1)]
public IndicatorDataSeries Hexadecimal { get; set; }

[Output("Name", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]
public IndicatorDataSeries Name { get; set; }

ملاحظة

يمكن أيضًا معاملة الألوان كمعلمات قابلة للتخصيص. للسماح للمستخدمين باختيار ألوان مخصصة (على سبيل المثال، ألوان الخطوط التي يرسمها المؤشر)، قم بإعلان معلمة من نوع Color.

1
2
[Parameter("Drawing Color", DefaultValue = "#f54242")]
public Color DrawingColor { get; set; }

في المثال أدناه، نقوم بإنشاء مؤشر بسيط (الأعلى ناقص الأدنى) والذي، عند تهيئته، يعرض نصًا على مخطط التداول الذي تم إرفاقه به.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Collections;
using cAlgo.API.Internals;

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class HighMinusLowColor: Indicator
    {
        [Parameter("Text Color", DefaultValue="#f54242")]
        public Color TextColor { get; set; }

        public override void Initialize()
        {
            var staticText = Chart.DrawStaticText("static", "This text shows how color parameters work", VerticalAlignment.Center, HorizontalAlignment.Center, TextColor);
        }
    }
}

أنواع المخرجات

هناك عدة أنواع مختلفة من المخرجات المتاحة للمؤشرات المخصصة:

  • Line - خط مستمر.
  • DiscontinuousLine - خط غير مستمر مفيد للحالات التي لا يكون فيها للمؤشر الخاص بك قيمة حساب دائمًا.
  • Points - نقطة أو نقطة لكل شريط.
  • Histogram - سلسلة من الأشرطة العمودية. عند استخدام هذا النوع، قم بتعيين خاصية IsOverlay للمؤشر الخاص بك إلى false.

لتعيين نوع المخرج، استخدم خاصية PlotType كما هو موضح أدناه.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[Output("Line", PlotType = PlotType.Line)]
public IndicatorDataSeries Line { get; set; }

[Output("Discontinuous Line", PlotType = PlotType.DiscontinuousLine)]
public IndicatorDataSeries DiscontinuousLine { get; set; }

[Output("Points", PlotType = PlotType.Points)]
public IndicatorDataSeries Points { get; set; }

[Output("Histogram", PlotType = PlotType.Histogram)]
public IndicatorDataSeries Histogram { get; set; }

معلمات التعداد

يلزم نوع enum لإنشاء معلمات لها عدة خيارات محددة مسبقًا يمكن للمستخدمين الاختيار من بينها. نستخدم نوع enum في المثال التالي:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public enum Options
{
    First,
    Second,
    Third,
    Fourth
}

[Parameter("Options", DefaultValue = Options.Third)]
public Options OptionsParameter { get; set; }

إذا أضفت هذه المعلمة إلى مؤشر أو cBot، فسترى قائمة تفاعلية متعددة الخيارات تسمح لك باختيار إحدى قيم enum المحددة.

العمل مع الوقت

وقت المنصة والخادم

يمكنك الحصول على وقت الخادم الحالي عن طريق الوصول إلى خاصية Server.Time أو Server.TimeInUtc.

1
2
var currentServerTimeInIndicatorTimeZone = Server.Time;
var currentServerTimeInUtc = Server.TimeInUtc;

تمثل خاصية Server.Time الوقت الحالي في المنطقة الزمنية للمؤشر أو cBot الخاص بك والتي تم تحديدها عبر خاصية TimeZone.

وقت فتح الشمعة

استخدم مجموعة Bars.OpenTime للحصول على أوقات فتح الشموع. ستعتمد المنطقة الزمنية على المنطقة الزمنية التي حددتها في سمة الفئة TimeZone.

1
2
3
4
public override void Calculate(int index)
{
    var barTime = Bars.OpenTimes[index];
}

فارق التوقيت للمنصة

استخدم خاصية Application.UserTimeOffset للحصول على المنطقة الزمنية لمنصة المستخدم. يُستخدم هذا بشكل أساسي لتحويل وقت المؤشر الخاص بك إلى المنطقة الزمنية للمستخدم.

1
var userPlatformTimeOffset = Application.UserTimeOffset;

تُرجع خاصية Application.UserTimeOffset كائن TimeSpan يمثل فارق التوقيت الذي حدده المستخدم في منصة cTrader الخاصة به مقارنة بتوقيت UTC.

يمكنك أيضًا اختيار تلقي إشعار عندما يقوم المستخدم بتغيير فارق التوقيت للمنصة. للقيام بذلك، استخدم حدث Application.UserTimeOffsetChanged.

1
2
3
4
5
6
7
8
9
protected override void Initialize()
{
    Application.UserTimeOffsetChanged += Application_UserTimeOffsetChanged;
}

private void Application_UserTimeOffsetChanged(UserTimeOffsetChangedEventArgs obj)
{
    var platformTimeOffset = obj.UserTimeOffset;
}

الحصول على الوقت باستخدام معامل

تدعم cTrader أنواع معاملات التاريخ والوقت المخصصة التي تسمح لك بالحصول على قيم التاريخ والوقت ذات الأنواع القوية كمدخلات للخوارزميات الخاصة بك بدلاً من استخدام نوع المعامل string.

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

للحصول على قيمة وقت معينة عبر معامل قابل للتخصيص، يمكنك استخدام أنواع C# التالية:

  • DateTime
  • DateOnly
  • TimeSpan

فيما يلي مثال على كيفية القيام بذلك:

 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
using cAlgo.API;
using System;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Sample : Indicator
    {
        [Parameter("DateTime Parameter", MinValue = "1970-01-01T00:00:00", MaxValue = "2025-11-01T00:00:00", DefaultValue = "2025-01-01T10:00:00")]
        public DateTime DateTimeParameter { get; set; }

        [Parameter("DateOnly Parameter", MinValue = "1970-01-01", MaxValue = "2025-11-01", DefaultValue = "2025-01-01")]
        public DateOnly DateOnlyParameter { get; set; }

        [Parameter("TimeSpan Parameter", MinValue = "00:00:00", MaxValue = "23:59:59", DefaultValue = "04:10:20")]
        public TimeSpan TimeSpanParameter { get; set; }

        protected override void Initialize()
        {
            Print($"DateTimeParameter: {DateTimeParameter:o}");
            Print($"DateOnlyParameter: {DateOnlyParameter:o}");
            Print($"TimeSpanParameter: {TimeSpanParameter}");
        }

        public override void Calculate(int index)
        {
        }
    }
}

Image title