Introduzione al Forecasting delle Serie temporali Finanziare – Parte II

Come descritto nel precedente articolo di questa serie, nel campo della finanza quantitativa in cui vi è un’abbondanza di dati di addestramento, quindi si potrebbe usare un modello come il Support Vector Machine (SVM). Tuttavia, gli SVM soffrono della mancanza di interpretabilità. Questo non è il caso degli Alberi Decisionali e i  Random Forest.

Questi ultimi sono spesso usati per preservare l’interpretabilità, qualcosa che i classificatori “black box” come SVM non forniscono. In definitiva, quando i dati sono molto numerosi (ad esempio i dati di tick), non è molto importante quale classificatore utilizzare. In questa fase sorgono altri fattori come l’efficienza computazionale e la scalabilità dell’algoritmo. La regola empirica prevede che il raddoppio dei dati di allenamento causa un aumento lineare delle prestazioni, ma poiché le dimensioni dei dati diventano considerevoli, questo miglioramento si riduce a un aumento sub-lineare delle prestazioni.

La teoria matematica e statistica alla base dei classificatori supervisionati è abbastanza complessa, ma l’intuizione di base di ciascun classificatore è semplice da comprendere. Inoltre, si noti che ognuna delle seguenti classificazioni avrà un diverso insieme di caratteristiche per le quali avranno migliori prestazioni, quindi se si riscontra un cattivo funzionamento del classificatore, ciò potrebbe essere dovuto al fatto che il set di dati utilizzato viola una di queste caratteristiche utilizzate.

Classificatore Naive Bayes

Nonostate questo classificatore non sia stato descritto nel precedente articolo, per completezza è opportuno introdurre anche questo tipo di classificatore. Il Naive Bayes (in particolare Multinomial Naive Bayes – MNB) è utile quando esiste un set di dati limitato. Questo perché è un classificatore ad alta distorsione. L’ipotesi principale del classificatore MNB è l’indipendenza condizionata. In sostanza, tale metodo non è in grado di discernere le interazioni tra le singole caratteristiche, a meno che non siano state specificatamente aggiunte come una caratteristica extra.

Ad esempio, si consideri uno scenario di classificazione dei documenti, che avviene nelle analisi finanziarie quando si tenta di eseguire l’analisi delle opinioni. L’MNB potrebbe apprendere che singole parole come “gatto” e “cane” potrebbero riferirsi rispettivamente ai documenti relativi a cani e gatti, ma la frase “gatti e cani” (gergo britannico che significa più o meno “piovere a catinelle”) non sarebbe considerata una caratteristica meteorologica dal classificatore! Una soluzione potrebbe essere considerare “gatti e cani” come una caratteristica extra, e quindi associarli a una categoria meteorologica.

Logistic Regression

La regressione logistica offre alcuni vantaggi rispetto al modello di Naive Bayes in quanto vi è meno attenzione sulla correlazione tra le caratteristiche e, per la natura del modello, c’è un’interpretazione probabilistica dei risultati. Questo è più adatto per un ambiente in cui è necessario utilizzare le soglie. Ad esempio, potremmo desiderare di posizionare una soglia dell’80% per un risultato “up” o “down” in modo che sia selezionata correttamente, anziché scegliere la categoria con la probabilità più elevata. In quest’ultimo caso, la previsione di “up” potrebbe essere del 51% e la previsione di “down” potrebbe essere del 49%. In questo caso impostare la categoria su “up” non è una previsione molto precisa.

Decision Tree and Random Forests
Gli alberi decisionali (DT) suddividono lo spazio in una gerarchia di scelte booleane che portano a una categorizzazione, o raggruppamento, in base alle rispettive decisioni. Questo li rende altamente interpretabili (assumendo un numero “ragionevole” di decisioni / nodi nell’albero!). DT ha molti vantaggi, inclusa la capacità di gestire le interazioni tra le caratteristiche, anche quelle non parametriche.
Sono anche utili nei casi in cui è difficile (o impossibile) separare linearmente i dati in classi (che è una condizione richiesta dai SVM). Lo svantaggio dell’uso di alberi decisionali individuali è che sono soggetti all’overfitting (alta varianza). Questo problema viene risolto utilizzando una Random Forest. Le foreste casuali sono in realtà alcuni dei classificatori “migliori” che sono utilizzati nelle applicazioni di machine learning, quindi devono essere sempre prese in considerazione.

Support Vector Machine
Support Vector Machines (SVM), pur avendo un complesso processo di allenamento, è in realtà relativamente semplice da comprendere. Gli SVM lineari tentano essenzialmente di partizionare uno spazio in gruppi distinti, utilizzando confini di separazione lineari. Per alcuni tipi di dati questo può funzionare molto bene e porta a buone previsioni. Tuttavia molti dati non sono linearmente separabili, quindi gli SVM lineari possono avere uno scarso rendimento.

La soluzione è modificare il kernel utilizzato dal SVM, in modo da permette l’uso di confini decisionali non lineari. Quindi sono modelli abbastanza flessibili. Tuttavia, il corretto confine del SVM deve essere scelto tra i migliori risultati. Gli SVM sono particolarmente adatti per i problemi di classificazione dei testi di gradi dimensioni. Hanno lo svantaggio di avere un’elevata complessità computazionale, dalla difficoltà di messa a punto e dal fatto che il modello allenato è difficile da interpretare.

Forecasting del Movimento di un Indice Azionario

L’indice S&P500 è un indice ponderato delle 500 maggiori società quotate in borsa (per capitalizzazione di mercato) nel mercato azionario statunitense. È spesso considerato un “benchmark” azionario. Esistono molti prodotti derivati ​​per consentire la speculazione su questo indice. In particolare, il contratto futures E-Mini S& P500 è uno strumento estremamente liquido per negoziare l’indice.

In questo esempio useremo un set di classificatori per prevedere la direzione del prezzo di chiusura al giorno k in base esclusivamente alle informazioni sui prezzi conosciute al giorno k-1. Un movimento direzionale verso l’alto significa che il prezzo di chiusura del giorno k è superiore al prezzo del giorno k-1, mentre un movimento al ribasso implica un prezzo di chiusura al giorno k è inferiore a quello del giorno  k-1.

Se siamo in grado di determinare la direzione del movimento con un metodo che superi significativamente un tasso di successo del 50%, con un basso errore e una buona significatività statistica, allora siamo sulla buona strada per creare una semplice strategia di trading sistematico, basata sulle nostre previsioni. In questa fase non ci occupiamo degli algoritmi di Machine Learning più aggiornati e di ultima generazione. In questo momento stiamo solo introducendo alcuni concetti e quindi iniziamo la discussione con alcuni metodi elementari.

Implementazione in Python

Per l’implementazione di questi forecaster si utilizza aclune librerie Python, quali NumPy, Pandas e Scikit-Learn, la cui installazione è stata descritta in un precedente articolo.

Il primo passo è importare i principali moduli e le librerie, in paticolare per questo esempio si deve importare i moduli per LogisticRegression, LDA, QDA, LinearSVC (una Support Vector Machine lineare), SVC (una Support Vector Machine non lineare) e i classificatori RandomForest:

#!/usr/bin/python
# -*- coding: utf-8 -*-
# forecast.py

import datetime
import numpy as np
import pandas as pd

import pandas_datareader as pdr
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
from sklearn.metrics import confusion_matrix
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis as QDA
from sklearn.svm import LinearSVC, SVC

Dopo aver importato le librerie, si deve creare un DataFrame di pandas che contenga i i ritorni (variazioni di prezzo) percentuali ritardati per un numero precedente di giorni (predefinito a cinque). La funzione create_lagged_series crea un DataFrame per un determinato simbolo azionario (come restituito da Yahoo Finance) eil periodo specificato.

Il codice è ben commentato quindi dovrebbe essere semplice capire il suo funzionamento:

def create_lagged_series(symbol, start_date, end_date, lags=5):
    """
    Questo crea un DataFrame Pandas che memorizza i rendimenti percentuali
    del prezzo di chiusura aggiustato delle barre di un titolo azionario scaricate
    da Yahoo Finance, e memorizza una serie di rendimenti ritardati dai giorni di
    negoziazione precedenti (il valore di ritardo predefinito è di 5 giorni).
    Sono inclusi anche i volume degli scambi, e la direzione del giorno precedente.
    """

    # Download dei ddti sulle azioni da Yahoo Finance
    ts = pdr.DataReader(
          symbol, "yahoo",
          start_date-datetime.timedelta(days=365),
          end_date
         )

    # Crea un nuovo DataFrame dei dati ritardati
    tslag = pd.DataFrame(index=ts.index)
    tslag["Today"] = ts["Adj Close"]
    tslag["Volume"] = ts["Volume"]

    # Crea una serie ritardata dei precendenti prezzi di chiusura dei periodi di trading
    for i in range(0, lags):
        tslag["Lag%s" % str(i+1)] = ts["Adj Close"].shift(i+1)

    # Crea il Dataframe dei rendimenti
    tsret = pd.DataFrame(index=tslag.index)
    tsret["Volume"] = tslag["Volume"]
    tsret["Today"] = tslag["Today"].pct_change()*100.0

    # Se qualsiasi dei valori dei rendimenti percentuali è pari a zero, si imposta questi con
    # un numero molto piccolo (in modo da evitare le criticità del modello QDA di Scikit-Learn)
    for i,x in enumerate(tsret["Today"]):
        if (abs(x) < 0.0001):
            tsret["Today"][i] = 0.0001
            
    # Crea la colonna dei rendimenti percentuali ritardati
    for i in range(0, lags):
        tsret["Lag%s" % str(i+1)] = tslag["Lag%s" % str(i+1)].pct_change()*100.0
    
    # Crea la colonna "Direction" (+1 or -1) che indica un giorno rialzista/ribassista
    tsret["Direction"] = np.sign(tsret["Today"])
    tsret = tsret[tsret.index >= start_date]

    return tsret

Inseriamo la funzione di classificazione all’interno di una procedura principale. In questo esempio specifico si vuol prevedere la direzione del mercato azionario statunitense nel 2005, utilizzando i dati sui rendimenti dal 2001 al 2004.

Innanzitutto si crea una serie ritardata di S&P500 utilizzando cinque ritardi. La serie include anche il volume degli scambi. Tuttavia, si limita il set predittore da utilizzare a solo i primi due ritardi. Quindi stiamo implicitamente affermando al classificatore che gli ulteriori ritardi sono di minor valore predittivo. Per inciso, questo effetto è studiato più concretamente sotto il concetto statistico di autocorrelazione, che va oltre lo scopo di questo articolo.
Dopo aver creato l’array di predittori X e il vettore di risposta Y, possiamo suddividere gli array in un set di training e un set di test. Il primo sottoinsieme viene utilizzato per addestrare effettivamente il classificatore, mentre il secondo viene utilizzato per testare le prestazioni. Si dividono i dati al 1 ° gennaio 2005, utilizzando i dati precedenti per il training e i dati successivi per il testing.

Una volta creata la divisione tra training e testing, è necessario creare un’array dei modelli di classificazione, ognuno dei quali è una tupla che contiene un identificativo e il nome della funzione o modulo. In questo esempio non si imposta nessun parametro per la regressione logistica, gli analizzatori discriminatori lineari / quadratici o i modelli di classificazione SVM lineare, mentre si utilizza un set di parametri predefiniti per i SVM  radiali (RSVM) e il Random Forest (RF).
Dopo aver iterato i dati sui  modelli, si forma (fitting) ciascun modello sui dati di training e poi si effettuano previsioni sui dati di testing. Infine si calcola il Hit-Rate e la matrice di confusione per ciascun modello:


if __name__ == "__main__":
    # Crea una serie ritardata dell'indice S&P500 del mercato azionario US
    snpret = create_lagged_series(
        "^GSPC", datetime.datetime(2001,1,10),
        datetime.datetime(2005,12,31), lags=5
       )

    # Uso il rendimento dei due giorni precedentei come valore
    # di predizione, con la direzione come risposta
    X = snpret[["Lag1","Lag2"]]
    y = snpret["Direction"]

    # I dati di test sono divisi in due parti: prima e dopo il 1 gennaio 2005.
    start_test = datetime.datetime(2005,1,1)

    # Crea il dataset di training e di test
    X_train = X[X.index < start_test]
    X_test = X[X.index >= start_test]
    y_train = y[y.index < start_test]
    y_test = y[y.index >= start_test]

    # Crea i modelli (parametrizzati)
    print("Hit Rates/Confusion Matrices:\n")
    models = [("LR", LogisticRegression()),
              ("LDA", LDA()),
              ("QDA", QDA()),
              ("LSVC", LinearSVC()),
              ("RSVM", SVC(
                 C=1000000.0, cache_size=200, class_weight=None,
                 coef0=0.0, degree=3, gamma=0.0001, kernel='rbf',
                 max_iter=-1, probability=False, random_state=None,
                 shrinking=True, tol=0.001, verbose=False)
                ),
              ("RF", RandomForestClassifier(
                 n_estimators=1000, criterion='gini',
                 max_depth=None, min_samples_split=2,
                 min_samples_leaf=1, max_features='auto',
                 bootstrap=True, oob_score=False, n_jobs=1,
                 random_state=None, verbose=0)
                )]

    # Iterazione attraverso i modelli
    for m in models:

        # Addestramento di ogni modello con il set di dati di training
        m[1].fit(X_train, y_train)

        # Costruisce un array di predizioni sui dati di test
        pred = m[1].predict(X_test)

        # Stampa del hit-rate e della confusion matrix di ogni modello.
        print("%s:\n%0.3f" % (m[0], m[1].score(X_test, y_test)))
        print("%s\n" % confusion_matrix(pred, y_test))

Risultati

Di seguito si riporta l’output di tutti i modelli di classificazione. Probabilmente avrai  valori diversi per l’output del RF (Random Forest) dato che quest’ultimo è intrinsecamente stocastico per definizione:
Hit Rates/Confusion Matrices:

LR:
0.560
[[ 35  35]
 [ 76 106]]

LDA:
0.560
[[ 35  35]
 [ 76 106]]

QDA:
0.599
[[ 30  20]
 [ 81 121]]

LSVC:
0.560
[[ 35  35]
 [ 76 106]]

RSVM:
0.563
[[  9   8]
 [102 133]]

RF:
0.504
[[48 62]
 [63 79]]

Da notare che tutti i tassi di successo si collocano tra il 50% e il 60%. Quindi si può concludere che le variabili ritardate non sono indicative della direzione futura. Tuttavia, se si osserva all’analizzatore discriminante quadratico (QDA), si nota che la sua prestazione predittiva complessiva sul set di test è appena inferiore al 60%.
Dalla matrice di confusione per questo modello (e gli altri in generale) si osserva che il tasso positivo per i giorni “down” è molto più alto rispetto ai giorni “up”. Quindi, se vogliamo creare una strategia di trading basata su queste informazioni, potremmo considerare di limitare le operazioni alle sole posizioni short del S&P500 come metodo potenziale per aumentare la redditività.

Negli articoli successivi useremo questi modelli come base di una strategia di trading incorporandoli direttamente nella struttura di backtesting event-driven e utilizzando uno strumento diretto, come un exchange traded fund (ETF), per poter accedere al trading del S&P500.

 

Per il codice completo riportato in questo articolo utilizzando il modulo di backtesting vettoriale VectorBacktest si può consultare il seguente repository di github:
https://github.com/datatrading-info/VectorBacktest

Introduzione al Forecasting delle Serie temporali Finanziare – Parte I

Il Processo di Previsione

In questa serie di articoli voglio descrivere un processo statisticamente robusto per la previsione delle serie temporali finanziarie. Queste previsioni formeranno la base per un gruppo di strategie di trading automatico. Il primo articolo della serie discuterà l’approccio alla modellazione e un gruppo di algoritmi di classificazione che ci consentiranno di prevedere la direzione del mercato.

All’interno di questi articoli faremo uso di scikit-learn, una libreria di apprendimento automatico per Python. Scikit-learn contiene l’implementazione di molte tecniche di machine learning. Questo non solo ci fa risparmiare molto tempo, ma minimizza il rischio di bug introdotti dal nostro codice e consente ulteriori verifiche con le librerie scritte in altri linguaggi, come R. Questo offre un buon grado di affidabilità per di creare la nostra implementazione personalizzata (se per esempio abbiamo bisogno di maggiore velocità di esecuzione).

Il machine learning statistico utilizza tecniche come la Logistic Regression (regressione logistica), la Linear Discriminant Analysis (analisi della discriminante lineare) e Linear Discriminant Analysis (analisi della discriminante quadratica). E’ necessario quindi introdurre delineare alcuni concetti di base.

Tecniche di Apprendimento Supervisionato

Le tecniche di Supervised Learning considerano un insieme noto di tuple \((x_i, y_i)\), \(i \in \{1,…,N \}\), con xi che rappresenta le variabili predittive (come i ritorni del mercato azionario o il volume negoziato) e yi che rappresenta la risposta/osservazione associata (come il rendimento del mercato azionario giornaliero). In questo caso siamo interessati alla previsione. Date le variabili predittive future, desideriamo stimare le risposte da questi predittori. Questo è in contrasto con l’inferenza in cui siamo più interessati alla relazione tra le variabili. Tutti gli algoritmi che utilizziamo in questo articolo, insieme a molti altri che impiegheremo in futuro, provengono dal dominio di apprendimento supervisionato.  

Misurare l'Accuratezza della Previsione

La particolare classe di metodi a cui siamo interessati riguarda la classificazione binaria. Cioè, tenteremo di classificare il rendimento percentuale di un particolare giorno in due insiemi: “Up” o “Down”. In un sistema reale di previsione l’interesse è rivolto verso l’entità di questa previsione e alle deviazioni della previsione dal valore effettivo.

In tali casi, possiamo utilizzare Mean-Squared ErrorMean Absolute Deviation e Root-Mean-Squared Error per fornire una stima della precisione della previsione. La letteratura fornisce numerosi altri esempi di metodi per misurare di accuratezza della previsione.

In questo articolo ci focalizziamo solamente su due misure: l’Hit-Rate, cioè la percentuale di volte in cui il forecaster ha ottenuto una previsione accurata, e la Confusion Matrix (una matrice di confusione, detta anche tabella di errata classificazione), per determinare le prestazioni di predizione. Inoltre, si calcolano i valori sopra menzionati e si incorporano nel processo di ricerca dei segnali.

Hit Rate

La domanda più semplice che potremmo chiedere al nostro classificatore supervisionato è “Quante volte abbiamo previsto la direzione corretta, come percentuale di tutte le previsioni? “.Questo motiva la definizione di un tasso di successo dell’allenamento, dato dalla seguente formula:

\(\frac{1}{n} \sum_{i=1}^{n} I(y_i = \hat{y_i})\)

Dove yi è la previsione (UP o DOWN) per il periodo di tempo i (ad esempio un giorno) utilizzando un particolare classificatore. \(I(y_i = \hat{y_i})\) è la funzione indicatore ed è uguale a 1 se \(y_i = \hat{y_i}\) e 0 se \(y_i \neq \hat{y_i}\).

Quindi l’Hit Rate fornisce un valore percentuale sul numero di volte in cui un classificatore ha correttamente previsto la direzione verso l’alto o verso il basso. Scikit-Learn fornisce una funzione per calcolare il tasso di successo come parte del processo di classificazione / 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 della previsione dei prezzi degli asset è la scelta dei fattori utilizzati come predittori. Ci sono un numero impressionante di  potenziali fattori da scegliere e può essere scoraggiante per una persona che non ha familiarità con le previsioni finanziarie. Tuttavia, anche le più semplici tecniche di machine learning produrranno risultati relativamente buoni se applicate con fattori scelti con cura.

La scelta dei fattori viene effettuata cercando di determinare gli aspetti  fondamentali che guidano il movimento degli asset. Nel caso dello S&P500 è chiaro che i 500 titoli che lo compongono, in modo ponderato, saranno per definizione i driver fondamentali del prezzo! Chiaramente si vuole conoscere il prezzo esatto della serie S&P500 nel caso in cui si conosca il valore istantaneo dei suoi componenti, ma esiste un potere predittivo nell’usare la storia precedente dei rendimenti per ciascun costituente nel predire la stessa serie?

In alternativa, potremmo considerare i tassi di cambio con paesi che effettuano molti scambi commerciali con gli Stati Uniti come driver del prezzo? Potremmo anche prendere in considerazione fattori economici e societari più fondamentali come i tassi di interesse, l’inflazione, i profitti trimestrali. La precisione del forecaster sarà in gran parte dovuta all’abilità del modellista nel determinare i fattori giusti prima di eseguire l’adattamento del modello.

Fattori di prezzi ritardati e volumi

Il primo tipo di fattore che viene spesso preso in considerazione nella previsione delle serie temporali sono i valori storici delle stesse serie temporali. Quindi un insieme di fattori p potrebbe essere ottenuto facilmente creando p “ritardi” dei prezzi di chiusura della serie storica. Se si considera una serie temporale giornaliera, per ogni specifico giorno k, i fattori sarebbero i valori giornalieri storici nei periodi di tempo k-1, k-2, …, k-p.

Oltre alla serie di prezzi, possiamo incorporare come indicatore anche il volume degli scambit, informazione che viene fornita quando si utilizzano dati OHLCV (ad esempio, i dati acquisiti da Yahoo Finance, Google Finance o Quandl). In questo modo possiamo creare un vettore di dimensione p+1 per ogni giorno delle serie temporali, che contiene i ritardi temporali p e il volume. Questo naturalmente porta a un insieme di coppie (Xk, yk) che rappresentano il vettore dei fattori Xk di dimensione p+1 al giorno k e l’effettivo prezzo di chiusura per il giorno k, yk.

Questo è tutto ciò di cui abbiamo bisogno per iniziare un esercizio di classificazione supervisionato. Di seguito considereremo serie temporali ritardate per l’S&P500 e applicheremo più tecniche di machine learning per vedere se possiamo prevederne la direzione.

Fattori Esterni

Mentre le serie ritardate dei prezzi e le informazioni sul volume sono un buon punto di partenza per l’analisi delle serie temporali, siamo ben lungi dall’essere limitati a tali dati. Ci sono una grande quantità di serie temporali macroeconomiche e serie di prezzi degli asset da  prendere in considerazione per effettuare le previsioni. Ad esempio, potremmo desiderare di fornire una previsione a lungo termine dei prezzi delle materie prime sulla base di modelli meteorologici, o accertare movimenti di direzione dei prezzi delle valute estere tramite movimenti dei tassi d’interesse internazionali.

Se tale relazione tra serie può essere accertata e dimostrata essere statisticamente significativa, allora possiamo considere il modello di trading come affidabile e robusto. Non voglio descrivere dettagliatamente tali approcci, poiché l’obbiettivo di tale articolo è introdurre la base delle tecniche di modellazione e di apprendimento automatico. È abbastanza facile formulare ipotesi sulle relazioni economiche e ottenere i dati delle serie temporali sia da un repository come Quandl, sia direttamente dai siti web delle statistiche governative.

Modelli di Classificazione

Il machine learning è un campo molto vasto e ci sono molti modelli tra cui scegliere, e in particolare nel campo della classificazione supervisionata. La letteratura accademica introduce nuovi modelli quasi ogni mese. Quindi fornire un elenco esaustivo dei classificatori supervisionati in questo articolo sarebbe piuttosto complicato, è invece più utile descrivere alcune delle tecniche più popolari in questo campo.

Logistic Regression

La prima tecnica che prenderemo in considerazione è la regressione logistica (LR). Nel nostro caso utilizzeremo LR per misurare la relazione tra una variabile dipendente dalla classificazione binaria (“Up” o “Down”) e più variabili continue indipendenti (i rendimenti percentuali ritardati). Il modello fornisce la probabilità che uno specifico giorno (il successivo) venga classificato come “Up” o “Down”. In questa implementazione abbiamo scelto di assegnare ogni giorno come “Up” se la probabilità supera 0,5. Potremmo fare uso di una soglia diversa, ma per semplicità ho scelto 0,5.

LR utilizza la formula logistica per modellare la probabilità di ottenere un giorno “Up” (Y = U) in base ai fattori di ritardo (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}\)

La funzione logistica viene utilizzata perché fornisce una probabilità tra [0,1] per tutti i valori di L1 e L2, diversamente dalla regressione lineare in cui è possibile generare anche probabilità negative.

Per adattare il modello (cioè stimare i coefficienti βi) viene utilizzato il metodo della massima verosimiglianza. Fortunatamente per noi, l’implementazione del fitting e della predizione del modello LR è gestita dalla libreria di scikit-learn.

Discriminant Analysis

L’analisi discriminante è una tecnica statistica alternativa alla regressione logistica. Mentre la regressione logistica è meno restrittiva nelle sue assunzioni rispetto all’analisi discriminante, quest’ultima può fornire una maggiore performance predittiva se vengono soddisfatte ipotesi più restrittive.
Considereremo ora un metodo lineare e un metodo non lineare di analisi discriminante.

Analisi discriminante lineare

Nella regressione logistica si modella la probabilità di vedere un periodo di tempo “Up”, cioè modelliamo \(P(Y=U|L_1,L_2)\) come una distribuzione condizionale della risposta Y dati i predittori Li, utilizzando una funzione logistica.

Nella Linear Discriminant Analysis (LDA), dato Y, la distribuzione delle variabili Li è modellizzata separatamente, e \(P(Y=U|L_1,L_2)\) è ottenuto tramite il Teorema di Bayes.
In sostanza, la LDA deriva dal presupposto che i predittori siano ottenuti tramite distribuzione gausiana multivariata. Dopo aver calcolato le stime per i parametri di questa distribuzione, i parametri possono essere inseriti nel Teorema di Bayes per fare previsioni relative alla classe di appartenenza di un’osservazione.
Un importante assunto matematico della LDA prevede che tutte le classi (ad esempio “up” e “down”) condividono la stessa matrice di covarianza.
Non mi dilungherò sulle formule per stimare la distribuzione o le probabilità che sono necessarie per fare previsioni, ancora una volta scikit-learn lo gestisce per noi.

Analisi discriminatoria quadratica

L’analisi quadratica discriminante (QDA) è strettamente legata alla LDA. La differenza significativa è che ogni classe può  possedere la propria matrice di covarianza.
Generalmente la QDA  funziona meglio quando i limiti decisionali non sono lineari, mentre la LDA è migliore quando ci sono meno osservazioni di allenamento (cioè quando è necessario ridurre la varianza). La QDA, d’altra parte, si comporta bene quando il set di allenamento è grande (cioè la varianza è meno importante). L’uso dell’uno o dell’altro alla fine si riduce ad compromesso tra varianza e distorsione.
Come con la LR e la LDA, Scikit-Learn implementa anche la QDA, quindi è sufficiente fornirgli i dati di allenamento/test e la stima dei parametri.

Support Vector Machines

Per descrivere il Support Vector Machines (SVM) si consideri un classificatore che separa diverse classi attraverso un confine di separazione. Se esistesse una separazione così diretta, si può creare un classificatore supervisionato basato unicamente sulla decisione che le nuove caratteristiche si trovano al di sopra o al di sotto di questo piano di classificazione lineare. In realtà, raramente tali separazioni esistono negli scenari di trading quantitativo e come tali dobbiamo considerare i soft margin classifiers o Support Vector Classifters (SVC).
Le SVC provano ad individuare un limite di separazione lineare nello spazio delle funzioni che classifica correttamente la maggior parte, ma non tutte, le osservazioni di allenamento creando un confine di separazione ottimale tra le due classi. A volte un tale limite è abbastanza efficace se la separazione delle classi è per lo più lineare. Tuttavia, altre volte tali separazioni non sono possibili ed è necessario utilizzare altre tecniche.

La motivazione alla base dell’estensione di un SVC è la possibilità di considerare limiti decisionali non lineari. Questo è il dominio di Support Vector Machine (SVM). Il vantaggio principale degli SVM è la possibilità di effettuare un ampliamento non lineare dello spazio delle caratteristiche per includere una significativa non linearità, mantenendo comunque un’efficienza computazionale, utilizzando un processo noto come “kernel trick”.

Gli SVM consentono limiti decisionali non lineari attraverso molte scelte differenti di “kernel”. In particolare, invece di utilizzare un limite di separazione completamente lineare come in SVC, possiamo usare i polinomi quadratici, i polinomi di ordine superiore o anche i kernal radiali per descrivere i limiti non lineari. Questo ci dà un significativo grado di flessibilità, a fronte dei bias sempre presenti nelle nostre stime. Utilizzeremo il SVM di  per provare a partizionare lo spazio delle caratteristiche (ovvero i fattori di prezzo ritardati e il volume) tramite un limite non lineare che ci consente di fare previsioni ragionevoli sul fatto che il giorno successivo ci sarà un movimento Up o Down.

Alberi Decisionali e Foreste Random

Gli alberi decisionali sono una tecnica di classificazione supervisionata che utilizza una struttura ad albero per suddividere lo spazio delle caratteristiche in sottoinsiemi ricorsivi tramite una “decisione” su ciascun nodo dell’albero.
Ad esempio, si potrebbe verificare se il prezzo di ieri fosse superiore o inferiore a una certa soglia. Tale soglia partiziona immediatamente lo spazio delle caratteristiche in due sottoinsiemi. Per ciascuno dei due sottoinsiemi si potrebbe quindi verficare se il volume era sopra o sotto una soglia, creando così quattro sottoinsiemi separati. Questo processo continua fino a quando non si ottiene più potenza predittiva dal partizionamento.
Un albero decisionale fornisce un meccanismo di classificazione naturalmente interpretabile rispetto ai più opachi approcci “black box” dell’SVM o dell’analisi discriminante e quindi è una popolare tecnica di classificazione supervisionata.

Con l’aumentare della potenza computazionale, è emerso un nuovo metodo per risolvere il problema della classificazione, quello del “ensemble learning”. L’idea di base è semplice: si crea una grande quantità di classificatori dallo stesso modello base e vengono tutti allenali con diversi parametri. Quindi si combinano i risultati della previsione in una media per ottenere, auspicabilmente, una maggiore precisione di previsione di quella ottenuta con uno qualsiasi dei singoli componenti.

Uno dei metodi di ensemble più diffusi è quello della  Random Forest, che considera molti alberi decisionali  (solitamente nell’ordine di decine di migliaia o più) e combina le predizioni. Tali ensemble lavorano spesso estremamente bene. Scikit-Learn contiene una classe RandomForestClassifier (RFC) nel suo modulo ensemble. I due principali parametri di interesse per RFC sono il n_estimators, che descrive il numero di alberi decisionali da creare e il n_jobs, che descrive il numero di core di elaborazione su cui vengono distribuiti i calcoli. 

Principal Components Analysis

Tutte le tecniche sopra descritte appartengono alla categoria della classificazione supervisionata. Un approccio alternativo alla classificazione delle prestazioni consiste nel non supervisionare la procedura di addestramento e consentire invece a un algoritmo di accertare “caratteristiche” in autonomia. Tali metodi sono noti come tecniche di apprendimento senza supervisione.
I casi di uso comune per le tecniche non supervisionate includono la riduzione del numero di dimensioni di un problema solo a quelle considerate importanti, la ricerca di informazioni all’interno di una grande quantità di documenti di testo o la scoperta di funzionalità che possono fornire una potenza predittiva nell’analisi delle serie temporali.
Di interesse per noi in questa sezione è il concetto di riduzione della dimensionalità, che mira a identificare le componenti più importanti di una serie di fattori che forniscono la massima prevedibilità. In particolare, si prende in considerazione una tecnica non supervisionata nota come Principal Components Analysis (PCA) per ridurre le dimensioni dello spazio delle funzioni prima di usare i  classificatori supervisionati. L’idea di base di un PCA è trasformare un insieme di variabili possibilmente correlate (come con la autocorrelazione delle serie temporali) in un insieme di variabili linearmente non correlate conosciute dette componenti principali. Tali componenti principali sono ordinati in base alla quantità di varianza che descrivono, in modo ortogonale. Pertanto, se disponiamo di uno spazio di caratteristiche molto elevato (oltre 10 caratteristiche), tramite PCA  la si può ridurre tale spazio a  2 o 3 componenti principali che forniscono quasi tutta la variabilità nei dati, in modo da avere un modello di classificatore supervisionato più solido quando applicato a questo set ridotto di dati.

Previsione del S&P500 utilizzando la Logistic Regression, il LDA e il QDA

L’indice S&P500 è un indice ponderato delle 500 maggiori società quotate in borsa (per capitalizzazione di mercato) nel mercato azionario statunitense. È spesso considerato un “benchmark” azionario. Esistono molti prodotti derivati ​​per consentire la speculazione su questo indice. In particolare, il contratto futures E-Mini S&P500 è uno strumento estremamente liquido per negoziare l’indice.

In questa sezione useremo tre classificatori per prevedere la direzione del prezzo di chiusura al giorno N in base esclusivamente alle informazioni sui prezzi conosciute al giorno N-1. Un movimento direzionale verso l’alto significa che il prezzo di chiusura di N è superiore al prezzo di N-1, mentre un movimento al ribasso implica un prezzo di chiusura di N inferiore a quello di N-1.

Se siamo in grado di determinare la direzione del movimento con un metodo supera significativamente un tasso di successo del 50%, con un basso errore e una buona significatività statistica, allora siamo sulla buona strada per creare una semplice strategia di trading sistematico, basata sulle nostre previsioni. In questa fase non ci occupiamo degli algoritmi di Machine Learning più aggiornati e di ultima generazione. In questo momento stiamo solo introducendo alcuni concetti e quindi iniziamo la discussione con alcuni metodi elementari.

Conclusione

Dopo aver introdotto i concetti base, nella seconda parte di questo articolo vedremo come implementare in python queste logiche.