Vai al contenuto

Esempi di codice cBot

Questa pagina fornisce diversi esempi di codice Python e C# per creare bot di trading e sviluppare algoritmi. Tieni presente che nessuno dei cBot elencati di seguito garantisce alcun rendimento finanziario. Assicurati di eseguire il backtest e personalizzare i tuoi cBot prima di distribuire qualsiasi istanza su un conto live.

Repository di esempi cBot

Esempi completi di codice cBot, inclusi modelli pronti all'uso per varie strategie automatizzate e stili di trading, sono disponibili in repository separati Python e C# in GitHub.

Operazioni sincrone

Tutti i cBot in questa sezione eseguono le loro operazioni in modo sincrono.

Eseguire ordini di mercato

  • Un semplice cBot che esegue operazioni con successo

    Il seguente bot di trading crea un ordine di mercato all'avvio e salva il risultato nella variabile result.

    Se l'esecuzione dell'ordine ha successo, il prezzo di entrata viene stampato nel registro.

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

    Output del registro

    • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
    • Esecuzione ordine di mercato per acquistare 10000 EURUSD
    • Esecuzione ordine di mercato per acquistare 10000 EURUSD RIUSCITA, Posizione PID14576001
    • Il prezzo di entrata della posizione è 1.19067
  • Un semplice cBot con parametri personalizzabili

    Quando dichiari varie proprietà del cBot, puoi trasformarle in parametri personalizzabili utilizzando la dichiarazione [Parameter()]. Quando viene avviata una nuova istanza del tuo cBot, tu (o altri utenti) sarete in grado di assegnare valori personalizzati a questi.

    Considera il seguente esempio.

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

    Nota

    I cBot Python utilizzano parametri personalizzabili dichiarati nei loro file .cs.

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

    Nell'esempio sopra, definiamo le seguenti caratteristiche:

    • Il nome del parametro. Successivamente, apparirà nell'interfaccia utente di cTrader ("SMA Period").
    • Il valore predefinito del parametro che si applicherà a tutte le nuove istanze a meno che non venga modificato dagli utenti (DefaultValue = 14).

    Nel codice seguente, mostriamo come la proprietà SmaPeriod può essere utilizzata in un bot di trading effettivo.

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

    Nota

    I cBot Python utilizzano parametri personalizzabili dichiarati nei loro file .cs.

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

    Il nostro bot prende la proprietà personalizzabile SmaPeriod e, all'avvio, passa il suo valore al metodo Indicators.GetIndicator<SampleSMA>(). Questo metodo restituisce un valore di media mobile semplice per il periodo specificato.

    Quando si crea un'istanza di cBot, tutti i parametri regolabili possono essere configurati nella finestra Aggiungi istanza.

    Una volta avviato, il cBot ci informa di quale fosse l'ultimo valore della media mobile semplice ad ogni tick.

    Output del registro

    • Istanza CBot [Sample cBot Reference SMA, EURUSD, h1] avviata.
    • 0.975685714285714
    • 0.975681428571429
    • 0.97568
    • Istanza CBot [Sample cBot Reference SMA, EURUSD, h1] interrotta dall'utente.
  • Eseguire un ordine di mercato con più argomenti

    Nell'esempio precedente, abbiamo passato il numero minimo possibile di argomenti al metodo ExecuteMarketOrder(). Erano il tipo di operazione (TradeType.Buy), il simbolo (Symbol) e il volume (-1).

    Il metodo ExecuteMarketOrder() può essere chiamato con argomenti aggiuntivi come Label, StopLoss, TakeProfit e Comment. L'esempio seguente specifica l'etichetta ("order 1"), il meccanismo di protezione stop loss (10) e il livello di take profit (10).

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

    Output del registro

    • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
    • Esecuzione ordine di mercato per acquistare 10000 EURUSD (SL: 10, TP: 10)
    • Esecuzione ordine di mercato per acquistare 10000 EURUSD (SL: 10, TP: 10) RIUSCITA, Posizione PID14576098
    • Il prezzo di entrata della posizione è 1.1896
    • Il prezzo SL della posizione è 1.1886

Modifica una posizione

Nell'esempio seguente, aggiungiamo solo un valore di take profit (10) quando viene eseguito un ordine. Successivamente, modifichiamo la posizione per aggiungere uno stop loss.

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

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

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

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

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

Output del registro

  • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
  • Esecuzione ordine di mercato per acquistare 10000 EURUSD (TP: 10)
  • Esecuzione ordine di mercato per acquistare 10000 EURUSD (TP: 10) RIUSCITA, Posizione PID14576161
  • Il prezzo SL della posizione è null
  • Modifica posizione PID14576161 (SL: 1.18744, TP: 1.18944)
  • Modifica posizione PID14576161 (SL: 1.18744, TP: 1.18944) RIUSCITA, Posizione PID14576161
  • Il nuovo prezzo SL della posizione è 1.18744

Chiudere una posizione

  • Eseguire una chiusura completa

    L'esempio di codice seguente piazza un ordine di mercato. Se il profitto lordo della posizione risultante supera un certo valore (null && position.GrossProfit > 10), viene chiusa.

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

    Output del registro

    • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
    • Esecuzione dell'ordine di mercato per acquistare 10000 EURUSD
    • Esecuzione dell'ordine di mercato per acquistare 10000 EURUSD RIUSCITA, Posizione PID14576180
  • Esegui una chiusura parziale

    Modificheremo l'esempio precedente per creare due ordini di mercato con le stesse etichette ("myLabel"). Ad ogni nuova barra, il nostro robot di trading chiuderà esattamente la metà di uno di questi ordini, ma solo se il suo volume è uguale o superiore a 20.000.

    Utilizziamo anche il metodo Positions.FindAll(). Restituisce un elenco di posizioni che possiamo scorrere.

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

    Output del registro

    • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
    • Esecuzione dell'ordine di mercato per acquistare 20000 EURUSD
    • Esecuzione dell'ordine di mercato per acquistare 20000 EURUSD RIUSCITA, Posizione PID14579299
    • Esecuzione dell'ordine di mercato per acquistare 30000 EURUSD
    • Esecuzione dell'ordine di mercato per acquistare 30000 EURUSD RIUSCITA, Posizione PID14579300

Crea ordini in sospeso

  • Crea ordini limite e stop

    Gli ordini limite e stop sono ordini in sospeso; nonostante ciò, vengono creati in modo simile agli ordini di mercato. Tuttavia, quando crei ordini limite e stop, devi anche specificare il loro prezzo target e non c'è un intervallo di mercato.

    Questo cBot crea due ordini limite e un ordine stop. Quindi scorre gli ordini e stampa le loro etichette e ID nel log.

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

    Output del registro

    • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
    • Piazzamento dell'ordine limite per acquistare 10000 EURUSD (Prezzo: 1.19036)
    • Piazzamento dell'ordine limite per acquistare 10000 EURUSD (Prezzo: 1.19036) RIUSCITO, Ordine in sospeso OID25220794
    • Piazzamento dell'ordine limite per acquistare 20000 EURUSD (Prezzo: 1.19017)
    • Piazzamento dell'ordine limite per acquistare 20000 EURUSD (Prezzo: 1.19017) RIUSCITO, Ordine in sospeso OID25220795
    • Piazzamento dell'ordine stop per acquistare 10000 EURUSD (Prezzo: 1.19040)
    • Piazzamento dell'ordine stop per acquistare 10000 EURUSD (Prezzo: 1.19040) RIUSCITO, Ordine in sospeso OID25220796
    • Ordine piazzato con etichetta myLimitOrder, id 25220794
    • Ordine piazzato con etichetta myLimitOrder, id 25220795
    • Ordine piazzato con etichetta myStopOrder, id 25220796
  • Crea ordini in sospeso con più parametri

    Come nel caso degli ordini di mercato, puoi anche specificare l'etichetta dell'ordine, vari meccanismi di protezione, la data di scadenza dell'ordine e fornire un commento.

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

    Output del registro

    • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
    • Piazzamento dell'ordine limite per acquistare 10000 EURUSD (Prezzo: 1.19049, SL: 10, Scadenza: 12/05/2018 00:00:00)
    • Piazzamento dell'ordine limite per acquistare 10000 EURUSD (Prezzo: 1.19049, SL: 10, Scadenza: 12/05/2018 00:00:00) RIUSCITO, Ordine in sospeso OID25220807
    • Piazzamento dell'ordine stop per acquistare 10000 EURUSD (Prezzo: 1.19053, SL: 10, TP: 10)
    • Piazzamento dell'ordine stop per acquistare 10000 EURUSD (Prezzo: 1.19053, SL: 10, TP: 10) RIUSCITO, Ordine in sospeso OID25220808
    • Ordine limite
    • Primo ordine limite SL: 1.18949
    • Secondo ordine stop SL: 1.18953 TP: 1.19153

Modificare gli ordini in sospeso

È possibile modificare diverse caratteristiche degli ordini in sospeso.

L'esempio seguente mostra come modificare il prezzo target, i livelli di protezione o la data e l'ora di scadenza di un ordine in sospeso.

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

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

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

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

Output del registro

  • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
  • Piazzamento dell'ordine stop per acquistare 10000 EURUSD (Prezzo: 1.19254, SL: 10, TP: 10, Scadenza: 11/05/2018 20:07:25)
  • Piazzamento dell'ordine stop per acquistare 10000 EURUSD (Prezzo: 1.19254, SL: 10, TP: 10, Scadenza: 11/05/2018 20:07:25) RIUSCITO, Ordine in sospeso OID25220877

Annullare gli ordini in sospeso

La sintassi per annullare un ordine è CancelPendingOrder(order), dove order è di tipo PendingOrder.

L'esempio seguente mostra l'annullamento di tutti gli ordini con l'etichetta "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)

Eventi della posizione

È possibile sottoscriversi agli eventi relativi a varie operazioni di trading. Ad esempio, per verificare se una posizione è aperta, ci sottoscriviamo a un evento che viene generato per tutti gli oggetti Position all'apertura.

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

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

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

Output del registro

  • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
  • Esecuzione dell'ordine di mercato per acquistare 10000 EURUSD (SL: 10, TP: 10)
  • Esecuzione dell'ordine di mercato per acquistare 10000 EURUSD (SL: 10, TP: 10) RIUSCITA, Posizione PID14579468
  • Posizione aperta a 1.19224

Allo stesso modo, è possibile sottoscriversi agli eventi che vengono generati ogni volta che una posizione viene chiusa.

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

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

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

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

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

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

Output del registro

  • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
  • Esecuzione dell'ordine di mercato per acquistare 10000 EURUSD (SL: 10, TP: 10)
  • Esecuzione dell'ordine di mercato per acquistare 10000 EURUSD (SL: 10, TP: 10) RIUSCITA, Posizione PID14579479
  • Chiusura della posizione PID14579299
  • Chiusura della posizione PID14579299 RIUSCITA, Posizione PID14579299
  • Posizione chiusa con profitto di 20.64

Conversione delle coordinate

Il cBot seguente consente agli utenti di piazzare ordini limite nella direzione appropriata semplicemente facendo clic con il tasto destro su un grafico. Ciò viene ottenuto convertendo le coordinate Y del mouse in coordinate Y del grafico (che, per i simboli, corrispondono ai prezzi dei simboli).

 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)

Esecuzione asincrona

Gli esempi di codice sopra sono progettati per implementare robot di trading utilizzando l'esecuzione sincrona. Sia C# che Python supportano operazioni asincrone, consentendo al tuo cBot di eseguire diverse azioni nello stesso intervallo di tempo.

Esegui ordini di mercato in modo asincrono

La sintassi dei metodi asincroni è simile a quella dei metodi sincroni. Sebbene accettino gli stessi tipi di argomenti, il loro tipo di ritorno è TradeOperation invece di TradeResult.

  • Operazioni asincrone di base

    Il seguente cBot dimostra come funzionano le operazioni asincrone. Viene creato un ordine di mercato; nella condizione successiva, il cBot verifica se l'operazione è in esecuzione.

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

    Output del registro

    • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
    • Esecuzione dell'ordine di mercato per acquistare 10000 EURUSD
    • Operazione in esecuzione
    • Esecuzione dell'ordine di mercato per acquistare 10000 EURUSD RIUSCITA, Posizione PID14579532
  • Esegui un ordine

    L'esempio successivo evidenzia la differenza tra metodi sincroni e asincroni.

    Il cBot verifica se un'operazione è in esecuzione subito dopo aver chiamato un metodo asincrono. Lo fa di nuovo dopo aver chiamato un metodo sincrono. L'output del log per queste due azioni è diverso.

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

    Output del registro

    • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
    • Esecuzione dell'ordine di mercato per acquistare 10000 EURUSD
    • Operazione in esecuzione
    • Esecuzione dell'ordine di mercato per acquistare 20000 EURUSD
    • Esecuzione dell'ordine di mercato per acquistare 10000 EURUSD RIUSCITA, Posizione PID14579541
    • Esecuzione dell'ordine di mercato per acquistare 20000 EURUSD RIUSCITA, Posizione PID14579542
    • Operazione eseguita
  • Esegui un ordine con più parametri

    Il seguente cBot piazza un ordine specificando la sua etichetta ("myLabel"), i livelli di protezione (10, 10), il simbolo (SymbolName) e il volume (10000).

    L'esempio contiene anche la collezione Positions e il metodo FindAll(). Find() e FindAll() possono essere utilizzati per trovare posizioni con la stessa etichetta, simbolo e tipo di operazione.

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

    Output del registro

    • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
    • Esecuzione dell'ordine di mercato per acquistare 10000 EURUSD (SL: 10, TP: 10)
    • Esecuzione dell'ordine di mercato per acquistare 10000 EURUSD (SL: 10, TP: 10) RIUSCITA, Posizione PID14579719
    • Acquisto a 1.19087 SL null
    • Acquisto a 1.19357 SL 1.19257
    • cBot "New cBot" è stato arrestato per EURUSD, h1.

Modifica la posizione in modo asincrono

Il cBot seguente piazza un ordine di mercato e quindi modifica la posizione appena aperta.

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

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

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

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

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

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

Output del registro

  • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
  • Esecuzione dell'ordine di mercato per acquistare 10000 EURUSD (TP: 10)
  • Esecuzione dell'ordine di mercato per acquistare 10000 EURUSD (TP: 10) RIUSCITA, Posizione PID14579736
  • Modifica della posizione PID14579300 (SL: 1.19213, TP: null)
  • Modifica della posizione PID14579300 (SL: 1.19213, TP: null) RIUSCITA, Posizione PID14579300

Chiudi una posizione in modo asincrono

L'esempio successivo dimostra la chiusura di una posizione in modo asincrono se esiste.

Il metodo Find() viene utilizzato per cercare nella collezione Positions la posizione con un'etichetta specifica.

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

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

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

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

        api.ClosePositionAsync(myPosition)
        api.Stop()        

Output del registro

  • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
  • Esecuzione di un ordine di mercato per acquistare 10000 EURUSD (TP: 10)
  • Esecuzione di un ordine di mercato per acquistare 10000 EURUSD (TP: 10) RIUSCITA, Posizione PID14579740
  • Chiusura della posizione PID14579300
  • Chiusura della posizione PID14579300 RIUSCITA, Posizione PID14579300
  • cBot "New cBot" è stato interrotto per EURUSD, h1.

Inserisci ordini limite e stop in modo asincrono

Come indicato sopra, l'inserimento di ordini in sospeso è simile alla creazione di ordini di mercato.

Tuttavia, ci sono alcune lievi differenze negli argomenti tra questi due metodi. L'intervallo di mercato è assente dall'elenco degli argomenti. Inoltre, devi specificare il prezzo target e puoi passare un argomento facoltativo che specifica la data di scadenza dell'ordine.

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

Output del registro

  • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
  • Inserimento di un ordine limite per acquistare 10000 EURUSD (Prezzo: 1.19382, Scadenza: 12/05/2018 00:18:19)
  • Inserimento di un ordine stop per acquistare 10000 EURUSD (Prezzo: 1.19487, Scadenza: 12/05/2018 00:18:19)
  • Inserimento di un ordine limite per acquistare 10000 EURUSD (Prezzo: 1.19382, Scadenza: 12/05/2018 00:18:19) RIUSCITO, Ordine in sospeso OID25221859
  • Inserimento di un ordine stop per acquistare 10000 EURUSD (Prezzo: 1.19487, Scadenza: 12/05/2018 00:18:19) RIUSCITO, Ordine in sospeso OID25221860

Modifica ordini in sospeso in modo asincrono

Il seguente cBot modifica gli ordini limite in modo asincrono.

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

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

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

Output del registro

  • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
  • Inserimento di un ordine limite per acquistare 10000 EURUSD (Prezzo: 1.19347, TP: 10, Scadenza: 12/05/2018 00:22:08)
  • Modifica dell'ordine in sospeso OID25221860 (Volume: 10000, Prezzo: 1.19487, SL: 10, TP: 10, Scadenza: 12/05/2018 00:18:19)
  • Inserimento di un ordine limite per acquistare 10000 EURUSD (Prezzo: 1.19347, TP: 10, Scadenza: 12/05/2018 00:22:08) RIUSCITO, Ordine in sospeso OID25221906
  • Modifica dell'ordine in sospeso OID25221860 (Volume: 10000, Prezzo: 1.19487, SL: 10, TP: 10, Scadenza: 12/05/2018 00:18:19) RIUSCITA, Ordine in sospeso OID25221860
  • Modifica dell'ordine in sospeso OID25221906 (Volume: 10000, Prezzo: 1.19347, SL: 10, TP: 10, Scadenza: 12/05/2018 00:22:08)
  • Modifica dell'ordine in sospeso OID25221906 (Volume: 10000, Prezzo: 1.19347, SL: 10, TP: 10, Scadenza: 12/05/2018 00:22:08) RIUSCITA, Ordine in sospeso OID25221906

Annulla ordini in sospeso in modo asincrono

  • Annulla tutti gli ordini in sospeso

    Il cBot qui sotto annulla in modo asincrono tutti gli ordini attualmente in sospeso.

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

    Output del registro

    • cBot "cancel pending order" è stato avviato correttamente per EURUSD, h1.
    • Annullamento dell'ordine in sospeso OID274705
    • Annullamento dell'ordine in sospeso OID274706
    • Annullamento dell'ordine in sospeso OID274707
    • Annullamento dell'ordine in sospeso OID274708
    • Annullamento dell'ordine in sospeso OID274709
    • Annullamento dell'ordine in sospeso OID274705 RIUSCITO, Ordine in sospeso OID274705
    • Annullamento dell'ordine in sospeso OID274706 RIUSCITO, Ordine in sospeso OID274706
    • Annullamento dell'ordine in sospeso OID274707 RIUSCITO, Ordine in sospeso OID274707
    • Annullamento dell'ordine in sospeso OID274708 RIUSCITO, Ordine in sospeso OID274708
    • Annullamento dell'ordine in sospeso OID274709 RIUSCITO, Ordine in sospeso OID274709
  • Annulla ordini in sospeso con una determinata etichetta

    Questo cBot annulla solo gli ordini in sospeso con una determinata etichetta.

     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)
    

Funzioni di callback per i metodi asincroni

Una volta restituito un risultato, l'utilizzo di operazioni asincrone richiede spesso il controllo dell'esecuzione. Per gestire questo, puoi aggiungere una funzione di callback alla fine dell'elenco dei parametri di tutti i metodi asincroni.

Questa funzione verrà chiamata non appena viene ricevuta una risposta dal server. Ad esempio, potrebbe essere chiamata quando una posizione viene aperta, modificata o chiusa.

  • Ordine di mercato asincrono con un callback

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

    Output del registro

    • cBot "New cBot" è stato avviato con successo per EURUSD, h1.
    • Esecuzione di un ordine di mercato per acquistare 10000 EURUSD
    • TradeOperation (Esecuzione di un ordine di mercato per acquistare 10000 EURUSD IN ESECUZIONE)
    • Esecuzione di un ordine di mercato per acquistare 10000 EURUSD RIUSCITA, Posizione PID14579835
    • TradeResult (Riuscito, Posizione: PID14579835)
    • Posizione 14579835 aperta a 1.19414
  • Utilizzo delle espressioni lambda

    Invece di definire un metodo di callback denominato puoi utilizzare le espressioni lambda.

    Nell'esempio seguente, quando viene inserito un ordine, la descrizione del risultato verrà stampata nel log.

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

    Log output

    • cBot "New cBot" è stato avviato correttamente per EURUSD, h1.
    • Inserimento di un ordine limite per acquistare 10000 EURUSD (Prezzo: 1.19320)
    • Inserimento di un ordine limite per acquistare 10000 EURUSD (Prezzo: 1.19320) RIUSCITO, Ordine in sospeso OID25222083
    • TradeResult (Riuscito, Ordine in sospeso: OID25222083)

Image title