Vai al contenuto

Crea un indicatore tecnico in cTrader

Questo articolo illustra i passaggi per creare indicatori tecnici personalizzati, inclusi gli strumenti per il trading algoritmico o le azioni manuali in cTrader.

Suggerimento

Scopri come creare indicatori tecnici guardando un video in una guida passo passo.

Nella scheda Indicatori dell'app Algo, fai clic sul pulsante Nuovo per aprire la procedura guidata di creazione dell'algoritmo.

Inserisci un nome per il tuo indicatore, quindi seleziona un linguaggio di programmazione tra C# e Python.

Scegli un metodo di creazione tra:

  • Da zero – il nuovo indicatore conterrà solo un modello di base.

  • Utilizzando un modello – potrai selezionare un algoritmo predefinito da un elenco di modelli Python# o C#, che coprono un'ampia gamma di tipi di indicatori, strumenti di analisi tecnica e altro ancora.

Nota

Gli algoritmi predefiniti contengono già la logica per i calcoli e parametri personalizzabili. Tali indicatori sono pronti per essere visualizzati sui grafici una volta salvati e compilati.

Dopo aver fatto clic su Crea, si apre l'editor di codice e puoi iniziare a modificare il codice dell'indicatore.

Modificare il codice

A seconda del metodo di creazione, il codice di esempio dell'indicatore dovrebbe contenere uno o più dei seguenti elementi:

 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
[Indicator(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class SimpleIndicator : Indicator
{
    [Parameter(DefaultValue = "Hello world!")]
    public string Message { get; set; }

    [Output("Main")]
    public IndicatorDataSeries Result { get; set; }

    protected override void Initialize()
    {
    // Called once when the indicator is launched
    // Initialise variables, nested indicators or series

        Print(Message);
    }

    public override void Calculate(int index)
    {
    // Called automatically on each historical bar
    // Also called in real-time on each tick
    // Place the indicator formula and logic here
    }

    // === Custom Methods ===
    // Add helper methods below to structure your indicator logic

}

L'attributo Indicator, insieme alle sue proprietà opzionali come TimeZone e AccessRights, precede la dichiarazione della classe dell'indicatore (SimpleIndicator).

Questi metodi sono inclusi in ogni indicatore per impostazione predefinita:

  • Il metodo Initialize() viene richiamato una volta quando l'indicatore si avvia. Viene generalmente utilizzato per configurare variabili, indicatori nidificati e serie che devono essere pronti dall'inizio.
  • Il metodo Calculate() viene richiamato automaticamente su ogni barra storica e in tempo reale su ogni nuovo tick. È qui che implementi la formula dell'indicatore e definisci come i risultati vengono calcolati e visualizzati.

L'attributo [Output()] specifica i valori prodotti dal tuo indicatore e come appaiono sul grafico. Puoi personalizzare il nome e lo stile di ogni output, ad esempio impostando il colore della linea.

I metodi Initialize() e Calculate() costituiscono le fondamenta di ogni indicatore personalizzato e non devono mai essere omessi. Puoi aggiungere i tuoi metodi per estendere le funzionalità, proprio come faresti quando programmi un cBot. Per saperne di più sugli algoritmi, inizia con la guida Nozioni di base su C# ed esplora gli esempi di codice degli indicatori.

Nota

Riferimenti include tutte le classi, gli eventi, i metodi, le variabili, ecc. per creare algoritmi in cTrader, mentre esempi completi di algoritmi e template sono disponibili in un repository GitHub.

Applica le tue nuove conoscenze per modificare il codice dell'indicatore e adattarlo alle tue esigenze.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class SimpleIndicator:
    def initialize(self):
        # Called once when the indicator is launched
        # Initialise variables, nested indicators or series
        api.Print(api.Message)

    def calculate(self, index):
        # Called automatically on each historical bar
        # Also called in real-time on each tick
        # Place the indicator formula and logic here
        api.Result[index] = 100 # Example calculation

    # === Custom Methods ===
    # Add helper methods below to structure your indicator logic

La classe SimpleIndicator definisce un indicatore personalizzato in Python.

Questi metodi sono inclusi in ogni indicatore per impostazione predefinita:

  • Il metodo initialize(self) viene richiamato una volta quando l'indicatore si avvia. Viene generalmente utilizzato per inizializzare variabili, indicatori nidificati e serie che devono essere pronti dall'inizio.
  • Il metodo calculate(self, index) viene richiamato automaticamente su ogni barra storica e in tempo reale su ogni nuovo tick. È qui che implementi la formula dell'indicatore e definisci come i risultati vengono calcolati e visualizzati.

I metodi initialize(self) e calculate(self, index) costituiscono le fondamenta di ogni indicatore personalizzato e non dovrebbero mai essere omessi. Puoi anche aggiungere i tuoi metodi helper all'interno della classe per estendere le funzionalità, proprio come faresti quando codifichi un cBot. Per saperne di più sugli algoritmi, inizia con Nozioni di base su Python ed esplora gli esempi di codice degli indicatori.

Applica le tue nuove conoscenze per modificare il codice dell'indicatore e adattarlo alle tue esigenze.

Salvare e compilare

Salva il codice facendo clic sul pulsante Salva nella parte superiore dell'editor di codice oppure usa la scorciatoia Ctrl+S.

Prima di poter utilizzare il cBot, è necessario convalidarne il codice compilando il progetto cBot. Fai clic sul pulsante Compila nella parte superiore dell'editor di codice oppure premi Ctrl+B.

Salva il codice facendo clic sull'icona Salva nella parte superiore dell'editor di codice oppure usa la scorciatoia Cmd+S.

Prima di poter utilizzare il cBot, è necessario convalidarne il codice compilando il progetto cBot. Fai clic sull'icona Compila nella parte superiore dell'editor di codice oppure premi Cmd+B.

Quando la compilazione ha esito positivo, viene visualizzato un messaggio di conferma in Risultato compilazione. Se la compilazione non riesce, viene visualizzato un riepilogo di tutti gli errori riscontrati.

Se sono presenti modifiche al codice dall'ultima compilazione, viene visualizzato un asterisco accanto all'icona Compila. In questo caso, dovresti compilare nuovamente l'indicatore prima di aggiungere un'istanza di esso a qualsiasi grafico.

Per utilizzare o visualizzare l'indicatore su un grafico, aggiungi un'istanza di esso, oppure puoi continuare a modificare il codice dell'indicatore come spiegato nelle sezioni.

Utilizzare l'aritmetica NaN

Gli indicatori eseguono calcoli per produrre elementi visivi specifici ed è essenziale che il tuo codice gestisca correttamente i casi limite e le condizioni al contorno durante questi calcoli.

Considera il seguente frammento di codice di un indicatore che produce un oscillatore di prezzo detrendizzato:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
private MovingAverage movingAverage;

protected override void Initialize()
{
    movingAverage = Indicators.SimpleMovingAverage(Source, Periods);
}

public override void Calculate(int index)
{
    Result[index] = Source[index] - movingAverage.Result[index - Periods / 2 - 1];
}

Il codice sopra definisce le regole di calcolo generali ma omette le condizioni al contorno. Ad esempio, se Periods è impostato su 10 e index rientra nell'intervallo 0–9, il calcolo restituirà NaN (Not a Number). Questo problema si verifica perché l'indicatore non può calcolare i valori per un grafico a barre con un indice negativo.

Per risolvere il problema, puoi aggiungere una condizione come mostrato di seguito:

1
2
3
4
5
6
7
public override void Calculate(int index)
{
    if (index >= Periods + Periods / 2 + 1)
    {
        Result[index] = Source[index] - movingAverage.Result[index - Periods / 2 - 1];
    }
}

Il codice per la media mobile semplice stessa deve anche verificare che index >= Periods. Se utilizzi un indicatore nidificato, come un altro tipo di media mobile, la condizione sarà diversa per tenere conto di calcoli aggiuntivi.

Sebbene tu possa definire condizioni al contorno esplicite, C# offre un modo conveniente per evitare questi problemi attraverso l'aritmetica NaN. In particolare, il tipo di dati double supporta completamente i calcoli NaN. Ad esempio:

1
2
3
4
5
double result = double.NaN + 1.4; 
// result will be NaN

bool isNaN = double.IsNaN(result); 
// isNaN will be true

Tuttavia, quando un qualsiasi operando in un calcolo è NaN, anche il risultato sarà NaN. Poiché gli indicatori personalizzati di cTrader operano sul tipo DataSeries, se tenti di accedere a un elemento DataSeries con un indice negativo, restituirà NaN e il valore non verrà disegnato sul grafico di trading. Questo comportamento consente all'indicatore di continuare a funzionare senza generare eccezioni. Nella maggior parte dei casi, puoi tranquillamente ignorare le condizioni al contorno e concentrarti solo sulla logica di calcolo generale.

Aggiungere controlli espliciti

Sebbene l'aritmetica NaN semplifichi la gestione delle condizioni al contorno, alcuni casi richiedono ancora controlli NaN espliciti. Gli indicatori ricorsivi sono un esempio comune. Un indicatore ricorsivo calcola il suo valore corrente in base al valore calcolato in precedenza.

Considera la seguente implementazione di una media mobile esponenziale:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public override void Calculate(int index)
{
    var previousValue = Result[index - 1];

    if (double.IsNaN(previousValue))
    {
        Result[index] = Source[index];
    }
    else
    {
        Result[index] = Source[index] * _exp + previousValue * (1 - _exp);
    }
}

Quando l'indicatore calcola il primo periodo, il valore iniziale deve essere impostato esplicitamente su un tipo non NaN. Altrimenti, tutti i calcoli successivi restituiranno NaN, rendendo l'indicatore inutile.

Nel codice sopra, questo viene gestito con il metodo double.IsNaN(previousValue). L'operatore == non può essere utilizzato per questo controllo (previousValue == double.NaN) perché qualsiasi confronto di NaN con un altro valore, incluso se stesso, restituisce sempre false.

Quando sei soddisfatto del codice dell'indicatore, compilalo, quindi utilizzalo aggiungendo un'istanza a un grafico.

Image title