In questo articolo descriviamo come gestire gli stop loss con Tradingview tramite Pinescript. In questo modo possiamo creare strategie realistiche e profittevoli di trading algoritmico, tramite una specifica gestione del rischio.
Fondamenti di Stop Loss
Prima di descrivere gli esempi che mostrano come gestire gli stop loss con Tradingview, è utile comprendere i concetti alla base degli stop loss/ordini stop. Dopo aver introdotto le basi è facile capire lo strano comportamento che pensiamo di vedere quando applichiamo questi ordini.
Può sembrare controintuitivo, ma gli stop loss non sono usati solo per fermare le perdite. Infatti possiamo inviare un ordine stop anche quando non abbiamo nemmeno una posizione aperta a mercato. Per questo motivo, sono spesso chiamati ordini stop anziché stop loss.
Gli ordini stop si riferiscono in realtà a un ordine di acquisto o vendita di un asset ad un prezzo svantaggioso. In altre parole, un prezzo peggiore di quello che possiamo avere con un ordine a mercato. Quindi, quando abbiamo una posizione long aperta, ha senso. impostare il prezzo di stop a un livello inferiore al prezzo corrente (o di entrata) anche se ora potremmo vendere a un prezzo migliore.
Perché dovremmo inviare un ordine stop quando non abbiamo una posizione aperta e perché dovremmo farlo ad un prezzo peggiore di quello che potremmo avere a mercato? Un caso è quello di inviare un ordine stop proprio su un livello di breakout sopra il prezzo corrente, in modo da entrare in posizione proprio nel momento esatto in cui il prezzo esplode. Se diamo un’occhiata alla strategia PSAR, integrata di Tradingview, vediamo che la strategia fa proprio questo!
Esecuzione dell’ordine
Una volta inviato, un ordine stop si trova nell’orderbook del broker o dell’exchange. L’ordine rimane valido fino a quando non viene attivato, scade o viene annullato. Nel mondo reale, l’attivazione (triggering) di un ordine stop significa che qualcun altro ha eseguito un ordine di mercato ed è disposto a negoziare al livello di prezzo che abbiamo impostato nel nostro ordine stop. Il broker o l’exchange abbina queste due operazioni ed effettua una transazione.
Tuttavia, nel nostro backtest isolato, le cose non funzionano esattamente in questo modo. Stiamo effettuando test con i dati storici e senza alcuna cronologia delle transazioni. Si presume che siamo evasi al livello di prezzo dell’ordine che abbiamo impostato. Questa ipotesi è accettabile per mercati molto liquidi come le azioni S&P500, obbligazioni, Forex ecc., ma non per le azioni a bassa capitalizzazione. Questo perché nei mercati dove non ci sono molti attori che comprano e vendono, potrebbe non esserci nessuno disposto ad acquistare a quel livello di stop loss! Siamo quindi eseguiti al prossimo prezzo più vicino per cui qualcuno è disposto ad acquistare. Questo fenomeno è noto come slippage e è stato descritto in molti articoli relativi al trading algoritmico sul sito DataTrading.info.
Invio di ordini stop
Con Pine-Script esistono in realtà diverse funzioni che possiamo utilizzare per inviare un ordine stop. Queste funzioni sono:
strategy.entry()
strategy.exit()
strategy.order()
Una delle prime domande che vengono in mente ai neofiti è quale funzione usare per gestire gli stop loss con Tradingview. Sfortunatamente, la risposta è tutte! C’è un motivo per cui Tradingview offre molteplici funzioni e ognuna di esse è utile in diversi scenari. Quindi, invece di dire quale usare, vediamo i casi d’uso ideali per ogni funzione.
Se vogliamo usare un semplice stop loss per USCIRE da una posizione, è più facile lavorare con strategy.exit()
.
Nel caso desideriamo usare un ordine stop per ENTRARE in una posizione invece che uscirne, allora dobbiamo usare la funzione strategy.entry()
. Tutto quello che dobbiamo fare è aggiungere il parametro stop
e fornire un prezzo valido che sia peggiore del prezzo corrente. In altre parole, un prezzo più alto per un’entrata long o un prezzo più basso per una entrata short. Se ti stai chiedendo cosa sia il parametro stop
e come usarlo, non preoccuparti, vediamo un esempio più avanti.
Infine, se vogliamo effettuare una gestione avanzata della posizione (ad es. liquidare metà della posizione) o collegare insieme gli ordini (in modo che un ordine ne annulli un altro), dobbiamo usare la funzione strategy.order()
.
Esempio di Strategy.Exit
In questo primo esempio, vediamo come gestire gli stop loss con Tradingview impostando un semplice stop loss usando la funzione strategy.exit()
. Per dimostrarlo in modo efficace, dobbiamo prevede di essere già entrati a mercato con una posizione. Quindi il seguente codice include alcuni semplici criteri di entrata, ed inoltre, mostra come visualizzare lo stop loss sul grafico.
//@version=3
strategy("Stop Loss Example: Simple Stoploss", overlay=true)
sma_per = input(200, title='SMA Lookback Period', minval=1)
sl_inp = input(2.0, title='Stop Loss %', type=float)/100
tp_inp = input(4.0, title='Take Profit %', type=float)/100
sma = sma(close, sma_per)
stop_level = strategy.position_avg_price * (1 - sl_inp)
take_level = strategy.position_avg_price * (1 + tp_inp)
strategy.entry("Simple SMA Entry", strategy.long, when=crossover(close, sma))
strategy.exit("Stop Loss/TP","Simple SMA Entry", stop=stop_level, limit=take_level)
plot(sma, color=orange, linewidth=2)
plot(stop_level, color=red, style=linebr, linewidth=2)
plot(take_level, color=green, style=linebr, linewidth=2)
Commento
Per calcolare il livello di stop, il nostro esempio usa strategy.position_avg_price
come base. In questo modo l’utente può determinare il prezzo di entrata. Quando conosciamo il nostro prezzo di entrata, possiamo facilmente impostare uno stop loss a un livello sopra/sotto quel prezzo. Da notare che strategy.position_avg_price
funziona bene se abbiamo una sola posizione. Se lavoriamo sulle posizioni di più trade, questo approccio potrebbe non essere l’opzione migliore poiché ogni nuova entrata influenzerebbe il prezzo medio e quindi lo stop loss.
L’esempio è stato codificato in modo da poter restituire un valore per lo stop loss per ogni singola barra. Questo ci permette di tracciare facilmente lo stop loss. Tracciare le linee di stop loss ci consente di vedere cosa è successo nella nostra strategia e perché la posizione è uscita.
Vale anche la pena notare che, quando non abbiamo una posizione aperta a mercato, il valore strategy.position_avg_price
è pari a na
. Questo è utile nella gestione grafica perché possiamo tracciare la linea dello stop loss solo quando siamo abbiamo una posizione aperta. Il valore na
non può essere mai tracciato.
Tuttavia, per garantire che le linee siano tracciate in modo ordinato, dobbiamo usare lo stile linebr
in modo da evitare di unire gli spazi tra quando il valore è na
. Vediamo la differenza solo se usiamo uno stile di linea normale.
Perdita vs Stop
Se leggiamo la documentazione relativa a strategy.exit()
, notiamo che ci sono due parametri sonori molto simili, stop
e loss
. Che cosa prevedono?
Ad alcuni trader piace lavorare con i tick, mentre altri trader preferiscono lavorare con i livelli dei prezzi. Questo riassume abbastanza la differenza tra questi due parametri. Il parametro loss
prevedere di ricevere un valore misurato in tick mentre il parametro stop
prevedere di ricevere un prezzo specifico.
Di seguito vediamo un semplice esempio dove usiamo i tick per definire il livello loss
.
//@version=3
strategy("Stop Loss Example: Loss Param", overlay=true)
sma_per = input(200, title='SMA Lookback Period', minval=1)
sl_inp = input(100, title='Stop Loss in Ticks', type=integer)
tp_inp = input(50, title='Take Profit in Ticks', type=integer)
sma = sma(close, sma_per)
strategy.entry("Simple SMA Entry", strategy.long, when=crossover(close, sma))
strategy.exit("Stop Loss/TP", "Simple SMA Entry", loss=sl_inp, profit=tp_inp)
plot(sma, color=orange, linewidth=2)
Come vediamo nel codice, Il parametro loss
è usato in modo molto semplice. Dobbiamo solamente fornire il numero di tick che vogliamo prevedere. Tuttavia, questo metodo non è privo di rischi. Prima di tutto, è più difficile calcolare l’ammontare di capitale di rischio a meno di non lavorare con il parametro syminfo.mintick
per determinare il valore di un tick.
Per completezza, un tick è l’importo minimo che il prezzo deve avere per spostarsi da un livello all’altro. In altre parole, azioni, titoli e altri asset non possono essere valutate a qualsiasi prezzo immaginabile. Il prezzo si muove a piccoli step fissi.
Prezzi errati
Un’altro aspetto che dobbiamo considerare è dover impostare i livelli di stop loss sul lato corretto del prezzo. Se non l’ho facciamo, lo stop loss si attiverà immediatamente all’apertura della barra successiva.
L’esempio seguente mostra un grafico dove per un’operazione long il livello di stop loss viene superato al di sopra del livello di prezzo corrente.
Possiamo vedere che lo stop loss viene attivato immediatamente sulla barra dove la posizione long è entrata a mercato. Questo si verifica perchè il prezzo è già al di sotto del livello di stop che abbiamo previsto. Come abbiamo descritto nel paragrafo iniziale, un ordine stop viene attivato ogni volta che il prezzo tocca o supera il livello di stop e quindi si attiva immediatamente.
Esempio di Strategy.Order
Per gestire gli stop loss con Tradingview la funzione più flessibile è sicuramente strategy.order()
perchè può essere usata sia per entrare che per uscire dalle posizioni. Inoltre, può essere usata per aggiungere o rimuovere una specifica quantità qty
da una posizione.
La maggiore flessibilità comporta anche una maggiore complessità e, come tale, ci sono una serie di cose di cui bisogna essere consapevoli quando usiamo questa funzione:
- Prima di tutto, dobbiamo definire se l’ordine è un ordine di acquisto o un ordine di vendita. Lo facciamo usando
true
ofalse
, come descritto nel successivo esempio . - Non possiamo inserire un livello limite e uno stop all’interno dello stesso ordine.
- Una volta che un ordine è aperto, dobbiamo ricordarci di annullarlo quando non lo desideriamo più. Altrimenti, rimane nell’orderbook per sempre o fino a quando non viene attivato. Questo accade sempre quando si lavora con più ordini come un take profit e uno stop loss allo stesso tempo. In questo caso, se si attiva il take profit non abbiamo più bisogno dello stop loss. Se non annulliamo l’ordine stop potremmo essere costretti a ricoprire una nuova posizione. Questo può essere evitato collegando insieme gli ordini tramite i parametri
oca_name
eoca_type
che permette di annullare automaticamente un ordine quando l’altro viene attivato. - Tradingview pone un limite di 2000 ordini ai backtest. Usare la funzione
strategy.order()
può consumare molto rapidamente il limite di 2000 ordini. Per evitare il limite possiamo creare l’ordine all’interno di una dichiarazioneif
o usare il parametrowhen
per limitare la frequenza con cui viene inviato un ordine. In questo modo evitiamo di inviare un nuovo ordine ad ogni singola barra!
//@version=3
strategy("Stop Loss Example: Simple Stoploss", overlay=true)
sma_per = input(200, title='SMA Lookback Period', minval=1)
sl_inp = input(2.0, title='Stop Loss %', type=float)/100
tp_inp = input(4.0, title='Take Profit %', type=float)/100
sma = sma(close, sma_per)
stop_level = strategy.position_avg_price * (1 - sl_inp)
take_level = strategy.position_avg_price * (1 + tp_inp)
strategy.entry("Simple SMA Entry", strategy.long, when=crossover(close, sma))
strategy.order("Stop Loss", false, stop=stop_level, oca_name='L', oca_type=strategy.oca.cancel, when=crossover(close, sma) and strategy.position_size > 0)
strategy.order("Take Profit", false, limit=take_level, oca_name='L', oca_type=strategy.oca.cancel, when=crossover(close, sma) and strategy.position_size > 0)
plot(sma, color=orange, linewidth=2)
plot(stop_level, color=red, style=linebr, linewidth=2)
plot(take_level, color=green, style=linebr, linewidth=2)
Questo script opera con la stessa logica del primo esempio di stop loss. Tuttavia, notiamo immediatamente che il codice è più complesso. Pertanto sconsigliamo l’uso della funzione strategy.order()
per stop loss semplici, mentre è sicuramente utile quando vogliamo sperimentare strategie più complesse e gestire più ordini contemporaneamente.
Esempio di Strategy.Entry
In questo ultimo esempio su come gestire gli stop loss con Tradingview, usiamo gli ordini stop per entrare nel mercato tramite il parametro stop
della funzione strategy.entry()
. Possiamo entrare nel mercato nel momento esatto in cui il prezzo tocca una media mobile di 200 periodi.
//@version=3
strategy("Stop Loss Example: Stop Entry", overlay=true)
sma = sma(close, 200)
strategy.entry("My Long Entry Id", strategy.long, stop=sma, when=close < sma)
strategy.entry("My Short Entry Id", strategy.short, stop=sma, when=close > sma)
plot(sma, color=orange, linewidth=2)
Nel codice possiamo vedere che stiamo usando un ordine stop per entrare nel mercato, ma in realtà non entriamo in una posizione fino a quando l’ordine non viene attivato. Cioè fino a quando il prezzo non tocca la media mobile di 200 giorni.
Speriamo che questo articolo abbia fornito una panoramica facile ed esaustiva su come gestire gli stop loss con pine-script di Tradingview.
Codice completo
In questo articolo abbiamo descritto come gestire gli stop loss con Tradingview tramite Pinescript 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