Se arrivi a QuantConnect da altre piattaforme, ti starai chiedendo come accedere al prezzo close
precedente o al valore precedente di un indicatore. Come per i consolidatori, la soluzione è disponibile nella documentazione di QuantConnect, ma i nuovi utenti potrebbero non trovare immediatamente una connessione tra il nome dell’argomento e ciò che si vuole ottenere. Per accedere ai valori precedenti con QuantConnect abbiamo bisogno è una finestra scorrevole!
Finestre scorrevoli
È abbastanza comune in tutte le piattaforme di trading accedere ai dati storici tramite l’indicizzazione. Ad esempio, in Backtrader, possiamo semplicemente fare riferimento a: self.data.close[-1]
. Questo ci fornisce il valore di chiusura precedente. Se vogliamo ottenere il valore prima di quello, sostituiamo [-1]
in [-2]
! È così semplice perché Backtrader memorizza tutti i dati close
in un oggetto seriale. Un oggetto seriale è essenzialmente un lungo elenco di valori memorizzati. Al contrario, QuantConnect ti fornisce solo i dati puri pezzo per pezzo. Quello che fai con quei dati dipende da te. Se non hai mai bisogno di accedere ai dati storici, non c’è alcun vantaggio nell’archiviarli. Si occupa solamente memoria e l’utilizzo della memoria è molto controllato in un ambiente in cui le persone condividono le risorse. Detto questo, ciò non significa che non possiamo o non dobbiamo archiviare i dati storici. QuantConnect fornisce strumenti specific per farlo. Dobbiamo solamente configurarlo personalmente quando ne abbiamo bisogno. È qui che entra in gioco la “Finestra scorrevole”.
RollingWindow
è un array di dati che consente l’accesso inverso all’elenco, dove l’oggetto con indice [0] si riferisce all’elemento più recente della finestra e l’indice [Length-1] si riferisce all’ultimo elemento nella finestra, dove Length è il numero di elementi della finestra.
Fonte: https://www.quantconnect.com/docs/algorithm-reference/rolling-window.
Sebbene questa descrizione possa intimidire i principianti, una finestra scorrevole è essenzialmente una scatola di memorizzazione. Man mano che i dati arrivano, li inseriamo nella scatola in modo da poterli ritrovare in seguito. Possiamo definire quanto è grande la scatola, ma lo spazio nella scatola è comunque limitato. Una volta che la scatola è piena, dobbiamo estrarre il primo oggetto/il più vecchio prima di inserirne uno nuovo. Quando vogliamo accedere agli oggetti nella scatola, lo facciamo specificando un valore di indice proprio come nell’esempio precedente di Backtrader.
Visualizzazione di una finestra scorrevole
Una volta capito come funziona una finestra scorrevole, sono estremamente semplici. Tuttavia, dato che su Internet c’è molta confusione, a volte concetti semplici possono sembrare più complessi di quello che sono. In quanto tale, può aiutare a visualizzare come funziona una finestra scorrevole. In questo modo vediamo anche perché QuantConnect ha scelto il nome “Rolling Window”. Consideriamo l’esempio della scatola.
A questo punto potrebbe diventare chiaro perché il nome “Rolling Window” sia abbastanza appropriato. È come attraversare un nastro trasportatore di prezzi.
Inserimento, aggiornamento e lettuer
Ora che sappiamo cos’è una finestra mobile, diamo un’occhiata a come lavorarci. La finestra mobile viene aggiunta durante Initialize()
con una chiamata RollingWindow[]()
. All’interno delle parentesi quadre []
dobbiamo specificare il tipo di oggetto da gestire e all’interno delle parentesi tonde ()
specifichiamo la dimensione della finestra. Ad esempio: con l’istruzione self.tradeBarWindow = RollingWindow[TradeBar](5)
creiamo una finestra scorrevole che permette di memorizzare fino a 5 TradeBars
. Successivamente, dobbiamo aggiungere dati alla nostra finestra. Possiamo farlo quando i dati vengono forniti all’interno di OnData()
. La finestra mobile ha un metodo (funzione) Add()
che possiamo usare per inserire i dati: self.tradeBarWindow.Add(data["AAPL"])
. L’accesso ai dati è facile come l’indicizzazione: self.tradeBarWindow[1]
. Dobbiamo solo fare attenzione di assicurarci che la finestra contenga dati nella posizione in cui stiamo tentando di accedere. Ad esempio, se proviamo ad accedere a Storage Box[2]
durante la prima o la seconda immagine dell’esempio precedente, otteniamo un errore.
Accedere ai valori precedenti con QuantConnect
Un esempio per accedere ai valori precedenti con QuantConnect è il seguente codice, dove facciamo un passo indietro rispetto ai tutorial più recenti in modo da mantenere le cose semplici e chiare. Si basa sullo script del primo tutorial. Questo ci consente di non far confusione con il codice aggiunto per i grafici, timeframe e trading su più asset.
###
### Simple RSI Strategy intended to provide a minimal algorithm example using
### one indicator
###
# region imports
from AlgorithmImports import *
from decimal 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.'''
# Parametri della strategia
self.SetStartDate(2018,1, 1) # Set Start Date
self.SetEndDate(2018,1,10) # Set End Date
self.SetCash(10000) # Set Strategy Cash
RSI_Period = 14 # RSI Look back period
self.RSI_OB = 60 # RSI Overbought level
self.RSI_OS = 40 # RSI Oversold level
self.Allocate = 0.25 # Percentage of captital to allocate
# Altri simboli disponibili su: https://www.quantconnect.com/datasets/
self.AddEquity("AAPL", Resolution.Daily)
self.RSI_Ind = self.RSI("AAPL", RSI_Period)
# Creare la finestra mobile
self.tradeBarWindow = RollingWindow[TradeBar](5) # Store the last 5 values
self.rsiWindow = RollingWindow[float](10) # Store the last 10 values
# Assicurarsi che l'indicatore ha sufficienti dati prima di iniziare il trading
self.SetWarmUp(RSI_Period)
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
'''
# Aggiornamento della finestra mobile
self.tradeBarWindow.Add(data["AAPL"])
self.rsiWindow.Add(self.RSI_Ind.Current.Value)
# Aspettare che la finestra sia pronta
if not (self.tradeBarWindow.IsReady and self.rsiWindow.IsReady): return
self.Debug('{} Current RSI: {}, Prev RSI: {}'.format(self.Time, round(self.rsiWindow[0],2), round(self.rsiWindow[1],2)))
self.Debug('{} Current Close: {}, Prev Close: {}'.format(self.Time, round(self.tradeBarWindow[0].Close,2), round(self.tradeBarWindow[1].Close,2)))
Il codice crea finestre mobili per acquisire i dati TradeBar
. Questo viene fatto in modo che possiamo accedere ai valori OHLCV
precedenti. Creiamo anche una seconda finestra mobile per memorizzare i valori degli indicatori RSI. La differenza è che questo tipo di finestra mobile può accettare qualsiasi numero float
.
# Creare la finestra mobile
self.tradeBarWindow = RollingWindow[TradeBar](5) # Store the last 5 values
self.rsiWindow = RollingWindow[float](10) # Store the last 10 values
Anche se nel codice di esempio stampiamo solo il debug per i valori correnti e precedenti, le finestre sono più grandi di 2 per dimostrare che possono avere qualsiasi dimensione desiderata. Successivamente, aggiorniamo la nostra finestra continua durante onData()
con:
# Aggiornamento della finestra mobile
self.tradeBarWindow.Add(data["AAPL"])
self.rsiWindow.Add(self.RSI_Ind.Current.Value)
Stiamo aggiungendo un dato TradeBar
da AAPL a tradeBarWindow
e un valore float
dall’indicatore RSI a rsiWindow
. Infine, dobbiamo impedire alla strategia di eseguire qualsiasi azione fino a quando le nostre finestre non saranno pronte. Questo aiuta ad evitare errori di indicizzazione mentre la finestra viene riempita. La riga seguente return
(cioè non eseguirà alcun codice che la segue) fino a quando le finestre non saranno piene.
# Aspettare che la finestra sia pronta
if not (self.tradeBarWindow.IsReady and self.rsiWindow.IsReady): return
Dobbiamo stare attenti a non posizionare questa riga sopra le righe in cui aggiungiamo i dati, altrimenti le finestre non si riempiranno mai e il codice che segue non verrà mai eseguito!
Verifica dei risultati
Dopo aver eseguito il codice, otteniamo la stampa dei valori RSI sul terminale. È qui che possiamo vedere il valore corrente diventare il valore precedente su ciascuna delle seguenti barre.
Codice completo
In questo articolo abbiamo descritto come accedere ai valori precedenti con QuantConnect. Per il codice completo riportato in questo articolo, si può consultare il seguente repository di github:
https://github.com/datatrading-info/QuantConnect