In questo articolo descriviamo come visualizzare i grafici con QuantConnect per il trading algoritmico, migliorando lo script RSI che abbiamo creato nel primo tutorial. Nell’articolo precedente non abbiamo descritto il grafico restituito dopo l’esecuzione del backtest perchè l’obiettivo era produrre un algoritmo base, praticabile e funzionante.
Ora che abbiamo descritto le basi, possiamo iniziare ad arricchire il codice e aggiungere parti che non sono strettamente necessarie ma sono spesso molto utili. Il grafico è uno di quegli elementi. Anche se i nostri algoritmi non hanno bisogno di guardare un grafico per prendere una decisione, il grafico è spesso molto utile per il trader algoritmico. Questo non solo per verificare che l’algoritmo si comporti come previsto, ma anche per aiutarci a identificare le aree di miglioramento. Il solo guardare i report statistici non ci consente di utilizzare una delle funzionalità più avanzate del nostro cervello, il riconoscimento dei pattern!
Introduzione
Con questo articolo vogliamo descrivere come tracciare l’indicatore RSI e la barra dei volumi nel grafico. In particolare vogliamo descrivere i seguenti argomenti:
- Una linea che traccia un indicatore con
self.PlotIndicator()
- Tracciare il grafico dei dati con
self.Plot()
- Creare un nuovo grafico personalizzato
- Aggiungere una serie al grafico
- Un breve sguardo a
SeriesType
eChartType
- Aggiungere un grafico personalizzato ad un algoritmo
- Limiti della stampa
Concetti generali
Prima di immergerci nel codice per visualizzare i grafici con QuantConnect, è necessario introdurre alcuni concetti generali per dare un contesto al codice. Il grafico è qualcosa che varia molto tra le piattaforme. Ad esempio, in Backtrader tutti gli indicatori vengono tracciati automaticamente quando vengono aggiunti. Infatti, se non vuoi tracciarli, devi disattivarli manualmente. In Pine Script, puoi semplicemente chiamare una funzione plot()
e tracciare praticamente tutto in qualsiasi momento. QuantConnect adotta un approccio un po’ ibrido. Solo i grafici Equity, Benchmark e Stock sono disponibili e visualizzati come impostazione di default. Tutto il resto deve essere espliticamente richiesto nel codice. Visualizzare un grafico in QuantConnect può essere semplice come chiamare una funzione self.Plot()
all’interno di OnData()
. Tuttavia, se si vogliono più opzioni, gli utenti possono approfondire e creare grafici personalizzati in modo molto simile alla creazione di un grafico matplotlib
(un popolare modulo Python per la creazione di grafici). In ogni fase del processo di creazione, possiamo specificare le opzioni per personalizzare il grafico secondo le nostre preferenze. Quindi, in sintesi, QuantConnect offre un buon livello di flessibilità. Possiamo semplificare le cose se necessario, ma ci sono molti strumenti disponibili per coloro che sono disposti a pagare un costo leggermente maggiore nella curva di apprendimento.
Funzioni fondamentali
Il codice in questo articolo è costituito da alcuni esempi. Questo ci consente di passare da un grafico più semplice fino alla creazione di un grafico personalizzato.
Indicatore Plot
Per visualizzare i grafici con QuantConnect iniziamo con il metodo (funzione) PlotIndicator()
, un semplice metodo di default che fa esattamente quello che dice il nome. Inoltre, possiamo usarlo nel metodo Initialize
. Ciò significa che una volta aggiunto il grafico, non è necessario aggiornarlo quando arrivano nuovi dati. Viene aggiornato automaticamente.
###
### Semplice strategia RSI che vuole fornire un esempio di un algoritmo
### usando un indicatore
###
#region imports
from AlgorithmImports import *
#endregion
class RSIAlgorithm(QCAlgorithm):
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.'''
# Impostazione parametri strategia
self.SetStartDate(2012,1, 1) # Data inizio
self.SetEndDate(2020,1,1) # Data Fine
self.SetCash(10000) # Capitale iniziale
RSI_Period = 14 # periodo del RSI
self.RSI_OB = 60 # Livello overcomprato
self.RSI_OS = 40 # Livello overvenduto
self.Allocate = 0.25 # Percentuale di capitale allocato
# Altri ticker sono disponibili in https://www.quantconnect.com/datasets/
self.AddEquity("AAPL", Resolution.Daily)
self.RSI_Ind = self.RSI("AAPL", RSI_Period)
# Verifica che ci siano abbastanza dati per calcolare l'indicatore prima del trading...
self.SetWarmUp(RSI_Period)
# Grafico il RSI
self.PlotIndicator("RSI", self.RSI_Ind)
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
'''
# Verifica se siamo a mercato
if not self.Portfolio.Invested:
# Se siamo flat verifichiamo l'RSI
if self.RSI_Ind.Current.Value < self.RSI_OS:
# Compriamo Apple
self.SetHoldings("AAPL", self.Allocate)
else:
if self.RSI_Ind.Current.Value > self.RSI_OB:
# Vendiamo Apple
self.Liquidate("AAPL")
I meno esperti potrebbero avere difficoltà a vedere la differenza con il primo script, descritto nel precedente articolo. Stiamo semplicemente aggiungendo la riga self.PlotIndicator("RSI", self.RSI_Ind)
al metodo Initialize()
.Questo crea un nuovo grafico chiamato RSI e visualizza qualsiasi valore riportato da self.RSI_Ind.Current.Value
. Bello e semplice!
Esecuzione dell’algoritmo
Eseguiamo l’algoritmo e diamo un’occhiata a ciò che abbiamo creato. Non appena il backtest è finito, otteniamo qualcosa che assomiglia a quanto segue:
Da notare che QuantConnect mostra solo alcuni grafici di default. Per visualizzare il grafico dell’indicatore è necessario selezionare l’opzione RSI nel pannello di destra, come evidenziato in figura.
QuantConnect aggiorna i risultanti aggiungendo il grafico selezionato.
Benchmark e Stockplot
Nel panello di destra possiamo selezionare anche le opzioni extra “Benchmark” e “Stock Plot”. Il grafico del benchmark fornisce un benchmark alternativo al buy&hold del S&P500 che è il benchmark di default. Premilo e lo vedrai apparire sotto il grafico RSI (supponendo che tu lo abbia ancora selezionato). Lo stockplot è più interessante. Fai clic sulla freccia giù e sarai in grado di selezionare AAPL dall’elenco. Qui appare solo AAPL perché è l’unica equity che abbiamo aggiunto nello script. La selezione di questo grafico ti mostrerà i prezzi di chiusura per AAPL e inoltre i marcatori di acquisto/vendita. Eccellente per valutare se stai comprando/vendendo nei momenti giusti. Questo non è sempre facile da decifrare dalla curva di equity.
La funzione Plot()
Un’altra funzione fondamentale per tracciare i grafici in QuantConnect è il metodo self.Plot()
. Questo può essere utilizzato semplicemente quando OnData()
viene chiamato (eseguito) oppure può essere utilizzato per aggiornare un grafico personalizzato che abbiamo precedentemente creato. Esaminiamo prima il metodo semplice e successivamente il metodo personalizzato nell’esempio finale. Aggiungiamo alcune informazioni sui Volume
utili alla nostra strategia. Descriviamo come usare il metodo plot() nel grafico standard e quindi descriviamo molto velocemente come può essere migliorato creando un grafico personalizzato!
###
### Semplice strategia RSI che vuole fornire un esempio di un algoritmo
### usando un indicatore
###
#region imports
from AlgorithmImports import *
#endregion
class RSIAlgorithm(QCAlgorithm):
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.'''
# Impostazione parametri strategia
self.SetStartDate(2012,1, 1) # Data inizio
self.SetEndDate(2020,1,1) # Data Fine
self.SetCash(10000) # Capitale iniziale
RSI_Period = 14 # periodo del RSI
self.RSI_OB = 60 # Livello overcomprato
self.RSI_OS = 40 # Livello overvenduto
self.Allocate = 0.25 # Percentuale di capitale allocato
# Altri ticker sono disponibili in https://www.quantconnect.com/datasets/
self.AddEquity("AAPL", Resolution.Daily)
self.RSI_Ind = self.RSI("AAPL", RSI_Period)
# Verifica che ci siano abbastanza dati per calcolare l'indicatore prima del trading...
self.SetWarmUp(RSI_Period)
# Grafico il RSI
self.PlotIndicator("RSI", self.RSI_Ind)
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.Plot('Volume', data["AAPL"].Volume)
# Verifica se siamo a mercato
if not self.Portfolio.Invested:
# Se siamo flat verifichiamo l'RSI
if self.RSI_Ind.Current.Value < self.RSI_OS:
# Compriamo Apple
self.SetHoldings("AAPL", self.Allocate)
else:
if self.RSI_Ind.Current.Value > self.RSI_OB:
# Vendiamo Apple
self.Liquidate("AAPL")
Nel secondo esempio per visualizzare i grafici con QuantConnect, abbiamo semplicemente aggiunto la riga self.Plot('Volume', data["AAPL"].Volume)
al metodo (funzione) On_Data()
. Questo traccerà i valori Volume
ogni volta che On_Data()
viene chiamato (nel nostro caso, On_Data()
viene chiamato ogni volta che riceviamo una nuova barra giornaliera). Il primo argomento 'Volume'
controlla il nome del grafico che verrà aggiornato. In questo caso si tratta di un grafico chiamato Volume
… Aspetta un attimo….. quale grafico del volume? Non abbiamo ancora aggiunto un grafico del volume! Bene, in realtà verrà creato dietro le quinte usando il nome specificato nella chiamata (In questo caso 'Volume'
). Pertanto, per questo esempio, in quell’argomento possiamo inserire qualsiasi testo che desideriamo. Se avessimo creato un grafico personalizzato (come nel paragrafo successivo) potremmo indirizzare il tracciato su quel grafico specifico assegnandogli il nome del grafico personalizzato.
Esecuzione dell’esempio 2
Dopo aver eseguito il backtest otteniamo avere un grafico della curva equity simile a questo:
Come possiamo vedere, il grafico dei volumi è sovrapposto al grafico dell’equity. Inoltre, poiché i valori Volume
sono molto più grandi dei valori dell’equity, la curva dell’equity è oscurata. Questo perché condividono lo stesso grafico e la stessa scala/indice. Quindi possiamo vedere che quando usiamo self.Plot()
senza impostare prima un grafico personalizzato, QuantConnect visualizza i valori che gli indichiamo con un set di valori predefiniti. In questo caso, uno dei valori predefiniti è quello di sovrapporre la linea sul grafico principale. Per questo motivo, chiamare self.Plot()
senza impostare prima un grafico personalizzato è probabilmente riservato alle occasioni in cui si desidera un rapido e sporco grafico di debug o per valori che condividono una scala simile alla curva di equity del proprio conto.
Visualizzare i grafici con QuantConnect
Nel nostro esempio finale, descriviamo come creare un grafico personalizzato e esaminiamo alcune delle opzioni a nostra disposizione.
###
### Semplice strategia RSI che vuole fornire un esempio di un algoritmo
### usando un indicatore
###
#region imports
from AlgorithmImports import *
#endregion
class RSIAlgorithm(QCAlgorithm):
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.'''
# Impostazione parametri strategia
self.SetStartDate(2012,1, 1) # Data inizio
self.SetEndDate(2020,1,1) # Data Fine
self.SetCash(10000) # Capitale iniziale
RSI_Period = 14 # periodo del RSI
self.RSI_OB = 60 # Livello overcomprato
self.RSI_OS = 40 # Livello overvenduto
self.Allocate = 0.25 # Percentuale di capitale allocato
# Altri ticker sono disponibili in https://www.quantconnect.com/datasets/
self.AddEquity("AAPL", Resolution.Daily)
self.RSI_Ind = self.RSI("AAPL", RSI_Period)
# Verifica che ci siano abbastanza dati per calcolare l'indicatore prima del trading...
self.SetWarmUp(RSI_Period)
# Grafico il RSI
self.PlotIndicator("RSI", self.RSI_Ind)
# Creazione di un grafico custom per i volumi
VolChart = Chart("Volume", ChartType.Stacked)
VolChart.AddSeries(Series('Buying Volume', SeriesType.Bar))
VolChart.AddSeries(Series('Selling Volume', SeriesType.Bar))
self.AddChart(VolChart)
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
'''
if data["AAPL"] is not None:
if data["AAPL"].Close >= data["AAPL"].Open:
self.Plot('Volume', 'Buying Volume', data["AAPL"].Volume)
else:
self.Plot('Volume', 'Selling Volume', data["AAPL"].Volume)
# Verifica se siamo a mercato
if not self.Portfolio.Invested:
# Se siamo flat verifichiamo l'RSI
if self.RSI_Ind.Current.Value < self.RSI_OS:
# Compriamo Apple
self.SetHoldings("AAPL", self.Allocate)
else:
if self.RSI_Ind.Current.Value > self.RSI_OB:
# Vendiamo Apple
self.Liquidate("AAPL")
Il codice per configurare il grafico appare nel metodo Initialize
. È qui che creiamo il nostro grafico e lo personalizziamo secondo i nostri gusti. Diamo un’occhiata al nostro nuovo codice e descriviamo alcune delle opzioni di personalizzazione disponibili. Per iniziare creiamo un nuovo grafico con: VolChart = Chart("Volume", ChartType.Stacked)
dove specifichiamo il nostro ChartType
e abbiamo a disposizione le seguenti opzioni :
Chart.Stacked
: Usato nel nostro esempio. Ciò significa che il grafico apparirà come un grafico separato sotto il grafico azionario principale.Chart.Overlay
: Ciò significa che il grafico sarà sovrapposto al grafico azionario principale.
Successivamente, aggiungiamo alcune serie di dati al grafico, cioè i dati che vogliamo tracciare. Poiché siamo interessati al volume, creeremo due serie. Uno per il “volume degli acquisti” e uno per il “volume delle vendite”. Volume d’acquisto significa semplicemente che la candela/barra si è chiusa (verde) e quindi significa che il volume visto in quel periodo ha visto più unità acquistate che vendute (altrimenti come si chiuderebbe il prezzo?). Al contrario, il “volume di vendita” è l’opposto. Un oggetto Series
può essere visualizzato in molti modi diversi e come tale QuantConnect fornisce alcuni tipi. Possiamo specificare le opzioni SeriesType
, come Line, Scatter, Candle, Bar, Flag, StackedArea e Pie. Nel nostro esempio, utilizziamo SeriesType.Bar
poiché questo è il modo standard del settore per visualizzare le informazioni sul volume. Infine, aggiungiamo il grafico al nostro algoritmo con self.AddChart()
. Se non lo facciamo, quando proviamo a tracciare i nostri valori di volume nel metodo OnData()
, il grafico non esisterà nell’algoritmo. Pertanto, Quanconnect creerà semplicemente un nuovo grafico utilizzando le impostazioni predefinite come descritto nell’esempio 2.
Il metodo OnData
Ok, quindi ora abbiamo il nostro grafico configurato e pronto, ora dobbiamo solo popolarlo! Poiché abbiamo creato due serie (volume di acquisto e volume di vendita), non possiamo semplicemente aggiungere ciecamente volume a entrambe. Invece, dobbiamo prima fare un piccolo controllo per vedere che tipo di volume abbiamo e poi tracciare la serie corretta. Questo è esattamente ciò che facciamo con le seguenti righe:
if data["AAPL"] is not None:
if data["AAPL"].Close >= data["AAPL"].Open:
self.Plot('Volume', 'Buying Volume', data["AAPL"].Volume)
else:
self.Plot('Volume', 'Selling Volume', data["AAPL"].Volume)
Da notare la condizione >=
sulla seconda riga. Dopo tutto, se Close
è uguale a Open
allora non abbiamo realmente volume di acquisto. E’ possibile essere più dettagliati aggiungendo semplicemente una terza serie al grafico.
Esecuzione dell’esempio 3
Una volta eseguito lo script, otteniamo un grafico del volume simile a questo:
Limiti di visualizzazione
Prima di concludere, dobbiamo sottolineare che QuantConnect limita il numero di punti che possono essere tracciati su un dato grafico. Il presupposto è che questo sia limitato per motivi di risorse. Dopotutto, hanno a disposizione enormi quantità di dati tick e tracciare i dati tick un lungo periodo di tempo è molto oneroso in termini di prestazione dei server. Per verificarlo, possiamo cambiare la riga self.AddEquity("AAPL", Resolution.Daily)
in self.AddEquity("AAPL", Resolution.Minute)
. Eseguendo nuovamente lo script, possiamo notare un avviso nel terminale che assomiglia a questo:
Inoltre, osservando il grafico RSI, vediamo che il grafico si è interrotto una volta raggiunto il limite di di punti per grafico.
Pertanto, ha senso selezionare intervalli di date specifici quando si desidera utilizzare il grafico per verificare che l’algoritmo stia funzionando come previsto o generare nuove idee.
Codice completo
In questo articolo abbiamo descritto come visualizzare i grafici 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