Bỏ qua

Mẫu mã cBot

Trang này cung cấp một số ví dụ mã PythonC# để tạo robot giao dịch và phát triển thuật toán. Lưu ý rằng không có cBot nào được liệt kê dưới đây đảm bảo bất kỳ lợi nhuận tài chính nào. Hãy đảm bảo backtest và tùy chỉnh cBot của bạn trước khi triển khai bất kỳ phiên bản nào trên tài khoản thực.

Kho lưu trữ mẫu cBot

Các mẫu mã cBot toàn diện, bao gồm các mẫu sẵn sàng chạy cho các chiến lược tự động và phong cách giao dịch khác nhau, có sẵn trong các kho lưu trữ PythonC# riêng biệt trên GitHub.

Các hoạt động đồng bộ

Tất cả các cBot trong phần này thực hiện các hoạt động của chúng một cách đồng bộ.

Thực hiện lệnh thị trường

  • Một cBot đơn giản thực hiện các hoạt động thành công

    Robot giao dịch sau đây tạo một lệnh thị trường khi khởi động và lưu kết quả vào biến result.

    Nếu việc thực hiện lệnh thành công, giá vào lệnh sẽ được in trong nhật ký.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            var result = ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000);
    
            if (result.IsSuccessful)
            {
                var position = result.Position;
                Print("Position entry price is {0}", position.EntryPrice);
            }
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    class Sample_cBot():
        def on_start(self):
            result = api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 10000)
    
            if result.IsSuccessful:
                position = result.Position
                api.Print(f"Position entry price is {position.EntryPrice}")
    

    Đầu ra nhật ký

    • cBot "New cBot" đã được khởi động thành công cho EURUSD, h1.
    • Đang thực hiện Lệnh Thị trường để Mua 10000 EURUSD
    • Thực hiện Lệnh Thị trường để Mua 10000 EURUSD THÀNH CÔNG, Vị thế PID14576001
    • Giá vào lệnh của vị thế là 1.19067
  • Một cBot đơn giản với các tham số có thể tùy chỉnh

    Khi khai báo các thuộc tính khác nhau của cBot, bạn có thể biến chúng thành các tham số có thể tùy chỉnh bằng cách sử dụng khai báo [Parameter()]. Khi một phiên bản mới của cBot của bạn được khởi chạy, bạn (hoặc người dùng khác) sẽ có thể gán các giá trị tùy chỉnh cho các tham số này.

    Hãy xem xét ví dụ sau.

    1
    2
    [Parameter("SMA Period", DefaultValue = 14)]
    public int SmaPeriod { get; set; }
    

    Ghi chú

    Các cBot Python sử dụng các tham số có thể tùy chỉnh được khai báo trong tệp .cs của chúng.

    1
    2
    [Parameter("SMA Period", DefaultValue = 14)]
    public int SmaPeriod { get; set; }
    

    Trong ví dụ trên, chúng tôi định nghĩa các đặc điểm sau:

    • Tên của tham số. Sau đó, nó sẽ xuất hiện trong giao diện người dùng cTrader ("SMA Period").
    • Giá trị mặc định của tham số sẽ áp dụng cho tất cả các phiên bản mới trừ khi nó được người dùng thay đổi (DefaultValue = 14).

    Trong đoạn mã dưới đây, chúng ta cho thấy cách thuộc tính SmaPeriod có thể được sử dụng trong một robot giao dịch thực tế.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SamplecBotReferenceSMA : Robot
    {
        [Parameter("Source")]
        public DataSeries Source { get; set; }
    
        [Parameter("SMA Period", DefaultValue = 14)]
        public int SmaPeriod { get; set; }
    
        private SampleSMA sma;
    
        protected override void OnStart()
        {
            sma = Indicators.GetIndicator<SampleSMA>(Source, SmaPeriod);
        }
    
        protected override void OnTick()
        {
            Print("{0}", sma.Result.LastValue);
        }
    }
    

    Ghi chú

    Các cBot Python sử dụng các tham số có thể tùy chỉnh được khai báo trong tệp .cs của chúng.

    1
    2
    3
    4
    5
    6
    class Sample_cBot():
        def on_start(self):
            self.sma = api.Indicators.GetIndicator<SampleSMA>(api.Source, api.SmaPeriod)
    
        def on_tick(self):
            api.Print(f"{self.sma.Result.LastValue}")
    

    Robot của chúng ta lấy thuộc tính SmaPeriod có thể tùy chỉnh và, khi bắt đầu, truyền giá trị của nó vào phương thức Indicators.GetIndicator<SampleSMA>(). Phương thức này trả về giá trị trung bình động đơn giản cho khoảng thời gian được chỉ định.

    Khi tạo một phiên bản cBot, tất cả các tham số có thể điều chỉnh có thể được thiết lập trong cửa sổ Thêm phiên bản.

    Khi được khởi chạy, cBot thông báo cho chúng ta biết giá trị trung bình động đơn giản cuối cùng là bao nhiêu trên mỗi tick.

    Đầu ra nhật ký

    • Phiên bản CBot [Sample cBot Reference SMA, EURUSD, h1] đã được khởi động.
    • 0.975685714285714
    • 0.975681428571429
    • 0.97568
    • Phiên bản CBot [Sample cBot Reference SMA, EURUSD, h1] đã bị dừng bởi người dùng.
  • Thực hiện lệnh thị trường với nhiều đối số hơn

    Trong ví dụ trước, chúng ta đã truyền số lượng đối số tối thiểu có thể cho phương thức ExecuteMarketOrder(). Chúng là loại giao dịch (TradeType.Buy), biểu tượng (Symbol) và khối lượng (-1).

    Phương thức ExecuteMarketOrder() có thể được gọi với các đối số bổ sung như Label, StopLoss, TakeProfitComment. Ví dụ dưới đây chỉ định nhãn ("order 1"), cơ chế bảo vệ cắt lỗ (10) và mức chốt lời (10).

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    [Robot(TimeZone = TimeZones.UTC)]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            var result = ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000, "order 1", 10, 10);
    
            if (result.IsSuccessful)
            {
                var position = result.Position;
                Print("Position entry price is {0}", position.EntryPrice);
                Print("Position SL price is {0}", position.StopLoss);
            }
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    class Sample_cBot():
        def on_start(self):
            result = api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 10000, "order 1", 10, 10)
    
            if result.IsSuccessful:
                position = result.Position
                api.Print(f"Position entry price is {position.EntryPrice}")
                api.Print(f"Position SL price is {position.StopLoss}")
    

    Đầu ra nhật ký

    • cBot "New cBot" đã được khởi động thành công cho EURUSD, h1.
    • Đang thực hiện Lệnh Thị trường để Mua 10000 EURUSD (SL: 10, TP: 10)
    • Thực hiện Lệnh Thị trường để Mua 10000 EURUSD (SL: 10, TP: 10) THÀNH CÔNG, Vị thế PID14576098
    • Giá vào lệnh của vị thế là 1.1896
    • Giá SL của vị thế là 1.1886

Chỉnh sửa một vị thế

Trong ví dụ dưới đây, chúng ta chỉ thêm giá trị chốt lời (10) khi một lệnh được thực hiện. Sau đó, chúng ta chỉnh sửa vị thế để thêm mức cắt lỗ.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
[Robot()]
public class SamplecBbot : Robot
{
    protected override void OnStart()
    {
        var result = ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000,
                                "order 1", null, 10);
        if (result.IsSuccessful)
        {
            var position = result.Position;
            Print("Position SL price is {0}", position.StopLoss);

            var stopLoss = position.EntryPrice - 10*Symbol.PipSize;
            ModifyPosition(position, stopLoss, position.TakeProfit);

            Print("New Position SL price is {0}", position.StopLoss);

        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Sample_cBot():
    def on_start(self):
        result = api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 10000, "order 1", None, 10)

        if result.IsSuccessful:
            position = result.Position
            api.Print(f"Position SL price is {position.StopLoss}")
            stopLoss = position.EntryPrice - 10 * api.Symbol.PipSize
            api.ModifyPosition(position, stopLoss, position.TakeProfit)
            api.Print(f"New Position SL price is {position.StopLoss}")

Đầu ra nhật ký

Đóng một vị thế

  • Thực hiện đóng toàn bộ

    Mẫu mã dưới đây đặt một lệnh thị trường. Nếu lợi nhuận gộp của vị thế kết quả vượt quá một giá trị nhất định (null && position.GrossProfit > 10), nó sẽ được đóng.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000, "myLabel");
        }
    
        protected override void OnTick()
        {
            var position = Positions.Find("myLabel");
            if (position != null && position.GrossProfit > 10)
            {
                ClosePosition(position);
                Stop();
            }
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Sample_cBot():
        def on_start(self):
            api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 10000, "myLabel")
    
        def on_tick(self):
            position = api.Positions.Find("myLabel")
            if position is not None and position.GrossProfit > 10:
                api.ClosePosition(position)
                api.Stop()
    

    Đầu ra nhật ký

    • cBot "New cBot" đã được khởi động thành công cho EURUSD, h1.
    • Đang thực hiện Lệnh Thị trường để Mua 10000 EURUSD
    • Thực hiện Lệnh Thị trường để Mua 10000 EURUSD THÀNH CÔNG, Vị thế PID14576180
  • Thực hiện đóng một phần

    Chúng ta sẽ chỉnh sửa ví dụ trước để tạo hai lệnh thị trường với cùng nhãn ("myLabel"). Trên mỗi nến mới, robot giao dịch của chúng ta sẽ đóng chính xác một nửa của một trong các lệnh này nhưng chỉ khi khối lượng của nó bằng hoặc lớn hơn 20.000.

    Chúng ta cũng sử dụng phương thức Positions.FindAll(). Nó trả về một danh sách các vị thế mà chúng ta có thể lặp qua.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 20000, "myLabel");
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 30000, "myLabel");
        }
    
        protected override void OnBar()
        {
            var positions = Positions.FindAll("myLabel", SymbolName, TradeType.Buy);
    
            foreach (var position in positions)
            {
                if (position.VolumeInUnits >= 20000)
                {
                    ClosePosition(position, 15000);
                }
            }
        }
    }
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    class Sample_cBot():
        def on_start(self):
            api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 20000, "myLabel")
            api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 30000, "myLabel")
    
        def on_tick(self):
            positions = api.Positions.FindAll("myLabel", api.SymbolName, TradeType.Buy)
            for position in positions:
                if position.VolumeInUnits >= 20000:
                    api.ClosePosition(position, 15000)
    

    Đầu ra nhật ký

    • cBot "New cBot" đã được khởi động thành công cho EURUSD, h1.
    • Đang thực hiện Lệnh Thị trường để Mua 20000 EURUSD
    • Thực hiện Lệnh Thị trường để Mua 20000 EURUSD THÀNH CÔNG, Vị thế PID14579299
    • Đang thực hiện Lệnh Thị trường để Mua 30000 EURUSD
    • Thực hiện Lệnh Thị trường để Mua 30000 EURUSD THÀNH CÔNG, Vị thế PID14579300

Tạo lệnh chờ

  • Tạo lệnh giới hạn và lệnh dừng

    Lệnh giới hạn và lệnh dừng là các lệnh chờ; mặc dù vậy, chúng được tạo tương tự như lệnh thị trường. Tuy nhiên, khi tạo lệnh giới hạn và lệnh dừng, bạn cũng phải chỉ định giá mục tiêu của chúng và không có phạm vi thị trường.

    cBot này tạo hai lệnh giới hạn và một lệnh dừng. Sau đó, nó lặp qua các lệnh và in nhãn và ID của chúng vào nhật ký.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            PlaceLimitOrder(TradeType.Buy, SymbolName, 10000, Symbol.Bid, "myLimitOrder");
            PlaceLimitOrder(TradeType.Buy, SymbolName, 20000, Symbol.Bid-2*Symbol.PipSize,
                    "myLimitOrder");
            PlaceStopOrder(TradeType.Buy, SymbolName, 10000, Symbol.Ask, "myStopOrder");
    
            foreach (var pendingOrder in PendingOrders)
            {
                Print("Order placed with label {0}, id {1}", pendingOrder.Label, pendingOrder.Id);
            }
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    class Sample_cBot():
        def on_start(self):
            api.PlaceLimitOrder(TradeType.Buy, api.SymbolName, 10000, api.Symbol.Bid, "myLimitOrder")
            api.PlaceLimitOrder(TradeType.Buy, api.SymbolName, 20000, api.Symbol.Bid - 2 * api.Symbol.PipSize, "myLimitOrder")
            api.PlaceStopOrder(TradeType.Buy, api.SymbolName, 10000, api.Symbol.Ask, "myStopOrder")
    
            for pendingOrder in api.PendingOrders:
                Print(f"Order placed with label {pendingOrder.Label}, id {pendingOrder.Id}")
    

    Đầu ra nhật ký

    • cBot "New cBot" đã được khởi động thành công cho EURUSD, h1.
    • Đặt lệnh giới hạn mua 10000 EURUSD (Giá: 1.19036)
    • Đặt lệnh giới hạn mua 10000 EURUSD (Giá: 1.19036) THÀNH CÔNG, Lệnh chờ OID25220794
    • Đặt lệnh giới hạn mua 20000 EURUSD (Giá: 1.19017)
    • Đặt lệnh giới hạn mua 20000 EURUSD (Giá: 1.19017) THÀNH CÔNG, Lệnh chờ OID25220795
    • Đặt lệnh dừng mua 10000 EURUSD (Giá: 1.19040)
    • Đặt lệnh dừng mua 10000 EURUSD (Giá: 1.19040) THÀNH CÔNG, Lệnh chờ OID25220796
    • Lệnh được đặt với nhãn myLimitOrder, id 25220794
    • Lệnh được đặt với nhãn myLimitOrder, id 25220795
    • Lệnh được đặt với nhãn myStopOrder, id 25220796
  • Tạo lệnh chờ với nhiều tham số hơn

    Như với lệnh thị trường, bạn cũng có thể chỉ định nhãn lệnh, các cơ chế bảo vệ khác nhau, ngày hết hạn lệnh và cung cấp một bình luận.

     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
    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            var midnight = Server.Time.AddDays(1).Date;
    
            PlaceLimitOrder(TradeType.Buy, SymbolName, 10000, Symbol.Bid, "mySample_cBot", 10, null, midnight, "First");
    
            PlaceStopOrder(TradeType.Buy, SymbolName, 10000, Symbol.Ask, "mySample_cBot", 10, 10, null, "Second");
    
            foreach (var order in PendingOrders)
            {
                var sl = order.StopLoss == null ? "" : "SL: " + order.StopLoss;
                var tp = order.TakeProfit == null ? "" : " TP: " + order.TakeProfit;
    
                var text = string.Format("{0} {1}", sl, tp);
    
                if (order.OrderType == PendingOrderType.Limit)
                    Print(order.Comment + " Limit Order " + text);
                else
                    Print(order.Comment + " Stop Order " + text);
            }
        }
    }
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    class Sample_cBot():
        def on_start(self):
            midnight = api.Server.Time.AddDays(1).Date
    
            api.PlaceLimitOrder(TradeType.Buy, api.SymbolName, 10000, api.Symbol.Bid, "mySample_cBot", 10, None, midnight, "First")
            api.PlaceStopOrder(TradeType.Buy, api.SymbolName, 10000, api.Symbol.Ask, "mySample_cBot", 10, 10, None, "Second")
    
            for order in api.PendingOrders:
                sl = "" if order.StopLoss is None else f"SL: {order.StopLoss}"
                tp = "" if order.TakeProfit is None else f"TP: {order.TakeProfit}"
    
                api.Print(f"{order.Comment} {order.OrderType} Order {sl} {tp}")
    

    Đầu ra nhật ký

    • cBot "New cBot" đã được khởi động thành công cho EURUSD, h1.
    • Đặt lệnh giới hạn mua 10000 EURUSD (Giá: 1.19049, Cắt lỗ: 10, Thời gian hết hạn: 12/05/2018 00:00:00)
    • Đặt lệnh giới hạn mua 10000 EURUSD (Giá: 1.19049, Cắt lỗ: 10, Thời gian hết hạn: 12/05/2018 00:00:00) THÀNH CÔNG, Lệnh chờ OID25220807
    • Đặt lệnh dừng mua 10000 EURUSD (Giá: 1.19053, Cắt lỗ: 10, Chốt lời: 10)
    • Đặt lệnh dừng mua 10000 EURUSD (Giá: 1.19053, Cắt lỗ: 10, Chốt lời: 10) THÀNH CÔNG, Lệnh chờ OID25220808
    • Lệnh giới hạn
    • Lệnh giới hạn đầu tiên Cắt lỗ: 1.18949
    • Lệnh dừng thứ hai Cắt lỗ: 1.18953 Chốt lời: 1.19153

Chỉnh sửa lệnh chờ

Có thể chỉnh sửa một số đặc điểm của lệnh chờ.

Ví dụ dưới đây minh họa cách chỉnh sửa giá mục tiêu, mức bảo vệ hoặc ngày và giờ hết hạn của một lệnh chờ.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[Robot()]
public class Sample_cBot : Robot
{
    protected override void OnStart()
    {
        var price = Symbol.Ask + 10 * Symbol.PipSize;
        var expiry = Server.Time.AddHours(12);
        PlaceStopOrder(TradeType.Buy, SymbolName, 10000, price, "myLabel", 10, 10, expiry);
    }

    protected override void OnBar()
    {
        foreach (var order in PendingOrders)
        {
            if (order.Label == "myLabel")
            {
                double newPrice = Symbol.Ask + 5 * Symbol.PipSize;
                ModifyPendingOrder(order, newPrice, order.StopLossPips,
                                                            order.TakeProfitPips, order.ExpirationTime);
            }
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Sample_cBot():
    def on_start(self):
        price = api.Symbol.Ask + 10 * api.Symbol.PipSize
        expiry = Server.Time.AddHours(12)

        api.PlaceStopOrder(TradeType.Buy, api.SymbolName, 10000, price, "myLabel", 10, 10, expiry)

    def on_bar(self):
        for order in api.PendingOrders:
            if order.Label == "myLabel":
                newPrice = api.Symbol.Ask + 5 * api.Symbol.PipSize
                api.ModifyPendingOrder(order, newPrice, order.StopLossPips, order.TakeProfitPips, order.ExpirationTime)

Đầu ra nhật ký

Hủy lệnh chờ

Cú pháp để hủy một lệnh là CancelPendingOrder(order), trong đó order thuộc loại PendingOrder.

Ví dụ dưới đây cho thấy cách hủy tất cả các lệnh có nhãn "myLabel".

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
[Robot()]
public class Sample_cBot : Robot
{
    protected override void OnTick()
    {
        foreach (var order in PendingOrders)
        {
            if (order.Label == "myLabel")
            {
                CancelPendingOrder(order);
            }
        }
    }
}
1
2
3
4
5
class Sample_cBot():
    def on_tick(self):
        for order in api.PendingOrders:
            if order.Label == "myLabel":
                api.CancelPendingOrder(order)

Sự kiện vị thế

Có thể đăng ký các sự kiện liên quan đến các hoạt động giao dịch khác nhau. Ví dụ, để kiểm tra xem một vị thế có được mở hay không, chúng ta đăng ký một sự kiện được kích hoạt cho tất cả các đối tượng Position khi mở.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[Robot()]
public class Sample_cBot : Robot
{
    protected override void OnStart()
    {
        Positions.Opened += PositionsOnOpened;
        ExecuteMarketOrder(TradeType.Buy, Symbol, 10000, "myLabel", 10, 10);
    }

    private void PositionsOnOpened(PositionOpenedEventArgs args)
    {
        var pos = args.Position;
        Print("Position opened at {0}", pos.EntryPrice);
    }
}
1
2
3
4
5
6
7
8
class Sample_cBot():
    def on_start(self):
        api.Positions.Opened += self.on_position_opened
        api.ExecuteMarketOrder(TradeType.Buy, api.Symbol, 10000, "myLabel", 10, 10)

    def on_position_opened(self, args):
        pos = args.Position
        api.Print(f"Position opened at {pos.EntryPrice}")

Đầu ra nhật ký

Tương tự, có thể đăng ký các sự kiện được kích hoạt mỗi khi một vị thế được đóng.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
[Robot()]
public class Sample_cBot : Robot
{
    protected override void OnStart()
    {
        Positions.Closed += PositionsOnClosed;
        ExecuteMarketOrder(TradeType.Buy, Symbol, 10000, "myLabel", 10, 10);
    }

    protected override void OnBar()
    {
        var position = Positions.Find("myLabel");
        if (position != null)
            ClosePosition(position);
    }

    private void PositionsOnClosed(PositionClosedEventArgs args)
    {
        var pos = args.Position;
        Print("Position closed with {0} profit", pos.GrossProfit);
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Sample_cBot():
    def on_start(self):
        api.Positions.Closed += self.on_position_closed
        api.ExecuteMarketOrder(TradeType.Buy, api.Symbol, 10000, "myLabel", 10, 10)

    def on_bar(self):
        position = api.Positions.Find("myLabel")

        if position is not None:
            api.ClosePosition(position);            

    def on_position_closed(self, args):
        pos = args.Position
        api.Print(f"Position closed with {pos.GrossProfit} profit")

Đầu ra nhật ký

Chuyển đổi tọa độ

cBot dưới đây cho phép người dùng đặt lệnh giới hạn theo hướng phù hợp chỉ bằng cách nhấp chuột phải vào biểu đồ. Nó thực hiện điều này bằng cách chuyển đổi tọa độ Y của chuột thành tọa độ Y của biểu đồ (đối với các cặp tiền tệ, tương ứng với giá của cặp tiền tệ).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[Robot(AccessRights = AccessRights.None)]
public class CoordinatesConverter : Robot
{
    protected override void OnStart()
    {
        Chart.MouseUp += Chart_MouseUp;
    }

    private void Chart_MouseUp(ChartMouseEventArgs obj)
    {
        var desiredPrice = Chart.YToYValue(obj.MouseY);
        var desiredTradeType = desiredPrice > Symbol.Bid ? TradeType.Sell : TradeType.Buy;
        PlaceLimitOrder(desiredTradeType, SymbolName, 10000, desiredPrice);
    }
}
1
2
3
4
5
6
7
8
class Sample_cBot():
    def on_start(self):
        api.Chart.MouseUp += self.on_chart_mouse_up        

    def on_chart_mouse_up(self, args):
        desiredPrice = api.Chart.YToYValue(args.MouseY)
        desiredTradeType = TradeType.Sell if desiredPrice > api.Symbol.Bid else TradeType.Buy
        api.PlaceLimitOrder(desiredTradeType, api.SymbolName, 10000, desiredPrice)

Thực thi bất đồng bộ

Các mẫu mã trên được thiết kế để triển khai robot giao dịch sử dụng thực thi đồng bộ. Cả C# và Python đều hỗ trợ các hoạt động bất đồng bộ, cho phép cBot của bạn thực hiện nhiều hành động trong cùng một khung thời gian.

Thực hiện lệnh thị trường bất đồng bộ

Cú pháp của các phương thức bất đồng bộ tương tự như các phương thức đồng bộ. Mặc dù chúng chấp nhận các loại đối số giống nhau, kiểu trả về của chúng là TradeOperation thay vì TradeResult.

  • Các hoạt động bất đồng bộ cơ bản

    cBot sau đây minh họa cách hoạt động của các hoạt động bất đồng bộ. Một lệnh thị trường được tạo; trong điều kiện tiếp theo, cBot kiểm tra xem hoạt động có đang thực thi hay không.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            var operation = ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 10000);
    
            if (operation.IsExecuting)
            {
                Print("Operation Is Executing");
            }
        }
    }
    
    1
    2
    3
    4
    5
    6
    class Sample_cBot():
        def on_start(self):
            operation = api.ExecuteMarketOrderAsync(TradeType.Buy, api.SymbolName, 10000)
    
            if operation.IsExecuting:
                api.Print("Operation Is Executing")
    

    Đầu ra nhật ký

    • cBot "New cBot" đã được khởi động thành công cho EURUSD, h1.
    • Thực hiện lệnh thị trường mua 10000 EURUSD
    • Hoạt động đang thực thi
    • Thực hiện lệnh thị trường mua 10000 EURUSD THÀNH CÔNG, Vị thế PID14579532
  • Thực hiện một lệnh

    Ví dụ tiếp theo nhấn mạnh sự khác biệt giữa các phương thức đồng bộ và bất đồng bộ.

    cBot kiểm tra xem một hoạt động có đang thực thi ngay sau khi gọi một phương thức bất đồng bộ hay không. Nó thực hiện lại sau khi gọi một phương thức đồng bộ. Đầu ra nhật ký cho hai hành động này là khác nhau.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            var operation = ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 10000);
            Print(operation.IsExecuting ? "Operation Is Executing" : "Operation executed");
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 20000);
            Print(operation.IsExecuting ? "Operation Is Executing" : "Operation executed");
        }
    }
    
    1
    2
    3
    4
    5
    6
    class Sample_cBot():
        def on_start(self):
            operation = api.ExecuteMarketOrderAsync(TradeType.Buy, api.SymbolName, 10000)
            api.Print("Operation Is Executing" if operation.IsExecuting else "Operation executed")
            api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 20000)
            api.Print("Operation Is Executing" if operation.IsExecuting else "Operation executed")
    

    Đầu ra nhật ký

    • cBot "New cBot" đã được khởi động thành công cho EURUSD, h1.
    • Thực hiện lệnh thị trường mua 10000 EURUSD
    • Hoạt động đang thực thi
    • Thực hiện lệnh thị trường mua 20000 EURUSD
    • Thực hiện lệnh thị trường mua 10000 EURUSD THÀNH CÔNG, Vị thế PID14579541
    • Thực hiện lệnh thị trường mua 20000 EURUSD THÀNH CÔNG, Vị thế PID14579542
    • Hoạt động đã thực thi
  • Thực hiện một lệnh với nhiều tham số hơn

    cBot sau đây đặt một lệnh chỉ định nhãn của nó ("myLabel"), mức bảo vệ (10, 10), cặp tiền tệ (SymbolName) và khối lượng (10000).

    Ví dụ cũng chứa bộ sưu tập Positions và phương thức FindAll(). Find()FindAll() có thể được sử dụng để tìm các vị thế có cùng nhãn, cặp tiền tệ và loại giao dịch.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 10000, "myLabel", 10, 10);
        }
        protected override void OnTick()
        {
            var positions = Positions.FindAll("myLabel", SymbolName, TradeType.Buy);
    
            if (positions.Length == 0)
                return;
    
            foreach (var position in positions)
                Print("Buy at {0} SL {1}", position.EntryPrice, position.StopLoss);
    
            Stop();
        }
    }
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    class Sample_cBot():
        def on_start(self):
            api.ExecuteMarketOrderAsync(TradeType.Buy, api.SymbolName, 10000, "myLabel", 10, 10)
    
        def on_tick(self):
            positions = api.Positions.FindAll("myLabel", api.SymbolName, TradeType.Buy)
    
            if positions.Length == 0:
                return
    
            for position in positions:
                api.Print(f"Buy at {position.EntryPrice} SL {position.StopLoss}")
    
            api.Stop()            
    

    Đầu ra nhật ký

    • cBot "New cBot" đã được khởi động thành công cho EURUSD, h1.
    • Thực hiện lệnh thị trường mua 10000 EURUSD (Cắt lỗ: 10, Chốt lời: 10)
    • Thực hiện lệnh thị trường mua 10000 EURUSD (Cắt lỗ: 10, Chốt lời: 10) THÀNH CÔNG, Vị thế PID14579719
    • Mua tại 1.19087 Cắt lỗ null
    • Mua tại 1.19357 Cắt lỗ 1.19257
    • cBot "New cBot" đã dừng cho EURUSD, h1.

Chỉnh sửa vị thế bất đồng bộ

cBot dưới đây đặt một lệnh thị trường và sau đó chỉnh sửa vị thế mới mở.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
[Robot()]
public class Sample_cBot : Robot
{
    protected override void OnStart()
    {
        ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 10000, "myLabel", null, 10);
    }

    protected override void OnTick()
    {
        Position myPosition = Positions.Find("myLabel");
        if (myPosition != null && myPosition.StopLoss == null)
        {
            double stopLoss = Symbol.Bid - 10 * Symbol.PipSize;
            ModifyPositionAsync(myPosition, stopLoss, myPosition.TakeProfit);
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Sample_cBot():
    def on_start(self):
        api.ExecuteMarketOrderAsync(TradeType.Buy, api.SymbolName, 10000, "myLabel", None, 10)

    def on_tick(self):
        myPosition = Positions.Find("myLabel")

        if myPosition is None or myPosition.StopLoss is not None:
            return

        stopLoss = api.Symbol.Bid - 10 * api.Symbol.PipSize

        api.ModifyPositionAsync(myPosition, stopLoss, myPosition.TakeProfit)        

Đầu ra nhật ký

Đóng một vị thế bất đồng bộ

Ví dụ tiếp theo minh họa việc đóng một vị thế bất đồng bộ nếu nó tồn tại.

Phương thức Find() được sử dụng để tìm kiếm trong bộ sưu tập Positions vị thế có nhãn cụ thể.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
[Robot()]
public class Sample_cBot : Robot
{
    protected override void OnStart()
    {
        ExecuteMarketOrderAsync(TradeType.Buy, Symbol, 10000, "myLabel", null, 10);
    }

    protected override void OnTick()
    {
        Position myPosition = Positions.Find("myLabel");
        if (myPosition != null && myPosition.GrossProfit > 10)
        {
            ClosePositionAsync(myPosition);
            Stop();
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Sample_cBot():
    def on_start(self):
        api.ExecuteMarketOrderAsync(TradeType.Buy, api.SymbolName, 10000, "myLabel", None, 10)

    def on_tick(self):
        myPosition = Positions.Find("myLabel")

        if myPosition is None or myPosition.GrossProfit <= 10:
            return

        api.ClosePositionAsync(myPosition)
        api.Stop()        

Đầu ra nhật ký

Đặt lệnh giới hạn và lệnh dừng bất đồng bộ

Như đã nêu ở trên, việc đặt lệnh chờ tương tự như tạo lệnh thị trường.

Tuy nhiên, có một số khác biệt nhỏ trong các đối số giữa hai phương thức này. Phạm vi thị trường không có trong danh sách đối số. Hơn nữa, bạn phải chỉ định giá mục tiêu, và bạn có thể truyền một đối số tùy chọn chỉ định ngày hết hạn lệnh.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[Robot()]
public class Sample_cBot : Robot
{
    protected override void OnStart()
    {
        var expiry = Server.Time.AddHours(12);
        PlaceLimitOrderAsync(TradeType.Buy, SymbolName, 10000, Symbol.Bid, "myLabel", null, null, expiry);
        PlaceStopOrderAsync(TradeType.Buy, SymbolName, 10000, Symbol.Ask + 10 * Symbol.PipSize, "myLabel", null, null, expiry);
    }
}
1
2
3
4
5
class Sample_cBot():
    def on_start(self):
        expiry = api.Server.Time.AddHours(12)
        api.PlaceLimitOrderAsync(TradeType.Buy, api.SymbolName, 10000, api.Symbol.Bid, "myLabel", None, None, expiry)
        api.PlaceStopOrderAsync(TradeType.Buy, api.SymbolName, 10000, api.Symbol.Ask + 10 * api.Symbol.PipSize, "myLabel", None, None, expiry)    

Đầu ra nhật ký

Chỉnh sửa lệnh chờ bất đồng bộ

cBot sau đây chỉnh sửa lệnh giới hạn một cách bất đồng bộ.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
[Robot()]
public class Sample_cBot : Robot
{
    protected override void OnStart()
    {
        var expiry = Server.Time.AddHours(12);
        PlaceLimitOrderAsync(TradeType.Buy, SymbolName, 10000, Symbol.Bid, "myLabel", null, 10, expiry);

    }
    protected override void OnTick()
    {
        foreach (var order in PendingOrders)
        {
            if (order.Label == "myLabel" && order.StopLoss == null)
                ModifyPendingOrderAsync(order, order.TargetPrice, 10, 10, null);
        }
    }
}
1
2
3
4
5
6
7
8
9
class Sample_cBot():
    def on_start(self):
        expiry = api.Server.Time.AddHours(12)
        api.PlaceLimitOrderAsync(TradeType.Buy, api.SymbolName, 10000, api.Symbol.Bid, "myLabel", None, 10, expiry)

    def on_tick(self):
        for order in api.PendingOrders:
            if order.Label == "myLabel" and order.StopLoss is None:
                api.ModifyPendingOrderAsync(order, order.TargetPrice, 10, 10, None)

Đầu ra nhật ký

Hủy lệnh chờ bất đồng bộ

  • Hủy tất cả lệnh chờ

    cBot dưới đây hủy bất đồng bộ tất cả các lệnh chờ hiện tại.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnBar()
        {
            foreach (var pendingOrder in PendingOrders)
            {
                CancelPendingOrderAsync(pendingOrder);
            }
        }
    }
    
    1
    2
    3
    4
    class Sample_cBot():
        def on_bar(self):
            for order in api.PendingOrders:
                api.CancelPendingOrderAsync(order)
    

    Đầu ra nhật ký

    • cBot "hủy lệnh chờ" đã được khởi động thành công cho EURUSD, h1.
    • Đang hủy lệnh chờ OID274705
    • Đang hủy lệnh chờ OID274706
    • Đang hủy lệnh chờ OID274707
    • Đang hủy lệnh chờ OID274708
    • Đang hủy lệnh chờ OID274709
    • Hủy lệnh chờ OID274705 THÀNH CÔNG, Lệnh chờ OID274705
    • Hủy lệnh chờ OID274706 THÀNH CÔNG, Lệnh chờ OID274706
    • Hủy lệnh chờ OID274707 THÀNH CÔNG, Lệnh chờ OID274707
    • Hủy lệnh chờ OID274708 THÀNH CÔNG, Lệnh chờ OID274708
    • Hủy lệnh chờ OID274709 THÀNH CÔNG, Lệnh chờ OID274709
  • Hủy lệnh chờ với một nhãn nhất định

    cBot này chỉ hủy các lệnh chờ có một nhãn nhất định.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnBar()
        {
            foreach (var pendingOrder in PendingOrders)
            {
                if (pendingOrder.Label == "myLabel")
                    CancelPendingOrderAsync(pendingOrder);
            }
        }
    }
    
    1
    2
    3
    4
    5
    class Sample_cBot():
        def on_bar(self):
            for order in api.PendingOrders:
                if order.Label == "myLabel":
                    api.CancelPendingOrderAsync(order)
    

Hàm gọi lại cho các phương thức bất đồng bộ

Khi một kết quả được trả về, việc sử dụng các hoạt động bất đồng bộ thường đòi hỏi kiểm soát thực thi. Để xử lý điều này, bạn có thể thêm một hàm gọi lại vào cuối danh sách tham số của tất cả các phương thức bất đồng bộ.

Hàm này sẽ được gọi ngay khi nhận được phản hồi từ máy chủ. Ví dụ, nó có thể được gọi khi một vị thế được mở, chỉnh sửa hoặc đóng.

  • Lệnh thị trường bất đồng bộ với một hàm gọi lại

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            var operation = ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 10000, PositionOpened);
            if (operation.IsExecuting)
                Print(operation.ToString());
            else
                Print(operation.TradeResult.ToString());
    
        }
    
        private void PositionOpened(TradeResult tradeResult)
        {
            var position = tradeResult.Position;
            Print(tradeResult.ToString());
            if (tradeResult.IsSuccessful)
                Print("Position {0} opened at {1}", position.Id, position.EntryPrice);
        }
    }
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    from System import Action
    
    class Sample_cBot():
        def on_start(self):
            operation = api.ExecuteMarketOrderAsync(TradeType.Buy, api.SymbolName, 10000, Action[TradeResult](self.on_position_opened))
    
            if (operation.IsExecuting)
                api.Print(operation.ToString())
            else
                api.Print(operation.TradeResult.ToString())
    
        def on_position_opened(self, tradeResult):
            position = tradeResult.Position
    
            api.Print(tradeResult.ToString())
    
            if tradeResult.IsSuccessful:
                api.Print(f"Position {position.Id} opened at {position.EntryPrice}")
    

    Đầu ra nhật ký

    • cBot "New cBot" đã được khởi động thành công cho EURUSD, h1.
    • Thực hiện Lệnh thị trường để Mua 10000 EURUSD
    • TradeOperation (Thực hiện Lệnh thị trường để Mua 10000 EURUSD ĐANG THỰC HIỆN)
    • Thực hiện Lệnh thị trường để Mua 10000 EURUSD THÀNH CÔNG, Vị thế PID14579835
    • TradeResult (Thành công, Vị thế: PID14579835)
    • Vị thế 14579835 được mở tại 1.19414
  • Sử dụng biểu thức lambda

    Thay vì định nghĩa một phương thức gọi lại có tên, bạn có thể sử dụng biểu thức lambda.

    Trong ví dụ sau, khi một lệnh được đặt, mô tả của kết quả sẽ được in ra nhật ký.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            PlaceLimitOrderAsync(TradeType.Buy, SymbolName, 10000,
                    Symbol.Ask - 20 * Symbol.PipSize, "myLabel", result => Print(result.ToString()));
        }
    }
    
    1
    2
    3
    4
    5
    from System import Action
    
    class Samples():
        def on_start(self):
            operation = api.PlaceLimitOrderAsync(TradeType.Buy, api.SymbolName, 10000, api.Symbol.Ask - 20 * api.Symbol.PipSize, "myLabel", Action[TradeResult](lambda result: api.Print(result.ToString())))
    

    Đầu ra nhật ký

    • cBot "New cBot" đã được khởi động thành công cho EURUSD, h1.
    • Đặt Lệnh giới hạn để Mua 10000 EURUSD (Giá: 1.19320)
    • Đặt Lệnh giới hạn để Mua 10000 EURUSD (Giá: 1.19320) THÀNH CÔNG, Lệnh chờ OID25222083
    • TradeResult (Thành công, Lệnh chờ: OID25222083)

Image title