Lewati ke isi

Sampel kode cBot

Halaman ini menyediakan beberapa contoh kode Python dan C# untuk membuat bot trading dan mengembangkan algoritma. Perhatikan bahwa tidak ada cBot yang tercantum di bawah ini menjamin keuntungan finansial apa pun. Pastikan untuk melakukan backtesting dan menyesuaikan cBot Anda sebelum menerapkan instansi apa pun pada akun riil.

Repositori sampel cBot

Sampel kode cBot yang komprehensif, termasuk template siap pakai untuk berbagai strategi otomatis dan gaya trading, tersedia di repositori terpisah Python dan C# di GitHub.

Operasi sinkron

Semua cBot di bagian ini menjalankan operasinya secara sinkron.

Eksekusi order market

  • Sebuah cBot sederhana yang melakukan operasi berhasil

    Bot trading berikut membuat order market saat startup dan menyimpan hasilnya dalam variabel result.

    Jika eksekusi order berhasil, harga entri akan dicetak di log.

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

    Output log

    • cBot "New cBot" berhasil dimulai untuk EURUSD, h1.
    • Menjalankan Order Market untuk Beli 10000 EURUSD
    • Menjalankan Order Market untuk Beli 10000 EURUSD BERHASIL, Posisi PID14576001
    • Harga entri posisi adalah 1.19067
  • Sebuah cBot sederhana dengan parameter yang dapat disesuaikan

    Saat mendeklarasikan berbagai properti cBot, Anda dapat mengubahnya menjadi parameter yang dapat disesuaikan menggunakan deklarasi [Parameter()]. Ketika instansi baru cBot Anda diluncurkan, Anda (atau pengguna lain) akan dapat menetapkan nilai khusus untuk ini.

    Pertimbangkan contoh berikut.

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

    Catatan

    cBot Python menggunakan parameter yang dapat disesuaikan yang dideklarasikan dalam file .cs.

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

    Dalam contoh di atas, kami mendefinisikan karakteristik berikut:

    • Nama parameter. Ini akan muncul di UI cTrader ("SMA Period").
    • Nilai default parameter yang akan berlaku untuk semua instansi baru kecuali diubah oleh pengguna (DefaultValue = 14).

    Dalam kode di bawah ini, kami menunjukkan bagaimana properti SmaPeriod dapat digunakan dalam bot trading yang sebenarnya.

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

    Catatan

    cBot Python menggunakan parameter yang dapat disesuaikan yang dideklarasikan dalam file .cs.

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

    Bot kami mengambil properti yang dapat disesuaikan SmaPeriod dan, saat mulai, meneruskan nilainya ke metode Indicators.GetIndicator<SampleSMA>(). Metode ini mengembalikan nilai moving average sederhana untuk periode yang ditentukan.

    Saat membuat instansi cBot, semua parameter yang dapat disesuaikan dapat diatur di jendela Tambahkan instansi.

    Saat diluncurkan, cBot memberi tahu kami tentang nilai moving average sederhana terakhir pada setiap tick.

    Output log

    • Instansi cBot [Sample cBot Reference SMA, EURUSD, h1] dimulai.
    • 0.975685714285714
    • 0.975681428571429
    • 0.97568
    • Instansi cBot [Sample cBot Reference SMA, EURUSD, h1] dihentikan oleh pengguna.
  • Eksekusi order market dengan lebih banyak argumen

    Dalam contoh sebelumnya, kami meneruskan jumlah argumen minimum yang mungkin ke metode ExecuteMarketOrder(). Argumen tersebut adalah jenis trade (TradeType.Buy), simbol (Symbol) dan volume (-1).

    Metode ExecuteMarketOrder() dapat dipanggil dengan argumen tambahan seperti Label, StopLoss, TakeProfit dan Comment. Contoh di bawah ini menentukan label ("order 1"), mekanisme proteksi stop-loss (10) dan level take-profit (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}")
    

    Output log

    • cBot "New cBot" berhasil dimulai untuk EURUSD, h1.
    • Menjalankan Order Market untuk Beli 10000 EURUSD (SL: 10, TP: 10)
    • Menjalankan Order Market untuk Beli 10000 EURUSD (SL: 10, TP: 10) BERHASIL, Posisi PID14576098
    • Harga entri posisi adalah 1.1896
    • Harga SL posisi adalah 1.1886

Modifikasi posisi

Dalam contoh di bawah ini, kami hanya menambahkan nilai take profit (10) saat order dieksekusi. Setelah itu, kami memodifikasi posisi untuk menambahkan stop loss.

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

Output log

Tutup posisi

  • Lakukan penutupan penuh

    Sampel kode di bawah ini menempatkan order market. Jika laba kotor dari posisi yang dihasilkan melebihi nilai tertentu (null && position.GrossProfit > 10), posisi tersebut akan ditutup.

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

    Output log

    • cBot "New cBot" berhasil dimulai untuk EURUSD, h1.
    • Menjalankan Order Market untuk Beli 10000 EURUSD
    • Menjalankan Order Market untuk Beli 10000 EURUSD BERHASIL, Posisi PID14576180
  • Lakukan penutupan sebagian

    Kami akan memodifikasi contoh sebelumnya untuk membuat dua order market dengan label yang sama ("myLabel"). Pada setiap bar baru, bot trading kami akan menutup tepat setengah dari salah satu order ini tetapi hanya jika volumenya sama dengan atau lebih besar dari 20.000.

    Kami juga menggunakan metode Positions.FindAll(). Metode ini mengembalikan daftar posisi yang dapat kami iterasi.

     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)
    

    Output log

    • cBot "New cBot" berhasil dimulai untuk EURUSD, h1.
    • Menjalankan Order Market untuk Beli 20000 EURUSD
    • Menjalankan Order Market untuk Beli 20000 EURUSD BERHASIL, Posisi PID14579299
    • Menjalankan Order Market untuk Beli 30000 EURUSD
    • Menjalankan Order Market untuk Beli 30000 EURUSD BERHASIL, Posisi PID14579300

Buat order pending

  • Buat order limit dan stop

    Order limit dan stop adalah order pending; meskipun demikian, mereka dibuat mirip dengan order market. Namun, saat membuat order limit dan stop, Anda juga harus menentukan harga targetnya dan tidak ada rentang pasar.

    cBot ini membuat dua order limit dan satu order stop. Kemudian, cBot ini mengiterasi melalui order dan mencetak label serta ID mereka ke log.

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

    Output log

    • cBot "New cBot" berhasil dimulai untuk EURUSD, h1.
    • Menempatkan Order Limit untuk Beli 10000 EURUSD (Harga: 1.19036)
    • Menempatkan Order Limit untuk Beli 10000 EURUSD (Harga: 1.19036) BERHASIL, PendingOrder OID25220794
    • Menempatkan Order Limit untuk Beli 20000 EURUSD (Harga: 1.19017)
    • Menempatkan Order Limit untuk Beli 20000 EURUSD (Harga: 1.19017) BERHASIL, PendingOrder OID25220795
    • Menempatkan Order Stop untuk Beli 10000 EURUSD (Harga: 1.19040)
    • Menempatkan Order Stop untuk Beli 10000 EURUSD (Harga: 1.19040) BERHASIL, PendingOrder OID25220796
    • Order ditempatkan dengan label myLimitOrder, id 25220794
    • Order ditempatkan dengan label myLimitOrder, id 25220795
    • Order ditempatkan dengan label myStopOrder, id 25220796
  • Buat order pending dengan lebih banyak parameter

    Seperti halnya dengan order pasar, Anda juga dapat menentukan label order, berbagai mekanisme perlindungan, tanggal kedaluwarsa order, dan memberikan komentar.

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

    Output log

    • cBot "New cBot" berhasil dimulai untuk EURUSD, h1.
    • Memasang Order Limit Beli 10000 EURUSD (Harga: 1.19049, SL: 10, ExpireTime: 12/05/2018 00:00:00)
    • Memasang Order Limit Beli 10000 EURUSD (Harga: 1.19049, SL: 10, ExpireTime: 12/05/2018 00:00:00) BERHASIL, OrderPending OID25220807
    • Memasang Order Stop Beli 10000 EURUSD (Harga: 1.19053, SL: 10, TP: 10)
    • Memasang Order Stop Beli 10000 EURUSD (Harga: 1.19053, SL: 10, TP: 10) BERHASIL, OrderPending OID25220808
    • Order Limit
    • Order Limit Pertama SL: 1.18949
    • Order Stop Kedua SL: 1.18953 TP: 1.19153

Modifikasi order pending

Dimungkinkan untuk memodifikasi beberapa karakteristik order pending.

Contoh di bawah ini menunjukkan cara memodifikasi harga target, tingkat perlindungan, atau tanggal dan waktu kedaluwarsa dari order pending.

 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)

Output log

Batalkan order pending

Sintaks untuk membatalkan order adalah CancelPendingOrder(order), di mana order bertipe PendingOrder.

Contoh di bawah ini menunjukkan pembatalan semua order dengan label "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)

Peristiwa posisi

Dimungkinkan untuk berlangganan peristiwa yang terkait dengan berbagai operasi trading. Misalnya, untuk menguji apakah suatu posisi dibuka, kita berlangganan peristiwa yang diangkat untuk semua objek Position saat dibuka.

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

Output log

Demikian pula, dimungkinkan untuk berlangganan peristiwa yang diangkat setiap kali suatu posisi ditutup.

 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")

Output log

Konversi koordinat

cBot di bawah ini memungkinkan pengguna untuk memasang order limit dalam arah yang sesuai hanya dengan mengklik kanan pada grafik. Hal ini dicapai dengan mengubah koordinat Y mouse menjadi koordinat Y grafik (yang, untuk simbol, sesuai dengan harga simbol).

 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)

Eksekusi asinkron

Contoh kode di atas dirancang untuk mengimplementasikan robot trading menggunakan eksekusi sinkron. C# dan Python keduanya mendukung operasi asinkron, memungkinkan cBot Anda untuk melakukan beberapa tindakan dalam periode waktu yang sama.

Eksekusi order pasar secara asinkron

Sintaks metode asinkron mirip dengan metode sinkron. Meskipun mereka menerima jenis argumen yang sama, tipe pengembalian mereka adalah TradeOperation alih-alih TradeResult.

  • Operasi asinkron dasar

    cBot berikut ini menunjukkan cara kerja operasi asinkron. Order pasar dibuat; dalam kondisi berikutnya, cBot memeriksa apakah operasi sedang dieksekusi.

     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")
    

    Output log

    • cBot "New cBot" berhasil dimulai untuk EURUSD, h1.
    • Mengeksekusi Order Pasar Beli 10000 EURUSD
    • Operasi Sedang Dieksekusi
    • Mengeksekusi Order Pasar Beli 10000 EURUSD BERHASIL, Position PID14579532
  • Eksekusi order

    Contoh berikut ini menyoroti perbedaan antara metode sinkron dan asinkron.

    cBot memeriksa apakah operasi sedang dieksekusi tepat setelah memanggil metode asinkron. Hal ini dilakukan lagi setelah memanggil metode sinkron. Output log untuk kedua tindakan ini berbeda.

     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")
    

    Output log

    • cBot "New cBot" berhasil dimulai untuk EURUSD, h1.
    • Mengeksekusi Order Pasar Beli 10000 EURUSD
    • Operasi Sedang Dieksekusi
    • Mengeksekusi Order Pasar Beli 20000 EURUSD
    • Mengeksekusi Order Pasar Beli 10000 EURUSD BERHASIL, Position PID14579541
    • Mengeksekusi Order Pasar Beli 20000 EURUSD BERHASIL, Position PID14579542
    • Operasi dieksekusi
  • Eksekusi order dengan lebih banyak parameter

    cBot berikut ini memasang order dengan menentukan labelnya ("myLabel"), tingkat perlindungan (10, 10), simbol (SymbolName) dan volume (10000).

    Contoh ini juga mencakup koleksi Positions dan metode FindAll(). Find() dan FindAll() dapat digunakan untuk menemukan posisi dengan label, simbol, dan jenis perdagangan yang sama.

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

    Output log

    • cBot "New cBot" berhasil dimulai untuk EURUSD, h1.
    • Mengeksekusi Order Pasar Beli 10000 EURUSD (SL: 10, TP: 10)
    • Mengeksekusi Order Pasar Beli 10000 EURUSD (SL: 10, TP: 10) BERHASIL, Position PID14579719
    • Beli pada 1.19087 SL null
    • Beli pada 1.19357 SL 1.19257
    • cBot "New cBot" dihentikan untuk EURUSD, h1.

Modifikasi posisi secara asinkron

cBot di bawah ini memasang order pasar dan kemudian memodifikasi posisi yang baru dibuka.

 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)        

Output log

Tutup posisi secara asinkron

Contoh berikut ini menunjukkan penutupan posisi secara asinkron jika posisi tersebut ada.

Metode Find() digunakan untuk mencari koleksi Positions untuk posisi dengan label tertentu.

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

Output log

Pasang order limit dan stop secara asinkron

Seperti yang telah disebutkan di atas, memasang order pending mirip dengan membuat order market.

Namun, ada beberapa perbedaan kecil dalam argumen antara kedua metode ini. Rentang pasar tidak ada dalam daftar argumen. Selain itu, Anda harus menentukan harga target, dan Anda dapat memberikan argumen opsional yang menentukan tanggal kedaluwarsa order.

 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)    

Output log

Modifikasi order pending secara asinkron

Berikut adalah cBot yang memodifikasi order limit secara asinkron.

 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)

Output log

Batalkan order pending secara asinkron

  • Batalkan semua order pending

    cBot di bawah ini secara asinkron membatalkan semua order pending yang sedang aktif.

     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)
    

    Output log

    • cBot "batalkan order pending" berhasil dimulai untuk EURUSD, h1.
    • Membatalkan order pending OID274705
    • Membatalkan order pending OID274706
    • Membatalkan order pending OID274707
    • Membatalkan order pending OID274708
    • Membatalkan order pending OID274709
    • Membatalkan order pending OID274705 BERHASIL, PendingOrder OID274705
    • Membatalkan order pending OID274706 BERHASIL, PendingOrder OID274706
    • Membatalkan order pending OID274707 BERHASIL, PendingOrder OID274707
    • Membatalkan order pending OID274708 BERHASIL, PendingOrder OID274708
    • Membatalkan order pending OID274709 BERHASIL, PendingOrder OID274709
  • Batalkan order pending dengan label tertentu

    cBot ini hanya membatalkan order pending dengan label tertentu.

     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)
    

Fungsi callback untuk metode asinkron

Setelah hasil dikembalikan, menggunakan operasi asinkron sering kali memerlukan kontrol eksekusi. Untuk menangani ini, Anda dapat menambahkan fungsi callback di akhir daftar parameter semua metode asinkron.

Fungsi ini akan dipanggil segera setelah respons diterima dari server. Misalnya, fungsi ini dapat dipanggil ketika posisi dibuka, dimodifikasi, atau ditutup.

  • Order market asinkron dengan callback

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

    Output log

    • cBot "New cBot" berhasil dimulai untuk EURUSD, h1.
    • Mengeksekusi Order Market untuk Membeli 10000 EURUSD
    • TradeOperation (Mengeksekusi Order Market untuk Membeli 10000 EURUSD SEDANG DIEKSEKUSI)
    • Mengeksekusi Order Market untuk Membeli 10000 EURUSD BERHASIL, Position PID14579835
    • TradeResult (Berhasil, Position: PID14579835)
    • Posisi 14579835 dibuka pada 1.19414
  • Menggunakan ekspresi lambda

    Alih-alih mendefinisikan metode callback bernama, Anda dapat menggunakan ekspresi lambda.

    Dalam contoh berikut, ketika order dipasang, deskripsi hasil akan dicetak ke log.

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

    Output log

    • cBot "New cBot" berhasil dimulai untuk EURUSD, h1.
    • Memasang Order Limit untuk Membeli 10000 EURUSD (Harga: 1.19320)
    • Memasang Order Limit untuk Membeli 10000 EURUSD (Harga: 1.19320) BERHASIL, PendingOrder OID25222083
    • TradeResult (Berhasil, PendingOrder: OID25222083)

Image title