Bỏ qua

Các thao tác nâng cao với chỉ báo

Bài viết này bổ sung cho danh sách mẫu mã chỉ báo đầy đủ của chúng tôi. Chúng tôi mở rộng một số khái niệm được đề cập trong các mẫu mã này và thảo luận về một số tính năng nâng cao mà bạn có thể triển khai khi tạo các chỉ báo mới.

Thuộc tính cloud

Có lẽ bạn đã từng thấy các đám mây trong suốt trên các biểu đồ giao dịch.

Image title

Bạn có thể thêm các đám mây vào đầu ra chỉ báo của mình bằng cách sử dụng thuộc tính lớp CloudAttribute như trong ví dụ dưới đây:

 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
    }
}

Hàm tạo CloudAttribute nhận hai tên đường đầu ra. Sau đó, nó tự động vẽ đám mây để khớp với khoảng trống giữa hai đầu ra này.

Bạn cũng có thể đặt độ mờ của đám mây bằng cách sử dụng thuộc tính Opacity. Để thiết lập màu sắc của đám mây, hãy sử dụng thuộc tính FirstColor. Theo mặc định, màu sắc của đám mây sẽ khớp với màu sắc của đường đầu tiên trong đầu ra chỉ báo.

Làm việc với màu sắc

Algo API bao gồm enum Color có thể được sử dụng để cấu hình màu sắc cho các đối tượng Chart, điều khiển biểu đồ và đầu ra.

Các giá trị của enum Color đại diện cho các màu thường được sử dụng. Bạn có thể sử dụng chúng mà không cần phải xử lý các mã màu thập lục phân hoặc ARGB.

Khi tùy chỉnh đầu ra, bạn có thể đặt màu sắc của chúng bằng cách sử dụng thuộc tính chuỗi LineColor. Như được hiển thị bên dưới, nó chấp nhận cả tên màu và mã màu thập lục phân.

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; }

Ghi chú

Màu sắc cũng có thể được coi là các tham số có thể tùy chỉnh. Để cho phép người dùng chọn màu tùy chỉnh (ví dụ: màu sắc của các đường được vẽ bởi một chỉ báo), hãy khai báo một tham số thuộc loại Color.

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

Trong ví dụ dưới đây, chúng ta tạo một chỉ báo đơn giản (cao trừ thấp) mà khi được khởi tạo, hiển thị văn bản trên biểu đồ giao dịch mà nó được gắn vào.

 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);
        }
    }
}

Các loại đầu ra

Có một số loại đầu ra khác nhau có sẵn cho các chỉ báo tùy chỉnh:

  • Line - một đường liên tục.
  • DiscontinuousLine - một đường không liên tục hữu ích cho các trường hợp mà chỉ báo của bạn không phải lúc nào cũng có giá trị tính toán.
  • Points - một điểm hoặc một chấm cho mỗi thanh.
  • Histogram - một chuỗi các thanh dọc. Khi sử dụng loại này, hãy đặt thuộc tính IsOverlay của chỉ báo của bạn thành false.

Để đặt loại đầu ra, hãy sử dụng thuộc tính PlotType như được minh họa dưới đây.

 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; }

Tham số enum

Loại enum cần thiết để tạo các tham số có một số tùy chọn được xác định trước mà người dùng có thể chọn. Chúng ta sử dụng loại enum trong ví dụ sau:

 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; }

Nếu bạn thêm tham số này vào một chỉ báo hoặc cBot, bạn sẽ thấy một menu tương tác đa lựa chọn cho phép bạn chọn một trong các giá trị enum được chỉ định.

Làm việc với thời gian

Thời gian nền tảng và máy chủ

Bạn có thể lấy thời gian máy chủ hiện tại bằng cách truy cập thuộc tính Server.Time hoặc Server.TimeInUtc.

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

Thuộc tính Server.Time đại diện cho thời gian hiện tại trong múi giờ chỉ báo hoặc cBot của bạn được thiết lập thông qua thuộc tính TimeZone.

Thời gian mở thanh

Sử dụng bộ sưu tập Bars.OpenTime để lấy thời gian mở thanh. Múi giờ sẽ dựa trên múi giờ bạn đã chỉ định trong thuộc tính lớp TimeZone.

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

Độ lệch thời gian nền tảng

Sử dụng thuộc tính Application.UserTimeOffset để lấy múi giờ của nền tảng của người dùng. Điều này chủ yếu được sử dụng để chuyển đổi thời gian chỉ báo của bạn sang múi giờ của người dùng.

1
var userPlatformTimeOffset = Application.UserTimeOffset;

Thuộc tính Application.UserTimeOffset trả về một đối tượng TimeSpan đại diện cho độ lệch thời gian được người dùng đặt trong nền tảng cTrader của họ so với thời gian UTC.

Bạn cũng có thể chọn được thông báo khi người dùng thay đổi độ lệch thời gian nền tảng của họ. Để làm điều này, hãy sử dụng sự kiện 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;
}

Lấy thời gian bằng tham số

cTrader hỗ trợ các loại tham số ngày và giờ chuyên dụng cho phép bạn nhận các giá trị ngày và giờ được định kiểu mạnh làm đầu vào cho các thuật toán của bạn thay vì sử dụng loại tham số string.

Bằng cách sử dụng các loại tham số ngày và giờ mới, bạn có thể nhận được các giá trị trong múi giờ thuật toán của bạn với xác thực tối thiểu và tối đa tích hợp sẵn và hỗ trợ tối ưu hóa đầy đủ, giống như các loại tham số khác.

Để lấy một giá trị thời gian nhất định thông qua một tham số có thể tùy chỉnh, bạn có thể sử dụng các loại C# này:

  • DateTime
  • DateOnly
  • TimeSpan

Dưới đây là một ví dụ về cách thực hiện điều này:

 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