Zum Inhalt

cBot-Codebeispiele

Diese Seite bietet mehrere Python- und C#-Codebeispiele zum Erstellen von Handelsbots und zur Entwicklung von Algorithmen. Beachten Sie, dass keiner der unten aufgeführten cBots finanzielle Erträge garantiert. Stellen Sie sicher, dass Sie Ihre cBots einem Backtest unterziehen und anpassen, bevor Sie Instanzen auf einem Live-Konto bereitstellen.

cBot-Beispiel-Repositorys

Umfassende cBot-Codebeispiele, einschließlich sofort ausführbarer Vorlagen für verschiedene automatisierte Strategien und Handelsstile, sind in separaten Python- und C#-Repositorys in GitHub verfügbar.

Synchrone Operationen

Alle cBots in diesem Abschnitt führen ihre Operationen synchron aus.

Markt-Ordern ausführen

  • Ein einfacher cBot, der erfolgreiche Operationen durchführt

    Der folgende Handelsbot erstellt beim Start eine Markt-Order und speichert das Ergebnis in der Variablen result.

    Wenn die Orderausführung erfolgreich ist, wird der Einstiegskurs im Protokoll ausgegeben.

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

    Log-Ausgabe

    • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
    • Ausführung der Markt-Order zum Kauf von 10000 EURUSD
    • Ausführung der Markt-Order zum Kauf von 10000 EURUSD ERFOLGREICH, Position PID14576001
    • Positionseinstiegskurs ist 1.19067
  • Ein einfacher cBot mit anpassbaren Parametern

    Beim Deklarieren verschiedener cBot-Eigenschaften können Sie diese mithilfe der Deklaration [Parameter()] in anpassbare Parameter umwandeln. Wenn eine neue Instanz Ihres cBots gestartet wird, können Sie (oder andere Benutzer) diesen benutzerdefinierte Werte zuweisen.

    Betrachten Sie das folgende Beispiel.

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

    Hinweis

    Python-cBots verwenden anpassbare Parameter, die in ihren .cs-Dateien deklariert sind.

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

    Im obigen Beispiel definieren wir die folgenden Merkmale:

    • Den Namen des Parameters. Er wird anschließend in der cTrader-Benutzeroberfläche angezeigt ("SMA Period").
    • Den Standardwert des Parameters, der für alle neuen Instanzen gilt, sofern er nicht von Benutzern geändert wird (DefaultValue = 14).

    Im folgenden Code zeigen wir, wie die Eigenschaft SmaPeriod in einem tatsächlichen Handelsbot verwendet werden kann.

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

    Hinweis

    Python-cBots verwenden anpassbare Parameter, die in ihren .cs-Dateien deklariert sind.

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

    Unser Bot nimmt die anpassbare Eigenschaft SmaPeriod und übergibt beim Start ihren Wert an die Methode Indicators.GetIndicator<SampleSMA>(). Diese Methode gibt einen einfachen gleitenden Durchschnittswert für den angegebenen Zeitraum zurück.

    Beim Erstellen einer cBot-Instanz können alle anpassbaren Parameter im Fenster Instanz hinzufügen eingerichtet werden.

    Nach dem Start informiert uns der cBot bei jedem Tick darüber, was der letzte einfache gleitende Durchschnittswert war.

    Log-Ausgabe

    • CBot-Instanz [Sample cBot Reference SMA, EURUSD, h1] gestartet.
    • 0.975685714285714
    • 0.975681428571429
    • 0.97568
    • CBot-Instanz [Sample cBot Reference SMA, EURUSD, h1] vom Benutzer gestoppt.
  • Eine Markt-Order mit mehr Argumenten ausführen

    Im vorherigen Beispiel haben wir die minimal mögliche Anzahl von Argumenten an die Methode ExecuteMarketOrder() übergeben. Dies waren der Handelstyp (TradeType.Buy), das Symbol (Symbol) und das Volumen (-1).

    Die Methode ExecuteMarketOrder() kann mit zusätzlichen Argumenten wie Label, StopLoss, TakeProfit und Comment aufgerufen werden. Das folgende Beispiel gibt das Label ("order 1"), den Stop-Loss-Schutzmechanismus (10) und das Take-Profit-Niveau (10) an.

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

    Log-Ausgabe

    • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
    • Ausführung der Markt-Order zum Kauf von 10000 EURUSD (SL: 10, TP: 10)
    • Ausführung der Markt-Order zum Kauf von 10000 EURUSD (SL: 10, TP: 10) ERFOLGREICH, Position PID14576098
    • Positionseinstiegskurs ist 1.1896
    • Positions-SL-Kurs ist 1.1886

Eine Position ändern

Im folgenden Beispiel fügen wir nur einen Take-Profit-Wert (10) hinzu, wenn eine Order ausgeführt wird. Anschließend ändern wir die Position, um einen Stop-Loss hinzuzufügen.

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

Log-Ausgabe

  • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
  • Ausführung der Markt-Order zum Kauf von 10000 EURUSD (TP: 10)
  • Ausführung der Markt-Order zum Kauf von 10000 EURUSD (TP: 10) ERFOLGREICH, Position PID14576161
  • Positions-SL-Kurs ist null
  • Änderung der Position PID14576161 (SL: 1.18744, TP: 1.18944)
  • Änderung der Position PID14576161 (SL: 1.18744, TP: 1.18944) ERFOLGREICH, Position PID14576161
  • Neuer Positions-SL-Kurs ist 1.18744

Eine Position schließen

  • Eine vollständige Schließung durchführen

    Das folgende Codebeispiel platziert eine Markt-Order. Wenn der Bruttogewinn der resultierenden Position einen bestimmten Wert überschreitet (null && position.GrossProfit > 10), wird sie geschlossen.

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

    Log-Ausgabe

    • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
    • Ausführung der Markt-Order zum Kauf von 10000 EURUSD
    • Ausführung der Markt-Order zum Kauf von 10000 EURUSD ERFOLGREICH, Position PID14576180
  • Eine teilweise Schließung durchführen

    Wir werden das vorherige Beispiel ändern, um zwei Markt-Ordern mit denselben Labels ("myLabel") zu erstellen. Bei jedem neuen Balken schließt unser Handelsbot genau die Hälfte einer dieser Ordern, jedoch nur, wenn ihr Volumen gleich oder größer als 20.000 ist.

    Wir verwenden auch die Methode Positions.FindAll(). Sie gibt eine Liste von Positionen zurück, durch die wir iterieren können.

     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)
    

    Log-Ausgabe

    • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
    • Ausführung der Markt-Order zum Kauf von 20000 EURUSD
    • Ausführung der Markt-Order zum Kauf von 20000 EURUSD ERFOLGREICH, Position PID14579299
    • Ausführung der Markt-Order zum Kauf von 30000 EURUSD
    • Ausführung der Markt-Order zum Kauf von 30000 EURUSD ERFOLGREICH, Position PID14579300

Ausstehende Ordern erstellen

  • Limit- und Stop-Ordern erstellen

    Limit- und Stop-Ordern sind ausstehende Ordern; dennoch werden sie ähnlich wie Markt-Ordern erstellt. Beim Erstellen von Limit- und Stop-Ordern müssen Sie jedoch auch deren Zielkurs angeben, und es gibt keine Marktspanne.

    Dieser cBot erstellt zwei Limit-Ordern und eine Stop-Order. Anschließend iteriert er durch die Ordern und gibt deren Labels und IDs im Protokoll aus.

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

    Log-Ausgabe

    • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
    • Limit-Order zum Kauf von 10000 EURUSD wird erteilt (Kurs: 1.19036)
    • Limit-Order zum Kauf von 10000 EURUSD wird erteilt (Kurs: 1.19036) ERFOLGREICH, PendingOrder OID25220794
    • Limit-Order zum Kauf von 20000 EURUSD wird erteilt (Kurs: 1.19017)
    • Limit-Order zum Kauf von 20000 EURUSD wird erteilt (Kurs: 1.19017) ERFOLGREICH, PendingOrder OID25220795
    • Stop-Order zum Kauf von 10000 EURUSD wird erteilt (Kurs: 1.19040)
    • Stop-Order zum Kauf von 10000 EURUSD wird erteilt (Kurs: 1.19040) ERFOLGREICH, PendingOrder OID25220796
    • Order mit Label myLimitOrder erteilt, ID 25220794
    • Order mit Label myLimitOrder erteilt, ID 25220795
    • Order mit Label myStopOrder erteilt, ID 25220796
  • Ausstehende Orders mit mehr Parametern erstellen

    Wie bei Markt-Orders können Sie auch das Order-Label, verschiedene Schutzmechanismen, das Ablaufdatum der Order angeben und einen Kommentar hinzufügen.

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

    Log-Ausgabe

    • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
    • Limit-Order zum Kauf von 10000 EURUSD wird erteilt (Kurs: 1.19049, SL: 10, ExpireTime: 12/05/2018 00:00:00)
    • Limit-Order zum Kauf von 10000 EURUSD wird erteilt (Kurs: 1.19049, SL: 10, ExpireTime: 12/05/2018 00:00:00) ERFOLGREICH, PendingOrder OID25220807
    • Stop-Order zum Kauf von 10000 EURUSD wird erteilt (Kurs: 1.19053, SL: 10, TP: 10)
    • Stop-Order zum Kauf von 10000 EURUSD wird erteilt (Kurs: 1.19053, SL: 10, TP: 10) ERFOLGREICH, PendingOrder OID25220808
    • Limit-Order
    • Erste Limit-Order SL: 1.18949
    • Zweite Stop-Order SL: 1.18953 TP: 1.19153

Ausstehende Orders ändern

Es ist möglich, mehrere Merkmale ausstehender Orders zu ändern.

Das folgende Beispiel zeigt, wie der Zielkurs, die Schutzniveaus oder das Ablaufdatum und die Ablaufzeit einer ausstehenden Order geändert werden.

 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)

Log-Ausgabe

  • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
  • Stop-Order zum Kauf von 10000 EURUSD wird erteilt (Kurs: 1.19254, SL: 10, TP: 10, ExpireTime: 11/05/2018 20:07:25)
  • Stop-Order zum Kauf von 10000 EURUSD wird erteilt (Kurs: 1.19254, SL: 10, TP: 10, ExpireTime: 11/05/2018 20:07:25) ERFOLGREICH, PendingOrder OID25220877

Ausstehende Orders stornieren

Die Syntax zum Stornieren einer Order lautet CancelPendingOrder(order), wobei order vom Typ PendingOrder ist.

Das folgende Beispiel zeigt das Stornieren aller Orders mit dem 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)

Positionsereignisse

Es ist möglich, Ereignisse im Zusammenhang mit verschiedenen Handelsoperationen zu abonnieren. Um beispielsweise zu testen, ob eine Position eröffnet wird, abonnieren wir ein Ereignis, das für alle Position-Objekte beim Öffnen ausgelöst wird.

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

Log-Ausgabe

  • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
  • Markt-Order zum Kauf von 10000 EURUSD wird ausgeführt (SL: 10, TP: 10)
  • Markt-Order zum Kauf von 10000 EURUSD wird ausgeführt (SL: 10, TP: 10) ERFOLGREICH, Position PID14579468
  • Position eröffnet bei 1.19224

Ebenso ist es möglich, Ereignisse zu abonnieren, die jedes Mal ausgelöst werden, wenn eine Position geschlossen wird.

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

Log-Ausgabe

  • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
  • Markt-Order zum Kauf von 10000 EURUSD wird ausgeführt (SL: 10, TP: 10)
  • Markt-Order zum Kauf von 10000 EURUSD wird ausgeführt (SL: 10, TP: 10) ERFOLGREICH, Position PID14579479
  • Position PID14579299 wird geschlossen
  • Position PID14579299 wird geschlossen ERFOLGREICH, Position PID14579299
  • Position mit 20,64 Gewinn geschlossen

Koordinatenumwandlung

Der folgende cBot ermöglicht es Benutzern, Limit-Orders in eine geeignete Richtung zu erteilen, indem sie einfach mit der rechten Maustaste auf ein Chart klicken. Dies wird erreicht, indem Maus-Y-Koordinaten in Chart-Y-Koordinaten umgewandelt werden (die bei Symbolen den Symbolkursen entsprechen).

 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)

Asynchrone Ausführung

Die obigen Codebeispiele sind darauf ausgelegt, Handelsroboter mit synchroner Ausführung zu implementieren. C# und Python unterstützen beide asynchrone Operationen, sodass Ihr cBot mehrere Aktionen innerhalb desselben Zeitrahmens ausführen kann.

Markt-Orders asynchron ausführen

Die Syntax der asynchronen Methoden ähnelt der der synchronen. Während sie die gleichen Arten von Argumenten akzeptieren, ist ihr Rückgabetyp TradeOperation anstelle von TradeResult.

  • Grundlegende asynchrone Operationen

    Der folgende cBot zeigt, wie asynchrone Operationen funktionieren. Eine Markt-Order wird erstellt; in der nächsten Bedingung prüft der cBot, ob die Operation ausgeführt wird.

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

    Log-Ausgabe

    • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
    • Markt-Order zum Kauf von 10000 EURUSD wird ausgeführt
    • Operation wird ausgeführt
    • Markt-Order zum Kauf von 10000 EURUSD wird ausgeführt ERFOLGREICH, Position PID14579532
  • Eine Order ausführen

    Das nächste Beispiel hebt den Unterschied zwischen synchronen und asynchronen Methoden hervor.

    Der cBot prüft, ob eine Operation ausgeführt wird, direkt nachdem eine asynchrone Methode aufgerufen wurde. Er tut dies erneut, nachdem eine synchrone Methode aufgerufen wurde. Die Log-Ausgabe für diese beiden Aktionen ist unterschiedlich.

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

    Log-Ausgabe

    • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
    • Markt-Order zum Kauf von 10000 EURUSD wird ausgeführt
    • Operation wird ausgeführt
    • Markt-Order zum Kauf von 20000 EURUSD wird ausgeführt
    • Markt-Order zum Kauf von 10000 EURUSD wird ausgeführt ERFOLGREICH, Position PID14579541
    • Markt-Order zum Kauf von 20000 EURUSD wird ausgeführt ERFOLGREICH, Position PID14579542
    • Operation ausgeführt
  • Eine Order mit mehr Parametern ausführen

    Der folgende cBot erteilt eine Order unter Angabe ihres Labels ("myLabel"), der Schutzniveaus (10, 10), des Symbols (SymbolName) und des Volumens (10000).

    Das Beispiel enthält auch die Positions-Sammlung und die FindAll()-Methode. Find() und FindAll() können verwendet werden, um Positionen mit demselben Label, Symbol und Handelstyp zu finden.

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

    Log-Ausgabe

    • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
    • Markt-Order zum Kauf von 10000 EURUSD wird ausgeführt (SL: 10, TP: 10)
    • Markt-Order zum Kauf von 10000 EURUSD wird ausgeführt (SL: 10, TP: 10) ERFOLGREICH, Position PID14579719
    • Kauf bei 1.19087 SL null
    • Kauf bei 1.19357 SL 1.19257
    • cBot „New cBot wurde für EURUSD, h1 gestoppt."

Position asynchron ändern

Der folgende cBot erteilt eine Markt-Order und ändert dann die neu eröffnete Position.

 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)        

Log-Ausgabe

  • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
  • Markt-Order zum Kauf von 10000 EURUSD wird ausgeführt (TP: 10)
  • Markt-Order zum Kauf von 10000 EURUSD wird ausgeführt (TP: 10) ERFOLGREICH, Position PID14579736
  • Position PID14579300 wird geändert (SL: 1.19213, TP: null)
  • Position PID14579300 wird geändert (SL: 1.19213, TP: null) ERFOLGREICH, Position PID14579300

Position asynchron schließen

Das nächste Beispiel demonstriert das asynchrone Schließen einer Position, falls sie existiert.

Die Methode Find() wird verwendet, um die Sammlung Positions nach der Position mit einem bestimmten Label zu durchsuchen.

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

Log-Ausgabe

  • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
  • Ausführung einer Market-Order zum Kauf von 10000 EURUSD (TP: 10)
  • Ausführung einer Market-Order zum Kauf von 10000 EURUSD (TP: 10) ERFOLGREICH, Position PID14579740
  • Schließen der Position PID14579300
  • Schließen der Position PID14579300 ERFOLGREICH, Position PID14579300
  • cBot „New cBot" wurde für EURUSD, h1 gestoppt.

Limit- und Stop-Orders asynchron platzieren

Wie oben angegeben, ist das Platzieren ausstehender Orders ähnlich wie das Erstellen von Market-Orders.

Es gibt jedoch einige leichte Unterschiede in den Argumenten zwischen diesen beiden Methoden. Die Marktspanne fehlt in der Argumentliste. Außerdem müssen Sie den Zielpreis angeben und können ein optionales Argument übergeben, das das Ablaufdatum der Order festlegt.

 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)    

Log-Ausgabe

  • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
  • Platzierung einer Limit-Order zum Kauf von 10000 EURUSD (Preis: 1.19382, Ablaufzeit: 12/05/2018 00:18:19)
  • Platzierung einer Stop-Order zum Kauf von 10000 EURUSD (Preis: 1.19487, Ablaufzeit: 12/05/2018 00:18:19)
  • Platzierung einer Limit-Order zum Kauf von 10000 EURUSD (Preis: 1.19382, Ablaufzeit: 12/05/2018 00:18:19) ERFOLGREICH, ausstehende Order OID25221859
  • Platzierung einer Stop-Order zum Kauf von 10000 EURUSD (Preis: 1.19487, Ablaufzeit: 12/05/2018 00:18:19) ERFOLGREICH, ausstehende Order OID25221860

Ausstehende Orders asynchron ändern

Der folgende cBot ändert Limit-Orders asynchron.

 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)

Log-Ausgabe

  • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
  • Platzierung einer Limit-Order zum Kauf von 10000 EURUSD (Preis: 1.19347, TP: 10, Ablaufzeit: 12/05/2018 00:22:08)
  • Änderung der ausstehenden Order OID25221860 (Volumen: 10000, Preis: 1.19487, SL: 10, TP: 10, Ablaufzeit: 12/05/2018 00:18:19)
  • Platzierung einer Limit-Order zum Kauf von 10000 EURUSD (Preis: 1.19347, TP: 10, Ablaufzeit: 12/05/2018 00:22:08) ERFOLGREICH, ausstehende Order OID25221906
  • Änderung der ausstehenden Order OID25221860 (Volumen: 10000, Preis: 1.19487, SL: 10, TP: 10, Ablaufzeit: 12/05/2018 00:18:19) ERFOLGREICH, ausstehende Order OID25221860
  • Änderung der ausstehenden Order OID25221906 (Volumen: 10000, Preis: 1.19347, SL: 10, TP: 10, Ablaufzeit: 12/05/2018 00:22:08)
  • Änderung der ausstehenden Order OID25221906 (Volumen: 10000, Preis: 1.19347, SL: 10, TP: 10, Ablaufzeit: 12/05/2018 00:22:08) ERFOLGREICH, ausstehende Order OID25221906

Ausstehende Orders asynchron stornieren

  • Alle ausstehenden Orders stornieren

    Der nachstehende cBot storniert asynchron alle derzeit ausstehenden Orders.

     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)
    

    Log-Ausgabe

    • cBot „cancel pending order" wurde erfolgreich für EURUSD, h1 gestartet.
    • Stornierung der ausstehenden Order OID274705
    • Stornierung der ausstehenden Order OID274706
    • Stornierung der ausstehenden Order OID274707
    • Stornierung der ausstehenden Order OID274708
    • Stornierung der ausstehenden Order OID274709
    • Stornierung der ausstehenden Order OID274705 ERFOLGREICH, ausstehende Order OID274705
    • Stornierung der ausstehenden Order OID274706 ERFOLGREICH, ausstehende Order OID274706
    • Stornierung der ausstehenden Order OID274707 ERFOLGREICH, ausstehende Order OID274707
    • Stornierung der ausstehenden Order OID274708 ERFOLGREICH, ausstehende Order OID274708
    • Stornierung der ausstehenden Order OID274709 ERFOLGREICH, ausstehende Order OID274709
  • Ausstehende Orders mit einem bestimmten Label stornieren

    Dieser cBot storniert nur ausstehende Orders mit einem bestimmten Label.

     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)
    

Callback-Funktionen für asynchrone Methoden

Sobald ein Ergebnis zurückgegeben wird, erfordert die Verwendung asynchroner Operationen oft eine Steuerung der Ausführung. Um dies zu handhaben, können Sie am Ende der Parameterliste aller asynchronen Methoden eine Callback-Funktion hinzufügen.

Diese Funktion wird aufgerufen, sobald eine Antwort vom Server empfangen wird. Sie könnte zum Beispiel aufgerufen werden, wenn eine Position eröffnet, geändert oder geschlossen wird.

  • Asynchrone Market-Order mit einem 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}")
    

    Log-Ausgabe

    • cBot "New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
    • Ausführung einer Market-Order zum Kauf von 10000 EURUSD
    • TradeOperation (Ausführung einer Market-Order zum Kauf von 10000 EURUSD WIRD AUSGEFÜHRT)
    • Ausführung einer Market-Order zum Kauf von 10000 EURUSD ERFOLGREICH, Position PID14579835
    • TradeResult (Erfolgreich, Position: PID14579835)
    • Position 14579835 eröffnet bei 1.19414
  • Verwendung von Lambda-Ausdrücken

    Anstatt eine benannte Callback-Methode zu definieren, können Sie Lambda-Ausdrücke verwenden.

    Im folgenden Beispiel wird die Beschreibung des Ergebnisses im Log ausgegeben, wenn eine Order platziert wird.

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

    Log-Ausgabe

    • cBot „New cBot" wurde erfolgreich für EURUSD, h1 gestartet.
    • Platzierung einer Limit-Order zum Kauf von 10000 EURUSD (Preis: 1.19320)
    • Platzierung einer Limit-Order zum Kauf von 10000 EURUSD (Preis: 1.19320) ERFOLGREICH, ausstehende Order OID25222083
    • TradeResult (Erfolgreich, ausstehende Order: OID25222083)

Image title