Esistono differenze significative tra un trading system genetico ed uno tradizionale?
Un trading system tradizionale è generalmente basato su un insieme di regole e indicatori predefiniti che sono stati scelti dal trader, o da un team di analisti, in base all’esperienza e alle conoscenze del mercato. Questo tipo di sistema di solito richiede una conoscenza approfondita del mercato stesso e una grande quantità di analisi per identificare le opportunità di compravendita. Si può partire da un’idea, da un paper o da un codice disponibile, per raffinarlo a step successivi.
Un trading system genetico, invece, utilizza algoritmi di machine learning per identificare le regole di trading migliori in modo autonomo. Questi algoritmi creano una popolazione di strategie di trading e le fanno evolvere attraverso iterazioni successive, in cui le strategie con i migliori risultati vengono selezionate per la generazione successiva. Questo processo di evoluzione genetica consente al sistema di adattarsi alle condizioni di mercato in continua evoluzione e di produrre regole di trading migliori nel tempo.
Una delle principali differenze tra i due tipi di trading system è che un trading system genetico è in grado di gestire una quantità maggiore di dati rispetto a un sistema di trading tradizionale. Inoltre, il trading system genetico è in grado di adattarsi alle condizioni di mercato in evoluzione in modo molto più rapido ed efficace rispetto a un sistema di trading tradizionale, sia pure manutenuto nel tempo. Ciò non vale se parliamo di trading system genetici “statici”, che cioè non vengono ri-ottimizzati su base periodica.
Se parliamo di algoritmi genetici applicati alla creazione di trading system, possiamo scomporre come di seguito gli elementi costitutivi:
- Inizializzazione: a. Si genera una popolazione iniziale di strategie di trading casuali (individui). b. Si imposta il numero di generazioni e i parametri dell’algoritmo genetico (probabilità di crossover, probabilità di mutazione, ecc.).
- Valutazione: a. Si valuta la performance di ogni strategia nella popolazione utilizzando dati storici e una metrica di fitness (ad esempio, PnL, Sharpe ratio, ecc.). b. Si ordinano le strategie in base alla loro fitness.
- Selezione: a. Si selezionano le strategie migliori (i genitori) in base alla loro fitness, utilizzando metodi come la selezione proporzionale alla fitness, la selezione tramite torneo o la selezione per rango.
- Crossover (ricombinazione): a. Si accoppiano i genitori selezionati e si applicano l’operatore di crossover per generare nuove strategie (i figli). b. Si possono utilizzare diversi metodi di crossover, come il crossover a punto singolo, il crossover a due punti o il crossover uniforme.
- Mutazione: a. Si applica l’operatore di mutazione ai figli con una certa probabilità. b. La mutazione può essere applicata modificando i parametri delle strategie o cambiando le regole di trading.
- Sostituzione: a. Si sostituiscono le strategie meno performanti nella popolazione con i nuovi figli generati. b. Si mantengono le strategie migliori nella popolazione per garantire che la fitness complessiva aumenti nel tempo (elitismo).
- Controllo di terminazione: a. Si verifica se è stato raggiunto il numero massimo di generazioni. b. Se non è stato raggiunto, si torna al passo 2 (valutazione). c. Se è stato raggiunto, si termina l’algoritmo genetico.
- Estrazione del risultato: a. Si seleziona la strategia con la migliore fitness dalla popolazione finale come risultato ottimale.
E se per sistema “tradizionale” ci riferissimo ad un trading system quantitativo, cosa cambierebbe nel confronto con i sistemi genetici?
Entrambi sono approcci “algoritmici” per il trading sui mercati finanziari, ma differiscono nella metodologia e nella filosofia sottostante.
- Un trading system quantitativo si basa su modelli matematici e statistici per analizzare i dati di mercato e generare segnali di trading. Questo approccio è spesso utilizzato in combinazione con le scienze informatiche e la ricerca finanziaria per sviluppare strategie di trading basate su regole ben definite.
- I modelli quantitativi possono essere basati su vari fattori, come l’analisi tecnica, l’analisi fondamentale, i dati macroeconomici e le informazioni sul “sentiment” di mercato.
- Queste strategie sono spesso testate su dati storici per verificare la loro efficacia e ottimizzate prima di essere implementate sul mercato in tempo reale.
- I trading system quantitativi possono essere più veloci e meno complessi rispetto ai sistemi genetici, ma potrebbero non essere in grado di adattarsi alle mutevoli condizioni del mercato nella stessa misura.
In sintesi, i trading system genetici e quantitativi rappresentano due approcci algoritmici distinti. Mentre i sistemi genetici utilizzano algoritmi basati sull’evoluzione per trovare le strategie di trading ottimali, i sistemi quantitativi si basano su modelli matematici e statistici per analizzare i dati di mercato e generare segnali di trading. Entrambi gli approcci hanno vantaggi e svantaggi, e il successo dipende dalla capacità del trader di applicare e gestire correttamente le strategie sviluppate.
Tuttavia esiste un massimo comune denominatore che rappresenta il principale demone di un trading system: la ricerca della “robustezza” o “robustness“.
Ci si riferisce alla capacità di un trading system di mantenere un livello di performance accettabile di fronte a condizioni di mercato diverse e mutevoli, e di produrre risultati coerenti su dati sia conosciuti (storici) che sconosciuti (futuri). Un trading system robusto è in grado di adattarsi e funzionare in modo efficace in diversi scenari di mercato, riducendo il rischio di perdite dovute a cambiamenti imprevisti nelle condizioni di mercato.
Per migliorare la robustezza di un trading system, è possibile considerare i seguenti elementi:
- Diversificazione: Un trading system robusto dovrebbe essere in grado di operare su più mercati o asset class, riducendo il rischio di dipendere da un singolo mercato o da condizioni specifiche di mercato.
- Adattabilità: Un sistema robusto dovrebbe essere in grado di adattarsi alle mutevoli condizioni del mercato. Ciò può essere ottenuto utilizzando algoritmi che apprendono e si adattano ai dati, come le reti neurali o gli algoritmi genetici.
- Semplicità: Un sistema di trading robusto dovrebbe essere semplice e basato su regole chiare e ben definite. Sistemi complessi e sovra-ottimizzati possono funzionare bene sui dati storici ma fallire quando applicati a dati futuri sconosciuti.
- Walk-forward testing: Questa metodologia di testing implica la divisione del campione di dati storici in diversi segmenti temporali, ognuno dei quali viene utilizzato per ottimizzare e testare il sistema di trading. Il processo viene ripetuto, “camminando in avanti” nel tempo, e consente di valutare la performance del sistema su diversi periodi e condizioni di mercato.
- Cross-validation: La cross-validation è una tecnica di convalida del modello che prevede la divisione del campione di dati in diversi sottoinsiemi, utilizzando alcuni di questi per addestrare il sistema e gli altri per testarne le prestazioni. Questo processo viene ripetuto più volte, utilizzando diverse combinazioni di dati di addestramento e di test, per valutare la robustezza del sistema.
- Out-of-sample testing: Per verificare la robustezza di un trading system, è importante testarlo su dati “out-of-sample”, ovvero su dati non utilizzati durante la fase di ottimizzazione del sistema. Ciò aiuta a valutare la capacità del sistema di generalizzare e adattarsi a nuove condizioni di mercato.
- Controllo del rischio: Un trading system robusto dovrebbe includere meccanismi di controllo del rischio, come la gestione delle posizioni, il calcolo del rischio per trade e l’utilizzo di stop loss e take profit. Queste misure aiutano a limitare le perdite e a mantenere la stabilità del sistema durante periodi di volatilità del mercato. Ovviamente, a seconda delle caratteristiche del singolo sistema, è possibile fare a meno di uno o di tutti questi elementi.
Incorporando questi tasselli nel processo di sviluppo e ottimizzazione di un trading system, è possibile aumentarne la robustezza e migliorare le sue prestazioni su dati sconosciuti e in condizioni di mercato mutevoli.
Esistono poi alcuni algoritmi specifici che possono aumentare la probabilità di persistenza delle performance di un sistema di trading: i modelli di validazione periodica (come la GSA) e l’operatività statistica (che associa una probabilità a ciascun trade).
Partiamo da un esempio che utilizza il nuovo motore genetico Akira (scritto in Julia e fornito all’interno del Modulo 4 della Machine Learning Academy).
L’asset di analisi è il titolo Apple (ticker AAPL) con un lotto di 10000$ ad operazione e 40$ di costi fissi round turn. Abbiamo applicato un approccio genetico basato su prezzi e derivata dei prezzi. Chiediamo al motore di generare un sistema long (solo trade al rialzo), ordini market e uscite a tempo, senza stop-loss.
I parametri genetici prevedono un DNA ad unico cromosoma caratterizzato da tre regole elementari, 1000 trader per 100 generazioni (per un totale di 100000 combinazioni). Come Fitness Function abbiamo utilizzato il Profit Factor con soglia minima a 0.8.
Per la validazione abbiamo diviso lo storico, distribuito tra il 2000 e marzo 2023, tra un 70% di Training (In Sample) e il 30% più recente come Test (Out of Sample).
Facciamo partire il processo evolutivo e già dopo la prima generazione notiamo una buona dinamica, che continua anche oltre la linea rossa su dati non conosciuti dalla macchina. Il Profit Factor del miglior rappresentante di tale generazione (primo per Profit Factor tra 1000 rappresentanti) vale 1.61 (al netto dei costi fissi).

In generazione 2 il Profit Factor passa a 1.62, eppure quella piccola differenza si declina, nella prima fase del training (2000-2006), in una maggiore erraticità, ma anche in una migliore performance nel periodo di test (oltre la linea rossa).

Dobbiamo attendere la generazione 74 per portarci ad un Profit Factor di 2.03. La forma della curva di equity in training è di gran lunga la più regolare, tuttavia, se guardiamo la sola fase di test, le performance sono meno vivaci.

Uno degli output più interessanti prodotti dal motore genetico è il profilo della curva di evoluzione: in ascissa il numero delle generazioni ed in ordinata la fitness function (in questo caso il Profit Factor). All’aumentare delle generazioni assistiamo ad un miglioramento progressivo della fitness. Per lunghi periodi tale miglioramento non avviene poi, improvvisamente il crossover e la mutazione danno vita ad una nuova classe di individui più “capaci”.

Ma quale degli individui sarà più robusto in futuro?
Per rispondere a tale quesito passiamo all’applicazione di un modello ad operatività statistica (integrato dentro il motore Akira): associamo il 90% di probabilità ad ogni trade di avvenire e rilanciamo la medesima simulazione.
Il miglior rappresentante della prima generazione ha delle zone di sofferenza tra il 2001 e il 2004 oltre che un brusco draw down nel 2011.

In generazione 7 le cose iniziano a migliorare e cambia completamente l’andamento della curva di equity in test.

Tale miglioramento prosegue in generazione 12, dove assistiamo anche ad una diminuzione della varianza in out of sample.

Ad un quarto dell’elaborazione (generazione 25) registriamo un profit factor di 2.05 e la curva si conferma particolarmente appetibile.

L’ultimo step evolutivo porta il profit factor a 2.10.

La curva di evoluzione testimonia l’approccio statistico: la tendenza al miglioramento è visibile, ma meno estremizzato e ci consente di muoverci in un intorno, senza dover selezionare per forza il miglior organismo. Ora di generazione in generazione è possibile attingere anche a classi di organismi sub-ottimi ed è possibile un peggioramento delle prestazioni, esattamente come avviene con gli algoritmi di “Gradient Descend”.

Infine possiamo ordinare per “robustness” le auto-soluzioni prodotte, che rappresentano gli individui in grado di superare il test dell’out of sample. Non è dunque il miglior individuo per fitness (“score”) a garantire la migliore tenuta, ma uno sciame di individui sub-ottimi che risultano più resistenti alle mutevoli condizioni di mercato. Non a caso molte di queste soluzioni vengono determinate nelle prime generazioni. Nella tavola potete trovare anche la regola di compravendita decodificata:
Nel caso del rappresentante della generazione 12 (Profit Factor di 1.84) sono state selezionate le regole 1940-3363-1010 che corrispondono al seguente setup:
avg_price(0) > high(3) and med_body_price(4) > bbl50(3) and low(0) > sma5(2)

Uno degli elementi di progetto più importanti che può aiutare nella generazione di sistemi durevoli è il basket di regole elementari (geni) cui la macchine possa attingere. Possiamo passare da prezzi ed indicatori statistici a classificatori, trasformazioni algoritmiche ecc.
Se avete apprezzato questo articolo e avete voglia di approfondire questi temi in modo professionale, potete valutare gli acceleratori didattici di punta tenuti da Gandalf Project e sempre disponibili:
- La Machine Learning Academy :un percorso di 12 settimane dedicato ad Analisi Quantitativa e Intelligenza Artificiale, passando dal Supervised Learning, all’Unsupervised Learning fino alla codifica di tecniche di Reinforcement Learning. All’interno del Modulo 4, invece, dedichiamo ben due settimane all’approfondimento e alla codifica in Python e Julia degli Algoritmi Evolutivi e in particolare modo dell’utilizzo degli Algoritmi Genetici per la codifica di trading system su asset di diversa natura e time frame.
- La Python Academy: un percorso di 16 settimane dedicato all’applicazione dell’analisi quantitativa mediante codifica in Python di sistemi di analisi dei dati, backtest e validazione di trading system e sistemi di investing, equity & performance control, aggregazione di portafogli di trading system e di asset e andata mercato diretta in Python.
Buona evoluzione e buon trading!
Giovanni Trombetta
Founder – Head of R&D Gandalf Project
chatGPT4
OpenAI