ข้ามไปที่เนื้อหา

ตัวอย่างโค้ด cBot

หน้านี้จัดเตรียมตัวอย่างโค้ด Python และ C# หลายตัวอย่างสำหรับการสร้างหุ่นยนต์เทรดและการพัฒนาอัลกอริทึม โปรดทราบว่าไม่มี cBot ที่ระบุไว้ด้านล่างนี้รับประกันผลตอบแทนทางการเงินใดๆ โปรดแน่ใจว่าได้ทำการ backtest และปรับแต่ง cBot ของคุณก่อนที่จะใช้งานจริงในบัญชีเทรดจริง

ตัวอย่างที่เก็บ cBot

ตัวอย่างโค้ด cBot ที่ครอบคลุม รวมถึงเทมเพลตที่พร้อมใช้งานสำหรับกลยุทธ์อัตโนมัติและสไตล์การเทรดต่างๆ มีอยู่ในที่เก็บแยกต่างหากสำหรับ Python และ C# ใน GitHub

การดำเนินการแบบซิงโครนัส

cBot ทั้งหมดในส่วนนี้ ดำเนินการแบบซิงโครนัส

ดำเนินการคำสั่งตลาด

  • cBot ง่ายๆ ที่ดำเนินการสำเร็จ

    หุ่นยนต์เทรดต่อไปนี้สร้างคำสั่งตลาดเมื่อเริ่มต้นและบันทึกผลลัพธ์ไว้ในตัวแปร result

    หากการดำเนินการคำสั่งสำเร็จ ราคาเข้าจะถูกพิมพ์ในบันทึก

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

    ผลลัพธ์บันทึก

    • cBot "New cBot" เริ่มต้นสำเร็จสำหรับ EURUSD, h1
    • กำลังดำเนินการคำสั่งตลาดเพื่อซื้อ 10000 EURUSD
    • กำลังดำเนินการคำสั่งตลาดเพื่อซื้อ 10000 EURUSD สำเร็จ, โพสิชัน PID14576001
    • ราคาเข้าของโพสิชันคือ 1.19067
  • cBot ง่ายๆ ที่มีพารามิเตอร์ที่ปรับแต่งได้

    เมื่อประกาศคุณสมบัติต่างๆ ของ cBot คุณสามารถเปลี่ยนให้เป็นพารามิเตอร์ที่ปรับแต่งได้โดยใช้การประกาศ [Parameter()] เมื่อมีการเปิดอินสแตนซ์ใหม่ของ cBot ของคุณ คุณ (หรือผู้ใช้อื่นๆ) จะสามารถกำหนดค่าที่ปรับแต่งเองให้กับ สิ่งเหล่านี้ ได้

    พิจารณาตัวอย่างต่อไปนี้

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

    หมายเหตุ

    cBot ที่ใช้ Python ใช้พารามิเตอร์ที่ปรับแต่งได้ซึ่งประกาศในไฟล์ .cs

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

    ในตัวอย่างด้านบน เรากำหนดลักษณะต่อไปนี้:

    • ชื่อของพารามิเตอร์ ซึ่งจะปรากฏใน UI ของ cTrader ("SMA Period")
    • ค่าเริ่มต้นของพารามิเตอร์ที่จะใช้กับอินสแตนซ์ใหม่ทั้งหมด เว้นแต่ผู้ใช้จะเปลี่ยน (DefaultValue = 14)

    ในโค้ดด้านล่างนี้ เราจะแสดงวิธีใช้คุณสมบัติ SmaPeriod ในหุ่นยนต์เทรดจริง

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

    หมายเหตุ

    cBot ที่ใช้ Python ใช้พารามิเตอร์ที่ปรับแต่งได้ซึ่งประกาศในไฟล์ .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}")
    

    หุ่นยนต์ของเรารับคุณสมบัติ SmaPeriod ที่ปรับแต่งได้ และเมื่อเริ่มต้น จะส่งค่าของมันไปยังเมธอด Indicators.GetIndicator<SampleSMA>() เมธอดนี้จะคืนค่าการเคลื่อนที่เฉลี่ยอย่างง่ายสำหรับช่วงเวลาที่กำหนด

    เมื่อสร้างอินสแตนซ์ cBot พารามิเตอร์ที่ปรับแต่งได้ทั้งหมดสามารถตั้งค่าได้ในหน้าต่าง Add instance

    เมื่อเริ่มต้น cBot จะแจ้งให้เราทราบว่าค่าการเคลื่อนที่เฉลี่ยอย่างง่ายล่าสุดคืออะไรในทุกๆ tick

    ผลลัพธ์บันทึก

    • อินสแตนซ์ cBot [Sample cBot Reference SMA, EURUSD, h1] เริ่มต้นแล้ว
    • 0.975685714285714
    • 0.975681428571429
    • 0.97568
    • อินสแตนซ์ cBot [Sample cBot Reference SMA, EURUSD, h1] หยุดโดยผู้ใช้
  • ดำเนินการคำสั่งตลาดด้วยอาร์กิวเมนต์เพิ่มเติม

    ในตัวอย่างก่อนหน้านี้ เราส่งจำนวนอาร์กิวเมนต์ขั้นต่ำไปยังเมธอด ExecuteMarketOrder() ซึ่งได้แก่ ประเภทการเทรด (TradeType.Buy), สัญลักษณ์ (Symbol) และปริมาณ (-1)

    เมธอด ExecuteMarketOrder() สามารถเรียกใช้ด้วยอาร์กิวเมนต์เพิ่มเติมเช่น Label, StopLoss, TakeProfit และ Comment ตัวอย่างด้านล่างระบุป้ายกำกับ ("order 1"), กลไกการป้องกัน Stop-Loss (10) และระดับ 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}")
    

    ผลลัพธ์บันทึก

    • cBot "New cBot" เริ่มต้นสำเร็จสำหรับ EURUSD, h1
    • กำลังดำเนินการคำสั่งตลาดเพื่อซื้อ 10000 EURUSD (SL: 10, TP: 10)
    • กำลังดำเนินการคำสั่งตลาดเพื่อซื้อ 10000 EURUSD (SL: 10, TP: 10) สำเร็จ, โพสิชัน PID14576098
    • ราคาเข้าของโพสิชันคือ 1.1896
    • ราคา SL ของโพสิชันคือ 1.1886

ปรับเปลี่ยนโพสิชัน

ในตัวอย่างด้านล่างนี้ เราจะเพิ่มค่า Take-Profit (10) เมื่อคำสั่งถูกดำเนินการ หลังจากนั้น เราจะปรับเปลี่ยนโพสิชันเพื่อเพิ่ม 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}")

ผลลัพธ์บันทึก

ปิดโพสิชัน

  • ปิดทั้งหมด

    ตัวอย่างโค้ดด้านล่างนี้ส่งคำสั่งตลาด หากกำไรรวมของโพสิชันที่ได้เกินค่าหนึ่ง (null && position.GrossProfit > 10), มันจะถูกปิด

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

    ผลลัพธ์บันทึก

    • cBot "New cBot" เริ่มต้นสำเร็จสำหรับ EURUSD, h1
    • กำลังดำเนินการคำสั่งตลาดเพื่อซื้อ 10000 EURUSD
    • กำลังดำเนินการคำสั่งตลาดเพื่อซื้อ 10000 EURUSD สำเร็จ, โพสิชัน PID14576180
  • ปิดบางส่วน

    เราจะปรับเปลี่ยนตัวอย่างก่อนหน้านี้เพื่อสร้างคำสั่งตลาดสองคำสั่งที่มีป้ายกำกับเดียวกัน ("myLabel") ในแต่ละแท่งใหม่ หุ่นยนต์เทรดของเราจะปิดครึ่งหนึ่งของคำสั่งเหล่านี้ แต่เฉพาะเมื่อปริมาณของมันเท่ากับหรือมากกว่า 20,000

    เรายังใช้เมธอด Positions.FindAll() ซึ่งจะคืนค่าลิสต์ของโพสิชันที่เราสามารถวนซ้ำได้

     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)
    

    ผลลัพธ์บันทึก

    • cBot "New cBot" เริ่มต้นสำเร็จสำหรับ EURUSD, h1
    • กำลังดำเนินการคำสั่งตลาดเพื่อซื้อ 20000 EURUSD
    • กำลังดำเนินการคำสั่งตลาดเพื่อซื้อ 20000 EURUSD สำเร็จ, โพสิชัน PID14579299
    • กำลังดำเนินการคำสั่งตลาดเพื่อซื้อ 30000 EURUSD
    • กำลังดำเนินการคำสั่งตลาดเพื่อซื้อ 30000 EURUSD สำเร็จ, โพสิชัน PID14579300

สร้างคำสั่งที่รอดำเนินการ

  • สร้างคำสั่ง Limit และ Stop

    คำสั่ง Limit และ Stop เป็นคำสั่งที่รอดำเนินการ อย่างไรก็ตาม พวกมันถูกสร้างขึ้นในลักษณะเดียวกับคำสั่งตลาด แต่เมื่อสร้างคำสั่ง Limit และ Stop คุณต้องระบุราคาเป้าหมายด้วย และไม่มีช่วงตลาด

    cBot นี้สร้างคำสั่ง Limit สองคำสั่งและคำสั่ง Stop หนึ่งคำสั่ง จากนั้นมันจะวนซ้ำผ่านคำสั่งและพิมพ์ป้ายกำกับและ ID ของพวกมันลงในบันทึก

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

    ผลลัพธ์บันทึก

    • cBot "New cBot" เริ่มต้นสำเร็จสำหรับ EURUSD, h1
    • กำลังส่งคำสั่ง Limit เพื่อซื้อ 10000 EURUSD (ราคา: 1.19036)
    • กำลังส่งคำสั่ง Limit เพื่อซื้อ 10000 EURUSD (ราคา: 1.19036) สำเร็จ, คำสั่งที่รอดำเนินการ OID25220794
    • กำลังส่งคำสั่ง Limit เพื่อซื้อ 20000 EURUSD (ราคา: 1.19017)
    • กำลังส่งคำสั่ง Limit เพื่อซื้อ 20000 EURUSD (ราคา: 1.19017) สำเร็จ, คำสั่งที่รอดำเนินการ OID25220795
    • กำลังส่งคำสั่ง Stop เพื่อซื้อ 10000 EURUSD (ราคา: 1.19040)
    • กำลังส่งคำสั่ง Stop เพื่อซื้อ 10000 EURUSD (ราคา: 1.19040) สำเร็จ, คำสั่งที่รอดำเนินการ OID25220796
    • คำสั่งถูกส่งด้วยป้ายกำกับ myLimitOrder, id 25220794
    • คำสั่งถูกส่งด้วยป้ายกำกับ myLimitOrder, id 25220795
    • คำสั่งถูกส่งด้วยป้ายกำกับ myStopOrder, id 25220796
  • สร้างคำสั่งที่รอดำเนินการด้วยพารามิเตอร์เพิ่มเติม

    เช่นเดียวกับคำสั่ง Market คุณยังสามารถระบุป้ายกำกับคำสั่ง กลไกการป้องกันต่างๆ วันหมดอายุของคำสั่ง และเพิ่มความคิดเห็นได้

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

    ผลลัพธ์บันทึก

    • cBot "New cBot" เริ่มต้นสำเร็จสำหรับ EURUSD, h1
    • ส่งคำสั่ง Limit เพื่อซื้อ 10000 EURUSD (ราคา: 1.19049, SL: 10, เวลาหมดอายุ: 12/05/2018 00:00:00)
    • ส่งคำสั่ง Limit เพื่อซื้อ 10000 EURUSD (ราคา: 1.19049, SL: 10, เวลาหมดอายุ: 12/05/2018 00:00:00) สำเร็จแล้ว, คำสั่งที่รอดำเนินการ OID25220807
    • ส่งคำสั่ง Stop เพื่อซื้อ 10000 EURUSD (ราคา: 1.19053, SL: 10, TP: 10)
    • ส่งคำสั่ง Stop เพื่อซื้อ 10000 EURUSD (ราคา: 1.19053, SL: 10, TP: 10) สำเร็จแล้ว, คำสั่งที่รอดำเนินการ OID25220808
    • คำสั่ง Limit
    • คำสั่ง Limit แรก SL: 1.18949
    • คำสั่ง Stop ที่สอง SL: 1.18953 TP: 1.19153

แก้ไขคำสั่งที่รอดำเนินการ

เป็นไปได้ที่จะแก้ไขลักษณะหลายอย่างของคำสั่งที่รอดำเนินการ

ตัวอย่างด้านล่างแสดงวิธีการแก้ไขราคาเป้าหมาย ระดับการป้องกัน หรือวันและเวลาหมดอายุของคำสั่งที่รอดำเนินการ

 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)

ผลลัพธ์บันทึก

ยกเลิกคำสั่งที่รอดำเนินการ

ไวยากรณ์สำหรับการยกเลิกคำสั่งคือ CancelPendingOrder(order) โดยที่ order เป็นประเภท PendingOrder

ตัวอย่างด้านล่างแสดงการยกเลิกคำสั่งทั้งหมดที่มีป้ายกำกับ "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)

อีเวนต์โพสิชัน

เป็นไปได้ที่จะสมัครรับอีเวนต์ที่เกี่ยวข้องกับการดำเนินการเทรดต่างๆ ตัวอย่างเช่น เพื่อทดสอบว่าโพสิชันถูกเปิดหรือไม่ เราสมัครรับอีเวนต์ที่ถูกเรียกสำหรับวัตถุ Position ทั้งหมดเมื่อเปิด

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

ผลลัพธ์บันทึก

ในทำนองเดียวกัน เป็นไปได้ที่จะสมัครรับอีเวนต์ที่ถูกเรียกทุกครั้งที่โพสิชันถูกปิด

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

ผลลัพธ์บันทึก

การแปลงพิกัด

cBot ด้านล่างนี้ช่วยให้ผู้ใช้สามารถส่งคำสั่ง Limit ในทิศทางที่เหมาะสมได้โดยการคลิกขวาบนกราฟ มันทำได้โดยการแปลงพิกัด Y ของเมาส์เป็นพิกัด Y ของกราฟ (ซึ่งสำหรับสัญลักษณ์ จะตรงกับราคาของสัญลักษณ์)

 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)

การดำเนินการแบบอะซิงโครนัส

ตัวอย่างโค้ดด้านบนถูกออกแบบมาเพื่อใช้หุ่นยนต์เทรดโดยใช้การดำเนินการแบบซิงโครนัส ทั้ง C# และ Python รองรับการดำเนินการแบบอะซิงโครนัส ซึ่งช่วยให้ cBot ของคุณสามารถดำเนินการหลายอย่างในเวลาเดียวกันได้

ดำเนินการคำสั่ง Market แบบอะซิงโครนัส

ไวยากรณ์ของเมธอดแบบอะซิงโครนัสคล้ายกับเมธอดแบบซิงโครนัส แม้ว่าพวกเขาจะรับประเภทอาร์กิวเมนต์เดียวกัน แต่ประเภทการส่งคืนคือ TradeOperation แทนที่จะเป็น TradeResult

  • การดำเนินการแบบอะซิงโครนัสพื้นฐาน

    cBot ต่อไปนี้แสดงวิธีการทำงานของการดำเนินการแบบอะซิงโครนัส คำสั่ง Market ถูกสร้างขึ้น ในเงื่อนไขถัดไป cBot จะตรวจสอบว่าการดำเนินการกำลังดำเนินการอยู่หรือไม่

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

    ผลลัพธ์บันทึก

    • cBot "New cBot" เริ่มต้นสำเร็จสำหรับ EURUSD, h1
    • ดำเนินการคำสั่ง Market เพื่อซื้อ 10000 EURUSD
    • การดำเนินการกำลังดำเนินการ
    • ดำเนินการคำสั่ง Market เพื่อซื้อ 10000 EURUSD สำเร็จแล้ว, โพสิชัน PID14579532
  • ดำเนินการคำสั่ง

    ตัวอย่างถัดไปเน้นความแตกต่างระหว่างเมธอดแบบซิงโครนัสและอะซิงโครนัส

    cBot ตรวจสอบว่าการดำเนินการกำลังดำเนินการอยู่หรือไม่ทันทีหลังจากเรียกเมธอดแบบอะซิงโครนัส มันทำอีกครั้งหลังจากเรียกเมธอดแบบซิงโครนัส ผลลัพธ์บันทึกสำหรับการกระทำทั้งสองนี้แตกต่างกัน

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

    ผลลัพธ์บันทึก

    • cBot "New cBot" เริ่มต้นสำเร็จสำหรับ EURUSD, h1
    • ดำเนินการคำสั่ง Market เพื่อซื้อ 10000 EURUSD
    • การดำเนินการกำลังดำเนินการ
    • ดำเนินการคำสั่ง Market เพื่อซื้อ 20000 EURUSD
    • ดำเนินการคำสั่ง Market เพื่อซื้อ 10000 EURUSD สำเร็จแล้ว, โพสิชัน PID14579541
    • ดำเนินการคำสั่ง Market เพื่อซื้อ 20000 EURUSD สำเร็จแล้ว, โพสิชัน PID14579542
    • การดำเนินการเสร็จสิ้น
  • ดำเนินการคำสั่งด้วยพารามิเตอร์เพิ่มเติม

    cBot ต่อไปนี้ส่งคำสั่งโดยระบุป้ายกำกับ ("myLabel"), ระดับการป้องกัน (10, 10), สัญลักษณ์ (SymbolName) และปริมาณ (10000)

    ตัวอย่างนี้ยังรวมถึงคอลเลกชัน Positions และเมธอด FindAll() Find() และ FindAll() สามารถใช้เพื่อค้นหาโพสิชันที่มีป้ายกำกับ สัญลักษณ์ และประเภทการเทรดเดียวกัน

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

    ผลลัพธ์บันทึก

    • cBot "New cBot" เริ่มต้นสำเร็จสำหรับ EURUSD, h1
    • ดำเนินการคำสั่ง Market เพื่อซื้อ 10000 EURUSD (SL: 10, TP: 10)
    • ดำเนินการคำสั่ง Market เพื่อซื้อ 10000 EURUSD (SL: 10, TP: 10) สำเร็จแล้ว, โพสิชัน PID14579719
    • ซื้อที่ 1.19087 SL null
    • ซื้อที่ 1.19357 SL 1.19257
    • cBot "New cBot" ถูกหยุดสำหรับ EURUSD, h1.

แก้ไขโพสิชันแบบอะซิงโครนัส

cBot ด้านล่างนี้ส่งคำสั่ง Market และจากนั้นแก้ไขโพสิชันที่เปิดใหม่

 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)        

ผลลัพธ์บันทึก

ปิดโพสิชันแบบอะซิงโครนัส

ตัวอย่างถัดไปแสดงการปิดโพสิชันแบบอะซิงโครนัสหากมีอยู่

เมธอด Find() ถูกใช้เพื่อค้นหาโพสิชันในคอลเลกชัน Positions ที่มีป้ายกำกับเฉพาะ

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

ผลลัพธ์บันทึก

ส่งคำสั่ง Limit และ Stop แบบอะซิงโครนัส

ตามที่ระบุไว้ ด้านบน การส่งคำสั่งที่รอดำเนินการคล้ายกับการสร้างคำสั่ง Market

อย่างไรก็ตาม มีความแตกต่างเล็กน้อยในอาร์กิวเมนต์ระหว่างสองเมธอดนี้ ช่วง Market ไม่มีอยู่ในรายการอาร์กิวเมนต์ นอกจากนี้ คุณต้องระบุราคาเป้าหมาย และคุณสามารถส่งอาร์กิวเมนต์เพิ่มเติมเพื่อระบุวันหมดอายุของคำสั่งได้

 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)    

ผลลัพธ์บันทึก

แก้ไขคำสั่งที่รอดำเนินการแบบอะซิงโครนัส

cBot ต่อไปนี้แก้ไขคำสั่ง Limit แบบอะซิงโครนัส

 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)

ผลลัพธ์บันทึก

ยกเลิกคำสั่งที่รอดำเนินการแบบอะซิงโครนัส

  • ยกเลิกคำสั่งที่รอดำเนินการทั้งหมด

    cBot ด้านล่างนี้จะยกเลิกคำสั่งที่รอดำเนินการทั้งหมดในปัจจุบันแบบอะซิงโครนัส

     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)
    

    ผลลัพธ์บันทึก

    • cBot "cancel pending order" เริ่มต้นสำเร็จสำหรับ EURUSD, h1
    • กำลังยกเลิกคำสั่งที่รอดำเนินการ OID274705
    • กำลังยกเลิกคำสั่งที่รอดำเนินการ OID274706
    • กำลังยกเลิกคำสั่งที่รอดำเนินการ OID274707
    • กำลังยกเลิกคำสั่งที่รอดำเนินการ OID274708
    • กำลังยกเลิกคำสั่งที่รอดำเนินการ OID274709
    • การยกเลิกคำสั่งที่รอดำเนินการ OID274705 สำเร็จ, PendingOrder OID274705
    • การยกเลิกคำสั่งที่รอดำเนินการ OID274706 สำเร็จ, PendingOrder OID274706
    • การยกเลิกคำสั่งที่รอดำเนินการ OID274707 สำเร็จ, PendingOrder OID274707
    • การยกเลิกคำสั่งที่รอดำเนินการ OID274708 สำเร็จ, PendingOrder OID274708
    • การยกเลิกคำสั่งที่รอดำเนินการ OID274709 สำเร็จ, PendingOrder OID274709
  • ยกเลิกคำสั่งที่รอดำเนินการที่มีป้ายกำกับเฉพาะ

    cBot นี้จะยกเลิกเฉพาะคำสั่งที่รอดำเนินการที่มีป้ายกำกับเฉพาะ

     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)
    

ฟังก์ชันคอลแบ็กสำหรับเมธอดแบบอะซิงโครนัส

เมื่อได้รับผลลัพธ์ การดำเนินการแบบอะซิงโครนัสมักต้องการการควบคุมการดำเนินการ เพื่อจัดการกับสิ่งนี้ คุณสามารถเพิ่มฟังก์ชันคอลแบ็กที่ส่วนท้ายของรายการพารามิเตอร์ของเมธอดแบบอะซิงโครนัสทั้งหมด

ฟังก์ชันนี้จะถูกเรียกทันทีที่ได้รับคำตอบจากเซิร์ฟเวอร์ ตัวอย่างเช่น มันอาจถูกเรียกเมื่อเปิด โมดิฟาย หรือปิดโพสิชัน

  • คำสั่งตลาดแบบอะซิงโครนัสพร้อมคอลแบ็ก

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

    ผลลัพธ์บันทึก

    • cBot "New cBot" เริ่มต้นสำเร็จสำหรับ EURUSD, h1
    • กำลังดำเนินการคำสั่งตลาดเพื่อซื้อ 10000 EURUSD
    • TradeOperation (กำลังดำเนินการคำสั่งตลาดเพื่อซื้อ 10000 EURUSD กำลังดำเนินการ)
    • การดำเนินการคำสั่งตลาดเพื่อซื้อ 10000 EURUSD สำเร็จ, โพสิชัน PID14579835
    • TradeResult (สำเร็จ, โพสิชัน: PID14579835)
    • โพสิชัน 14579835 เปิดที่ 1.19414
  • การใช้ lambda expressions

    แทนที่จะกำหนดเมธอดคอลแบ็กที่มีชื่อ คุณสามารถใช้ lambda expressions ได้

    ในตัวอย่างต่อไปนี้ เมื่อมีการวางคำสั่ง คำอธิบายของผลลัพธ์จะถูกพิมพ์ลงในล็อก

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

    !!! abstract "บันทึกเอาต์พุต" ((8)) * cBot "New cBot" เริ่มต้นสำเร็จสำหรับ EURUSD, h1 * กำลังวางคำสั่ง Limit เพื่อซื้อ 10000 EURUSD (ราคา: 1.19320) * การวางคำสั่ง Limit เพื่อซื้อ 10000 EURUSD (ราคา: 1.19320) สำเร็จ, PendingOrder OID25222083 * TradeResult (สำเร็จ, PendingOrder: OID25222083)"

Image title