Mẫu mã chỉ báo
Trang này cung cấp một số ví dụ mã Python và C# để tạo các chỉ báo kỹ thuật được sử dụng cho giao dịch thủ công hoặc thuật toán.
Kho lưu trữ mẫu chỉ báo
Các mẫu mã chỉ báo toàn diện, bao gồm các mẫu sẵn sàng chạy cho các loại chỉ báo và công cụ phân tích kỹ thuật khác nhau, có sẵn trong các kho lưu trữ Python và C# riêng biệt trên GitHub.
Chỉ báo đơn giản
Chỉ báo cao trừ thấp tính toán sự chênh lệch giữa giá cao và giá thấp của thanh hiện tại và hiển thị nó trong một chuỗi đầu ra. Chuỗi này được vẽ trên biểu đồ dưới dạng một đường nối các giá trị kết quả ở mỗi thanh.
1 2 3 4 5 6 7 8 9 10 11 | |
Ghi chú
Các chỉ báo Python sử dụng các tham số có thể tùy chỉnh được khai báo trong các tệp .cs của chúng.
1 2 3 4 5 6 7 | |
Khai báo [Indicator...] bao gồm một số tham số được định nghĩa như sau:
IsOverlay- một boolean xác định liệu đường sẽ được xếp chồng lên biểu đồ hay hiển thị trong một bảng UI riêng biệt.TimeZone- một trường lớpTimeZoneschỉ định múi giờ của dữ liệu chỉ báo và thời gian máy chủ.AccessRights- một trường lớpAccessRightsxác định quyền truy cập được cấp cho chỉ báo của bạn.ScalePrecision- một int thiết lập độ chính xác của tỷ lệ đầu ra chỉ báo.
Như bạn đã học trước đây khi chỉnh sửa mã chỉ báo, thuộc tính Output được khai báo để đánh dấu một thuộc tính là đầu ra chỉ báo. Thuộc tính này nên là public để có thể được tham chiếu bởi các lớp khác.
Đầu ra chỉ báo luôn phải thuộc loại dữ liệu IndicatorDataSeries là một danh sách các số double có thể được lập chỉ mục như một mảng. Do đó, giá trị tại mỗi [index] trong danh sách Result có thể được gán trong phương thức Calculate như sau.
1 2 3 4 | |
1 2 | |
Chỉ báo có tham số
Trong hầu hết các trường hợp, kết quả đầu ra của chỉ báo có thể thay đổi tùy thuộc vào dữ liệu đầu vào của người dùng. Cách thiết lập các tham số có thể tùy chỉnh cho chỉ báo tương tự như cách thực hiện cho cBot.
Chỉ báo trung bình động đơn giản dưới đây được thiết kế để chấp nhận nguồn giá và khoảng thời gian làm tham số có thể tùy chỉnh. Các tham số như vậy (Source và Periods trong ví dụ cụ thể này) phải được đặt trước bởi thuộc tính Parameter.
Tương tự như các thuộc tính [Indicator()] và [Output()] đã thảo luận trước đó, thuộc tính [Parameter()] có thể xác định một số đặc điểm áp dụng cho dữ liệu đầu vào của người dùng.
1 | |
Ghi chú
Các chỉ báo Python sử dụng các tham số có thể tùy chỉnh được khai báo trong các tệp .cs của chúng.
Ở trên, chúng ta chỉ định các đặc điểm sau:
- Tên hiển thị để biểu thị tham số này trong giao diện người dùng cTrader (
"MA Periods"). - Giá trị mặc định của tham số; nó có thể được thay đổi bởi người dùng khi tùy chỉnh một phiên bản (
DefaultValue = 14) - Giá trị tối thiểu và tối đa của tham số (
MinValue = 1, MaxValue = 20)
Trong đoạn mã dưới đây, chúng ta thể hiện cách tích hợp các tham số có thể tùy chỉnh vào mã chỉ báo.
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 | |
Ghi chú
Các chỉ báo Python sử dụng các tham số có thể tùy chỉnh được khai báo trong các tệp .cs của chúng.
1 2 3 4 5 6 7 8 | |
Chỉ báo lồng nhau
Chỉ báo lồng nhau được định nghĩa là các chỉ báo mà giá trị của chúng phụ thuộc vào kết quả tính toán của các chỉ báo khác. Chúng hữu ích khi viết một số loại tiện ích mở rộng nhất định như chỉ báo DeMark 9. Hãy xem xét đoạn mã mẫu sau:
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 | |
Ghi chú
Các chỉ báo Python sử dụng các tham số có thể tùy chỉnh được khai báo trong các tệp .cs của chúng.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
Trong ví dụ trên, deMinMA và deMaxMA là hai biến được sử dụng để tính toán giá trị của chỉ báo DeMarker của chúng ta.
Các chỉ báo lồng nhau cần được định nghĩa trong phương thức Initialize(). Ví dụ, deMinMA được định nghĩa là trung bình động đơn giản của chuỗi deMin.
1 | |
1 | |
deMin, đến lượt nó, được định nghĩa trong phương thức Calculate() là giá trị lớn nhất của hai giá thấp nhất gần đây nhất.
1 | |
1 | |
Để đơn giản hóa việc làm việc với các chỉ báo lồng nhau, IntelliSense tự động điền danh sách tất cả các chỉ báo tích hợp sẵn khi bạn nhập Indicators theo sau là dấu chấm vào trình soạn thảo mã. Nó cũng sẽ hiển thị tất cả các tham số đầu vào liên quan khi bạn chọn một chỉ báo nhất định từ danh sách này.

Tải lười biếng
cTrader Algo sử dụng tải lười biếng khi bạn sử dụng các chỉ báo được tham chiếu. Các giá trị được cung cấp bởi chỉ báo được tham chiếu không được tính toán cho đến khi mã của bạn bắt đầu sử dụng chúng một cách tích cực.
Nếu bạn truy cập dữ liệu Outputs của một chỉ báo được tham chiếu, cTrader sẽ bắt đầu tải dữ liệu chỉ báo bằng cách gọi phương thức Calculate() của nó trên các nến quá khứ và tương lai. Trong mọi trường hợp khác, chỉ báo được tham chiếu sẽ vẫn ở trạng thái không hoạt động và do đó sẽ không tiêu tốn bất kỳ tài nguyên hệ thống nào.
Điều này cũng có nghĩa là nếu chỉ báo của bạn không có bất kỳ Output nào hoặc nếu bạn cố gắng truy cập bất kỳ thuộc tính công khai nào của nó, bạn sẽ nhận được giá trị mặc định của thuộc tính đó. Để giải quyết vấn đề này, hãy gọi phương thức Calculate() của chỉ báo tùy chỉnh của bạn từ phương thức Calculate() của chỉ báo hiện tại.
Dao động kế và thuộc tính levels
Thuật ngữ "dao động kế" bao gồm tất cả các chỉ báo dao động quanh một biến không đổi nhất định.
Khi tạo dao động kế, việc đầu tiên vẽ một đường ngang hoặc đường "mức" tại giá trị không đổi đó là hữu ích; chỉ báo sau đó sẽ dao động quanh đường này. Trong nhiều trường hợp, giá trị không đổi bằng không.
Trong ví dụ dưới đây, chúng ta định nghĩa một dao động kế động lượng. Nó thường dao động quanh giá trị 100. Chúng ta thêm một đường mức tại giá trị này bằng cách sử dụng thuộc tính Levels được khai báo trước các thuộc tính chỉ báo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Ghi chú
Các chỉ báo Python sử dụng các tham số có thể tùy chỉnh được khai báo trong các tệp .cs của chúng.
1 2 3 4 | |
Lưu ý rằng thuộc tính Levels chỉ có thể được sử dụng nếu chỉ báo không được xếp chồng lên biểu đồ, nghĩa là thuộc tính IsOverlay không được đặt thành true. Theo mặc định, giá trị của IsOverlay là false. Nếu thuộc tính này bị bỏ qua trong mã của bạn, Levels sẽ hoạt động bình thường.
Nếu bạn cần thiết lập nhiều đường "mức", hãy thêm một danh sách các giá trị được phân tách bằng dấu phẩy trong dấu ngoặc đơn như hiển thị bên dưới.
1 | |
1 | |
1 | |
Levels trong Chỉ báo Python
Trong Python, bạn khai báo Levels trong tệp chỉ báo C# của mình giống như các chỉ báo C#.
Thuộc tính IsLastBar
Trong một số trường hợp, bạn có thể muốn tạo một chỉ báo chỉ cần được tính toán cho nến cuối cùng trong biểu đồ giao dịch. Đơn giản hóa điều này, thuộc tính IsLastBar có thể được sử dụng để kiểm tra xem tham số chỉ mục của phương thức Calculate() có phải là của nến cuối cùng hay không.
Chỉ báo dưới đây dựa trên thời gian UTC; tuy nhiên, nó có thể hiển thị thời gian mở cửa cuối cùng ở New York và Tokyo.
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 | |
Kết hợp các chỉ báo
cTrader cho phép kết hợp nhiều chỉ báo trong cùng một bảng điều khiển hoặc trong cùng một biểu đồ.
Chỉ báo sau đây kết hợp các chỉ báo Aroon, RSI và hệ thống chuyển động có hướng trong một.
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 | |
Ghi chú
Các chỉ báo Python sử dụng các tham số có thể tùy chỉnh được khai báo trong các tệp .cs của chúng.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Nhiều khung thời gian
-
Sử dụng nhiều khung thời gian
Ví dụ sau đây hiển thị chỉ báo Moving Averages trên các khung thời gian khác nhau.
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]; } }Ghi chú
Các chỉ báo Python sử dụng các tham số có thể tùy chỉnh được khai báo trong các tệp
.cscủa chúng.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] -
Sử dụng nhiều khung thời gian và cặp tiền tệ
Ví dụ sau đây hiển thị chỉ báo Moving Averages trên nhiều khung thời gian và biểu tượng.
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); } }Ghi chú
Các chỉ báo Python sử dụng các tham số có thể tùy chỉnh được khai báo trong các tệp
.cscủa chúng.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)
