Bỏ qua

Cách thêm phương thức vào API cTrader

Phương thức mở rộng là một công cụ quan trọng nếu bạn muốn thêm chức năng mới vào API cTrader. Bằng cách sử dụng cú pháp tương đối đơn giản, bạn có thể thêm các hành vi mới vào bất kỳ lớp API được định nghĩa trước nào, chẳng hạn như Symbol hoặc Position. Sau khi bạn định nghĩa một phương thức mở rộng, bạn có thể gọi nó từ bất kỳ đối tượng nào của lớp mà bạn đã mở rộng.

Trường hợp sử dụng cho phương thức mở rộng

Đầu tiên, chúng ta sẽ thực hiện một minh họa nhanh về lý do tại sao bạn có thể muốn sử dụng phương thức mở rộng.

Sử dụng một cBot, chúng ta muốn có thể truy cập kích thước của một vị thế nhất định theo lot vì thông tin này trực tiếp ảnh hưởng đến chiến lược giao dịch ưa thích của chúng ta. Để làm điều này, chúng ta có thể thử khởi tạo một biến của lớp Position và sau đó cố gắng truy cập phương thức Lots() của nó.

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

Nếu chúng ta chỉ đơn giản gõ mã như vậy, chúng ta sẽ nhận được một lỗi cho biết rằng phương thức truy cập Lots() không tồn tại trong API. Nhưng nếu có cách để thêm một phương thức mới vào một thành viên API hiện có mà không ảnh hưởng đến bất kỳ chức năng nào khác thì sao?

Giả sử phương thức này tồn tại, chúng ta có thể đã tạo một cBot đơn giản mà trên mỗi nến, nó sẽ lặp qua danh sách tất cả các vị thế hiện tại và in kích thước của chúng theo lot vào nhật ký. Chúng ta sẽ định nghĩa phương thức OnBar() như sau.

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

Phương thức mở rộng cho phép chúng ta thêm chức năng Lots() chỉ trong vài dòng mã và sau đó tái sử dụng nó bất cứ khi nào chúng ta muốn trên bất kỳ đối tượng nào của lớp Position. Dưới đây, chúng ta giải thích cách bạn có thể tạo một phương thức mở rộng và cung cấp một số ví dụ về thuật toán sử dụng chúng.

Cách thức hoạt động của phương thức mở rộng

Khi làm việc với phương thức mở rộng, hãy lưu ý các quy tắc sau.

  • Phương thức mở rộng luôn là static.

Để khai báo một phương thức static, tất cả những gì bạn cần làm là sử dụng từ khóa static. Dưới đây, khai báo phương thức Lots() với phần thân trống.

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

}
  • Phương thức mở rộng có thể có bất kỳ số lượng đối số nào nhưng đối số đầu tiên luôn phải chỉ định kiểu dữ liệu/lớp mà phương thức được gọi, đứng trước là từ khóa this.

Chúng ta sẽ thêm một đối tượng của lớp Position làm đối số đầu tiên và duy nhất của phương thức Lots(). Vì đối tượng Position cũng chứa thông tin về biểu tượng mà vị thế được mở, chúng ta không cần bất kỳ đối số nào khác.

1
2
3
public static class MyExtensions {
    public static double Lots(this Position position) {}
}
  • Phương thức mở rộng có thể chứa bất kỳ logic nào phù hợp với các đối số được cung cấp.

Không cần phải sử dụng cú pháp đặc biệt khi định nghĩa phần thân của phương thức mở rộng. Chúng ta có thể coi nó như bất kỳ phương thức nào khác và do đó, có thể định nghĩa phần thân của nó như sau.

1
2
3
4
5
public static class MyExtensions {
    public static double Lots(this Position position) {
        return position.VolumeInUnits / position.Symbol.LotSize;
    }
}
  • Phương thức mở rộng có thể được gọi như phương thức thể hiện hoặc phương thức static.

Có hai cách có thể để gọi phương thức mở rộng của chúng ta trong mã của một cBot.

Khi sử dụng cú pháp phương thức thể hiện, chúng ta gọi phương thức từ bất kỳ đối tượng phù hợp nào của kiểu Position.

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

Khi sử dụng cú pháp phương thức static, chúng ta có thể gọi phương thức mở rộng của mình sau khi chỉ định đầy đủ lớp static tương ứng của nó.

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

Tùy thuộc vào bạn để xác định phương pháp nào để gọi phương thức mở rộng là thuận tiện nhất.

Chữ ký phương thức

Khi sử dụng cú pháp thể hiện, tránh các trường hợp mà phương thức mở rộng của bạn có cùng chữ ký với bất kỳ phương thức API tích hợp nào (như Position.Close()). Trong những tình huống này, một phương thức tích hợp sẽ được gọi mỗi khi bạn cố gắng gọi một phương thức mở rộng có chữ ký trùng khớp.

IntelliSense

Khi chúng ta cố gắng gọi một phương thức mở rộng, IntelliSense sử dụng một biểu tượng đặc biệt để phân biệt nó với các thành viên API tích hợp.

Để minh họa phương thức mới của chúng ta trong hành động, chúng ta có thể tạo một cBot đặt ba lệnh khi bắt đầu, mỗi lệnh có khối lượng khác nhau. Trên mỗi nến, cBot in khối lượng của tất cả các vị thế hiện đang mở theo lot.

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

Sau khi xây dựng và khởi chạy cBot của chúng ta, chúng ta sẽ thấy các giá trị chính xác được in trong nhật ký.

Sử dụng phương thức mở rộng trong cBot

Bây giờ chúng ta sẽ thử tạo một cBot phức tạp hơn. Trên mỗi nến, thuật toán của chúng ta sẽ duyệt qua danh sách các vị thế hiện đang mở và điều chỉnh mức cắt lỗ của chúng để chúng ở mức hòa vốn. Để làm điều này, chúng ta sẽ cần tạo một phương thức mở rộng BreakEven() cho lớp Position.

Chúng ta tạo một cBot mới và đổi tên nó. Sau đó, chúng ta xóa tất cả mã mà chúng ta không cần và thêm lớp MyExtensions.

1
2
3
public static class MyExtensions {

}

Mã của chúng ta cho phương thức BreakEven() tương đối đơn giản. Chúng ta kiểm tra xem một vị thế có cắt lỗ hay không, liệu tổng lợi nhuận của nó có lớn hơn không và liệu mức cắt lỗ hiện tại có khác với giá vào lệnh của vị thế hay không. Nếu tất cả các điều kiện này đều đúng, chúng ta sửa đổi mức cắt lỗ của vị thế để nó bằng với giá vào lệnh của vị thế.

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

Trong chính cBot, chúng ta không cần sử dụng bất kỳ phương thức nào khác ngoài OnBar(). Trên mỗi nến, chúng ta yêu cầu cBot thực hiện một thao tác đơn giản, cụ thể là lặp qua bộ sưu tập Positions và gọi phương thức BreakEven() mới cho mỗi phần tử trong đó.

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

Sau khi chúng ta xây dựng và khởi chạy cBot của mình, chúng ta có thể thấy nó hoạt động. Nó có thể là một trợ lý giao dịch hữu ích, đặc biệt là khi quản lý nhiều vị thế mở.

Sử dụng phương thức mở rộng trong chỉ báo

Chúng ta cũng sẽ tạo một chỉ báo hữu ích dựa trên phương thức mở rộng. Chỉ báo sẽ đo lường biến động bằng cách vẽ phần trăm mà giá của một biểu tượng đã thay đổi trên mỗi nến so với giá mở cửa của nến đó.

Để làm điều này, chúng ta sẽ tạo một chỉ báo mới và đổi tên nó. Trong cửa sổ trình chỉnh sửa mã, chúng ta sẽ tạo lớp MyExtensions để mở rộng lớp Bar.

1
2
3
public static class MyExtensions {

}

Chúng ta cũng sẽ thêm phương thức PercentageChange(). Trong biến priceChange, chúng ta trừ giá đóng cửa của một nến từ giá mở cửa của nó. Phương thức trả về sự thay đổi giá của chúng ta chia cho giá mở cửa và nhân với 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;
    }
}

Trong mã chỉ báo chính, chúng ta không cần phương thức Initialize() và các tham số không cần thiết. Trong phần thân của phương thức Calculate(), chúng ta chỉ đơn giản gọi phương thức PercentageChange() mới của mình trên mỗi nến.

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

Sau đó, chúng ta lưu và xây dựng chỉ báo của mình. Sau khi tạo một thể hiện của nó, chúng ta sẽ thấy các thay đổi phần trăm chính xác được vẽ. Chúng có thể được sử dụng để xác định biến động ngắn hạn và dài hạn, mang lại lợi ích cho tất cả các loại chiến lược giao dịch.

Tổng quan

Để kết luận, phương thức mở rộng là một công cụ có giá trị nếu bạn muốn tạo mã có thể tái sử dụng để thêm chức năng mới vào API cTrader. Chúng tôi rất khuyến khích thử nghiệm với phương thức mở rộng vì chúng có thể làm cho thuật toán của bạn hiệu quả hơn và dễ bảo trì hơn.