indicatore Awesome Oscillator con QuantConnect

Indicatore Awesome Oscillator con QuantConnect

Continuando con la serie QuantConnect, iniziamo ad approfondire gli indicatori. Possiamo fare molte cose interessanti con gli indicatori su QuantConnect, ad esempio concatenare insieme i 100 e più indicatori disponibile nella libreria  di QuantConnect per creare alcuni risultati interessanti. In questo articolo descriviamo come creare l’indicatore Awesome Oscillator con QuantConnect per il trading algoritmico ed applicarlo alle strategie di trading algoritmico. In particolare approfondiamo la creazione di un nuovo indicatore da zero, l’importazione nel nostro algoritmo e quindi visualizzare il grafico del risultato.

Awesome Oscillator

Nel codice di esempio vediamo creeremo un  awesome oscillator. Abbiamo scelto questo indicatore perchè è abbastanza semplice da calcolare e possiamo costruirlo sulla base di un eccellente esempio nel forum di QuantConnect . In breve, l’Awesome Oscillator vuole misurare il momentum del mercato calcolando la differenza tra due medie mobili semplici. In particolare, usiamo le SMA a 34 periodi e a 5 periodi .

Awesome Oscillator = SMA a 5 periodi – SMA a 34 periodi

Nota: Nel seguente esempio copiamo/traduciamo la formula dall’Awesome Oscillator di Tradingview.

Indicatore Awesome Oscillator con QuantConnect

				
					import numpy as np
from collections import deque
from datetime import datetime


### <summary>
### Basic template algorithm simply initializes the date range and cash. This is a skeleton
### framework you can use for designing an algorithm.
### </summary>

class AwesomeOscillator:
    '''
    //@version=3
    study(title="Awesome Oscillator", shorttitle="AO")
    ao = sma(hl2,5) - sma(hl2,34)
    plot(ao, color = change(ao) <= 0 ? red : green, style=histogram)
    '''

    def __init__(self, period_fast=5, period_slow=34):
        self.Name = "Awesome Osc - {}, {}".format(period_fast, period_slow)
        self.Time = datetime.min
        self.Value = 0
        self.IsReady = False

        self.fast_sma_queue = deque(maxlen=period_fast)
        self.slow_sma_queue = deque(maxlen=period_slow)

    def __repr__(self):
        return "{0} -> IsReady: {1}. Time: {2}. Value: {3}".format(self.Name, self.IsReady, self.Time, self.Value)

    # metodo Update obbligatorio
    def Update(self, input):
        # Riempire le serie
        hl2 = (input.High + input.Low) / 2
        self.fast_sma_queue.appendleft(hl2)
        self.slow_sma_queue.appendleft(hl2)

        # Calcolare le SMA
        fast_count = len(self.fast_sma_queue)
        fast_sma = sum(self.fast_sma_queue) / fast_count

        slow_count = len(self.slow_sma_queue)
        slow_sma = sum(self.slow_sma_queue) / slow_count

        self.Value = fast_sma - slow_sma

        self.Time = input.EndTime
        self.IsReady = slow_count == self.slow_sma_queue.maxlen


class BasicTemplateAlgorithm(QCAlgorithm):
    '''Basic template algorithm simply initializes the date range and cash'''

    def Initialize(self):
        '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

        self.SetStartDate(2018, 1, 1)  # Imposta la data inizio
        self.SetEndDate(2019, 1, 1)  # Imposta la data fine
        self.SetCash(100000)  # Imposta il capitale della strategia
        # Find more symbols here: http://quantconnect.com/data
        self.AddEquity("SPY", Resolution.Daily)

        self.AO = AwesomeOscillator()
        self.RegisterIndicator("SPY", self.AO, Resolution.Daily)

        # Creare il grafico dell'indicatore
        AOChart = Chart("Awesome", ChartType.Stacked)
        AOChart.AddSeries(Series('AO', SeriesType.Line))

    def OnData(self, data):
        '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.

        Arguments:
            data: Slice object keyed by symbol containing the stock data
        '''

        self.Debug(self.AO)

        if not self.AO.IsReady: return

        self.Plot('Awesome', 'AO', self.AO.Value)
				
			

Commento al codice

A differenza degli articoli precedenti relativi a QuantConnect, in questo codice abbiamo una nuova importazione from collections import deque. Una deque è come una lista ma ha una dimensione fissa, cioè è più simile a un “contenitore” o una “coda”. Una volta che è pieno, cioè ha raggiunto la dimensione massima, se aggiungiamo un nuovo elemento allora l’elemento più vecchio viene eliminato dal contenitore. Questo oggetto è quindi perfetto per memorizzare i valori necessari per calcolare il valore della media mobile semplice. Per ulteriori informazioni si può leggere la seguente documentazione:  https://docs.python.org/3.7/library/collections.html#collections.deque.

Dopo le importazioni, passiamo alle classi Indicator e Algorithm. Questo è il nostro primo esempio su QuantConnect a contenere due classi, quindi descriviamo separatamente l’indicatore e l’algoritmo. Nei prossimi paragrafi approfondiamo  la gestione delle classi in QuantConnect cercando di essere il più semplice possibile. Se qualcosa non è chiaro potrebbe essere utile dare un’occhiata ad alcuni tutorial introduttivi di Python sulle classi.

La classe Indicator

Per creare un indicatore Awesome Oscillator con QuantConnect, dobbiamo creare una nuova classe python e assicurarci che abbia al suo interno alcuni metodi (funzioni) specifici.

__init__()

Il primo metodo obbligatorio è  __init__() che è chiamato (run/executed) quando si crea una nuova istanza dell’indicatore dai blueprint della classe. È durante l’inizializzazione della classe (quando creiamo l’indicatore/istanza) che impostiamo alcuni attributi (variabili) da usare successivamente. Impostando gli attributi quando si crea l’indicatore,  significa che gli attributi esistono e hanno valori validi prima che qualsiasi dato venga inviato all’indicatore. Gli attributi  da impostare sono:

  • Name: può essere usato per identificare l’indicatore durante il debug o la stampa dell’output (ne parleremo più avanti)
  • Time: è usato per il log dell’ultima volta che l’indicatore è stato aggiornato. Se lo impostiamo  con datetime.min. abbiamo il primo valore possibile di un datetime valido.
  • Value: è l’effettivo valore dell’indicatore da restituire. Se lo impostiamo a 0 significa che non abbiamo dati quando creiamo l’indicatore per la prima volta.
  • IsReady: è un attributo importante.  E’ usato da molti algoritmi per rilevare se l’indicatore ha dati sufficienti per effettuare calcoli accurati. Ad esempio, se si dispone di una media mobile di 200 giorni, IsReady è  False fino a quando l’indicatore non ha 200 giorni di dati per effettuare il calcolo.
  • fast_sma_queue e slow_sma_queue: sono due  contenitori deque che usiamo per archiviare i dati. Ci permettono di  memorizzare i valori SMA necessari per creare il Value finale dell’Awesome Oscillator.

Introduzione alle classi:  https://www.pythoncentral.io/introduction-to-python-classes/

__repr__()

Successivamente, abbiamo il metodo __repr__() che non è strettamente necessario. E’ usato per fornire alcune utili informazioni di debug se si  usa il self.Debug() con l’indicatore, come nel nostro l’algoritmo di esempio.

update()

Infine, c’è il metodo update() che è  assolutamente necessario. E’ chiamato e gli sono passati alcuni nuovi dati ogni volta che arriva una nuova barra o tick di dati. In questo metodo eseguiamo il calcolo dei numeri e otteniamo il valore  finale dell’indicatore. Nel nostro esempio, aggiungiamo i dati HL2 a ciascuna delle code man mano che arrivano nuovi dati. Otteniamo quindi il valore medio di ciascuna coda e sottraiamo una media dall’altra. Una volta che la coda è piena, impostiamo IsReady a true.

La classe Algorithm

La classe algoritmo in questo esempio è usata solamente per verificare che l’indicatore funzioni e per visualizzare i risultati finali. Su DataTrading.info abbiamo articoli che approfondiscono entrambi questi argomenti qui:

Per caricare il nostro indicatore personalizzato nel nostro algoritmo, dobbiamo solo creare un’istanza dell’indicatore all’interno del metodo __init__() dell’algoritmo. Quindi registriamo l’indicatore con un asset e un feed di dati (in questo caso i dati giornalieri di SPY).

				
					
self.AO = AwesomeOscillator()
self.RegisterIndicator("SPY", self.AO, Resolution.Daily)
				
			

In questo modo l’indicatore  ricevere i dati e li rende disponibili all’interno del  metodo OnData(), dove controlliamo se il nostro l’indicatore è IsReady, e in caso affermativo controlliamo il Value con self.AO.Value. Questa variabile può essere usata per aggiornare il grafico personalizzato che abbiamo creato.

Nota: al momento della scrittura, non è possibile usare PlotIndicator() all’interno del  metodo Initialize() quindi dobbiamo creare manualmente un grafico e aggiornarlo all’interno di  OnData(), come mostrato nel codice di esempio. Per maggiori dettagli si può consultare questo issue su GitHub.

Esecuzione dell’algoritmo

Durante l’esecuzione dell’algoritmo, possiamo vedere i debug stampati grazie al metodo __repr__ che abbiamo  implementato.

indicatore Awesome Oscillator con QuantConnect

Quando i risultati sono disponibili, possiamo visualizzare il grafico finale.

QuantConnect-Awesome-Oscillator-Grafico

Stiamo solo rappresentando l’indicatore come un semplice grafico a linee. L’indicatore su Tradingview (e forse su altre piattaforme) usa un istogramma e alcuni colori  per uno stile dinamico. Un buon esercizio di follow-up  è migliorare la trama per replicare l’aspetto grafico di tradingview.

Codice completo

In questo articolo abbiamo descritto come creare un indicatore Awesome Oscillator con QuantConnect per il trading algoritmico. Per il codice completo riportato in questo articolo, si può consultare il seguente repository di github:
https://github.com/datatrading-info/QuantConnect

Gli altri articoli di questa serie

Benvenuto su DataTrading!

Sono Gianluca, ingegnere software e data scientist. Sono appassionato di coding, finanza e trading. Leggi la mia storia.

Ho creato DataTrading per aiutare le altre persone ad utilizzare nuovi approcci e nuovi strumenti, ed applicarli correttamente al mondo del trading.

DataTrading vuole essere un punto di ritrovo per scambiare esperienze, opinioni ed idee.

SCRIVIMI SU TELEGRAM

Per informazioni, suggerimenti, collaborazioni...

Scroll to Top