In questo corso presentiamo un processo statisticamente solido per prevedere le serie temporali finanziarie. Queste previsioni costituiscono la base per un insieme di strategie di trading automatico. La prima lezione del corso introduce le tecniche di forecasting e un insieme di algoritmi di classificazione utili per stimare la direzione del mercato.
Durante il corso utilizziamo scikit-learn, una libreria di apprendimento automatico per Python. Scikit-learn offre molte tecniche di forecasting e di machine learning già implementate. Questo approccio ci fa risparmiare tempo, riduce il rischio di bug derivanti dal nostro codice e permette confronti con librerie sviluppate in altri linguaggi come R. In questo modo possiamo creare versioni personalizzate, soprattutto se vogliamo migliorare la velocità di esecuzione.
Tecniche di Forecasting
Il machine learning statistico sfrutta tecniche di forecasting come la Logistic Regression (regressione logistica), la Linear Discriminant Analysis (analisi della discriminante lineare) e la Quadratic Discriminant Analysis (analisi della discriminante quadratica). Per questo motivo conviene delineare alcuni concetti fondamentali.
Tecniche di Apprendimento Supervisionato
Le tecniche di Supervised Learning lavorano su un insieme noto di tuple \((x_i, y_i)\), \(i \in \{1,…,N \}\), dove xi indica le variabili predittive (come i ritorni di mercato o il volume scambiato) e yi rappresenta la risposta osservata (ad esempio il rendimento giornaliero del mercato azionario).
In questo contesto puntiamo alla previsione. Date le future variabili predittive, vogliamo stimare le risposte corrispondenti. Questo approccio differisce dall’inferenza, in cui ci concentriamo sulle relazioni tra le variabili.
Tutti gli algoritmi trattati in questa lezione, insieme ad altri che useremo in futuro, rientrano nel dominio dell’apprendimento supervisionato.
Misurare l’Accuratezza della Previsione
Ci concentriamo su una particolare classe di tecniche di forecasting: la classificazione binaria. In pratica, classifichiamo il rendimento percentuale di una giornata in due categorie: “Up” o “Down”. Nei sistemi previsionali reali, ci interessa valutare sia l’entità della previsione che le deviazioni rispetto al valore reale.
In questi casi, possiamo usare Mean-Squared Error, Mean Absolute Deviation e Root-Mean-Squared Error per stimare la precisione delle previsioni. La letteratura presenta molti altri esempi di metodi per valutare l’accuratezza della previsione.
In questa lezione ci focalizziamo su due metriche: l’Hit-Rate, ovvero la percentuale di previsioni corrette effettuate dal forecaster, e la Confusion Matrix (nota anche come matrice di confusione), che permette di valutare le prestazioni del modello predittivo. Inoltre, calcoliamo questi valori e li integriamo nella ricerca dei segnali di trading.
Hit Rate
La domanda più semplice che possiamo porre al nostro classificatore supervisionato è: “In quante occasioni abbiamo previsto correttamente la direzione, in percentuale sul totale delle previsioni?”. Questo porta alla definizione del tasso di successo dell’allenamento, espresso dalla formula seguente:
\(\frac{1}{n} \sum_{i=1}^{n} I(y_i = \hat{y_i})\)
Qui yi rappresenta la previsione (UP o DOWN) per il giorno i usando un dato classificatore. La funzione \(I(y_i = \hat{y_i})\) è un’indicatore: vale 1 se \(y_i = \hat{y_i}\), altrimenti vale 0.
L’Hit Rate indica quindi in percentuale quante volte un classificatore ha previsto correttamente la direzione del mercato. Scikit-learn include una funzione per calcolare il tasso di successo all’interno del processo di classificazione e addestramento.
Confusion Matrix
La matrice di confusione (o tabella di contingenza) è il passo successivo dopo aver calcolato il tasso di successo. È motivato da domande come “Quante volte l’UP è stato previsto correttamente mentre quante volte è stato previsto correttamente il DOWN?”.
Ad esempio, potrebbe risultare che un particolare algoritmo è costantemente più accurato nel prevedere i “giorni down”. Ciò motiva una strategia che enfatizza la necessità di andare short su uno strumento al fine di aumentare il profitto.
Una matrice di confusione caratterizza questa idea determinando il tasso di falsi positivi (noto statisticamente come errore di Tipo I) e tasso di falsi negativi (noto statisticamente come errore di Tipo II) per un classificatore supervisionato. Nel caso della classificazione binaria (UP o DOWN) si ha una matrice 2×2:
\( \begin{pmatrix}U_{T}&U_{F}\\D_{F}&D_{T}\end{pmatrix} \)
Dove Ut rappresenta i periodi Up correttamente classificati, Uf rappresenta quelli erroneamente classificati (cioè classificati come down), Df rappresenta i periodi Down classificati erroneamente (cioè classificati come Up) e Dt rappresenta i periodi Down correttamente classificati.
Oltre all’Hit-Rate, Scikit-Learn fornisce un metodo per calcolare la matrice di confusione, come parte del processo di classificazione / addestramento.
Fattori di previsione
Uno degli aspetti cruciali delle tecniche di forecasting dei prezzi degli asset riguarda la scelta dei fattori utilizzati come predittori. Troviamo un numero impressionante di potenziali fattori tra cui scegliere, e per chi non ha familiarità con le previsioni finanziarie il compito può risultare scoraggiante. Tuttavia, anche le tecniche più semplici di machine learning offrono risultati relativamente validi quando applichiamo fattori selezionati con attenzione.
Scegliamo i fattori cercando di identificare gli elementi fondamentali che influenzano il movimento degli asset. Nel caso dell’S&P500, risulta evidente che i 500 titoli che lo compongono, ponderati in modo appropriato, rappresentano i principali driver del prezzo! Quando conosciamo il valore istantaneo dei suoi componenti, vogliamo prevedere il prezzo esatto della serie S&P500, ma possiamo sfruttare la storia dei rendimenti dei singoli costituenti per prevedere l’intera serie?
In alternativa, consideriamo i tassi di cambio con paesi che commerciano intensamente con gli Stati Uniti come possibili driver del prezzo. Possiamo anche includere fattori economici e aziendali più fondamentali come i tassi d’interesse, l’inflazione, i profitti trimestrali. La precisione del modello di previsione dipende in gran parte dalla nostra abilità nel selezionare i fattori giusti prima di adattare il modello.
Fattori di prezzi ritardati e volumi
Come primo tipo di fattore da considerare nella previsione delle serie temporali, utilizziamo i valori storici della stessa serie. Otteniamo quindi un insieme di fattori p creando p ritardi dei prezzi di chiusura della serie. Per una serie temporale giornaliera, al giorno k associamo i fattori corrispondenti ai valori nei giorni k-1, k-2, …, k-p.
Oltre ai prezzi, integriamo anche il volume degli scambi, informazione disponibile nei dati OHLCV (ad esempio da Yahoo Finance, Google Finance o Quandl). In questo modo costruiamo un vettore di dimensione p+1 per ogni giorno, che include i p ritardi temporali più il volume. Otteniamo così un insieme di coppie (Xk, yk) dove Xk rappresenta il vettore dei fattori al giorno k e yk indica il prezzo di chiusura reale di quel giorno.
Questi dati ci forniscono tutto ciò di cui abbiamo bisogno per avviare un esercizio di classificazione supervisionato. Nei prossimi passaggi useremo serie temporali ritardate dell’S&P500 e applicheremo diverse tecniche di machine learning per valutarne la direzione.
Fattori Esterni
Anche se i prezzi ritardati e i volumi costituiscono un ottimo punto di partenza per analizzare le serie temporali, non ci limitiamo affatto a questi dati. Esploriamo un ampio ventaglio di serie temporali macroeconomiche e prezzi di altri asset per migliorare le previsioni. Ad esempio, possiamo prevedere i prezzi delle materie prime a lungo termine sfruttando modelli meteorologici, oppure individuare variazioni nei tassi di cambio osservando i tassi d’interesse internazionali.
Quando accertiamo una relazione tra due serie e dimostriamo che risulta statisticamente significativa, consideriamo il modello di trading come affidabile e robusto. Non entriamo nei dettagli di questi approcci, poiché vogliamo introdurre i fondamenti delle tecniche di forecasting e apprendimento automatico. Risulta piuttosto semplice formulare ipotesi sulle relazioni economiche e raccogliere i dati dalle serie temporali usando repository come Quandl o siti ufficiali di statistiche governative.
Modelli di Classificazione
Il machine learning è un ambito vasto che offre molti modelli, specialmente nella classificazione supervisionata. La letteratura accademica propone nuovi classificatori quasi ogni mese. Non ci proponiamo di elencare tutti i modelli in questa lezione, ma preferiamo descrivere alcune delle tecniche di forecasting più diffuse in questo campo.
Logistic Regression
Esaminiamo innanzitutto la regressione logistica (LR). In questo caso, usiamo la LR per misurare la relazione tra una variabile dipendente binaria (“Up” o “Down”) e più variabili indipendenti continue (ritardi dei rendimenti percentuali). Il modello stima la probabilità che il giorno successivo venga classificato come “Up” o “Down”. Abbiamo deciso di assegnare “Up” se la probabilità supera 0,5, anche se potremmo scegliere una soglia diversa.
La LR impiega la formula logistica per modellare la probabilità di osservare un giorno “Up” (Y = U) sulla base dei fattori ritardati (L1, L2):
\(\begin{eqnarray}
p(Y=U|L_1, L_2) = \frac{e^{\beta_0 + \beta_1 L_1 + \beta_2 L_2}}{1+e^{\beta_0 + \beta_1 L_1 + \beta_2 L_2}}
\end{eqnarray}\)
Adottiamo la funzione logistica perché fornisce probabilità comprese tra [0,1] per tutti i valori di L1 e L2, a differenza della regressione lineare che potrebbe restituire valori negativi.
Per adattare il modello e stimare i coefficienti βi, applichiamo il metodo della massima verosimiglianza. Fortunatamente possiamo utilizzare la libreria scikit-learn per gestire l’intero processo di fitting e predizione.
Discriminant Analysis
Utilizziamo la tecnica di forecasting basata sull’analisi discriminante come alternativa statistica alla regressione logistica. Anche se la regressione logistica impone meno assunzioni, l’analisi discriminante può offrire prestazioni migliori quando le ipotesi più restrittive risultano soddisfatte. Tratteremo ora un metodo lineare e uno non lineare di analisi discriminante.
Analisi discriminante lineare
Con la regressione logistica modelliamo la probabilità di osservare un periodo “Up”, quindi stimiamo \(P(Y=U|L_1,L_2)\) come distribuzione condizionale della risposta Y dati i predittori Li, utilizzando una funzione logistica.
Con la Linear Discriminant Analysis (LDA), modelliamo separatamente la distribuzione delle variabili Li dato Y, e otteniamo \(P(Y=U|L_1,L_2)\) applicando il Teorema di Bayes.
La LDA si basa sull’ipotesi che i predittori seguano una distribuzione gaussiana multivariata. Dopo aver stimato i parametri di questa distribuzione, li inseriamo nel Teorema di Bayes per determinare la classe a cui appartiene l’osservazione.
Un presupposto fondamentale della LDA è che tutte le classi (ad esempio “up” e “down”) condividano la stessa matrice di covarianza. Non ci soffermeremo sulle formule per stimare distribuzioni e probabilità, dato che anche in questo caso scikit-learn gestisce tutto per noi.
Analisi discriminante quadratica
L’analisi discriminante quadratica (QDA) è molto simile alla LDA, ma ogni classe dispone della propria matrice di covarianza.
In genere, la QDA funziona meglio quando i limiti decisionali risultano non lineari, mentre la LDA è preferibile quando abbiamo pochi dati di allenamento (cioè quando vogliamo ridurre la varianza). La QDA, invece, dà ottimi risultati quando disponiamo di un grande set di allenamento, dove la varianza conta meno. La scelta tra i due metodi dipende sempre dal compromesso tra varianza e distorsione.
Come per LR e LDA, anche la QDA è disponibile in Scikit-Learn: basta fornirle i dati di allenamento e test per stimare i parametri.
Support Vector Machines
Nella lezione sul Support Vector Machines (SVM), immaginiamo un classificatore che separa diverse classi attraverso un confine netto. Quando troviamo una separazione chiara, costruiamo un classificatore supervisionato che decide se le nuove caratteristiche si trovano sopra o sotto un piano di classificazione lineare. Tuttavia, nel trading quantitativo, difficilmente incontriamo separazioni così evidenti. Per affrontare questa realtà, adottiamo i soft margin classifiers, conosciuti anche come Support Vector Classifiers (SVC).
Utilizziamo tecniche di forecasting basate sulle SVC per trovare un confine di separazione lineare nello spazio delle funzioni, in grado di classificare correttamente la maggior parte delle osservazioni di allenamento. Creiamo così un confine ottimale tra due classi. Quando la separazione è abbastanza lineare, otteniamo buoni risultati. Altrimenti, esploriamo tecniche più avanzate per gestire separazioni non lineari.
Introduciamo allora le Support Vector Machine (SVM) per gestire limiti decisionali non lineari. Questo approccio ci consente di espandere lo spazio delle caratteristiche in modo non lineare e di catturare relazioni complesse, mantenendo un’efficienza computazionale grazie al “kernel trick”.
Con gli SVM, possiamo definire limiti non lineari scegliendo tra diversi tipi di kernel. Invece di limitarci a un confine lineare come nelle SVC, applichiamo polinomi quadratici, polinomi di ordine superiore o kernel radiali. In questo modo, otteniamo una flessibilità significativa, nonostante i bias presenti nelle nostre stime. Applichiamo l’SVM per partizionare lo spazio delle caratteristiche (come fattori di prezzo ritardati e volume), creando un limite non lineare che ci permette di prevedere se il giorno successivo avremo un movimento Up o Down.
Alberi Decisionali e Foreste Random
Gli alberi decisionali rappresentano una tecnica di forecasting per la classificazione supervisionata in cui costruiamo una struttura ad albero per suddividere lo spazio delle caratteristiche in sottoinsiemi ricorsivi, prendendo decisioni a ogni nodo.
Per esempio, verifichiamo se il prezzo di ieri supera una certa soglia. Questa soglia divide lo spazio in due sottoinsiemi. In ciascun sottoinsieme, analizziamo se il volume supera un’altra soglia, generando così quattro gruppi distinti. Continuiamo questo processo finché non rileviamo più potere predittivo dal partizionamento.
Utilizziamo gli alberi decisionali perché offrono un sistema di classificazione facilmente interpretabile, a differenza dei metodi più opachi come SVM o l’analisi discriminante. Per questo motivo, li consideriamo una tecnica popolare nella classificazione supervisionata.
Grazie alla potenza computazionale attuale, adottiamo un approccio noto come “ensemble learning” per migliorare la classificazione. Creiamo numerosi classificatori dallo stesso modello base, ognuno con parametri diversi, e combiniamo le previsioni in una media, sperando così di migliorare l’accuratezza rispetto a quella di ogni singolo modello.
Tra i metodi ensemble più efficaci troviamo la Random Forest, che unisce le predizioni di molti alberi decisionali (spesso decine di migliaia o più). Questo tipo di ensemble funziona molto bene. In Scikit-Learn utilizziamo la classe RandomForestClassifier (RFC) presente nel modulo ensemble. I parametri principali che ci interessano sono n_estimators, che indica il numero di alberi da creare, e n_jobs, che specifica quanti core di elaborazione utilizziamo per distribuire i calcoli.
Principal Components Analysis
Tutte le tecniche di forecasting che abbiamo visto finora rientrano nella classificazione supervisionata. Tuttavia, adottiamo anche un approccio diverso: lasciamo che l’algoritmo apprenda le “caratteristiche” in modo autonomo, senza supervisione. Questo metodo prende il nome di apprendimento non supervisionato.
Applichiamo le tecniche non supervisionate quando vogliamo ridurre la dimensionalità di un problema, trovare informazioni nei dati testuali o scoprire funzionalità utili nell’analisi delle serie temporali.
In questa lezione ci concentriamo sulla riduzione della dimensionalità. Vogliamo identificare le componenti fondamentali di un insieme di fattori per massimizzare la prevedibilità. Per farlo, utilizziamo una tecnica nota come Principal Components Analysis (PCA). Essa ci permette di ridurre lo spazio delle funzioni prima di applicare i classificatori supervisionati. Il PCA trasforma un insieme di variabili correlate (come nell’autocorrelazione delle serie temporali) in un nuovo insieme di variabili non correlate, chiamate componenti principali.
Queste componenti principali vengono ordinate secondo la varianza che spiegano, in modo ortogonale. Quando affrontiamo uno spazio con molte caratteristiche (oltre 10), applichiamo il PCA per ridurre il numero di dimensioni a 2 o 3 componenti principali. In questo modo, costruiamo un classificatore supervisionato più robusto e lo applichiamo a un set di dati ridotto ma informativo.
Previsione del S&P500 con la Logistic Regression, il LDA e il QDA
L’indice S&P500 rappresenta le 500 maggiori società quotate in borsa negli Stati Uniti, selezionate in base alla capitalizzazione di mercato. Lo consideriamo spesso un punto di riferimento per il mercato azionario. Utilizziamo numerosi strumenti derivati per speculare su questo indice. Tra questi, il contratto futures E-Mini S&P500 offre un’elevata liquidità e ci consente di negoziare facilmente sull’indice.
In questa lezione applichiamo tre classificatori per prevedere la direzione del prezzo di chiusura nel giorno N, utilizzando soltanto i dati sui prezzi disponibili fino al giorno N-1. Quando osserviamo un movimento al rialzo, il prezzo di chiusura di N supera quello di N-1. Al contrario, un movimento al ribasso indica che il prezzo di N scende sotto quello di N-1.
Se riusciamo a prevedere la direzione del mercato con una precisione che supera significativamente il 50%, mantenendo l’errore basso e garantendo una buona significatività statistica, possiamo impostare una strategia di trading sistematico semplice basata sulle nostre previsioni. Al momento non esploriamo i metodi più avanzati di tecniche di forecasting. In questa fase introduciamo i concetti fondamentali e partiamo con tecniche di base.
Conclusione
Dopo aver presentato le tecniche di forecasting delle serie temporali, nella seconda lezione di questo corso mostriamo come implementare queste logiche in Python.