
Parte Terza: Intro TS
In questa parte analizzeremo uno a uno gli elementi necessari per costruire un trading system completo. Per ogni componente vedremo il ruolo operativo e le possibili implementazioni. Ma che cos’è un trading system?
Un trading system (o sistema di trading) è un insieme di regole predefinite e meccaniche che guidano le decisioni di acquisto e vendita su un mercato finanziario.
L’obiettivo è l’eliminazione dell’emotività dalle decisioni, sostituendola con tecniche precise e disciplina operativa.
Perché usare un trading system? Perché operare nei mercati in modo improvvisato ed istintivo genera delle perdite.
Cosa fa un trading system? Codifica un edge (vantaggio statistico) e lo sfrutta in modo ripetibile nel tempo.
Capitolo 11: Step costruttivi
L’edge (vantaggio statistico) è il cuore di qualsiasi trading system: è la ragione per cui un sistema guadagna nel lungo periodo.
L’edge è la trasformazione di un’idea in regole formali testabili che dimostrano vantaggio statistico attraverso backtest e validazione out-of-sample prima dell’automazione.
L’edge può derivare da diversi fattori come: inefficienze di mercato, compensi per l’assunzione di rischi, ottimizzazioni tramite position size e risk management…
L’edge non si identifica in ogni caso con la percentuale di vincite (al di là di come sono ottenute): un sistema infatti può vincere solo 3 volte su 10 ed essere profittevole, se le vincite sono molto più grandi delle perdite.
Una cosa importante da chiarire subito è che un edge non dura per sempre. Fino a che il vantaggio statistico (misurato attraverso delle metriche che vedremo) sussiste allora utilizziamo il sistema. Quando, nell’operatività reale, il vantaggio statistico si discosta troppo da quello ottenuto nel backtest dobbiamo mettere in pausa il trading system e vedere se lo scostamento dal backtest è solo momentaneo oppure se il trading system si è rotto.
§ 11.1 – Principali step costruttivi di un TS
Vediamo ora i punti chiave, i principali passaggi, per costuire un trading system in ProRealTime:
1) Definire l’idea operativa: la prima cosa che dobbiamo avere per costruire un trading system è un’idea operativa. Vogliamo seguire il trend di un mercato ed impostare un sistema trend following o vogliamo costruire un sistema sulle inversioni? Vogliamo seguire il trend con degli indicatori, oppure vogliamo operare su dei breakout di livelli importanti? Rispondere a queste domande è la prima cosa da fare: sapere come vogliamo operare e con quale logica.
2) Selezione dello strumento: scegliere il mercato e l’asset su cui operare. È possibile individuare prima il settore di interesse, come indici, azionario, forex …, e successivamente lo strumento specifico (ad es. FTSE MIB, DAX, EUR/USD). Che si preferisca fare trading su azioni, sull’indice Nasdaq o su Bitcoin, è fondamentale considerare che ogni strumento finanziario possiede caratteristiche tecniche specifiche che è indispensabile analizzare prima di fare trading.
Una cosa importante da tenere conto nella selezione dello strumento operativo è la liquidità. Usando trading system è importante scegliere strumenti molto liquidi, in cui l’esecuzione degli ordini non trovi grossi spread nel book di negoziazione.
Un’altra cosa da considerare sono gli orari ed i costi operativi.
In quali orari vogliamo seguire i mercati?
In ogni caso, al di là delle preferenze personali, è fondamentale privilegiare strumenti con bassi costi di negoziazione, poiché le commissioni e lo spread possono incidere sulle performance del sistema di trading più di quanto si pensi.
Scegliere asset ad alta liquidità e volumi elevati (come i principali indici o le valute maggiormente scambiate) permette di ridurre al minimo questi costi e offre un ulteriore vantaggio decisivo: la disponibilità di uno storico dati ampio e affidabile, indispensabile per effettuare backtest accurati.
3) Selezione del timeframe operativo: scelto il mercato, dobbiamo scegliere il timeframe operativo.
Ecco i principali time frame con le rispettive caratteristiche:
– Tick / 1-5 minuti (Scalping)
Si basa sullo sfruttamento dei movimenti minimi di prezzo, attraverso decine o centinaia di operazioni al giorno. È uno stile che richiede piattaforme ultra-veloci, spread estremamente ridotti e un’esecuzione quasi automatizzata.
Tuttavia, il rumore di mercato è elevatissimo e i costi di transazione rischiano di erodere gran parte dei profitti. Tipicamente, chi pratica lo scalping opera attraverso una lettura analitica del book di negoziazione e del time & sales (o ticker), lo strumento che mostra in tempo reale gli ordini realmente eseguiti.
– 15-60 minuti (Intraday)
Rappresenta l’operatività intra-giornaliera classica: le posizioni vengono di norma chiuse entro la fine della seduta, anche se in alcuni casi possono essere mantenute overnight. Pur utilizzando un sistema automatizzato, il monitoraggio costante resta fondamentale. Questo approccio richiede una solida capacità di lettura della price action intraday e una disciplina rigorosa nella gestione dei punti di uscita.
–4 ore / Giornaliero (Swing Trading)
Si tratta di un’operatività multiday in cui le operazioni coprono un arco temporale da un giorno a qualche settimana. Questo approccio garantisce una maggiore qualità e affidabilità dei segnali, oltre a un impatto ridotto delle commissioni e a una gestione meno vincolante del tempo a schermo. Per contro, richiede un’attenta pianificazione del rischio overnight e di weekend, per tutelarsi da eventuali gap di prezzo causati da news inaspettate.
– Settimanale / Mensile (Position Trading)
Orizzonte di settimane o mesi. Si avvicina alla logica degli investitori. Richiede grande pazienza, drawdown potenzialmente lunghi, ma riduce drasticamente i costi e il rumore operativo.
4) Regole per i segnali di ingresso e di uscita da una posizione
Una volta definita la strategia, il passo successivo consiste nello stabilire con precisione le regole di ingresso, sia per le posizioni long (al rialzo) sia per quelle short (al ribasso). Tali condizioni possono basarsi su molteplici fattori tecnici, quali l’incrocio di medie mobili, la rottura di un livello chiave (breakout) o la formazione di specifici pattern sugli indicatori.
Legate ai segnali di ingresso ci sono le condizioni di chiusura di un trade: target di profitto, stop‑loss, trailing stop, uscita per inversione dei segnali…
Le regole di uscita si dividono in due categorie principali. Da un lato vi sono le uscite puramente tecniche o statistiche, slegate dal segnale iniziale (come il raggiungimento di un take profit fisso in punti o in percentuale). Dall’altro vi sono le uscite logiche o condizionali, legate direttamente alla dinamica di ingresso: in questo caso si chiude la posizione quando la tesi operativa che ne ha decretato l’apertura non è più valida (ad esempio, per l’inversione di un indicatore o l’invalidazione del setup).
5) Definire il controvalore e il numero dei contratti della posizione
Stabilire l’ampiezza della posizione (numero di lotti o contratti) e definire la perdita massima tollerabile per singola operazione (ad esempio l’1% o il 2% del capitale totale).
Impostare paletti giornalieri rigidi, come il numero massimo di operazioni consentite e la soglia di drawdown massimo giornaliero superata la quale il sistema deve arrestarsi.
6) Backtest ed ottimizzazione
Il backtest è il processo con cui si simula l’operatività di una strategia sui dati storici di mercato, consentendo di valutarne la potenziale redditività ed efficacia nel passato. L’ottimizzazione consiste invece nel calibrare e variare i parametri della strategia per individuarne le combinazioni più performanti. Affinché entrambe le analisi siano statisticamente attendibili, è indispensabile disporre di una serie storica di dati sufficientemente ampia e profonda.
7) Monitoraggio: Analizzare costantemente le prestazioni della strategia tramite i report di ProRealTime (quali la equity curve e il dettaglio eseguiti) è un passaggio fondamentale.
Regola base: non attivare mai un trading system con capitale reale senza un’adeguata fase di test preliminare. È consigliabile passare dal paper trading ad un’operatività reale con posizioni minime (micro-size): questo approccio permette di testare la strategia con denaro vero ed iniziare ad affrontare la componente psicologica del trading. Infine, occorre monitorare il sistema con regolarità, evitando di alterare le regole senza una valida motivazione statistica al solo scopo di rincorrere performance profittevoli solo sulla carta.
§ 11.2 – Metriche principali
Quando costruiamo un trading system, le metriche sono gli strumenti che ci permettono di capire se la nostra strategia funziona.
Possiamo immaginare le metriche come il cruscotto di un’auto: ci danno informazioni precise su velocità, carburante, temperatura e tutto ciò che serve per guidare in sicurezza.
Ecco una breve descrizione delle metriche più utilizzate:
Number of Trades: indica la frequenza operativa, quante volte il sistema opera sul mercato. Per avere significatività statistica sono necessari un numero elevato di trades.
Un sistema con 20 trade ha poca significatività. Servono almeno 100-200 trade per avere dati affidabili, in ogni caso più sono meglio è.
Win Rate (%): è la percentuale di operazioni vincenti sul totale delle operazioni eseguite. L’importanza del win rate dipende dal tipo di sistema. Ricordiamo che un sistema trend following profittevole ha generalmente un win rate sotto il 50%. Quindi l’importante è il rapporto tra win rate ed il profitto delle singole operazioni.
Avg Win / Avg Loss (Risk-Reward Ratio): indica quanto si guadagna in media sui trade vincenti rispetto alle perdite. Avere una media delle vincite sensibilmente più alta della media delle perdite permette di guadagnare anche con un win rate sotto il 50%.
Net Profit / Total Return: è il profitto netto totale generato dal sistema nel periodo analizzato. È il punto di partenza per capire se una strategia è profittevole e quanto guadagna, ma da solo non basta.
Max Drawdown (DD): la massima perdita dal picco al bottom nella curva del capitale. È sicuramente una delle metriche più importanti per la gestione del rischio. In generale più il DD è basso meglio è.
Una strategia caratterizzata da un elevato net profit unito a un drawdown significativo è quasi impossibile da seguire nella realtà. Durante le fasi di perdita, infatti, non abbiamo la certezza che il sistema tornerà a performare: sappiamo che quelle flessioni sono state recuperate solo guardando il grafico a posteriori. Il rischio concreto è quello di farsi prendere dal panico e staccare la spina alla strategia proprio nel punto di massima sofferenza, rinunciando così alla successiva fase di recupero e profitto.
Profit Factor: è il rapporto tra profitti lordi e perdite lorde.
Un Profit Factor pari a 1 indica che il sistema è a breakeven (i guadagni lordi equivalgono esattamente alle perdite lorde). Per considerare la strategia accettabile occorre un valore superiore a 1,5, mentre un Profit Factor maggiore di 2 è indice di un sistema decisamente robusto ed efficiente.
Sharpe Ratio: immaginiamo di confrontare due sistemi:
Sistema A: guadagna il 20% all’anno, ma il suo valore oscilla molto,
Sistema B: guadagna il 15% all’anno, ma è molto più stabile.
Qual è migliore? Il semplice rendimento non basta, è essenziale capire quanto abbiamo rischiato per ottenere quel guadagno.
È precisamente questo che misura lo Sharpe Ratio. Un valore inferiore a 1 evidenzia che il rendimento non premia a sufficienza il rischio assunto; di conseguenza, occorre ricercare strategie che evidenzino un parametro almeno superiore a 1.
Oltre le principali metriche, necessarie per giudicare la bontà di una strategia, quando parliamo di performance di un trading system, c’è un aspetto che spesso viene sottovalutato ma che può fare la differenza tra una strategia profittevole e una che perde denaro: i costi di transazione e lo slippage. Questi sono i “costi invisibili” che incidono concretamente sul risultato finale delle operazioni.
Partiamo dallo spread, che è il primo costo implicito che incontriamo quando entriamo nel mercato. Lo spread è la differenza tra il miglior prezzo disponibile per acquistare e il miglior prezzo per vendere uno strumento in un dato momento. È la commissione fissa decisa dal nostro intermediario per l’esecuzione dell’ordine. In condizioni normali, uno spread contenuto indica un mercato liquido e ordinato, mentre quando si allarga segnala minore liquidità, maggiore incertezza o volatilità intensa.
Questo è il motivo per il quale quando c’è molta volatilità i costi di transazione sono maggiori.
Alcuni broker incorporano le commissioni di negoziazione nello spread, altri invece utilizzano uno spread ridotto, ma a questo occorre poi aggiungere le commissioni.
Lo slippage è probabilmente il costo variabile più importante e incide maggiormente sui costi totali. Lo slippage è la differenza tra il prezzo atteso di un’operazione e quello a cui l’ordine viene realmente eseguito. È un’imperfezione del mercato che si verifica quando il mercato si muove rapidamente o quando non c’è sufficiente disponibilità di ordini al prezzo desiderato. Anche questo fenomeno è particolarmente rilevante nei momenti di maggiore volatilità o nei mercati meno liquidi, dove il prezzo può cambiare rapidamente tra l’invio dell’ordine e la sua effettiva esecuzione.
Nella pratica, quando eseguiamo il backtesting di un trading system, dobbiamo includere realisticamente sia spread (ed eventuali commissioni) che slippage, altrimenti rischiamo di sovrastimare le performance.
Fra tutti i costi lo slippage è quello che incide maggiormente sul risultato finale in quanto il più imprevedibile.
In definitiva, spread e slippage insieme rappresentano la parte concreta, spesso invisibile, del funzionamento reale del mercato. Questo è il motivo principale per cui i sistemi con un’alta frequenza operativa (molte operazioni al giorno) sono particolarmente vulnerabili a tali costi.
§ 11.3 – Idee di trading
Le idee per costruire sistemi di trading nascono quasi sempre da una combinazione di:
– osservazione del mercato,
– regole logiche,
– prove sistematiche.
Ecco alcuni spunti per iniziare:
– Partire da regole molto semplici: invece di cercare complessità, è meglio iniziare con logiche molto basilari che abbiamo già osservato in modo soggettivo sui grafici.
A questo scopo è molto importante la ricerca visuale. Apriamo i grafici e cerchiamo pattern ripetuti che notiamo sui grafici oppure che abbiamo studiato nei libri. Osserviamo i movimenti ricorrenti di prezzo, situazioni che riteniamo interessanti e che ci possono dare lo spunto per provare a formalizzare dei comportamenti di prezzo.
Trovata una regolarità, cerchiamo poi di trasformare l’idea in regole oggettive.
Molto spesso le idee migliori hanno un perché dietro. Perché i market maker agiscono in certi orari? Perché certi asset si muovono insieme o in modo opposto? In quali orari i mercati tendono a invertire un trend?
– Un altro approccio efficace per generare spunti operativi consiste nel rielaborare e combinare indicatori classici, esplorandone usi non convenzionali o variandone le logiche standard.
Ecco diverse idee e spunti tecnici da testare:
Medie Mobili e Trend: testare l’efficacia dei classici cross (incroci) su diversi time frame, oppure analizzare parametri meno tradizionali come l’inclinazione della media o la distanza percentuale del prezzo dalla media stessa.
Breakout e Pattern di Prezzo: sviluppare logiche di breakout sul superamento dei massimi/minimi a $N$ barre, oppure studiare tecniche di reversal (inversione) a seguito di spike rialzisti o ribassisti.
Volatilità e Momentum: testare ingressi a mercato su fortissime compressioni dell’ATR (volatilità pronta a esplodere) o impostare logiche di momentum puro (es. comprare quando la chiusura supera determinati livelli chiave).
Oscillatori e Divergenze: filtrare i segnali attraverso livelli estremi di ipercomprato/ipervenduto o tramite divergenze strutturali tra prezzo e oscillatore.
Gestione dell’Uscita: sperimentare diversi tipi di stop e dinamiche di trailing stop agganciate a specifici segnali o indicatori.
– Ancora più semplice è partire da sistemi famosi o tecniche importanti che si trovano in libri di trading, capirne l’idea operativa e provare a modificarli.
Oltre ai libri possiamo trovare nel forum di ProRealCode vari tipi di trading system su vari strumenti già pronti che possiamo studiare, smontare e modificare.
Un trading system infatti è l’insieme di più elementi integrati: segnali di entrata, filtri di mercato e regole di money management. Sperimentare queste componenti sui mercati scelti permette di individuare cosa funziona davvero sul mercato e sviluppare con il tempo un metodo operativo affine al proprio stile.
Per chi muove i primi passi nel trading algoritmico, un aspetto cruciale è evitare gli errori più comuni che rischiano di far sprecare tempo prezioso e risorse nello sviluppo e nel collaudo dei sistemi.
Tra i principali che possono capitare all’inizio:
– usare troppi indicatori insieme,
– ottimizzare eccessivamente certi parametri,
– creare regole troppo specifiche adatte solo per singoli sistemi,
– fare troppe operazioni al giorno senza una logica chiara dietro una strategia,
– dare poca importanza al peso di commissioni, spread e slippage,
– ignorare il risk management,
– operare con un capitale troppo ridotto che non ci permette di operare con tranquillità.
Capitolo 12: Indicatori
In ProRealTime, gli indicatori e gli oscillatori sono strumenti fondamentali per analizzare i mercati e supportare le decisioni di trading. Questi si basano su formule matematiche applicate ai dati di prezzo (e talvolta ai volumi) per fornire una lettura più chiara dell’andamento del mercato.
Gli indicatori non vanno considerati come un “Sacro Graal”. Come ricorda Larry Williams nel suo celebre libro I segreti del trading di breve termine: “Se non riuscite a fare soldi con i prezzi, non riuscirete a farne nemmeno con un indicatore derivato dai prezzi”.
Gli indicatori vanno intesi come semplici strumenti di supporto per sintetizzare l’informazione, non come oracoli infallibili. Tuttavia possono aiutare a capire meglio l’andamento dei prezzi nei grafici o vedere, ad esempio divergenze, che non sono visibili osservando direttamente i prezzi.
Come abbiamo detto, gli indicatori ci possono aiutare ad avere idee di trading. In ProRealTime ci sono tantissimi indicatori ed oscillatori che possiamo provare e poi scegliere quelli che troviamo più interessanti per fare delle prove.
All’interno della piattaforma, questi strumenti possono essere utilizzati sia in modo visivo (applicandoli direttamente sui grafici) sia all’interno di strategie automatiche, combinandoli tra loro per creare regole operative precise. Inoltre, ProRealTime consente di personalizzarli o crearne di nuovi tramite codice, offrendo grande flessibilità a chi vuole sviluppare un proprio metodo di analisi.
In sintesi, indicatori ed oscillatori costituiscono un ottimo supporto per interpretare il mercato e formalizzare le proprie idee operative. Rappresentano la base per trasformare spunti discrezionali in strategie di trading sistemico solide e ben strutturate.
ProRealTime possiede una libreria di indicatori ed oscillatori molto ampia.
E’ possibile richiamare gli indicatori che abbiamo programmato nelle nostre strategie in due modi: o inserendoli all’interno del codice (preferibile) oppure con l’istruzione CALL.
La differenza sostanziale tra indicatori ed oscillatori risiede nella scala di calcolo e nell’obiettivo analitico:
Gli indicatori (come le medie mobili) operano sulla scala del prezzo e servono a identificare e seguire il trend di fondo.
Gli oscillatori (come RSI, Stocastico e MACD) operano in finestre separate su scale normalizzate o fisse, con l’obiettivo di misurare il momentum del prezzo e rilevare fasi di eccesso (ipercomprato/ipervenduto) o di esaurimento della spinta del mercato.
Gli indicatori/oscllatori principali possono essere divisi in quattro grandi famiglie:
1. Indicatori di Trend (Trend-Following)
Operano direttamente sulla scala del prezzo e servono a identificare la direzione e la persistenza della tendenza principale.
Medie Mobili: I mattoni fondamentali per smussare il rumore di fondo e identificare il trend.
Supertrend: Basato sull’Average True Range (ATR), definisce in modo dinamico la direzione del trend e fornisce livelli chiari di stop trailing.
Donchian Channels: Tracciano i massimi e i minimi più alti/bassi di un dato periodo; ideali per strategie di breakout.
Bande di Bollinger: Combinano una media mobile centrale con due bande calcolate sulla deviazione standard del prezzo, misurando contemporaneamente trend e volatilità relativa.
2. Oscillatori di Momentum e Forza Relativa
Posizionati sotto il grafico in finestre separate, misurano la velocità del movimento del prezzo e identificano possibili punti di esaurimento o divergenza.
RSI (Relative Strength Index): Oscillatore normalizzato tra 0 e 100 che misura la velocità e il cambio dei movimenti di prezzo. Utilizzato per rilevare aree di ipercomprato (>70), ipervenduto (<30) e divergenze.
MACD (Moving Average Convergence Divergence): Calcolato come differenza tra due medie mobili esponenziali (di norma EMA 12 ed EMA 26) rispetto a una linea di segnale (EMA 9). Identifica sia la forza del momentum sia i cambi di trend.
Stocastico (Stochastic Oscillator): Confronta il prezzo di chiusura corrente con il range di prezzo registrato in un dato periodo, mostrando la posizione relativa del prezzo rispetto ai suoi massimi e minimi recenti.
3. Indicatori di Volatilità
Non indicano la direzione del mercato, ma misurano l’ampiezza o l’intensità delle oscillazioni di prezzo.
ATR (Average True Range): Sviluppato da J. Welles Wilder, misura la volatilità assoluta considerando anche i gap di apertura. Essenziale per dimensionare gli stop loss, impostare i take profit e calcolare il Position Sizing.
Deviazione Standard (Standard Deviation): Misura la dispersione dei prezzi rispetto alla loro media aritmetica, base fondamentale di indicatori come le Bande di Bollinger.
4. Indicatori di Volume
Integrano le informazioni di prezzo con la pressione dei volumi di scambio.
OBV (On-Balance Volume): Relaziona i volumi totali alla direzione della chiusura giornaliera per mostrare se il capitale sta entrando o uscendo dallo strumento.
VWAP (Volume Weighted Average Price): calcola la media del prezzo pesata sui volumi intraday, rappresentando il benchmark istituzionale per eccellenza.
§ 12.1 – Le medie mobili
Gli indicatori seguono generalmente il movimento del prezzo e aiutano a identificare il trend. Tra i più comuni ci sono le medie mobili. Una media mobile è un indicatore di analisi tecnica che calcola appunto la media dei prezzi di un asset (solitamente chiusura) su un certo numero di periodi, “smussando” le oscillazioni del mercato e mostrando meglio la direzione del trend, permettendoci di capire se il mercato è in fase rialzista, ribassista o laterale.
Le medie mobili sono tra gli strumenti più antichi e studiati dell’analisi tecnica, eppure dietro la loro semplicità apparente si nasconde una domanda filosofica profonda: è possibile catturare il presente guardando il passato?
La risposta è negativa, in quanto c’è un limite intrinseco al concetto di media: il ritardo.
Una media mobile su n periodi “vede” il passato, non il presente. Più il periodo è lungo, più la media insegue il prezzo anziché anticiparlo.
Il lag (ritardo) è il limite strutturale da cui discendono quasi tutti gli altri difetti degli indicatori trend-following. Non si tratta di un bug eliminabile, bensì di un vincolo matematico del calcolo: per calcolare una media occorre aggregare una serie di osservazioni, e tali dati appartengono per definizione al passato. Non esiste una media mobile “a lag zero” che mantenga contemporaneamente proprietà di smussamento e stabilità; azzerare del tutto il ritardo equivale semplicemente a ritornare al prezzo grezzo.
I due limiti principali delle medie mobili sono:
– I falsi segnali in laterale: sono la conseguenza pratica del lag. Se proviamo ad inserire una media mobile di basso periodo in un “mercato laterale” vedremo che ogni rimbalzo di tre o quattro barre genera un incrocio. Il mercato non sta andando da nessuna parte, ma la media identifica erroneamente un trend ad ogni oscillazione.
– L’overfitting: è il limite più insidioso perché si manifesta solo sul conto reale, mai nel backtest. Ogni volta che scegliamo il periodo 21 invece di 20 perché ha funzionato meglio storicamente, stiamo adattando il modello al rumore dei dati storici del passato, non alla struttura del mercato.
Nel tempo sono state sviluppate numerose varianti di medie mobili con l’obiettivo di ottimizzarne l’efficienza e ridurre il ritardo temporale. Tra le più diffuse, la Media Mobile Semplice (SMA) e la Media Mobile Esponenziale (EMA) rappresentano i due pilastri fondamentali per l’analisi del trend (trend smoothing), differenziandosi per la formula matematico-computazionale e per il livello di reattività.
SMA (Simple Moving Average): assegna il medesimo peso a ciascun prezzo del periodo considerato. È più stabile e lineare, filtra efficacemente il rumore di fondo, ma genera un lag maggiore sui cambi di direzione.
EMA (Exponential Moving Average): attribuisce un peso ponderato crescente ai prezzi più recenti. Risulta notevolmente più reattiva e vicina all’azione del prezzo, offrendo crossover più tempestivi al prezzo di una maggiore esposizione ai falsi segnali.
Le strategie più comuni basate sulle medie mobili si basano su due meccanismi di fondo:
– Prezzo e singola media: la media definisce la tendenza di fondo e serve da supporto o resistenza dinamica per il prezzo.
– Incrocio di due medie: il segnale di ingresso viene generato quando la media veloce incrocia al rialzo o al ribasso quella lenta.
Al di là del tipo ogni media porta comunque con sé un ritardo, ecco perché le medie mobili dovrebbero essere viste principalmente come uno strumento di contestualizzazione e non di previsione del mercato.
Servono a rispondere a “dove siamo rispetto alla tendenza recente?” più che a “dove andremo?”.
Usarle consapevolmente, come filtro di trend all’interno di un sistema più ampio, è molto più efficace che affidarsi ciecamente ai loro incroci come segnali assoluti.
La sintassi per scrivere una media in ProRealTime è:
Nome della funzione [n barre, tipo] (prezzo o indicatore)
Nella formula dobbiamo scegliere:
– il NUMERO di periodi (ad esempio: 20),
– il TIPO di media (semplice, esponenziale o altri tipi),
– APPLICAZIONE: generalmente la media mobile viene calcolata sul prezzo di chiusura (close), ma può essere applicata anche a prezzi di apertura, massimi, minimi o prezzi medi. Inoltre, è possibile applicare una media mobile sui dati derivati da un altro indicatore: un esempio chiave è il MACD, la cui Signal Line consiste proprio in una media mobile applicata sul valore dell’indicatore stesso.
In ambiente ProRealTime, la gestione delle medie mobili è estremamente versatile. Il linguaggio di programmazione mette a disposizione nove tipologie nativamente codificate, più altre come la adaptive, kama… che possiamo trovare in ProRealCode, la community ProRealTime (https://www.prorealcode.com/documentation/average/).
Ecco un elenco:
0 - Simple Moving Average (SMA)
1 - Exponential Moving Average (EMA)
2 - Weighted Moving Average (WMA)
3 - Wilder's Moving Average
4 - Triangular Moving Average
5 - End Point Moving Average
6 - Time Series Moving Average
7 - Hull Moving Average
7 - ZeroLag Moving Average In ProRealTime il tipo di media mobile può essere specificato richiamando il nome diretto della funzione (valido solo per alcune medie) oppure, modalità ampiamente preferibile, definendolo come parametro interno della funzione Average (es. average[20, 1](close)). Questo secondo metodo rende il codice più versatile e pronto per la fase di ottimizzazione.
Una media esponenziale a 20 periodi la possiamo quindi scrivere in due modi:
exponentialAverage[20](close)
average[20,1](close) Se desideriamo comprendere a fondo la costruzione della media mobile esponenziale (EMA) o codificarne una versione personalizzata la formula custom della media esponenziale è la seguente:
// ==============================================
// Calcolo Custom della Media Esponenziale (EMA)
// ==============================================
// 1. Inizializzazione della variabile ricorsiva alla prima barra
once customEMA = close
// 2. Definizione dei parametri e calcolo di Alpha
EMALength = 10
alpha = 2 / (EMALength + 1)
// 3. Algoritmo di calcolo ricorsivo dell'EMA
if barindex > EMALength then
customEMA = (alpha * close) + ((1 - alpha) * customEMA[1])
endif
// 4. Output a grafico
return customEMA as "Custom EMA"Tra le medie mobili più avanzate troviamo la Media Mobile di Hull (HMA), ideata da Alan Hull per azzerare quasi del tutto il ritardo delle medie classiche, conservando al tempo stesso una linea fluida, pulita e molto reattiva alle variazioni del prezzo.
Ecco la formula custom:
// ===============================================
// Media Mobile di Hull (HMA) - Formula Custom
// ===============================================
period = 130
// 1. Calcolo del valore intermedio (2 * WMA_mezzoperiodo - WMA_periodo)
inner = (2 * WeightedAverage[ROUND(period / 2)](close)) - WeightedAverage[period](close)
// 2. Calcolo finale dell'HMA (WMA sulla radice quadrata del periodo)
mHull = WeightedAverage[ROUND(SQRT(period))](inner)
return mHull COLOURED(255, 0, 0) AS "Hull Moving Average (130)"Vediamo in questo grafico la diversa reattività delle tre media mobili a 100 periodi di cui abbiamo parlato sopra applicate allo strumento Dax con timeframe a 2 ore (SMA – verde, EMA – rossa, HULL – blu):

§ 12.2 – Macd
Facciamo ora una veloce carrellata sui principali indicatori.
Il MACD (Moving Average Convergence Divergence) è uno degli indicatori più utilizzati nell’analisi tecnica perché consente di valutare contemporaneamente trend, forza del movimento e possibili inversioni di mercato.
Sviluppato da Gerald Appel, il MACD si basa sulla differenza tra due medie mobili esponenziali, generalmente a 12 e 26 periodi.
E’ costituito quindi da due medie mobili esponenziali, la prima è una sottrazione di due medie (12 e 26), mentre la seconda è una media a 9 periodi che si applica alla prima.
myMacd = average[12,1] - average[26,1]
myMacdSignal = average[9,1](myMacd)I segnali tipici del macd sono tre.
– Cross-over: la linea MACD attraversa quella del segnale, sia in senso rialzista che ribassista. È la strategia più usata con questo indicatore.
– Zero-line: cattura il momento in cui il MACD attraversa lo zero, che indica un cambio di momentum generale.
– Divergenza: rileva situazioni in cui il prezzo fa un nuovo estremo ma il MACD non lo conferma, spesso segnale di un’inversione imminente.
§ 12.3 – ROC
Il ROC (Rate of Change) è un indicatore di momentum che misura la velocità con cui il prezzo di uno strumento finanziario varia nel tempo. Il suo concetto fondamentale è molto semplice: confronta il prezzo attuale con quello di un determinato numero di periodi precedenti, esprimendo la differenza in termini percentuali.
Il momentum rappresenta la forza e la velocità con cui il prezzo di uno strumento finanziario si muove in una determinata direzione. Non misura semplicemente se il mercato sta salendo o scendendo, ma valuta quanto rapidamente sta avvenendo questo movimento.
In ProRealTime, il ROC viene generalmente rappresentato come una linea oscillante attorno allo zero. Gli attraversamenti della linea centrale possono fornire indicazioni sulla direzione prevalente del mercato, mentre i picchi eccessivamente elevati o bassi possono evidenziare condizioni di ipercomprato o ipervenduto.
§ 12.4 – KST
L’indicatore KST (Know Sure Thing) è un oscillatore di momentum sviluppato da Martin Pring. Il suo obiettivo è individuare la direzione e la forza del trend combinando più cicli temporali in un unico indicatore.
Il KST si basa sulla somma ponderata di diversi ROC (Rate of Change), cioè variazioni percentuali del prezzo su periodi differenti. Questo approccio permette di avere una visione più completa del mercato, riducendo il rumore tipico degli indicatori più semplici.
Il risultato è una linea principale (KST) spesso accompagnata da una linea di segnale (media applicata al KST), molto simile nella logica al MACD.
roc1 = ROC[10](close)
avgRoc1 = average[10](roc1)
roc2 = ROC[15](close)
avgRoc2 = average[10](roc2)
roc3 = ROC[20](close)
avgRoc3 = average[10](roc3)
roc4 = ROC[30](close)
avgRoc4 = average[15](roc4)
myKst = (avgRoc1+avgRoc2+avgRoc3+avgRoc4)/4
myKstSignal = average[9,1](myKst)
return myKst, myKstSignal§ 12.5 – Parabolic SAR
Il nome “parabolico” descrive la traiettoria che i punti disegnano lungo un trend: partono lontani dal prezzo e si avvicinano progressivamente con una curva che ricorda appunto una parabola. L’idea di fondo è elegante: non solo segnalare quando entrare, ma anche dire dove mettere lo stop e quando uscire e invertire la posizione.
Il cuore dell’indicatore è l’AF (Acceleration Factor). Inizia piccolo (di solito 0.02) e cresce ogni volta che il prezzo raggiunge un nuovo punto estremo nella direzione del trend, fino a un massimo configurabile (default 0.20).
Questo fa sì che lo stop si stringa progressivamente: all’inizio di un trend il SAR è lontano e dà respiro, verso la fine è vicino e protegge i profitti accumulati.
Questa è l’esempio di un sistema con il SAR, i cui segnali di entrata derivano dal cambiamento di colore del SAR.
defParam cumulateOrders = false
mySAR = SAR[0.02,0.02,0.2]
green = close > mySAR
red = close < mySAR
change = (green and red[1]) or (green[1] and red)
// LONG
if change and green and not longOnMarket then
buy 1 contract at market
endif
// SHORT
if change and red and not shortOnMarket then
sellShort 1 contract at market
endif§ 12.6 – SuperTrend
In ProRealTime, il SuperTrend è un indicatore molto popolare di tipo trend-following, utilizzato per identificare la direzione del mercato e generare segnali operativi chiari e immediati anche a livello visivo.
Il supertrend è una linea che si sovrappone al grafico del prezzo e cambia posizione in base al trend. Quando il prezzo si trova sopra la linea del SuperTrend, il trend viene considerato rialzista; quando invece il prezzo scende sotto la linea, il trend viene considerato ribassista.
Spesso il superTrend cambia anche colore (es. verde/rosso) per rendere ancora più intuitiva la lettura.
ll SuperTrend si basa su due elementi principali:
– ATR (Average True Range) per misura la volatilità
– Moltiplicatore per determinare quanto la linea si allontana dal prezzo.
I parametri tipici sono un atr di 10 e un moltiplicatore di 2 o 3.
Uno dei principali vantaggi del SuperTrend è la sua capacità di filtrare parte del rumore di mercato, mantenendo il trader all’interno dei movimenti direzionali più significativi. Essendo basato sulla volatilità, l’indicatore tende ad allargarsi durante le fasi più turbolente e a restringersi quando il mercato è più stabile, adattando automaticamente la distanza dai prezzi.
mySupertrend = supertrend[3,10] // formula superTrend§ 12.7 – CCI
Il CCI (Commodity Channel Index) è un indicatore di analisi tecnica usato per misurare quanto il prezzo si discosta dalla sua media.
In pratica, il CCI oscilla attorno a uno zero centrale: valori sopra +100 indicano spesso una forte fase rialzista o mercato rialzista, mentre valori sotto -100 suggeriscono una forte fase ribassista o mercato ribassista.
È quindi utile sia per il trading direzionale sia per cercare inversioni o divergenze tra prezzo e indicatore.
CCI = (Prezzo Tipico - SMA del Prezzo Tipico) / (0.015 × Deviazione Media Assoluta)Prezzo Tipico = (Massimo + Minimo + Chiusura) / 3
SMA = media mobile semplice del Prezzo Tipico, di solito su 14 o 20 periodi
0.015 è una costante scelta da Lambert per far sì che circa il 70-80% dei valori CCI rientri tra -100 e +100
Come si legge
Sopra +100: il prezzo è forte, possibile ipercomprato o inizio di trend rialzista
Sotto -100: il prezzo è debole, possibile ipervenduto o inizio di trend ribassista
Tra -100 e +100: il mercato è in una fase “normale”, senza estremi
A differenza di RSI o Stocastico, il CCI non è limitato in un range fisso: può salire o scendere ben oltre ±100, il che lo rende utile sia per strategie di ipercomprato/ipervenduto sia per strategie di breakout/trend following.
Strategie tipiche
1. Ipercomprato/Ipervenduto
Vendita quando il CCI supera +100 e poi ridiscende sotto
Acquisto quando il CCI scende sotto -100 e poi risale sopra
2. Trend following / Breakout
Acquisto quando il CCI rompe sopra +100 (segnale di forza)
Vendita quando il CCI rompe sotto -100 (segnale di debolezza)
§ 12.8 – Magic Trend
Il Magic Trend è un indicatore di trend following che combina due strumenti classici dell’analisi tecnica — il CCI (Commodity Channel Index) e l’ATR (Average True Range) — per costruire un livello dinamico di supporto/resistenza che si adatta alla volatilità del mercato.
L’indicatore calcola due buffer dinamici attorno al prezzo:
buffUP — tracciato sotto i minimi, agisce da supporto dinamico in trend rialzista
buffDN — tracciato sopra i massimi, agisce da resistenza dinamica in trend ribassista
La distanza di questi buffer dal prezzo non è fissa, ma proporzionale all’ATR medio: quando il mercato è volatile, i buffer si allargano; quando è compresso, si stringono.
Il CCI svolge il ruolo di filtro direzionale: determina quale dei due buffer è attivo in ogni momento e segnala i cambi di trend quando attraversa la linea dello zero.
Una caratteristica fondamentale è la logica trailing: il buffer rialzista non può mai scendere, quello ribassista non può mai salire. Questo crea un effetto di stop progressivo che protegge la posizione man mano che il trend si sviluppa.
Parametri configurabili:
cciP (default 14) – Periodo del CCI; valori più alti rendono il filtro direzionale più lento e stabile
atrP (default 14) – Periodo dell’ATR; controlla la sensibilità alla volatilità
atrM (default 1) – Moltiplicatore ATR; regola l’ampiezza dei buffer rispetto al prezzo
smaP (default 5) – Periodo della media applicata all’ATR per smussare i buffer
In sintesi
Il Magic Trend è uno strumento visivamente immediato: fintanto che il prezzo rimane al di sopra della linea, il trend è considerato rialzista; quando scende al di sotto, il trend è ribassista. La sua forza sta nella capacità di adattarsi alla volatilità evitando i falsi segnali tipici degli indicatori a banda fissa, rendendolo utilizzabile su qualsiasi timeframe e strumento finanziario.
cciP = max(1, min(999, 14))
atrP = max(1, min(999, 14))
atrM = max(0.0000001, min(999, 1))
smaP = max(1, min(999, 5))
myATR = averageTrueRange[atrP](close)
thisCCI = CCI[cciP](typicalPrice)
if barIndex > max(cciP, atrP) then
temp1 = myATR * atrM
temp2 = average[smaP](myATR) * atrM
// Calcola i buffer di base
rawUP = low - temp2
rawDN = high + temp2
// Gestione crossover CCI
if (thisCCI >= 0) AND (thisCCI[1] < 0) then
buffUP = buffDN[1]
elsif (thisCCI <= 0) AND (thisCCI[1] > 0) then
buffDN = buffUP[1]
else
buffUP = rawUP
buffDN = rawDN
endif
// Logica trailing (non far scendere buffUP, non far salire buffDN)
if thisCCI >= 0 then
if buffUP < buffUP[1] then
buffUP = buffUP[1]
endif
magicTrend = buffUP
elsif thisCCI <= 0 then
if buffDN > buffDN[1] then
buffDN = buffDN[1]
endif
magicTrend = buffDN
endif
else
buffUP = 0
buffDN = 0
magicTrend = 0
endif
return magicTrend as "MagicTrend"§ 12.9 – Perfect Trend
Il Perfect Trend è un indicatore di trend-following costruito su ProBuilder che traccia due linee dinamiche di supporto/resistenza, calcolate sui massimi e minimi degli ultimi periodi
L’indicatore sfrutta due orizzonti temporali distinti, definiti dai parametri $x$ (26 periodi, reattivo) e $y$ (50 periodi, strutturale), per costruire livelli dinamici di supporto e resistenza:
Rilevazione degli estremi: Per ciascuna finestra temporale vengono identificati i relativi estremi di prezzo:
Hx, Lx = Massimo e minimo calcolati sulle ultime x barre.
Hy, Ly = Massimo e minimo calcolati sulle ultime y barre.
LineBlu (Linea Veloce – x periodi): Determina il trend di breve termine.
Se il prezzo di chiusura conferma la permanenza sopra il livello precedente, la linea si adegua al minimo locale (Lx), fungendo da supporto dinamico per il trend rialzista.
In caso contrario, la linea sale al massimo locale (Hx), agendo da resistenza dinamica per il trend ribassista.
LineRed (Linea Lenta – y periodi): Adotta la medesima logica computazionale sull’orizzonte esteso (y). Risultando meno sensibile alle fluttuazioni di breve, è ideale per filtrare il trend di fondo e ridurre i falsi segnali.
Utilizzo pratico:
Quando il prezzo è sopra entrambe le linee, il trend è considerato rialzista; quando è sotto entrambe, ribassista. L’incrocio tra lineBlu e lineRed, oppure la rottura del prezzo attraverso di esse, può essere usato come segnale operativo di ingresso o uscita.
// --- Parametri dell'indicatore (puoi anche impostarli come variabili esterne)
x = 26 // LONG FLOOR (Periodo per la Linea Blu)
y = 50 // SHORT FLOOR (Periodo per la Linea Rossa)
// --- Calcolo dei Massimi e Minimi sui rispettivi periodi
Hx = highest[x](high)
Lx = lowest[x](low)
Hy = highest[y](high)
Ly = lowest[y](low)
// --- Logica del Perfect Trend
if barindex = 0 then
lineBlu = close
lineRed = close
else
// Gestione Linea Blu
if close > lineBlu[1] then
lineBlu = Lx
else
lineBlu = Hx
endif
// Gestione Linea Rossa
if close > lineRed[1] then
lineRed = Ly
else
lineRed = Hy
endif
endif
return lineBlu as "Linea Blu", lineRed as "Linea Rossa"Capitolo 13: Oscillatori
Gli oscillatori a differenza degli indicatori di trend si muovono all’interno di un intervallo definito (ad esempio da 0 a 100) e sono particolarmente utili per individuare condizioni di ipercomprato e ipervenduto.
Questo li rende ideali nei mercati laterali o per anticipare possibili inversioni, mentre tendono a dare falsi segnali in mercati direzionali.
§ 13.1 – RSI
L’RSI (relative strength index) è uno degli oscillatori più utilizzati per misurare la forza e velocità dei movimenti di prezzo. Sviluppato da J. Welles Wilder è diventato uno standard dell’analisi tecnica.
L’RSI è un oscillatore che varia tra 0 e 100 e confronta la media dei movimenti rialzisti con quelli ribassisti in un certo periodo, 14 di default.
Vengono identificati due livelli (soglie): di ipercomprato sopra 70 ed ipervenduto sotto 30. Ecco la formula in cui occorre definire i periodi:
lenghtRsi = 14
rsi[lengthRsi](close)In ProRealTime, l’RSI viene utilizzato principalmente per valutare la forza di un trend, individuare possibili punti di inversione e riconoscere eventuali divergenze tra l’andamento dei prezzi e quello dell’indicatore.
A differenza di altri oscillatori, l’RSI non si limita a indicare la direzione del movimento, ma fornisce una misura dell’equilibrio tra compratori e venditori, aiutando il trader a comprendere se il mercato sta guadagnando o perdendo forza.
Questa è la formula custom:
up = max(0, close - close[1])
down = max(0, close[1] - close)
avgUp = average[p,3](up)
avgDown = average[p,3](down)
RS = avgUp / avgDown
myRSI = 100 - (100 / (1 + RS))
Ob = 70
Os = 30
return myRSI AS "Rsi",Os AS "Os",Ob AS "Ob", 50 as "Mid"§ 13.2 – Stocastico
L’Oscillatore Stocastico è uno strumento di momentum sviluppato da George Lane per misurare la posizione relativa dell’ultimo prezzo di chiusura rispetto all’escursione totale (range High-Low) registrata in un determinato orizzonte temporale.
Il principio di fondo assume che nelle fasi rialziste i prezzi tendano a chiudere vicino ai massimi di periodo, mentre nelle fasi ribassiste la chiusura si concentri nei pressi dei minimi. L’indicatore oscilla all’interno di una scala fissa tra 0 e 100:
Valori superiori a 80 (Ipercomprato): segnalano che il prezzo sta chiudendo molto vicino ai massimi di periodo, indicando una forte spinta rialzista o un possibile eccesso temporaneo.
Valori inferiori a 20 (Ipervenduto): indicano che il prezzo è prossimo ai minimi di periodo, evidenziando una pressione ribassista marcata o una potenziale area di rimbalzo.
L’utilizzo dello Stocastico nei trading system si concentra principalmente su due logiche operative:
– Incroci nelle Zone Estreme:
Segnale Long: La linea veloce %K incrocia al rialzo la linea di segnale %D mentre entrambe si trovano al di sotto della soglia di ipervenduto (< 20).
Segnale Short: La linea %K incrocia al ribasso la linea %D mentre entrambe si trovano al di sopra della soglia di ipercomprato (> 80).
Filtrare gli incroci richiedendo che avvengano all’interno o durante l’uscita dalle zone estreme riduce drasticamente i falsi segnali generati nelle fasi di mercato laterale.
– Divergenze Prezzo / Indicatore:
Divergenza Ribassista: si verifica quando la price action registra un nuovo massimo relativo più alto rispetto al precedente, ma lo Stocastico fallisce il superamento del suo massimo relativo, mostrando un picco inferiore. Segnala l’esaurimento della spinta rialzista.
Divergenza Rialzista: si verifica quando il prezzo segna un nuovo minimo relativo più basso, mentre lo Stocastico registra un minimo più alto rispetto al precedente, preannunciando una potenziale inversione al rialzo.
Questa è la formula dello stocastico:
period = 20 // lunghezza periodo
stochK = 20 // prima media K
averageD = 5 // seconda media D
myStochK = stochastic[period, stochK](close)
myStochSignal = average[averageD](myStochK)
return myStochK as "StochK", myStochSignal as "Signal"Questa è la formula custom:
// Stocastico con valori: (10,5,3)
periods = 10
Kline = 5
Dline = 3
avgType = 0 // Sma
K = average[Kline,avgType](((close - lowest[periods](low)) / (highest[periods](high) - lowest[periods](low))) * 100)
D = average[Dline,avgType](K)
return K AS "%K", D AS "%D"§ 13.3 – PercentB
Il Percent B (%B) è un indicatore sviluppato da John Bollinger per misurare la posizione relativa del prezzo all’interno delle Bande di Bollinger.
L’indicatore percentB ci dice dove si trova il prezzo rispetto alle Bollinger Bands, quindi aiuta a capire se il mercato è vicino alla banda inferiore, alla media o alla banda superiore.
A differenza delle bande stesse, che rappresentano graficamente la volatilità del mercato, il Percent B traduce questa informazione in un oscillatore facilmente interpretabile.
Ecco il codice in PRT:
lengthBol = 50
multiplier = 1.3
avg = average [lengthBol] (close)
stDev = std [lengthBol] (close)
bolH = avg + multiplier * stDev
bolL = avg - multiplier * stDev
percB = (close - bolL) / (bolH-bolL)*100
oversold = 30
overbought = 70
return percB as "%B",oversold as "oversold", overbought as "overbought"Nel trading algoritmico il Percent B viene spesso impiegato come filtro direzionale seguire la continuazione del movimento dopo la rottura delle Bande di Bollinger.
§ 13.4 – Oscillatori ciclici – DPO
Gli oscillatori ciclici rappresentano una categoria avanzata di indicatori tecnici progettati per identificare e misurare le oscillazioni periodiche presenti nei mercati finanziari. A differenza degli oscillatori tradizionali, che si limitano a valutare condizioni di ipercomprato o ipervenduto, gli oscillatori ciclici cercano di individuare il ritmo naturale con cui il mercato alterna fasi di espansione e contrazione.
L’idea alla base dell’analisi ciclica è che i prezzi non si muovono in modo completamente casuale, ma tendono a sviluppare movimenti ricorrenti caratterizzati da una determinata durata. Questi cicli possono essere influenzati da fattori economici, comportamentali e strutturali che si ripetono nel tempo.
L’obiettivo principale di un oscillatore ciclico non è prevedere il futuro, ma identificare la posizione corrente del mercato all’interno del proprio ciclo dominante. Quando il ciclo si avvicina a una fase di minimo, il trader può ricercare opportunità di acquisto; quando si avvicina a una fase di massimo, può valutare prese di profitto o operazioni di vendita.
Vediamo come esempio il Detrended Price Oscillator (DPO).
A differenza di un normale oscillatore di momentum, il DPO sposta la media mobile nel passato. Questo elimina l’influenza del trend a lungo termine, isolando i cicli puri e facilitando l’individuazione dei cicli di massimo e minimo.
Quando il DPO si trova sopra la linea dello zero, il ciclo di breve periodo è in fase positiva.
Quando si trova sotto lo zero, il ciclo è in fase negativa.
periodo = 20
// Spostamento per centrare il DPO sul ciclo passato
spostamento = (periodo / 2) + 1
// Calcolo del DPO
mediaSpostata = average[periodo](close)[spostamento]
myDPO = close - mediaSpostata
ZeroLine = 0
RETURN myDPO AS "Oscillatore DPO", ZeroLine AS "Linea Zero"Il DPO è quindi utile soprattutto per misurare quanto dura un ciclo e individuare la posizione del prezzo all’interno di quel ciclo.
Immaginiamo un titolo in trend laterale con oscillazioni regolari ogni 20 barre: il DPO sale sopra zero quando il prezzo è nella metà rialzista del ciclo e torna sotto zero quando entra nella metà ribassista. Se misuriamo la distanza tra due picchi del DPO e troviamo 20 barre, abbiamo individuato un ciclo dominante di 20 barre.
Capitolo 14: La volatilità
La volatilità è uno dei concetti più importanti nei mercati finanziari e rappresenta la velocità e l’ampiezza con cui i prezzi si muovono nel tempo. La volatilità misura quanto un mercato tende a oscillare.
Un aspetto fondamentale da ricordare è che la volatilità non indica la direzione, ossia un mercato molto volatile può salire o scendere.
Un mercato molto volatile presenta movimenti ampi e rapidi, con forti variazioni di prezzo in poco tempo. Al contrario, un mercato con bassa volatilità tende a muoversi in modo più lento e stabile.
Conoscere la volatilità è molto importante dal punto di vista pratico, in quanto la volatilità è direttamente correlata con il rischio. Per controllare questo rischio possiamo fare essenzialmente due cose:
– utilizzare stop loss più ampi,
– utilizzare size più piccole.
§ 14.1 – Bollinger e standard deviation
Le Bande di Bollinger sono uno degli strumenti più utilizzati per analizzare la volatilità e individuare possibili punti di ingresso e uscita dal mercato.
Le bande di Bollinger sono un indicatore composto da tre linee:
– una media mobile centrale (di solito a 20 periodi),
– una banda superiore,
– una banda inferiore.
Le due bande esterne si allargano o si restringono in base alla volatilità del mercato: quando il mercato è più movimentato, le bande si espandono; quando è più calmo, si contraggono.
Nelle bande di Bollinger la volatilità si misura tramite la deviazione Standard (σ), che misura quanto i prezzi si disperdono attorno alla loro media in un dato periodo.
In pratica la deviazione standard risponde alla domanda: il mercato è calmo o agitato?
La formula, calcolata su N barre:
– si calcola la media degli N prezzi di chiusura (SMA),
– si sommano i quadrati degli scarti rispetto alla media,
– si divide per n e si estrae la radice quadrata,
Il moltiplicatore classico di Bollinger è m=2 con periodo 20, ma si può adattare a: m=1.5 per segnali più frequenti, oppure m=2.5 per filtri più selettivi su timeframe intraday.
Ecco due formule per usare la standard deviation in punti ed in percentuale:
stD = Std[n](Close) // in punti
stD-Perc = (Std[n](Close) / Close) * 100 // in percentualeApplichiamo quindi la deviazione standard in punti a Bollinger:
lenghtBol = 20 // periodi
mm = 2 // moltiplicatore
myAvg = average[20] (close)
stDev = std[lenghtBol] (close)
bolH = myAvg + mm * stDev
bolL = myAvg - mm * stDevIn questo esempio usiamo la funzione multiTimeframe per usare due bande di bollinger relative a timeframe differenti, in modo da avere una panoramica più chiara del mercato:
// --- Timeframe 4h ---
timeframe (4h, updateonClose)
bbH4 = 20 // periodi
bbDev4 = 2.0 // deviazioni standard
bbAvg4 = average[bbH4](close) // media di Bollinger
upBollH4 = bbAvg4 + (std[bbH4](close) * bbDev4) // banda superiore
lowBollH4 = bbAvg4 - (std[bbH4](close) * bbDev4) // banda inferiore
// --- Timeframe 1h ---
timeframe (1h, updateonClose)
bbH1 = 20 // periodi
bbDev1 = 2.0 // deviazioni standard
bbAvg1 = average[bbH1](close) // media di Bollinger
upBollH1 = bbAvg1 + (std[bbH1](close) * bbDev1) // banda superiore
lowBollH1 = bbAvg1 - (std[bbH1](close) * bbDev1) // banda inferioreRicordiamo due modi di scrivere del codice per uscire da una posizione, in questo caso usciamo sulla banda superiore di Bollinger:
if longOnMarket then
sell positionSize contracts at bollH limit
endif
oppure:
if longOnMarket then
set target price bollH
endif§ 14.2 – ATR
Per determinare l’ampiezza di una barra ProRealTime ci mette a disposizione la funzione range (differenza massimo – minimo). Possiamo usare il range medio delle ultime 20 barre, come nell’esempio, per creare delle condizioni basate sulla volatilità da inserire in un nostro sistema.
avgRange = average[20,0](range)
// il range deve essere maggiore del range medio delle ultime 20 barre
tradeOFF = range > (avgRange * 2) Per essere più precisi, al posto di usare il semplice range della barra, in analisi tecnica si utilizza l’indicatore ATR (Average True Range). L’ATR, infatti, non si limita a considerare la differenza tra massimo e minimo della barra corrente, ma tiene conto anche degli eventuali gap rispetto alla chiusura precedente, calcolando il cosiddetto True Range. In questo modo si ottiene una misura di volatilità più robusta e significativa, specialmente su timeframe dove i gap tra una barra e l’altra sono frequenti.
L’ATR è stato sviluppato da J. Welles Wilder nel 1978, misura la volatilità media di uno strumento finanziario. A differenza della deviazione standard, l’ATR tiene conto dei gap tra una sessione e l’altra — ed è proprio questa la sua caratteristica distintiva.
Il True Range (TR) non è semplicemente High − Low. Wilder capì che i gap notturni fanno parte del rischio reale. Quindi il TR è il massimo tra tre misure:
high − low: escursione interna alla barra,
high − close[1]: gap verso l’alto rispetto alla chiusura precedente,
low − close[1]: gap verso il basso rispetto alla chiusura precedente
In pratica, su mercati con molti gap (come le azioni overnight) l’ATR è più affidabile della σ per dimensionare il rischio reale.
L’ATR (Average True Range) misura la volatilità come media mobile (spesso esponenziale) del True Range. L’ATR è quindi calcolato come media del TR su un certo numero di periodi, tipicamente 14, ed è espresso in punti (o, se normalizzato, in percentuale). Un valore di ATR elevato indica una volatilità crescente, mentre un ATR basso segnala una fase di mercato più compressa. Per questo motivo l’ATR è ampiamente utilizzato per definire stop loss dinamici (ad esempio 2 × ATR) e target profit coerenti con la volatilità corrente.
// Strategia esempio con ATR codice CAMBIATO
// Parametri
atrPeriod = 14
atrMultStop = 2.0 // stop loss = 2 × ATR
atrMultTarget = 3.0 // target profit = 3 × ATR
// Calcolo ATR
atrValue = atr[atrPeriod]
// Condizione di ingresso long (esempio molto semplice)
if close crosses over average[20](close) and not onmarket then
buy 1 contract at next open
endif
// Gestione uscita con ATR
if longOnMarket then
// Stop loss dinamico: prezzo di ingresso - 2 × ATR
set stop loss atrValue * atrMultStop
// Target profit dinamico: prezzo di ingresso + 3 × ATR
set target profit atrValue * atrMultTarget
endif§ 14.3 – ADX
In ProRealTime l’ADX (Average Directional Index) è un indicatore sviluppato sempre da J. Welles Wilder nel suo libro del 1978 dal titolo “New Concepts in Technical Trading Systems” e serve a misurare la forza di un trend, indipendentemente dalla sua direzione.
L’ADX fa parte del sistema Directional Movement di Wilder ed è composto da tre elementi:
+DI (Positive Directional Indicator) → misura la forza rialzista
-DI (Negative Directional Indicator) → misura la forza ribassista
ADX → misura la forza complessiva del trend
L’ADX viene calcolato utilizzando il True Range e i movimenti direzionali positivi e negativi.
Un ADX sopra 30 indica che il mercato è in una fase di trend forte e ben definito. L’ADX (Average Directional Index) non fornisce informazioni sulla direzione del trend, ma ne misura l’intensità: valori bassi (sotto 20–25) segnalano un mercato laterale o debole, mentre valori sopra 30 confermano la presenza di un movimento direzionale significativo. Per questo motivo molti trader sistematici usano l’ADX come filtro per attivare o disattivare strategie trend-following, evitando di operare in fasi di mercato troppo piatte.
Importante è anche l’osservazione del +DI e del −DI, le due linee direzionali che accompagnano l’ADX. Il +DI (Positive Directional Indicator) riflette la forza del movimento al rialzo, mentre il −DI (Negative Directional Indicator) misura la forza del movimento al ribasso. L’incrocio tra +DI e −DI viene spesso utilizzato come segnale di ingresso: ad esempio, un incrocio del +DI sopra il −DI può indicare l’inizio di un trend rialzista, mentre l’incrocio opposto suggerisce una possibile inversione al ribasso. Tuttavia, questi segnali sono generalmente più affidabili quando confermati da un ADX elevato, che attesta la presenza di un trend effettivamente forte.
§ 14.4 – Canali di Keltner
I Canali di Keltner sono indicatori di volatilità formati da una EMA centrale e due bande (±2 ATR), usati per breakout trend e squeeze (compressione di volatilità).
Si distinguono dalle Bollinger per la reattività all’ATR invece che Standard Deviation.
myATR = averageTrueRange[10](close)
keltnerMiddle = exponentialAverage[20](close)
keltnerUpper = keltnerMiddle + 2 * myATR
keltnerLower = keltnerMiddle - 2 * myATREcco la formula con cui sono costruiti i canali di Keltner:
periodMA = 20
periodATR = 10
k=2
MA = exponentialAverage[periodMA](typicalPrice)
upperBand = MA + k*averageTrueRange[periodATR](typicalPrice)
lowerBand = MA - k*averageTrueRange[periodATR](typicalPrice)
return MA AS "Keltner MA" , UpperBand AS "Keltner Upper Band" , LowerBand as "Keltner Lower Band"§ 14.5 – Canali di Donchian
I Canali di Donchian, sviluppati da Richard Donchian, sono uno strumento di analisi tecnica utilizzato per identificare trend, breakout e livelli dinamici di supporto e resistenza.
Il canale è composto da tre linee:
Banda Superiore: massimo più alto degli ultimi N periodi.
Banda Inferiore: minimo più basso degli ultimi N periodi.
Linea Centrale: media tra la banda superiore e quella inferiore.
periodo = 20
upperBand = highest[periodo](high)
lowerBand = lowest[periodo](low)
middleBand = (upperBand + lowerBand) / 2
return upperBand COLOURED(0,128,255) STYLE(LINE,2),
middleBand COLOURED(255,165,0) STYLE(LINE,1),
lowerBand COLOURED(0,128,255) STYLE(LINE,2)Gli utilizzi più comune sono:
– utilizzare le bande superiori ed inferiori per identificare livelli di breakout del prezzo,
– utilizzare le bande come filtro di volatilità: solo se tra le due bande ci sono determinati punti allora possiamo entrare.
Vediamo un utilizzo dei canali usati come filtro di volatilità:
periodo = 20
rangeMinimo = 100
upperBand = highest[periodo](high)
lowerBand = lowest[periodo](low)
ampiezzaCanale = upperBand - lowerBand
filtroVolatilita = ampiezzaCanale > rangeMinimoCapitolo 15: Pivot point
I Pivot Points sono uno strumento classico dell’analisi tecnica, molto usato dai trader intraday per avere dei riferimenti precisi su dove il prezzo potrebbe trovare supporto o resistenza durante la giornata.
In pratica, partendo dai dati della sessione precedente (massimo, minimo e chiusura), si calcolano:
– un punto centrale (il Pivot Point principale, PP),
– una serie di livelli di resistenza sopra di esso (R1, R2, R3…),
– una serie di livelli di supporto sotto di esso (S1, S2, S3…).
Graficamente, questi livelli appaiono come linee orizzontali sul grafico e fungono da zone dove il prezzo potrebbe reagire.
§ 15.1 – Pivot point standard
Il metodo più comune è quello dei Pivot Points standard (in ProRealTime abbiamo anche altre tipi di pivot come i pivot Fibonacci, Camarilla…).
Per i vari tipi di calcolo si utilizzano i valori della candela giornaliera precedente:
H = massimo (high)
L = minimo (low)
C = chiusura (close)
Le formule principali utilizzate nella versione standard sono:
PP (Pivot Point) = (H + L + C) / 3
R1 = (2 × PP) − L
R2 = PP + (H − L)
R3 = H + 2 × (PP − L)
S1 = (2 × PP) − H
S2 = PP − (H − L)
S3 = L − 2 × (H − PP)
Questi livelli vengono poi proiettati sulla seduta successiva come possibili zone di supporto/resistenza: se il prezzo apre sopra il PP, il sentiment della giornata tende a essere considerato rialzista; se apre sotto, ribassista.
I livelli R1, R2, R3 agiscono come resistenze: zone dove il prezzo potrebbe frenare o invertire al rialzo.
I livelli S1, S2, S3 agiscono come supporti: zone dove il prezzo potrebbe trovare acquisto o rimbalzo
Calcolo Base (Standard)
Pivot Point (PP) = (high + low + close) / 3
Primo Livello:
R1 = (2 × PP) - low
S1 = (2 × PP) - high
Secondo Livello:
R2 = PP + (high - low)
S2 = PP - (high - low)Ecco un esempio di utilizzo:
if close > R1 and RSI[14] > 70 then
sell short at market // Ritracciamento atteso
endifPivot Point personalizzati:
inizio = 090000
fine = 130000
if openTime = inizio them
myOpen = open
myHigh = high
myLow = low
myClose = close
endif
if openTime >= inizio and openTime <= fine them
myHigh = max(myHigh,high)
myLow = min(myLow,low)
myClose = close
endif
// Pivots
Pivot = (High + Low + Close) / 3 //Pivot
//
ResR1 = Pivot + (Pivot - myLow)
ResR2 = Pivot + (myHigh - myLow)
ResR3 = myHigh + (2 * (Pivot - myLow))
//
SupS1 = Pivot - (myHigh - Pivot)
SupS2 = Pivot - (myHigh - myLow)
SupS3 = myLow - (2 * (myHigh - Pivot))
return Pivot AS "Pivot",ResR1 AS "R1",ResR2 AS "R2",ResR3 AS "R3",SupS1 AS "S1",SupS2 AS "S2",SupS3 AS "S3"Capitolo 16: Filtri
Nel contesto di un trading system, un filtro è una regola che affianca le condizioni principali di entrata e stabilisce se un segnale debba essere eseguito oppure ignorato e non genera un segnale operativo autonomo.
Un filtro è una condizione aggiuntiva che deve essere soddisfatta perché un segnale operativo venga eseguito. Serve a selezionare le situazioni ritenute più favorevoli e a escludere, per quanto possibile, i trade di qualità inferiore.
I pericoli principali di aggiungere filtri al sistema sono:
– pericolo dell’overfitting (in particolare se si usano troppi filtri insieme),
– pericolo di snaturare la natura del trading system se il filtro è troppo invasivo e va a limitare troppo le logiche di entrata del sistema.
Un filtro quindi, dato che aggiunge complessità, va usato con delle motivazioni precise. Al di là del tipo di filtro comunque lo scopo è ridurre il numero di operazioni e cercare di aumentare la qualità dei segnali.
§ 16.1 – Filtri temporali
Limitazioni orarie: alcuni sistemi ottengono risultati migliori operando solo in determinate fasce orarie; altri, invece, rendono meglio senza limitazioni. In ProRealTime, è possibile definire gli orari di operatività con la funzione Time.
Nel seguente esempio, il sistema apre posizioni long solo in alcune fasce orarie e posizioni short in fasce diverse:
cTimeLong = time >= 090000 and time <= 170000
cTimeShort = time >= 000000 and time <= 230000Il filtro delle ore del giorno è il più classiico dei filtri ed in pratica viene quasi sempre aggiunto ad un sistema.
Tra i filtri temporali rientra anche la selezione dei giorni in cui operare.
Come per le fasce orarie, non sempre è conveniente mantenere il sistema attivo tutti i giorni: alcuni sistemi, per esempio, possono ottenere risultati migliori escludendo il lunedì o il venerdì.
Vediamo come scrivere una riga di codice per impedire al sistema di operare il lunedi:
if not onMarket and cLong and dayOfWeek <> 1 thenIl concetto di filtro temporale si lega a quello di BIAS.
Un bias è un comportamento ricorrente che accade con regolarità e che possiamo sfruttare. Un bias importante è quello delle ore del giorno o dei giorni della settimana.
Il bias risponde alla domanda: in quali orari un mercato tende a salire ed in quali a correggere? Ci sono dei giorni della settimana in cui è conveniente andare prevalentemente long o in cui non è conveniente operare?
Vediamo un esempio concreto sul bias giornaliero sullo strumento Dax. Ecco i risultati di un sistema che compra ogni giorno il cfd sul Dax (1 euro a punto, timeframe orario) alle ore 08:00 e lo rivende alle ore 22:00.

Si vede chiaramente che nei primi tre giorni della settimana (gg = 1 lunedi, gg = 2 martedi …) il Dax ha un bias giornaliero rialzista mentre il giovedi ed il venerdi ha una tendenza giornaliera ribassista (periodo dal 2018 al 2026).
Un altro bias importante su cui si possono costure dei filtri temporali è il concetto di “stagionalità”. Con questo termine ci riferiamo alla tendenza dei mercati a mostrare comportamenti ricorrenti in determinati periodi dell’anno. Sono noti comportamenti specifici delle commodity legati ai cicli produttivi e alle stagioni climatiche ad esempio.
Un esempio classico di bias legato alla stagionalità sulle commodity è il comportamento del petrolio, che tende sistematicamente a rialzarsi da metà febbraio a maggio e a scendere da ottobre a fine dicembre.
§ 16.2 – Filtri di volatilità
Un filtro di volatilità si utilizza all’interno di una strategia di trading per isolare le condizioni di mercato ideali. Il suo scopo principale è duplice: evitare i “falsi segnali” durante le fasi di mercato laterale (bassa volatilità) e proteggere il capitale durante le fasi di espansione del prezzo (alta volatilità).
In parole semplici, risponde alla domanda: “Il mercato si sta muovendo abbastanza per giustificare l’apertura di una posizione?”, oppure:
“La volatilità è sufficientemente contenuta da consentire l’apertura di una posizione senza esporsi a un rischio eccessivo?”
Consideriamo un semplice filtro basato sul range: si definisce un’ampiezza minima che il mercato deve aver raggiunto in un determinato intervallo di tempo. Per esempio, il sistema opera solo se, nelle ultime 40 barre, il mercato si è mosso di almeno 50 punti.
period = 40
minLevel = 50*pointSize
amplitudeRange = highest[period](high)-lowest[period](low)
cMinRange = amplitudeRange > minLevelEcco un filtro basato sull’average true range: verifica che la volatilità recente non sia troppo bassa per giustificare un’operazione. Il sistema prende in considerazione il segnale solo quando l’ATR a 40 barre supera la soglia minima impostata.
period = 40
minATR = 10 * pointSize
cMinVolatility = averageTrueRange[period](close) > minATR§ 16.3 – Filtri di trend
Molti trading system tendono a ottenere risultati migliori quando operano nella direzione del trend dominante, anziché contro di esso. Un filtro di trend serve a verificare la direzione del mercato e a consentire l’apertura di posizioni solo quando il segnale è coerente con tale direzione, escludendo così alcune operazioni potenzialmente sfavorevoli.
I principali strumenti per identificare il trend sono le medie mobili come abbiamo indicato nella sezione indicatori. Senza confondere segnali di entrata ed uscita di un TS dati dalle medie (livelli, cross…) prendiamo qui due semplici concetti che possiamo utilizzare come filtri: la distanza dalla media e la pendenza.
Non sempre è sufficiente sapere dove si trova il prezzo rispetto alla media mobile. In alcuni casi è utile verificare che la media sia sufficientemente distante dal prezzo.
Questo approccio evita di considerare trend validi situazioni in cui il prezzo si trova appena sopra una media sostanzialmente piatta.
// Calcolo della media mobile
myAvg = average[20](close)
// Distanza assoluta (in punti)
distanza = abs (close - myAvg) // abs è il valore assoluto che rimuove il segno + / -
// Distanza percentuale (%)
distanzaPct = (abs((close - myAvg) / myAvg) * 100Un altro filtro che si usa spesso per capire la reale forza di un mercato è l’Adx.
L’Adx (Average Directional Index) misura la forza del trend senza indicarne la direzione.
adxValue = ADX[14]
strongTrend = adxValue > 30 § 16.4 – Pendenza e filtri angolari
Oltre alla distanza del prezzo da una media mobile, un altro importante filtro di trend è rappresentato dalla pendenza della media stessa. La pendenza fornisce infatti un’indicazione diretta della forza e della direzione del movimento in atto.
In questo esempio, il filtro confronta il valore attuale della media mobile a 20 periodi con il valore assunto dalla stessa media 10 barre prima.
Se la media attuale è superiore a quella di 10 barre fa, la pendenza è positiva e suggerisce un contesto rialzista; viceversa, una pendenza negativa indica un possibile indebolimento del trend o una fase ribassista.
ma = average[20](close)
bullTrend = ma > ma[10]Oltre alla semplice direzione della media mobile, è possibile utilizzare un filtro angolare per misurare l’intensità del trend. L’idea è che non basta sapere se una media sta salendo o scendendo: è utile anche valutare quanto rapidamente lo stia facendo.
In ProRealTime possiamo calcolare la pendenza perrcentuale della media mobile MM20 ed utilizzarla per filtrare il trend:
MM20 = average[20](close)
// Calcolo della variazione percentuale della MM20 tra il valore attuale e quello di 10 barre fa, divisa per 10 per ottenere la variazione media per barra
slopePct = ((MM20 - MM20[10]) / MM20[10]) * 100 / 10
bullTrend = slopePct > 0.05
bearTrend = slopePct < -0.05In questo caso slopePct esprime la variazione percentuale media per barra.
La soglia 0.05 significa che la MM20 deve salire mediamente di oltre lo 0,05% per barra per considerare il trend rialzista.
Capitolo 17: Snippets Code
Quando sviluppiamo un trading system, non è necessario riscrivere ogni volta tutto il codice da zero. Possiamo infatti utilizzare blocchi di codice già pronti, testati e riutilizzabili, da integrare all’interno dei nostri sistemi.
Questo approccio consente di risparmiare tempo, ridurre la possibilità di errori e mantenere il codice più ordinato e facilmente modificabile. Filtri di trend, gestione del rischio, condizioni di ingresso, uscite e funzioni di supporto possono essere salvati e riutilizzati ogni volta che servono.
In pratica, questi moduli diventano una vera e propria cassetta degli attrezzi del trader sistematico: componenti affidabili che possono essere combinati tra loro per costruire nuovi sistemi in modo più rapido ed efficiente.
Rimandiamo alla snippet library in proRealCode per una lista esaustiva di codici: https://docs.google.com/spreadsheets/d/1rgboqj7sVwsP9ZRhOduOefye48QMWC07jWVXCl-KJPU/edit?pli=1&gid=0#gid=0
In questa sezione vedremo alcuni snippet pronti all’uso dedicati al trade management. Ogni esempio affronta uno specifico aspetto della gestione delle posizioni e può essere utilizzato come base per sviluppare sistemi più complessi in modo rapido ed efficiente.
§ 17.1 – Max Monetary Daily Loss
Nella progettazione di un trading system, uno degli aspetti più importanti è la gestione del rischio giornaliero. Tra i parametri fondamentali rientra la massima perdita consentita in una giornata, cioè il limite oltre il quale il sistema deve interrompere l’operatività per evitare che una sequenza sfavorevole comprometta in modo eccessivo il capitale.
La massima perdita giornaliera non rappresenta soltanto una protezione del capitale, ma anche uno strumento di disciplina operativa. Impedisce infatti di continuare a operare in condizioni di stress, sovraesposizione o eccessiva fiducia dopo una serie di risultati negativi. In questo modo, il sistema diventa più ordinato, controllabile e sostenibile nel tempo.
In questo snippet il sistema smette di operare su base giornaliera (riprende quindi le operazioni il giorno dopo) se nella gioranata si presentano perdite complessive superiori ad un certo importo. È importante sottolineare che questo codice non chiude le posizioni già aperte: si limita a impedire l’apertura di nuovi trade dopo il raggiungimento del limite di perdita giornaliero.
maxDailyLoss = 200
floatingPosition = positionPerf*positionPrice/pointSize*pointValue
once tradeAllowed = 1
if intradayBarIndex = 0 then
myProfit = strategyProfit
tradeAllowed = 1
endif
if (strategyProfit + floatingPosition) <= (myProfit - maxDailyLoss) then
tradeAllowed = 0
endif§ 17.2 – Singola operazione intraday
Quando si sviluppa un trading system, non è sufficiente stabilire le condizioni di ingresso e di uscita. È altrettanto importante definire quante operazioni il sistema può eseguire in una singola giornata.
Limitare il numero di trade consente di controllare il rischio, evitare fenomeni di overtrading e adattare meglio il comportamento della strategia al contesto di mercato. In molti casi, un semplice limite giornaliero può migliorare sensibilmente la stabilità dei risultati e la qualità complessiva dell’operatività.
Un sistema che esegue poche operazioni tende a essere più selettivo e spesso punta a cogliere movimenti più chiari e affidabili. Al contrario, un sistema con molte operazioni può sfruttare più opportunità di mercato, ma è anche più esposto a costi di transazione, rumore di mercato e sequenze di perdite. Per questo motivo, il conteggio delle operazioni giornaliere diventa un parametro fondamentale sia nella progettazione sia nella valutazione di una strategia.
Questo semplice snippet permette di eseguire un solo trade al giorno.
Abbiamo visto all’inizio di questa guida queste fondamentali funzioni che ripassiamo velocemente.
Con barIndex – tradeIndex(1) calcoliamo quante barre fa è stato aperto l’ultimo trade. Se barIndex, che è il contatore complessivo, è 1000 e tradeIndex(1), ultimo trade, è 950, allora l’ultimo trade è stato aperto 50 barre fa.
IntradaybarIndex ci dice invece quante barre sono trascorse oggi. Se intradayBarIndex è uguale a 30, vuol dire che oggi sono passate 30 barre. Poichè 30 è meno di 50 vuol dire che l’ultimo trade è stato aperto ieri ed oggi quindi è permesso ancora un trade.
OTD = (barIndex - tradeIndex(1) > intradayBarIndex) § 17.3 – Numero di operazioni
Con questo snippets stabiliamo invece quante operazioni fare al giorno.
Limitare il numero di operazioni al giorno può rendere il sistema più selettivo, consentendogli di concentrarsi sui segnali potenzialmente più interessanti e riducendo l’impatto dei trade di minor qualità.
Questo codice serve a limitare il numero di operazioni giornaliere a un massimo di 5 operazioni:
once maxTrades = 5 //maxNumberDailyTrades
once nTrades = 0
if intradayBarIndex = 0 then
nTrades = 0
endif
newTrades = (onMarket and not onMarket[1]) or ((not onMarket and not onMarket[1]) and (strategyProfit <> strategyProfit[1])) or (longOnMarket and ShortOnMarket[1]) or (longOnMarket[1] and shortOnMarket) or ((tradeIndex(1) = tradeIndex(2)) and (barIndex = tradeIndex(1)) and (barIndex > 0) and (strategyProfit = strategyProfit[1]))
if newTrades then
nTrades = nTrades +1
endif
if mieCondizioni and nTrades < maxTrades then...NEWTRADES è uno snippet sviluppato dal moderatore del forum ProRealCode, Roberto Gozzi, che consente di identificare e conteggiare correttamente le operazioni eseguite da una strategia.
Il codice rileva diverse situazioni operative, tra cui:
– l’apertura di una nuova posizione;
– la chiusura di una posizione con conseguente variazione del profitto della strategia;
– il passaggio diretto da una posizione Short a una Long;
– il passaggio diretto da una posizione Long a una Short;
– il rilevamento di un nuovo trade tramite la variabile tradeIndex.
In altre parole, lo snippet è progettato per individuare qualsiasi evento che corrisponda all’avvio di una nuova operazione o a una transizione tra operazioni, comprese situazioni particolari come le reversal o i casi in cui ProRealTime aggiorna alcune variabili con un ritardo di una barra.
Grazie a questo approccio, il conteggio delle operazioni risulta più affidabile rispetto ai metodi tradizionali e può essere utilizzato come base per implementare filtri sul numero massimo di trade, statistiche operative o regole avanzate di gestione della strategia.
§ 17.4 – Numero di operazioni perdenti
In alcuni casi può essere utile non limitare il numero totale di operazioni, ma soltanto il numero di trade in perdita. Questo approccio consente al sistema di continuare a sfruttare eventuali opportunità profittevoli, interrompendo invece l’operatività quando viene raggiunto un determinato numero di operazioni negative.
once nLoss = 0 //maxNumberDailyLosses
nMaxLosses = 3
if intradayBarIndex = 0 then
nLoss=0
endif
if strategyProfit < strategyProfit[1] then
nLoss = nLoss +1
endif
if mieCondizioni and nLoss < nMaxLosses then
// Istruzioni di ingresso
endif§ 17.5 – Numero di operazioni “New Instructions”
Per determinare quante operazioni fare durante la singola giornate di trading, possiamo anche utilzzare questo nuovo snippet scritto con le nuove istruzioni di PRT con cui possiamo anche separare il numero di operazioni long e short.
Ecco il riferimento:
https://www.prorealcode.com/topic/new-trading-instructions-better-management-of-your-orders/
Questo codice è progettato per consentire al massimo un’operazione long e un’operazione short per ogni giornata di trading. Una volta eseguito un trade long, il sistema non potrà aprire ulteriori posizioni long fino alla sessione successiva; lo stesso principio si applica alle posizioni short.
once maxOrdersL = 1 //max-Orders per Day
once maxOrdersS = 1
if intradayBarIndex = 0 then //reset orders count
ordersCountL = 0
ordersCountS = 0
endif
if longTriggered then //check if an order has opened in the current bar
ordersCountL = ordersCountL + 1
endif
if shortTriggered then //check if an order has opened in the current bar
ordersCountS = ordersCountS + 1
endifQuesto è il codice complessivo senza distinzioni long e short.
// Numero massimo di operazioni giornaliere
once maxOrders = 3
// Reset del contatore all'inizio della giornata
if intradayBarIndex = 0 then
ordersCount = 0
endif
// Conteggio dei nuovi ingressi
if newTrades then
ordersCount = ordersCount + 1
endif
// Ingresso long
if close crosses over average[50](close) and not onMarket and ordersCount < maxOrders then
buy 1 contract at market
endif
// Ingresso short
if close crosses under average[50](close) and not onMarket and ordersCount < maxOrders then
sellShort 1 contact at market
endif
// Target e stop loss
set target pprofit 100
set stop pLoss 100§ 17.6 – Barre di attesa tra operazioni
In alcuni casi, attendere un determinato intervallo di tempo tra un’operazione e la successiva può portare benefici significativi alle performance del sistema.
Questo approccio contribuisce a ridurre l’overtrading, evitando ingressi troppo ravvicinati quando il mercato è ancora caratterizzato dalla stessa dinamica che ha appena generato l’uscita.
Inoltre, può migliorare la qualità media dei trade, perché costringe la strategia ad attendere la formazione di un nuovo contesto operativo invece di inseguire movimenti di breve durata o segnali generati dal rumore di mercato.
In molti sistemi, un semplice periodo di attesa tra due operazioni consecutive rappresenta un filtro efficace per aumentare la selettività e rendere l’operatività più stabile e robusta nel tempo.
Il codice serve a introdurre un periodo di attesa di 10 barre dopo un evento operativo, prima di consentire una nuova entrata:
once barCount = 0
waitingBars = 10 //barsToWaitAfterTrade
once tradeCount = 1
newTrades = (onMarket and not onMarket[1]) or ((not onMarket and not onMarket[1]) and (strategyProfit <> strategyProfit[1])) or (longOnMarket and ShortOnMarket[1]) or (longOnMarket[1] and shortOnMarket) or ((tradeIndex(1) = tradeIndex(2)) and (barIndex = tradeIndex(1)) and (barIndex > 0) and (strategyProfit = strategyProfit[1]))
if newTrades then
tradeCount = 0
barCount = 0
endif
if not onMarket then
barCount = barCount + 1
endif
if barCount > waitingBars then
tradeCount = 1
endifCapitolo 18: Backtest
Un trading system è un insieme strutturato di regole che definiscono in modo preciso quando entrare, quando uscire e come gestire una posizione sui mercati finanziari. In altre parole, trasforma le decisioni di trading da discrezionali (basate su intuizione o esperienza) a oggettive e ripetibili.
La forza principale di un trading system è la possibilità di analizzare il comportamento che ha avuto nel passato per capire se certe tecniche, sistemi, pattern che si utilizzano hanno un reale vantaggio operativo.
Questo aspetto è molto meno banale di quanto possa sembrare. Spesso si è convinti, a livello intuitivo, della validità di una determinata idea operativa, salvo poi scoprire, attraverso analisi approfondite e test rigorosi, che il vantaggio atteso in realtà non esiste o risulta troppo debole per essere sfruttato in modo affidabile.
Lo strumento che abbiamo per capire se la nostra strategia ha un effettivo edge (vantaggio) sul mercato, e in che cosa consiste questo vantaggio, è il backtest.
§ 18.1 – Backtest
Un backtest è la simulazione di un sistema di trading su dati storici, eseguita prima di impiegare capitale reale sui mercati. Il suo scopo non è dimostrare che il sistema “funziona”, bensì analizzarne il comportamento in differenti condizioni di mercato e comprenderne punti di forza e debolezza.
L’aspetto più importante non è il profitto ottenuto nel passato, ma la capacità di valutare se i risultati osservati derivano da un vantaggio statistico reale e ripetibile oppure da circostanze favorevoli e casuali. In altre parole, il backtest serve a verificare se le condizioni che hanno generato le performance sono strutturali e robuste o semplicemente il frutto del caso.
L’overfitting (o sovra-ottimizzazione) è probabilmente il problema più insidioso nel trading algoritmico. È la trappola in cui cadono molti trader, anche esperti, dovuto a un eccessivo adattamento ai dati storici. Ciò può avvenire in diversi modi:
– troppi parametri o variabili che tendono a identificare correlazioni spurie nei dati storici, scambiando fluttuazioni casuali per regole valide,
– ottimizzazione eccessiva dei parametri, si ottimizzano dettagli irrilevanti come micro-oscillazioni o eventi isolati,
– utilizzo di campioni storici troppo brevi o limitati a specifiche condizioni di mercato, con il rischio di sovrastimare la robustezza del sistema.
Per limitare il rischio di overfitting, la semplicità rappresenta uno dei fattori più importanti nella costruzione di sistemi robusti.
Una strategia basata su una logica chiara, comprensibile e supportata da pochi parametri tende ad adattarsi meglio alle inevitabili variazioni del mercato rispetto a un sistema eccessivamente complesso e fortemente ottimizzato sui dati storici.
Quando eseguiamo un backtest la cosa più importante da capire prima di tutto il resto è la separazione tra “In-Sample (IS)” e “Out-of-Sample (OOS)”.
Il periodo IS è quello su cui si sviluppa e si ottimizza la strategia; il periodo OOS è quello su cui la si valida, senza mai toccarla. Un sistema che funziona bene solo in IS è probabilmente vittima di overfitting, ha imparato ad adattarsi al rumore del passato, ma non possiede una logica di mercato.
§ 18.2 – Cosa dimostra un backtest
Che cosa dimostra realmente un backtest? Una risposta provocatoria potrebbe essere: nulla. Per quanto un test storico possa essere accurato e per quanto ci si impegni a evitare l’overfitting, rimane un limite inevitabile: stiamo sempre analizzando dati del passato.
Questo è un punto concettuale fondamentale, che va ben oltre la questione tecnica dell’overfitting. Riguarda la natura stessa del backtest ed i suoi limiti strutturali.
Il dato fondamentale è che il futuro può discostarsi eccessivamente dai dati del passato in quanto il mercato è un sistema adattivo complesso, composto da milioni di agenti umani, ed oggi soprattutto algoritmici.
Una strategia backtestata in un periodo di trend potrebbe essere costruita su quel trend senza che il sistema lo sappia. Quando il regime cambia, la strategia crolla, o come si dice tecnicamente, decade. Il backtest assume implicitamente una certa stabilità statistica, ma quella stabilità spesso non esiste in quanto ci sono eventi che il backtest non può catturare.
Alcuni fenomeni sono per definizione irripetibili o imprevedibili:
– Cigni neri (Taleb): eventi estremi con bassa probabilità ma alto impatto. Il backtest li include solo se sono già accaduti nel periodo testato,
– Cambiamenti strutturali: l’introduzione degli ETF, del trading ad alta frequenza (HFT), delle criptovalute hanno cambiato profondamente i mercati,
– Interventi delle banche centrali: il QE post-2008 ha creato oltre un decennio di mercati anomali, difficilmente replicabili,
– Crisi uniche: il Covid del 2020, il flash crash del 2010, il crollo di Lehman nel 2008 sono eventi con dinamiche irripetibili.
C’è anche un problema opposto, quando si trova qualcosa che funziona e viene adottata da molti, allora smette di funzionare.
Quando un’inefficienza del mercato viene scoperta e sfruttata massicciamente, il mercato si adatta e l’inefficienza scompare. Il backtest non può modellare questo fenomeno, perché al momento del test la strategia era ancora poco utilizzata.
Le inefficienze che offrivano opportunità negli anni ’90 non sono necessariamente le stesse che esistono oggi. Molte di esse sono state progressivamente arbitraggiate, altre sono semplicemente scomparse con l’evoluzione dei mercati.
§ 18.3 – Il regime di mercato
Un regime di mercato è lo stato strutturale in cui si trova un mercato finanziario in un determinato periodo di tempo. È l’ambiente operativo entro cui si svolgono i movimenti di prezzo: capire in quale regime ci si trova è fondamentale perché strategie efficaci in un regime tendono a fallire in un altro.
L’idea centrale è che i mercati non si comportano in modo uniforme nel tempo. Al contrario, attraversano fasi caratterizzate da dinamiche differenti e relativamente persistenti, comunemente definite regimi di mercato.
Ogni regime presenta caratteristiche specifiche in termini di trend, volatilità, liquidità e correlazione tra gli asset. Una strategia che genera ottimi risultati in un determinato contesto può quindi mostrare prestazioni molto diverse quando il mercato entra in un regime differente.
Elenchiamo per semplicità quattro dimensioni del regime:
– Direzione: il mercato sale, scende o si muove lateralmente? È la dimensione più ovvia. Le medie mobili sono lo strumento di riferimento per identificare la direzione,
– Forza: quanto è intenso il movimento direzionale? Un trend forte e uno debole richiedono strategie diverse. L’ADX è lo strumento classico per misurarlo: valori sopra 25 indicano un trend definito, sotto 20 un mercato senza direzione chiara,
– Volatilità: quanto ampie sono le oscillazioni di prezzo? In un regime ad alta volatilità il rischio aumenta e i livelli di stop-loss vanno adeguati. Le Bande di Bollinger e l’ATR sono i riferimenti principali,
– Correlazione tra asset: in certi regimi (tipicamente nelle crisi) gli asset tendono a muoversi all’unisono verso il basso. La correlazione tra mercati è essa stessa un segnale di regime.
Il regime è il contesto che determina quale strategia ha senso applicare.
Un trader di momentum guadagnerà in un trend forte ma perderà in un mercato laterale. Viceversa, un trader di mean-reversion sarà redditizio in mercati laterali, ma subirà perdite se il mercato rompe e sviluppa un trend.
Questo dimostra che un sistema, dato che è costruito con una certa logica non può guadagnare sempre, ma dovrebbe performare bene quando il mercato si adatta ai suoi principi e tenere sotto controllo il rischio quando cambiano le condizioni di mercato.
Alcuni esempio chiariscono meglio questi concetti.
Per quanto riguarda la direzione, come dicevamo, si usa principalmente la posizione di alcune medie mobili importanti che vengono prese come riferimento. Ecco un semplice schema:
MA50 = average[50](Close)
MA200 = average[200](Close)
if close > MA50 and MA50 > MA200 then
// regime rialzista → favorire il long
elsif close < MA50 and MA50 < MA200 then
// regime ribassista → favorire lo short o stare fuori dal mercato
else
// zona di transizione → massima cautela
endifUno degli strumenti più utilizzati per misurare la forza di un trend è l’ADX. A differenza di molti indicatori trend-following, l’ADX valuta esclusivamente l’intensità del movimento, senza distinguere tra trend rialzista e ribassista. Per approfondire il suo funzionamento rimandiamo alla sezione dedicata agli indicatori.
valoreADX = ADX[14]
if valoreADX > 25 then
// regime di trend → usare una strategia trend following
elsif valoreADX < 20 then
// regime laterale → usare una strategia mean reverting
endifPer misurare la volatilità in genere si utilizza la standard deviation.
In questo esempio confrontiamo la volatilità attuale con la sua media storica.
// Volatilità normalizzata
volAttuale = stdDev[20](close)
volMedia = average[100](stdDev[20](close))
volRatio = volAttuale / volMedia
//Valori > 1.5: la volatilità attuale è del 50% superiore alla sua media storica (fase di mercato turbolenta o breakout).
if volRatio > 1.5 then
// alta volatilità → ridurre esposizione
elsif volRatio < 0.7 then
// bassa volatilità → regime tranquillo
endif§ 18.4 – Limiti del regime
Il discorso sui regimi è sicuramente utile in quanto ci fornisce un immagine più concreta della natura mutevole del mercato e del modo di affrontarla.
Il problema è che nel mercato, a differenza delle stagioni, non sappiamo mai in anticipo quando cambia il regime, ma lo sappiamo solo a posteriori.
Di conseguenza, anche il rilevamento dei regimi soffre dello stesso limite del backtest: tutti gli indicatori di regime guardano inevitabilmente al passato.
In ogni caso il concetto di regime di mercato ci porta a una visione più matura e umile del trading sistematico: non esiste una strategia per tutte le stagioni: il mercato è un sistema vivo che cambia.
Il miglior trader sistematico non è chi trova la strategia perfetta, ma chi costruisce un sistema adattivo capace di sopravvivere ai cambi di regime, e di limitare i danni quando il regime non è riconoscibile.
È essenziale comprendere che la costante evoluzione dei mercati rende inevitabile il decadimento delle strategie. Quando un sistema perde la capacità di adattarsi, la sospensione è l’unica scelta corretta: nessun modello è eterno.
Per questo è importante avere un certo numero di sistemi, meglio se:
– su diversi strumenti,
– su diversi orizzonti temporali,
– costruiti con logiche differenti (trend following, mean reverting,…).
In pratica, finché un sistema conserva il proprio vantaggio competitivo e riesce ad assecondare le variazioni di regime, rimane attivo. Quando non lo fa più, va messo in panchina, proprio come farebbe un allenatore con un giocatore in calo di forma, e sostituito con un modello adatto alla nuova fase di mercato
In definitiva, il vero obiettivo nello sviluppo di trading system non è la ricerca di un irrealizzabile Sacro Graal, bensì la costruzione di strategie robuste (capaci di performare su dati mai visti), adattive (capaci di adattarsi alla mutevolezza dei regimi di mercato) e resilienti (in grado di sopportare i periodi di perdita).
§ 18.5 – Tipi di perdite in un TS
La gestione delle operazioni perdenti è la vera sfida fondamentale nella costruzione di un trading system e, più in generale, nell’attività di trading. Accettare le perdite è un concetto fisiologico che sembra ovvio in teoria, ma che si rivela difficilissimo all’atto pratico. La maggior parte dei trader fa di tutto per evitarle: dall’evitare del tutto l’uso dello stop loss, fino al modificarlo o revocarlo non appena il prezzo comincia ad avvicinarsi.
Ma perché accade questo? Le ragioni risiedono in una combinazione di trappole psicologiche e dinamiche statistiche:
– A livello emotivo lo stop loss viene vissuto come la certificazione di un errore personale, e la mente umana ha un’innata resistenza ad ammettere di aver sbagliato. Inoltre lo stop loss trasforma una perdita virtuale in un danno definitivo. Questo genera un dolore psicologico reale, ma il nostro cervello è biologicamente programmato per sfuggire al dolore (tanto che molti sostenitori della finanza comportamentale affermano che la mente umana non sia strutturata per fare trading),
– A livello statistico si verifica di frequente il cosiddetto effetto “beffa”: subito dopo la chiusura in stop, il mercato si riallinea nella direzione originaria e la posizione sarebbe risultata profittevole. Ciò genera sfiducia nell’efficacia dello stop loss (spesso posizionato senza un criterio tecnico solido) e lascia spazio all’illusione che attendere porti al recupero.
Purtroppo, quando nel trading subentra la speranza, significa che si è perso il controllo: una deriva da evitare in ogni modo per preservare il capitale.
Un motivo fondamentale e ampiamente sottovalutato del fatto che non si rispettano gli stop loss è la dimensione della size nel trading in rapporto al capitale utilizzato. Con una size contenuta l’impatto economico della perdita diminuisce e il peso emotivo della speranza è minore, facilitando un comportamento più disciplinato.
Ciò mette in luce due verità strutturali: la maggior parte dei trader opera sottocapitalizzata rispetto all’esposizione assunta e ignora una corretta gestione della leva finanziaria, trasformando uno strumento di opportunità in un fattore di rischio non controllato.
Nei sistemi di trading abbiamo la fortuna che la componente emotiva che ostacola l’utilizzo degli stop loss non è presente, tuttavia questo non significa che il trader sistematico è disposto a prendere le perdite senza contraccolpo emotivo in quanto una perdita monetaria è sempre una perdita sia discrezionale che sistematica!
Il trader sistematico potrebbe spegnere il sistema quando questo entra in una fase negativa prolungata… Anche in questo caso il sovradimensionamento è una delle cause principale che portano a bloccare prematuramente un sistema prima di una motivazione tecnico-razionale: in pratica si guarda il profitto-perdite invece che il funzionamento del sistema.
Dobbiamo quindi rivedere e riclassificare il problema dele perdite nei trading system in questo modo:
Loss fisiologico: il trade rispetta le regole e la performance rimane entro i limiti statistici attesi, quindi il sistema non si deve bloccare e se lo facciamo è per errori di size management.
Loss strutturale: il mercato è cambiato e l’edge del sistema si è deteriorato. In questo caso la motivazione è tecnica e dobbiamo spegnere il sistema.
In questo caso dobbiamo avere regole precise di quando stoppare un sistema e ciò deve essere compatibile con la nostra situazione finanziaria: fermiamo un sistema perchè non funziona più e non perchè perdiamo troppo!
Come possiamo distinguere un loss fisiologico da un loss strutturale?
Sul singolo trade è impossibile distinguerli. Un loss isolato non dice nulla in quanto anche un sistema eccellente con un win/rate del 60% perde 4 volte su 10. Il mercato ha una componente stocastica irriducibile: il singolo trade è casuale.
Su una serie di trades con grandi campioni di dati emergono invece dei segnali.
– Indicatori che il loss è “fisiologico” (rumore di mercato):
Le perdite rientrano nella distribuzione storica del sistema (drawdown entro i parametri attesi)
Il pattern di trade vincenti/perdenti è casuale, non clusterizzato in modo anomalo
Le metriche aggregate (win rate, profit factor, average win/loss ratio) restano stabili
Le perdite avvengono in condizioni di mercato che il sistema ha già “visto”
– Indicatori che il sistema sta smettendo di funzionare:
Il drawdown supera significativamente il massimo storico in backtest
Il profit factor scende stabilmente sotto 1 su finestre rolling
La distribuzione delle perdite cambia forma (più frequenti, o più grandi del solito)
Le perdite si concentrano in condizioni di mercato specifiche e ricorrenti
Il mercato sottostante ha subito un regime change strutturale (volatilità, liquidità, correlazioni)
Il vero problema: il bias del sopravvissuto al contrario
C’è un rischio simmetrico e sottovalutato:
Interrompere troppo presto un sistema in drawdown fisiologico: perdi i trade recupero
Continuare troppo a lungo un sistema che è broken: accumuli perdite evitabili
La maggior parte dei trader retail sbaglia nel primo senso (troppa impazienza). I sistematici esperti rischiano il secondo (troppa fede nel backtest).
Capitolo 19: Ottimizzazione
Nel contesto dei trading system, l’ottimizzazione è il processo con cui si cercano i valori dei parametri che fanno funzionare meglio una strategia sui dati storici.
§ 19.1 – Ottimizzazione classica
Un trading system dispone di solito di alcuni parametri modificabili: i periodi degli indicatori, le soglie di ingresso, lo stop loss, il take profit, i filtri temporali e così via. Con l’ottimizzazione si testa una gamma di valori per ciascun parametro, si simula il sistema sui dati storici e si seleziona la combinazione che produce i risultati migliori secondo un criterio prestabilito.
Un criterio basato sul basso drawdown, ad esempio, è spesso preferibile a uno che privilegia i parametri con il massimo profitto: consente infatti al sistema di sopravvivere nel tempo e di affrontare le fasi avverse senza essere interrotto prematuramente.
Un altro criterio è la robustezza dei parametri. Come vedremo più dettagliatamente nella quarta parte, con la creazione di un sistema di prova, è preferibile selezionare un intervallo di valori che mantenga risultati stabili in diverse zone, anziché puntare su un singolo picco di performance.
Esistono diversi tipi di ottimizzazione. La più semplice è quella classica, che ricerca i parametri migliori, indipendentemente dal criterio utilizzato, impiegando un unico blocco di dati.
Si prende l’intero storico disponibile e si cerca la combinazione di parametri che massimizza un criterio scelto, come il profitto netto, il profit factor o un drawdown contenuto.
Il vantaggio principale è la semplicità: alla fine si ottiene una sola configurazione “migliore”, calcolata sull’intero campione storico.
In questo tipo di ottimizzazione stiamo implicitamente assumendo che:
– il passato sia omogeneo
– il mercato sia stazionario
– l’edge sia stabile nel tempo
Tuttavia i mercati reali non funzionano così.
Un altro limite di questa ottimizzazione unitaria è concettuale: stiamo usando gli stessi dati sia per scegliere i parametri sia per giudicare il sistema, quindi il rischio di overfitting è alto. In definitiva il risultato può sembrare molto buono solo perché il sistema è stato adattato troppo bene al passato. Stiamo mediando regimi incompatibili, per cui uno stop può essere troppo largo per un perido di bassa volatilità o troppo stretto per un periodo di alta volatilità, in pratica non distinguiamo regimi di mercato.
§ 19.2 – Testare singoli periodi
Invece di ottimizzare i parametri su tutto lo storico disponibile (in-sample unico), possiamo dividere lo storico anno per anno (come esempio) e ottimizzare i parametri separatamente per ciascun anno.
Differenza rispetto al walk-forward classico: mentre il walk-forward tradizionale impiega una finestra di ottimizzazione fissa che avanza nel tempo con incrementi prestabiliti, testando fuori campione il periodo immediatamente successivo, l’approccio basato su singole finestre temporali (ad esempio coincidenti con gli anni di calendario) permette di segmentare l’analisi in modo più intuitivo, facilitando l’interpretazione visiva e il confronto dei risultati tra periodi distinti.
Con l’ottimizzazione annuale possiamo vedere se i parametri sono stabili, oppure migrano continuamente. Nel blocco unico, ad esempio, un grande bull market può dominare tutto. Ottimizzando anno per anno invece ogni regime pesa di più individualmente.
Suddividendo lo storico in anni possiamo osservare semplicemente:
– il decadimento di un sistema negli anni,
– come migrano i parametri,
– la sensibilità alla volatilità,
– analisi dei regimi,
– capire la natura dell’hedge.
Ottimizzare anno per anno usando solo dati in-sample è già meglio dell’ottimizzazione “monoblocco”, ma resta un approccio con un limite importante; manca la validazione.
Manca l’out of sample, ma questo approccio può essere un ottimo filtro preliminare: se un sistema non mostra alcuna stabilità neppure anno per anno, quasi certamente non sopravviverà al test out of sample.
l seguente codice permette di identificare singoli anni o intervalli temporali personalizzati, inclusi periodi parziali. Le variabili generate possono essere impiegate nelle condizioni di ingresso della strategia per eseguire analisi mirate su specifiche porzioni dello storico.
year2026 = date >= 20260101 and date <= 20261231
year2025 = date >= 20250101 and date <= 20251231
year2024 = date >= 20240101 and date <= 20241231
year2023 = date >=20230101 and date <= 20231231
year2022 = date >=20220101 and date <= 20221231
year2021 = date >= 20210101 and date <= 20211231
year2020 = date >= 20200101 and date <= 20201231
// per testare il singolo anno basta scrivere:
if year2025 then
if not onMarket and cLong then
buy 1 contract at market
endif
endifOppure se pensiamo di usare l’intero anno:
anno = 2025
yearSelected = date >= anno * 10000 + 101 AND date <= anno * 10000 + 1231
if yearSelected then
if not onMarket and cLong then
buy 1 contract at market
endif
endifUn approccio professionale richiede l’integrazione di entrambe le tipologie di analisi:
– Analisi In-Sample (IS): studio approfondito dei parametri, valutazione della stabilità del modello e analisi del comportamento nei diversi regimi di mercato.
– Validazione Out-of-Sample (OOS): verifica rigorosa della robustezza attraverso test OOS, analisi walk-forward, simulazioni Monte Carlo e monitoraggio delle performance in forward test live.
§ 19.3 – Walk-Forward Analysis (WFA)
La walk forward analysis (WFA) parte dall’idea che il mercato cambi nel tempo, quindi un sistema va testato come se fosse sviluppato e utilizzato in sequenza temporale.
È la tecnica più avanzata per testare la robustezza parametrica. Invece di ottimizzare una volta su tutto lo storico, o su parti complete di storico, si divide la storia in finestre temporali (occorrenze): si ottimizza su una finestra, si testa sulla successiva e così via.
Se i parametri ottimali cambiano radicalmente da una finestra all’altra, il sistema è fragile.
La Walk Forward Analysis aiuta a risolvere il problema fondamentale dell’overfitting: un sistema ottimizzato su tutta la serie storica è quasi certamente adattato al rumore di quei dati, non alle strutture di mercato reali.
La Walk-Forward Analysis (WFA) suddivide lo storico in una serie di finestre temporali scorrevoli. In ciascuna finestra, la strategia viene ottimizzata esclusivamente sui dati In-Sample (IS) e successivamente validata sui dati immediatamente successivi, non utilizzati durante l’ottimizzazione, definiti Out-of-Sample (OOS).
Il processo viene quindi ripetuto avanzando progressivamente nel tempo, replicando in modo realistico il ciclo operativo di un trader che sviluppa, aggiorna e applica il sistema in condizioni reali di mercato.
La Walk-Forward Analysis non rappresenta un’alternativa all’ottimizzazione completa, bensì uno strumento di validazione successivo. L’ottimizzazione globale consente di identificare configurazioni potenzialmente efficaci sulla totalità dei dati storici, mentre la Walk-Forward Analysis verifica se tali configurazioni rimangono robuste quando vengono applicate a dati mai utilizzati durante l’ottimizzazione. In altre parole, l’ottimizzazione misura il passato, mentre la Walk-Forward cerca di simulare il futuro.
§ 19.4 – Il concetto di “Out of sample”
I risultati out of sample (dati fuori dal campione di ottimizzazione, ossia nuovi) nella WFA si interpretano come il vero test di robustezza della strategia: non misurano quanto il sistema si adatta ai dati usati per ottimizzarlo, ma quanto riesce a comportarsi bene su dati successivi, mai “visti” in fase di taratura.
Il punto di base con la WFA non è solo controllare se l’out of sample è profittevole, ma quanto degrada rispetto al periodo in-sample. Se il sistema resta simile per qualità, drawdown e stabilità, è un segnale positivo; se invece crolla, è probabile che l’ottimizzazione abbia catturato rumore e non una vera inefficienza di mercato.
Se l’out of sample mantiene una parte ragionevole delle performance in-sample, la strategia ha più probabilità di essere robusta. Se invece l’in-sample è eccellente ma l’OOS è quasi piatto o negativo, il sistema è molto probabilmente sovraottimizzato.
L’in-sample serve a trovare una configurazione plausibile, mentre l’out of sample serve a capire se quella configurazione ha un vantaggio che sopravvive al tempo.
Uno degli errori più comuni consiste nel valutare una strategia esclusivamente sulla base del risultato finale ottenuto nel periodo Out-of-Sample (OOS). È invece preferibile analizzare l’insieme delle finestre walk-forward, poiché lo scopo principale della Walk-Forward Analysis (WFA) è verificare se il vantaggio della strategia si manifesta in modo coerente e ripetibile nel tempo, anziché dipendere da una singola fase di mercato particolarmente favorevole.
I singoli segmenti out of sample vanno letti come mini-test indipendenti della strategia: ogni segmento ci dice come il sistema si comporta in un tratto di mercato successivo a quello usato per l’ottimizzazione. Non vanno giudicati solo dal profitto finale, ma soprattutto dalla coerenza tra un segmento e l’altro. Un singolo segmento positivo non è sufficiente: conta se i risultati si ripetono con una certa regolarità.
Se un segmento OOS è leggermente peggiore dell’in-sample ma resta profittevole e con drawdown accettabile, di solito è un segnale positivo. Se invece uno o più segmenti crollano, o mostrano performance molto diverse tra loro, significa che la strategia è probabilmente troppo sensibile ai parametri o alle condizioni di mercato.
La Walk-Forward Analysis può essere distinta in concatenata e non concatenata.
– nella WFA concatenata sommiamo progressivamente tutti i risultati delle varie finestre, creando un’unica curva di equity,
– nella WFA non concatenata ogni periodo viene valutato separatamente e viene misurata la robustezza della strategia nei singoli periodi.
In ProRealTime si utilizzano di base 5 occorrenze con un rapporto IS/OSS di 70/30.
Si ottimizza il 70% di ogni finestra e poi si usano i parametri migliori trovati (in ogni finestra) nel 30% dei dati di quella specifica finestra (parte OOS).
In questo modo è possibile valutare se quel set di dati ottimizzati regge nel 30% restante della finestra.
In ProRealTime, nel metodo walk-forward non ancorato, ogni nuovo ciclo utilizza come base di partenza una finestra temporale che include progressivamente il precedente periodo Out-of-Sample (OOS). Di conseguenza, le finestre In-Sample (IS) e Out-of-Sample (OOS) dei cicli successivi tendono a sovrapporsi temporalmente.
Per questo nel grafico osserviamo una sola grande area IS iniziale e una sequenza di aree OOS; le finestre IS successive risultano infatti sovrapposte ai periodi già rappresentati e non vengono evidenziate separatamente.
Un test Walk-Forward non concatenato in ProRealTime può essere considerato affidabile quando soddisfa una serie di criteri di robustezza e coerenza tra le diverse finestre di analisi.
In primo luogo, la performance Out-of-Sample (OOS) dovrebbe conservare una quota significativa dei risultati ottenuti In-Sample (IS): è spesso auspicabile che il risultato OOS raggiunga almeno il 50% della performance IS, corrispondente a una Walk-Forward Efficiency (WFE) superiore al 50-60%.
Un altro aspetto fondamentale è la distribuzione dei risultati tra le diverse finestre OOS. La maggior parte dei segmenti dovrebbe risultare profittevole e, idealmente, non si dovrebbe riscontrare più di una finestra negativa ogni cinque analizzate.
L’obiettivo non è ottenere un unico risultato finale positivo, ma verificare che il vantaggio della strategia si manifesti con una certa regolarità nel tempo.
È inoltre importante che le performance mostrino una buona continuità tra un periodo e l’altro. Differenze moderate sono normali, poiché i mercati evolvono continuamente, ma la presenza di forti deterioramenti o di singoli segmenti particolarmente negativi può indicare una scarsa robustezza del sistema.
Anche la stabilità dei parametri ottimizzati rappresenta un elemento chiave della valutazione. Se i parametri cambiano drasticamente da una finestra all’altra per mantenere la redditività, si è spesso in presenza di un fenomeno di overfitting, ovvero di un eccessivo adattamento ai dati storici.
Infine, osservando i risultati complessivi delle finestre OOS, l’equity dovrebbe mostrare una tendenza crescente nel lungo periodo, pur attraversando normali fasi di drawdown. Una crescita progressiva e relativamente regolare costituisce uno dei segnali più importanti della presenza di un vantaggio statistico reale e potenzialmente sfruttabile anche in condizioni operative future.
§ 19.5 – Diversificazione
La diversificazione è un concetto ben noto negli investimenti tradizionali, pensiamo alla diversificazione di portafoglio.
Questo concetto assume un’importanza ancora maggiore nel trading algoritmico.
Ogni trading system attraversa inevitabilmente fasi di espansione e fasi di difficoltà.
Un sistema trend following può soffrire durante i mercati laterali, mentre una strategia mean reverting può incontrare problemi nelle fasi di forte direzionalità. Affidare tutto il capitale a una sola logica operativa significa accettare che i risultati complessivi dipendano interamente dalla capacità di quel sistema di adattarsi alle condizioni di mercato future.
Diversificare significa invece distribuire il rischio tra strategie differenti, mercati differenti e, quando possibile, timeframe differenti. L’obiettivo non è massimizzare il rendimento del singolo sistema, ma ridurre la dipendenza da una specifica condizione di mercato. Quando una strategia entra in drawdown, un’altra potrebbe trovarsi nella sua fase migliore, contribuendo a stabilizzare l’andamento complessivo del portafoglio.
Vediamo le più comuni forme di diversificazione:
– Diversificazione per mercato: il primo livello di diversificazione consiste nel operare su diverse classi di attività: azioni e indici (equity), valute (forex), materie prime come oro e petrolio (commodity) e criptovalute (crypto). Ogni mercato presenta dinamiche proprie di volatilità e correlazione; pertanto, una crisi localizzata in un settore non dovrebbe compromettere l’intero portafoglio.
– Diversificazione per strategia: rappresenta il cuore della diversificazione.
Le tre famiglie principali sono:
Trend following: sfrutta i movimenti direzionali prolungati, entrando nella direzione del momentum prevalente.
Mean reverting: punta al ritorno del prezzo verso una media o un valore di equilibrio, operando in presenza di eccessi temporanei.
Breakout: entra quando il prezzo rompe un range di consolidamento o un livello tecnico significativo.
Queste logiche hanno basi strutturali diverse e tendono quindi a generare drawdown in momenti differenti: quando una strategia è in perdita, le altre possono contribuire a compensare.
– Diversificazione per timeframe: un sistema intraday (M5–M15) reagisce rapidamente ai micro-movimenti ma è molto esposto ai costi di transazione. Un sistema swing (H4–D1) ha meno operazioni e cattura movimenti più grandi.
Avere sistemi su timeframe diversi riduce la concentrazione del rischio in una sola “finestra temporale” di mercato. Ogni timeframe “vive” infatti su una scala temporale diversa del mercato. I partecipanti che muovono i prezzi su M5 sono spesso diversi da quelli che operano su D1 o W1.
Attenzione alla over-diversification: un numero eccessivo di sistemi con logiche simili crea un’illusione di sicurezza: diluisce i rendimenti, aumenta i costi operativi e non riduce realmente il rischio. Il numero ottimale di sistemi non dipende tanto dalla quantità, quanto dalla loro decorrelazione effettiva: cinque sistemi genuinamente indipendenti possono essere più utili di venti sistemi basati su logiche analoghe.
Un altro errore comune è sottovalutare la correlazione implicita. Nelle fasi di mercato estremo come crisi, crolli improvvisi o flash crash, le correlazioni tra asset tendono a convergere, riducendo temporaneamente l’efficacia della diversificazione tra mercati diversi. Per questo motivo, la diversificazione per logica operativa è generalmente la più robusta: sistemi costruiti su meccanismi diversi tendono a reagire in modo meno omogeneo anche durante gli shock.
Con queste considerazioni abbiamo terminato la parte teorica necessaria per la comprensione di quello che è un trading system e di quello che realmente può fare nel mercato.
Nella quarta parte vedremo come costruire in pratica un sistema in ProRealTime.
