In questo articolo descriviamo il monitoraggio del tempo con Tradingview per il trading algoritmico. Tradingview ha alcune utili variabili e funzioni basate sul tempo che ci permette di monitorare il tempo, gli eventi e le sessioni. Queste funzioni sono utili quando si desidera limitare i backtest solamente al trading durante le ore di sessione o fare in modo che gli indicatori siano resettati per determinati intervalli.
Tradingview Wiki
Per prima cosa, il wiki di Tradingview ha alcuni buoni esempi e tutorial che mostrano come utilizzare alcune delle variabili e delle funzioni. Invece di reinventare la ruota, questo articolo vuole aggiungere valore mostrando l’output di variabili che non hanno esempi nel wiki e descrivendo un esempio di strategia nel mondo reale.
Il tutorial wiki di Tradingview è disponibile al seguente link:
https://www.tradingview.com/wiki/Sessions_and_Time_Functions
Monitoraggio del Tempo con Tradingview
Per coloro che non hanno letto il wiki di Tradingview, una rapida introduzione aiuterà a capire il resto dell’articolo.
Per quanto riguarda il tempo, Pine Script mette a disposizione variabili speciali e un insieme di funzioni che usano lo stesso nome. Quindi per evitare errori di sintassi o comportamenti non intenzionali, dobbiamo prestare particolare attenzione che il codice contenga parentesi ()
alla fine del nome.
Un esempio del Wiki mostra:
- time: Una variabile – che restituisce un timestamp della data/ora corrente in un formato UNIX.
- time(): una funzione – che restituisce un timestamp per un timefare o sessione specificata in ingresso.
Per la descrizione di Wikipedia il tempo UNIX è un numero intero che rappresenta il numero di secondi trascorsi dalle 00:00:00 Coordinated Universal Time (UTC) di giovedì 1 gennaio 1970. Tuttavia, è importante notare che Pine Script funziona con timestamp in formato millisecondi anziché secondi dal 1970. Se sei interessato al motivo per cui viene utilizzato il 1 gennaio 1970, dai un’occhiata a questo post su stackoverflow che lo spiega molto bene:
https://stackoverflow.com/questions/1090869/why-is-1-1-1970-the-epoch-time
Successivamente, se plot(na(t) ? 0 : 1)
non ha alcun senso per te, potrebbe essere un’idea dare un’occhiata ad un precedente articolo sugli operatori condizionali ternari con Tradingview.
Esplorare le variabili
Come accennato in precedenza, Pinescript dispone di variabili integrate per il monitoraggio del tempo in Tradingview. Per capire come usarli, vale la pena visualizzare il grafico per ciascuno di essi in modo da poter vedere l’output previsto. Non tutte le variabili hanno un grafico come quello di time
dove si ha un andamento sempre crescente. Alcune variabili come dayofweek
e hour
ciclano all’interno di un intervallo. Diamo un’occhiata.
year
month
weekofyear
dayofmonth
Da notare come questa non aumenta in modo regolare come per le variabili month
e weekofyear
perché spesso mancano giorni di negoziazione a causa del fine settimana e delle festività nazionali.
dayofweek
Il range di dayofweek
prevede già che i fine settimana non sono inclusi. Nel grafico si possono però vedere chiaramente le festività nazionali.
hour
La variabile hour
contiene l’ora della barra corrente nel fuso orario dell’exchange.
minute
Come per hour
, la variabile minute
contiene il minuto della barra corrente nel fuso orario dell’exchange.
second
Come per hour
e minute
, la variabile second
contiene il secondo della barra corrente nel fuso orario dell’exchange.
time vs timenow
Time fornisce l’ora corrente della barra sul grafico. Pertanto aumenta con la stessa risoluzione del timeframe su cui si sta lavorando. Usando timenow
invece, abbiamo l’ora corrente in questo momento. In questo caso tutte le barre storiche mostrano l’orario attuale. Quando entrano in gioco i dati in tempo reale, vedrai le due linee convergere allo stesso valore.
Per conoscere le differenze tra le barre storiche dei dati e le barre in tempo reale, può essere utile leggere l’articolo sul lookahead dei dati realtime e dei dati storici con Tradingview
Esplorare le funzioni temporali:
La stessa funzione time()
è ben descritta nel wiki di Tradingview. Tuttavia, ci sono un paio di punti che possono essere approfonditi. Per prima cosa, diamo un’occhiata al codice:
study("Session bars")
t = time(period, "0930-1600")
plot(na(t) ? 0 : 1)
La spiegazione descritta nel wiki è la seguente:
La funzione
time
restituisce l’orario della barra nell’orario UNIX in millisecondi o un valore NaN se la barra si trova al di fuori della sessione di negoziazione specificata (09:30-16:00 nel nostro esempio).
Alcune note extra introduttive sono:
- La variabile
period
nell’esempio del wiki di Tradingview contiene il timeframe da visualizzare. - La stringa della sessione è data nel fuso orario dell’exchange e non nel fuso orario sul grafico! Di seguito sono descritti ulteriori dettagli.
NaN
significa “non un numero”, è questo che ci permette di distinguere facilmente tra barre aperte e chiuse. Quando la sessione è aperta, la variabile che contiene i dati della serie manterrà un timestamp UNIX per quella barra. Viceversa, se è chiusa, la serie conterrà un valoreNaN
per quella barra.- La funzione
na()
controlla un numero/valore in una serie. In questo caso, gli stiamo passando la variabile della seriet
. Quando si trovaNaN
, la funzionena()
restituisceTrue
, mentre nel caso di un numero valido restituisceFalse
. - Infine, la riga
plot
usa una condizione ternaria per verificare il valore restituito dana()
. Se restituisce un valoreTrue
(perché NON siamo in una sessione), si traccia 0 sugli indicatori. Se restituisceFalse
, allora si traccia 1 iato sull’indicatore.
Sessione vs fusi orari del grafico
Come descritto in precedenza, il valore della sessione che usiamo è relativo al fuso orario dell’exchange. Inizialmente può sembrare complicato ma usare il fuso orario della sessione invece del fuso orario del grafico semplifica la distribuzione del codice. Assicura che il codice possa essere copiato e incollato da qualsiasi utente in tutto il mondo. Utenti diversi avranno diverse impostazione orarie del grafico e, quindi potrebbero non essere sincronizzati con l’apertura/chiusura della sessione se non si trovano nello stesso fuso orario dello sviluppatore del codice. Usare il fuso orario dell’exchange garantisce che il codice apra e chiuda la sessione alla stessa ora indipendentemente dalle impostazioni dell’utente.
year(), month(), second() ecc….
Il resto delle funzioni basate sul tempo fanno più o meno la stessa cosa. Accettano tutte un timestamp UTC in millisecondi e restituiscono un anno, un mese, un secondo ecc. relativo al timestamp fornito.
Esempio pratico
La teoria è interessante ma è inutile se non la mettiamo in pratica. Un esempio del mondo reale è descritto di seguito per applicare il monitoraggio del tempo con Tradingview.
Trading in sessione
Questo esempio crea una semplice strategia stocastica per acquistare e vendere solo quando siamo nella sessione di trading asiatica e l’ADR (indice direzionale medio) dimostra che non siamo in una forte tendenza. La strategia chiuderà anche le posizioni aperte alla fine della sessione.
Il codice seguente è stato configurato per operare su GBPUSD. Il grafico è impostato sul fuso orario di Tokyo in modo da poter verificare che le operazioni sono correttamente aperte all’ora locale. Vediamo che gli orari dei trade usati nel codice non sono gli stessi dell’ora locale.
Il codice
//@version=3
strategy("Asian Stoch", overlay=true)
//########### Inputs #################\\
adxlen = input(14, title="ADX Smoothing")
dilen = input(14, title="DI Length")
maxADX = input(26, title="Maximum ADX value allowed to trade")
stPeriod = input(14, title="The lookback period for the stochastic")
stBuy = input(30, title="Buy below this stochastic value")
stSell = input(70, title="Sell above this stochastic value")
//########### ADR CODE #################\\
dirmov(len) =>
up = change(high)
down = -change(low)
truerange = rma(tr, len)
plus = fixnan(100 * rma(up > down and up > 0 ? up : 0, len) / truerange)
minus = fixnan(100 * rma(down > up and down > 0 ? down : 0, len) / truerange)
[plus, minus]
adx(dilen, adxlen) =>
[plus, minus] = dirmov(dilen)
sum = plus + minus
adx = 100 * rma(abs(plus - minus) / (sum == 0 ? 1 : sum), adxlen)
sig = adx(dilen, adxlen)
not_trending = sig < maxADX
//########### Asian Session CODE #################\\
t = time(period, "1900-0315")
session_open = na(t) ? false : true
//########### Stochastic CODE #################\\
stoch = stoch(close, high, low, stPeriod)
long = stoch < stBuy
short = stoch > stSell
//########### STRATEGY CODE #################\\
if (long and session_open and not_trending)
// strategy.close("Short 1")
strategy.entry("Long 1", strategy.long)
if (short and session_open and not_trending)
// strategy.close("Long 1")
strategy.entry("Short 1", strategy.short)
//Close out position before the end of the session.
if not (session_open)
strategy.close("Long 1")
strategy.close("Short 1")
Risultati
Eseguendo la strategia otteniamo un grafico simile al seguente.
Possiamo vedere che le chiusure viola corrispondano alla fine della giornata. Altrimenti, alterna posizioni lunghe e corte.
E i profitti? Non è niente di entusiasmante:
I risultati di cui sopra sono stati ottenuti con ordini di dimensione pari al 5% del capitale su un conto di 100.000 USD e non comprendo le commissioni. Tuttavia, non era quello lo scopo dell’esercizio!
Codice completo
In questo articolo abbiamo descritto il monitoraggio del tempo con Tradingview 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/TradingView