Aller au contenu

Exemples de code cBot

Cette page fournit plusieurs exemples de code Python et C# pour créer des bots de trading et développer des algorithmes. Notez qu'aucun des cBots répertoriés ci-dessous ne garantit de rendements financiers. Assurez-vous de backtester et de personnaliser vos cBots avant de déployer des instances sur un compte réel.

Référentiels d'exemples de cBot

Des exemples de code cBot complets, y compris des modèles prêts à l'emploi pour diverses stratégies automatisées et styles de trading, sont disponibles dans des référentiels Python et C# séparés dans GitHub.

Opérations synchrones

Tous les cBots de cette section exécutent leurs opérations de manière synchrone.

Exécuter des ordres de marché

  • Un cBot simple effectuant des opérations réussies

    Le robot de trading suivant crée un ordre de marché au démarrage et enregistre le résultat dans la variable result.

    Si l'exécution de l'ordre est réussie, le cours d'entrée est affiché dans le journal.

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

    Sortie du journal

    • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
    • Exécution de l'ordre de marché pour acheter 10000 EURUSD
    • Exécution de l'ordre de marché pour acheter 10000 EURUSD RÉUSSIE, Position PID14576001
    • Le cours d'entrée de la position est 1.19067
  • Un cBot simple avec des paramètres personnalisables

    Lors de la déclaration de diverses propriétés de cBot, vous pouvez les transformer en paramètres personnalisables en utilisant la déclaration [Parameter()]. Lorsqu'une nouvelle instance de votre cBot est lancée, vous (ou d'autres utilisateurs) pourrez attribuer des valeurs personnalisées à ceux-ci.

    Considérez l'exemple suivant.

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

    Remarque

    Les cBots Python utilisent des paramètres personnalisables déclarés dans leurs fichiers .cs.

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

    Dans l'exemple ci-dessus, nous définissons les caractéristiques suivantes :

    • Le nom du paramètre. Il apparaîtra ensuite dans l'interface utilisateur de cTrader ("SMA Period").
    • La valeur par défaut du paramètre qui s'appliquera à toutes les nouvelles instances à moins qu'elle ne soit modifiée par les utilisateurs (DefaultValue = 14).

    Dans le code ci-dessous, nous montrons comment la propriété SmaPeriod peut être utilisée dans un véritable robot de trading.

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

    Remarque

    Les cBots Python utilisent des paramètres personnalisables déclarés dans leurs fichiers .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}")
    

    Notre bot prend la propriété personnalisable SmaPeriod et, au démarrage, transmet sa valeur à la méthode Indicators.GetIndicator<SampleSMA>(). Cette méthode renvoie une valeur de moyenne mobile simple pour la période spécifiée.

    Lors de la création d'une instance de cBot, tous les paramètres ajustables peuvent être configurés dans la fenêtre Add instance.

    Une fois lancé, le cBot nous informe de la dernière valeur de la moyenne mobile simple à chaque tick.

    Sortie du journal

    • Instance de CBot [Sample cBot Reference SMA, EURUSD, h1] démarrée.
    • 0.975685714285714
    • 0.975681428571429
    • 0.97568
    • Instance de CBot [Sample cBot Reference SMA, EURUSD, h1] arrêtée par l'utilisateur.
  • Exécuter un ordre de marché avec plus d'arguments

    Dans l'exemple précédent, nous avons transmis le nombre minimum d'arguments possible à la méthode ExecuteMarketOrder(). Il s'agissait du type de trade (TradeType.Buy), du symbole (Symbol) et du volume (-1).

    La méthode ExecuteMarketOrder() peut être appelée avec des arguments supplémentaires tels que Label, StopLoss, TakeProfit et Comment. L'exemple ci-dessous spécifie le label ("order 1"), le mécanisme de protection stop-loss (10) et le niveau de 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}")
    

    Sortie du journal

    • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
    • Exécution de l'ordre de marché pour acheter 10000 EURUSD (SL: 10, TP: 10)
    • Exécution de l'ordre de marché pour acheter 10000 EURUSD (SL: 10, TP: 10) RÉUSSIE, Position PID14576098
    • Le cours d'entrée de la position est 1.1896
    • Le cours SL de la position est 1.1886

Modifier une position

Dans l'exemple ci-dessous, nous ajoutons uniquement une valeur de take profit (10) lorsqu'un ordre est exécuté. Ensuite, nous modifions la position pour ajouter un 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}")

Sortie du journal

  • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
  • Exécution de l'ordre de marché pour acheter 10000 EURUSD (TP: 10)
  • Exécution de l'ordre de marché pour acheter 10000 EURUSD (TP: 10) RÉUSSIE, Position PID14576161
  • Le cours SL de la position est null
  • Modification de la position PID14576161 (SL: 1.18744, TP: 1.18944)
  • Modification de la position PID14576161 (SL: 1.18744, TP: 1.18944) RÉUSSIE, Position PID14576161
  • Le nouveau cours SL de la position est 1.18744

Clôturer une position

  • Effectuer une clôture complète

    L'exemple de code ci-dessous passe un ordre de marché. Si le profit brut de la position résultante dépasse une certaine valeur (null && position.GrossProfit > 10), elle est clôturée.

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

    Sortie du journal

    • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
    • Exécution de l'ordre de marché pour acheter 10000 EURUSD
    • Exécution de l'ordre de marché pour acheter 10000 EURUSD RÉUSSIE, Position PID14576180
  • Effectuer une clôture partielle

    Nous allons modifier l'exemple précédent pour créer deux ordres de marché avec les mêmes labels ("myLabel"). À chaque nouvelle barre, notre robot de trading clôturera exactement la moitié de l'un de ces ordres, mais seulement si son volume est égal ou supérieur à 20 000.

    Nous utilisons également la méthode Positions.FindAll(). Elle renvoie une liste de positions que nous pouvons parcourir.

     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)
    

    Sortie du journal

    • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
    • Exécution de l'ordre de marché pour acheter 20000 EURUSD
    • Exécution de l'ordre de marché pour acheter 20000 EURUSD RÉUSSIE, Position PID14579299
    • Exécution de l'ordre de marché pour acheter 30000 EURUSD
    • Exécution de l'ordre de marché pour acheter 30000 EURUSD RÉUSSIE, Position PID14579300

Créer des ordres en cours

  • Créer des ordres limit et stop

    Les ordres limit et stop sont des ordres en cours ; malgré cela, ils sont créés de manière similaire aux ordres de marché. Cependant, lors de la création d'ordres limit et stop, vous devez également spécifier leur prix cible et il n'y a pas d'écart de marché.

    Ce cBot crée deux ordres limit et un ordre stop. Il parcourt ensuite les ordres et affiche leurs labels et ID dans le journal.

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

    Sortie du journal

    • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
    • Placement de l'ordre limit pour acheter 10000 EURUSD (Prix: 1.19036)
    • Placement de l'ordre limit pour acheter 10000 EURUSD (Prix: 1.19036) RÉUSSI, Ordre en cours OID25220794
    • Placement de l'ordre limit pour acheter 20000 EURUSD (Prix: 1.19017)
    • Placement de l'ordre limit pour acheter 20000 EURUSD (Prix: 1.19017) RÉUSSI, Ordre en cours OID25220795
    • Placement de l'ordre stop pour acheter 10000 EURUSD (Prix: 1.19040)
    • Placement de l'ordre stop pour acheter 10000 EURUSD (Prix: 1.19040) RÉUSSI, Ordre en cours OID25220796
    • Ordre passé avec le label myLimitOrder, id 25220794
    • Ordre passé avec le label myLimitOrder, id 25220795
    • Ordre passé avec le label myStopOrder, id 25220796
  • Créer des ordres en cours avec plus de paramètres

    Comme c'est le cas avec les ordres de marché, vous pouvez également spécifier le label de l'ordre, divers mécanismes de protection, la date d'expiration de l'ordre et fournir un commentaire.

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

    Sortie du journal

    • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
    • Placement de l'ordre limit pour acheter 10000 EURUSD (Prix: 1.19049, SL: 10, ExpireTime: 12/05/2018 00:00:00)
    • Placement de l'ordre limit pour acheter 10000 EURUSD (Prix: 1.19049, SL: 10, ExpireTime: 12/05/2018 00:00:00) RÉUSSI, Ordre en cours OID25220807
    • Placement de l'ordre stop pour acheter 10000 EURUSD (Prix: 1.19053, SL: 10, TP: 10)
    • Placement de l'ordre stop pour acheter 10000 EURUSD (Prix: 1.19053, SL: 10, TP: 10) RÉUSSI, Ordre en cours OID25220808
    • Ordre limit
    • Premier ordre limit SL: 1.18949
    • Deuxième ordre stop SL: 1.18953 TP: 1.19153

Modifier les ordres en cours

Il est possible de modifier plusieurs caractéristiques des ordres en cours.

L'exemple ci-dessous montre comment modifier le prix cible, les niveaux de protection ou la date et l'heure d'expiration d'un ordre en cours.

 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)

Sortie du journal

  • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
  • Placement de l'ordre stop pour acheter 10000 EURUSD (Prix: 1.19254, SL: 10, TP: 10, ExpireTime: 11/05/2018 20:07:25)
  • Placement de l'ordre stop pour acheter 10000 EURUSD (Prix: 1.19254, SL: 10, TP: 10, ExpireTime: 11/05/2018 20:07:25) RÉUSSI, Ordre en cours OID25220877

Annuler les ordres en cours

La syntaxe pour annuler un ordre est CancelPendingOrder(order), où order est de type PendingOrder.

L'exemple ci-dessous montre l'annulation de tous les ordres avec le 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)

Événements de la position

Il est possible de s'abonner à des événements liés à diverses opérations de trading. Par exemple, pour tester si une position est ouverte, nous nous abonnons à un événement qui est déclenché pour tous les objets Position à l'ouverture.

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

Sortie du journal

  • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
  • Exécution de l'ordre de marché pour acheter 10000 EURUSD (SL: 10, TP: 10)
  • Exécution de l'ordre de marché pour acheter 10000 EURUSD (SL: 10, TP: 10) RÉUSSIE, Position PID14579468
  • Position ouverte à 1.19224

De même, il est possible de s'abonner à des événements qui sont déclenchés chaque fois qu'une position est clôturée.

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

Sortie du journal

  • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
  • Exécution de l'ordre au marché pour acheter 10000 EURUSD (SL: 10, TP: 10)
  • Exécution de l'ordre au marché pour acheter 10000 EURUSD (SL: 10, TP: 10) RÉUSSIE, Position PID14579479
  • Clôture de la position PID14579299
  • Clôture de la position PID14579299 RÉUSSIE, Position PID14579299
  • Position clôturée avec un profit de 20,64

Conversion des coordonnées

Le cBot ci-dessous permet aux utilisateurs de placer des ordres limit dans une direction appropriée simplement en effectuant un clic droit sur un graphique. Il y parvient en convertissant les coordonnées Y de la souris en coordonnées Y du graphique (qui, pour les symboles, correspondent aux prix des symboles).

 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)

Exécution asynchrone

Les exemples de code ci-dessus sont conçus pour implémenter des robots de trading utilisant une exécution synchrone. C# et Python prennent tous deux en charge les opérations asynchrones, permettant à votre cBot d'effectuer plusieurs actions dans le même laps de temps.

Exécuter des ordres au marché de manière asynchrone

La syntaxe des méthodes asynchrones est similaire à celle des méthodes synchrones. Bien qu'elles acceptent les mêmes types d'arguments, leur type de retour est TradeOperation au lieu de TradeResult.

  • Opérations asynchrones de base

    Le cBot suivant démontre comment fonctionnent les opérations asynchrones. Un ordre au marché est créé ; dans la condition suivante, le cBot vérifie si l'opération est en cours d'exécution.

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

    Sortie du journal

    • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
    • Exécution de l'ordre au marché pour acheter 10000 EURUSD
    • L'opération est en cours d'exécution
    • Exécution de l'ordre au marché pour acheter 10000 EURUSD RÉUSSIE, Position PID14579532
  • Exécuter un ordre

    L'exemple suivant met en évidence la différence entre les méthodes synchrones et asynchrones.

    Le cBot vérifie si une opération est en cours d'exécution juste après avoir appelé une méthode asynchrone. Il le fait à nouveau après avoir appelé une méthode synchrone. La sortie du journal pour ces deux actions est différente.

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

    Sortie du journal

    • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
    • Exécution de l'ordre au marché pour acheter 10000 EURUSD
    • L'opération est en cours d'exécution
    • Exécution de l'ordre au marché pour acheter 20000 EURUSD
    • Exécution de l'ordre au marché pour acheter 10000 EURUSD RÉUSSIE, Position PID14579541
    • Exécution de l'ordre au marché pour acheter 20000 EURUSD RÉUSSIE, Position PID14579542
    • Opération exécutée
  • Exécuter un ordre avec plus de paramètres

    Le cBot suivant place un ordre en spécifiant son étiquette ("myLabel"), ses niveaux de protection (10, 10), son symbole (SymbolName) et son volume (10000).

    L'exemple contient également la collection Positions et la méthode FindAll(). Find() et FindAll() peuvent être utilisées pour trouver des positions avec la même étiquette, le même symbole et le même type de transaction.

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

    Sortie du journal

    • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
    • Exécution de l'ordre au marché pour acheter 10000 EURUSD (SL: 10, TP: 10)
    • Exécution de l'ordre au marché pour acheter 10000 EURUSD (SL: 10, TP: 10) RÉUSSIE, Position PID14579719
    • Achat à 1,19087 SL null
    • Achat à 1,19357 SL 1,19257
    • Le cBot "New cBot" a été arrêté pour EURUSD, h1.

Modifier une position de manière asynchrone

Le cBot ci-dessous place un ordre au marché puis modifie la position nouvellement ouverte.

 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)        

Sortie du journal

  • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
  • Exécution de l'ordre au marché pour acheter 10000 EURUSD (TP: 10)
  • Exécution de l'ordre au marché pour acheter 10000 EURUSD (TP: 10) RÉUSSIE, Position PID14579736
  • Modification de la position PID14579300 (SL: 1,19213, TP: null)
  • Modification de la position PID14579300 (SL: 1,19213, TP: null) RÉUSSIE, Position PID14579300

Clôturer une position de manière asynchrone

L'exemple suivant démontre la clôture d'une position de manière asynchrone si elle existe.

La méthode Find() est utilisée pour rechercher dans la collection Positions la position avec une étiquette spécifique.

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

Sortie du journal

  • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
  • Exécution de l'ordre au marché pour acheter 10000 EURUSD (TP: 10)
  • Exécution de l'ordre au marché pour acheter 10000 EURUSD (TP: 10) RÉUSSIE, Position PID14579740
  • Clôture de la position PID14579300
  • Clôture de la position PID14579300 RÉUSSIE, Position PID14579300
  • Le cBot "New cBot" a été arrêté pour EURUSD, h1.

Placer des ordres limit et stop de manière asynchrone

Comme indiqué ci-dessus, placer des ordres en cours est similaire à la création d'ordres au marché.

Cependant, il existe quelques légères différences dans les arguments entre ces deux méthodes. L'écart de marché est absent de la liste des arguments. De plus, vous devez spécifier le prix cible, et vous pouvez passer un argument optionnel spécifiant la date d'expiration de l'ordre.

 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)    

Sortie du journal

  • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
  • Placement de l'ordre limit pour acheter 10000 EURUSD (Prix: 1,19382, ExpireTime: 12/05/2018 00:18:19)
  • Placement de l'ordre stop pour acheter 10000 EURUSD (Prix: 1,19487, ExpireTime: 12/05/2018 00:18:19)
  • Placement de l'ordre limit pour acheter 10000 EURUSD (Prix: 1,19382, ExpireTime: 12/05/2018 00:18:19) RÉUSSI, Ordre en cours OID25221859
  • Placement de l'ordre stop pour acheter 10000 EURUSD (Prix: 1,19487, ExpireTime: 12/05/2018 00:18:19) RÉUSSI, Ordre en cours OID25221860

Modifier des ordres en cours de manière asynchrone

Le cBot suivant modifie des ordres limit de manière asynchrone.

 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)

Sortie du journal

  • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
  • Placement de l'ordre limit pour acheter 10000 EURUSD (Prix: 1,19347, TP: 10, ExpireTime: 12/05/2018 00:22:08)
  • Modification de l'ordre en cours OID25221860 (Volume: 10000, Prix: 1,19487, SL: 10, TP: 10, ExpireTime: 12/05/2018 00:18:19)
  • Placement de l'ordre limit pour acheter 10000 EURUSD (Prix: 1,19347, TP: 10, ExpireTime: 12/05/2018 00:22:08) RÉUSSI, Ordre en cours OID25221906
  • Modification de l'ordre en cours OID25221860 (Volume: 10000, Prix: 1,19487, SL: 10, TP: 10, ExpireTime: 12/05/2018 00:18:19) RÉUSSIE, Ordre en cours OID25221860
  • Modification de l'ordre en cours OID25221906 (Volume: 10000, Prix: 1,19347, SL: 10, TP: 10, ExpireTime: 12/05/2018 00:22:08)
  • Modification de l'ordre en cours OID25221906 (Volume: 10000, Prix: 1,19347, SL: 10, TP: 10, ExpireTime: 12/05/2018 00:22:08) RÉUSSIE, Ordre en cours OID25221906

Annuler des ordres en cours de manière asynchrone

  • Annuler tous les ordres en cours

    Le cBot ci-dessous annule de manière asynchrone tous les ordres actuellement en cours.

     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)
    

    Sortie du journal

    • Le cBot "cancel pending order" a été démarré avec succès pour EURUSD, h1.
    • Annulation de l'ordre en cours OID274705
    • Annulation de l'ordre en cours OID274706
    • Annulation de l'ordre en cours OID274707
    • Annulation de l'ordre en cours OID274708
    • Annulation de l'ordre en cours OID274709
    • Annulation de l'ordre en cours OID274705 RÉUSSIE, Ordre en cours OID274705
    • Annulation de l'ordre en cours OID274706 RÉUSSIE, Ordre en cours OID274706
    • Annulation de l'ordre en cours OID274707 RÉUSSIE, Ordre en cours OID274707
    • Annulation de l'ordre en cours OID274708 RÉUSSIE, Ordre en cours OID274708
    • Annulation de l'ordre en cours OID274709 RÉUSSIE, Ordre en cours OID274709
  • Annuler les ordres en cours avec une certaine étiquette

    Ce cBot annule uniquement les ordres en cours avec une certaine étiquette.

     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)
    

Fonctions de rappel pour les méthodes asynchrones

Une fois qu'un résultat est renvoyé, l'utilisation d'opérations asynchrones nécessite souvent de contrôler l'exécution. Pour gérer cela, vous pouvez ajouter une fonction de rappel à la fin de la liste des paramètres de toutes les méthodes asynchrones.

Cette fonction sera appelée dès qu'une réponse est reçue du serveur. Par exemple, elle pourrait être appelée lorsqu'une position est ouverte, modifiée ou clôturée.

  • Ordre au marché asynchrone avec un rappel

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

    Sortie du journal

    • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
    • Exécution de l'ordre au marché pour acheter 10000 EURUSD
    • TradeOperation (Exécution de l'ordre au marché pour acheter 10000 EURUSD EN COURS)
    • Exécution de l'ordre au marché pour acheter 10000 EURUSD RÉUSSIE, Position PID14579835
    • TradeResult (Succès, Position: PID14579835)
    • Position 14579835 ouverte à 1,19414
  • Utilisation d'expressions lambda

    Au lieu de définir une méthode de rappel nommée, vous pouvez utiliser des expressions lambda.

    Dans l'exemple suivant, lorsqu'un ordre est placé, la description du résultat sera imprimée dans le journal.

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

    Sortie du journal

    • cBot "New cBot" a été démarré avec succès pour EURUSD, h1.
    • Placement d'un ordre limit d'achat de 10000 EURUSD (Prix : 1.19320)
    • Placement d'un ordre limit d'achat de 10000 EURUSD (Prix : 1.19320) RÉUSSI, PendingOrder OID25222083
    • TradeResult (Success, PendingOrder: OID25222083)"

Image title