Vai al contenuto

Ciclo di vita del cBot

In questo articolo e nel video che lo accompagna, esaminiamo la struttura del codice e spieghiamo la logica dietro gli eventi e il ciclo di vita di un cBot di cTrader.

Come promemoria, puoi accedere ai tuoi cBot nell'applicazione Algo in cTrader. Per creare un nuovo cBot, fai semplicemente clic sul pulsante Nuovo cBot o seleziona questa opzione nel menu a discesa mostrato di seguito.

Interpretare il modello di base

Dopo aver creato un nuovo cBot, dovresti vedere la seguente struttura di base nella finestra dell'editor di codice.

 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
26
27
28
29
30
31
32
33
34
35
36
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter(DefaultValue = "Hello world!")]
        public string Message { get; set; }

        protected override void OnStart()
        {
            // To learn more about cTrader Algo visit our Help Center:
            // https://help.ctrader.com/ctrader-algo

            Print(Message);
        }

        protected override void OnTick()
        {
            // Handle price updates here
        }

        protected override void OnStop()
        {
            // Handle cBot stop here
        }
    }
}

Nota che nel modello di base sono visualizzati solo tre eventi; questi eventi sono gestiti dai metodi OnStart(), OnTick() e OnStop(). Aggiungeremo due metodi aggiuntivi (OnBar() e OnException()) e spiegheremo come funzionano più avanti; prima, discuteremo del metodo OnStart().

Utilizzare il metodo OnStart()

Il metodo OnStart() viene attivato quando un cBot viene avviato per la prima volta. Viene utilizzato per inizializzare qualsiasi variabile che prevedi di utilizzare nel tuo cBot, inclusi indicatori, contatori, gestori di eventi o timer.

Nota

Il modello di codice iniziale include già un'istruzione di codice per stampare un messaggio nel registro quando un cBot viene avviato. Come puoi vedere, il nostro cBot ha il parametro Message e il metodo OnStart() passa il valore di questo parametro al metodo Print().

Possiamo dimostrare come funziona il metodo OnStart() semplicemente avviando l'istanza del cBot nell'applicazione Trade e aprendo la scheda Registro per vedere il risultato.

Possiamo anche interrompere il cBot in qualsiasi momento, modificare il valore del parametro Message nella scheda Parametri e riavviare la nostra istanza. All'avvio, il nostro nuovo messaggio verrà comunque stampato nel registro.

Utilizzare il metodo OnTick()

Il metodo OnTick() viene attivato ogni volta che il prezzo bid o ask del simbolo cambia. All'interno di questo metodo, puoi in genere programmare le condizioni di entrata e uscita dalla posizione, nonché qualsiasi altra funzione ausiliaria che devi eseguire quando arriva un nuovo tick di dati.

Aggiungeremo il seguente codice al metodo OnTick() in modo che stampi un messaggio nel registro.

1
Print("OnTick. Bid: ", Symbol.Bid, ", Ask: ", Symbol.Ask);

Come puoi vedere di seguito, il nostro cBot ora stampa i prezzi bid e ask nel registro ad ogni variazione di prezzo.

Utilizzare il metodo OnBar()

Il metodo OnBar() non è incluso nel modello di codice cBot predefinito, quindi aggiungeremo il seguente frammento di codice per aggiungerlo.

1
2
3
4
protected override void OnBar() 
{
    Print("OnBar");
}

Il metodo OnBar() viene attivato ogni volta che una nuova barra o candela viene disegnata sul grafico a cui è collegato un cBot. Analogamente al metodo OnTick(), puoi utilizzare il metodo OnBar() per programmare le condizioni di entrata e uscita dalla posizione, nonché qualsiasi altra logica che deve essere eseguita alla formazione di ogni nuova barra.

Come viene attivato il metodo OnBar()

Se hai un grafico H1, una nuova barra viene formata ogni ora, il che significa che il metodo OnBar() verrà chiamato una volta all'ora. Se hai un grafico min1, lo stesso metodo verrà chiamato una volta al minuto.

Il nostro metodo OnBar() stamperà "OnBar" su ogni nuova barra/candela. Per dimostrare come funziona, collegheremo il nostro cBot a un grafico min1 e daremo un'occhiata al registro.

Utilizzare il metodo OnStop()

Il metodo OnStop() viene chiamato quando il cBot si interrompe, sia da parte dell'utente che tramite il codice. Quando ciò accade, viene eseguito qualsiasi codice all'interno del metodo OnStop(). Questo può essere utilizzato per eseguire operazioni finali, come la chiusura delle posizioni.

Aggiungeremo il seguente codice al nostro metodo OnStop() - come al solito, il nostro cBot stamperà il valore del parametro Message quando viene interrotto.

1
Print(Message);

Nello screenshot qui sotto, avviamo e interrompiamo un'istanza del nostro cBot per dimostrare come funziona tutto.

Utilizzare il metodo OnException()

Il metodo OnException() fornisce tolleranza agli errori catturando le eccezioni non gestite, consentendoti di decidere come gestirle. Non è incluso nel modello di codice predefinito, quindi lo aggiungeremo noi stessi utilizzando il seguente frammento.

1
2
3
4
protected override void OnException(Exception exception) 
{
    Print("Ooops, unhandled exception! No worries, cBot still alive");            
}

Per attivare il metodo OnException(), scriveremo del codice per catturare un'eccezione che si verifica quando proviamo ad accedere alle informazioni su un'operazione che non esiste più. Aggiungeremo il codice seguente al metodo OnStart().

1
ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "my label");

Il codice che abbiamo scritto nel metodo OnStart() eseguirà un ordine di mercato con i seguenti parametri configurabili.

  • Il tipo di operazione sarà un ordine di acquisto.
  • L'operazione verrà eseguita per il simbolo corrente del grafico a cui è collegato il cBot.
  • Il volume dell'ordine sarà di 1.000 unità.
  • L'etichetta univoca allegata all'ordine sarà "my label".

Aggiungeremo anche il seguente codice al metodo OnTick().

1
2
3
var position = Positions.Find("my label");
if (Positions.Find("my label") != null) Print("PositionId: ", position.Id);
Print("Message below");

Il codice che abbiamo scritto nel metodo OnTick() troverà la posizione che è stata aperta nel metodo OnStart() utilizzando il nome dell'etichetta "my label".

Se la posizione viene trovata con la stessa etichetta, stamperà quindi nel registro l'ID della posizione dell'operazione aperta. Stamperà anche un altro messaggio chiamato "Message below" quando verrà eseguita la riga di codice successiva.

Quando il nostro cBot viene avviato e il metodo OnTick() viene chiamato e l'ordine viene trovato, il cBot stamperà l'ID dell'ordine nel registro e, dopo l'ID dell'ordine, stamperà il messaggio "Message below".

Come puoi vedere, non si verificano eccezioni e il nostro cBot svolge il suo lavoro perfettamente.

Ora, tuttavia, chiuderemo manualmente la posizione aperta dal cBot e apporteremo piccole modifiche al codice in modo che si verifichi sicuramente un'eccezione. Nel metodo OnStart(), cambieremo l'etichetta dell'ordine in "cTrader". Nel metodo OnTick(), commenteremo la condizione che verifica se esiste una posizione con l'etichetta "my label".

Ecco il codice finale del nostro cBot - nota che questo codice attiverà sempre un'eccezione.

 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
26
27
28
29
30
31
32
namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class LifecycleTest : Robot
    {
        [Parameter(DefaultValue = "cTrader rocks!")]
        public string Message { get; set; }

        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "cTrader");
        }

        protected override void OnTick()
        {
            var position = Positions.Find("my label");
            //if (Positions.Find("my label") != null) 
            Print("PositionId: ", position.Id);
            Print("Message below");
        }

        protected override void OnStop()
        {
            Print(Message);
        }

        protected override void OnException(Exception exception) 
        {
            Print("Ooops, unhandled exception! No worries, cBot still alive");            
        }
    }
}

Eseguiremo nuovamente il cBot e vedremo cosa succede.

Quello che è successo è che è stato creato un nuovo ordine di mercato quando il cBot è stato avviato. L'etichetta associata a questo ordine era "cTrader". Nel metodo OnTick(), il codice ha tentato di ottenere una posizione con l'etichetta "my label" e poiché abbiamo commentato la riga di codice con la condizionale. Ha quindi tentato di stampare nel registro l'ID della posizione.

Ciò ha causato un errore di eccezione che normalmente avrebbe interrotto il cBot nelle versioni precedenti di cTrader, ma con il nuovo metodo OnException(), ora possiamo catturare e gestire l'errore. Il cBot continuerà a funzionare e possiamo registrare l'errore in modo che possa essere corretto.

Il ciclo di vita del cBot consiste in diversi eventi chiave che puoi gestire tramite i metodi OnStart(), OnTick(), OnStop(), OnBar() e OnException(). Personalizzando il modo in cui il tuo cBot risponde agli eventi principali, puoi assicurarti che i tuoi algoritmi si comportino esattamente come previsto.