In questa lezione descriviamo i metodi di ottimizzazione dei parametri nei modelli di trading in modo sistematico per migliorare la robustezza e le prestazioni delle strategie. A tal fine usiamo approcci statistici per la selezione del modello, come la convalida incrociata e la ricerca della griglia, descritti nel corso sul forecasting e l’analisi predittiva.
Ad esempio abbiamo evidenziamo come il Support Vector Machine o il Classificatore Random Forest prevedano molti parametri. Nel caso di un SVM abbiamo i parametri di “tuning” \(\gamma\) e C. Più semplicemente, in una strategia di crossover della media mobile si ha i parametri per le due finestre di ricerca della media mobile, usate come filtro.
La letteratura sulla selezione dei modelli e l’ottimizzazione dei parametri nel trading è vasta e la maggior parte dei metodi sono oltre lo scopo di questa lezione. Introduciamo l’argomento in modo che si possa esplorare autonomamente le tecniche più avanzate.
Ottimizzazione dei Parametri nel Trading
In questa fase, si impiegano uno o più parametri per far funzionare quasi tutte le strategie di trading e i modelli statistici sottostanti. Le strategie di momentum che utilizzano indicatori tecnici, come le medie mobili (semplici o esponenziali), richiedono una finestra di lookback: il numero di periodi passati su cui calcolare la media. Lo stesso vale per molte strategie mean-reverting, che necessitano di una finestra di lookback (rolling) per calcolare la regressione tra due serie temporali.
I modelli di machine learning statistico, come la regressione logistica, lo SVM o il Random Forest, funzionano solo se si impostano correttamente i parametri. L’ottimizzazione dei parametri nel trading rappresenta quindi una fase essenziale della costruzione strategica.
Il rischio principale associato all’ottimizzazione dei parametri nel trading è l’overfitting del modello o della strategia. Questo problema si verifica quando si addestra un modello su un dataset “in-sample” e lo si adatta per ottenere performance ottimali su quel campione, ma le sue prestazioni calano drasticamente su dati “out of sample“. Ad esempio, una strategia può sembrare perfetta nel backtest ma risultare inefficace nel live trading. L’ottimizzazione dei parametri nel trading deve quindi sempre considerare la robustezza fuori campione.
L’ottimizzazione dei parametri nel trading può anche risultare molto onerosa dal punto di vista computazionale. Oggi questo problema è meno rilevante grazie ai progressi nella parallelizzazione e alle CPU più performanti. Tuttavia, l’aumento del numero di parametri da ottimizzare può incrementare la complessità computazionale di diversi ordini di grandezza.
Quali parametri ottimizzare?
Un modello di trading algoritmico basato su approcci statistici presenta spesso molti parametri e diverse metriche di performance, poiché ogni algoritmo ha il proprio set di parametri. Nella regressione lineare o logistica multipla, questi parametri sono i coefficienti \(\beta_i\). In una Random Forest, ad esempio, uno dei parametri principali è il numero di alberi decisionali. Quando si applicano tali modelli al trading, entrano in gioco anche soglie operative come lo z-score, che a sua volta dipende da una finestra di rollback. L’insieme dei parametri può quindi diventare ampio, rendendo ancora più importante una gestione accurata dell’ottimizzazione dei parametri nel trading.
Oltre ai parametri, disponiamo di diversi strumenti per valutare le prestazioni di un modello statistico e della relativa strategia. Si utilizzano concetti come l’Hit Rate e la Matrice di Confusione, oltre a metriche come il Mean Squared Error (MSE). Queste misure vengono ottimizzate tramite parametri rilevanti per il modello. La strategia di trading, invece, si valuta secondo criteri come il CAGR o il massimo drawdown. È quindi necessario regolare criteri di entrata e uscita e soglie operative non direttamente collegate al modello. Tutto ciò rende cruciale pianificare in modo sistematico l’ottimizzazione dei parametri nel trading.
Questa complessità solleva la questione su quali parametri ottimizzare e in quale fase. Le sezioni seguenti spiegano come ottimizzare sia i parametri del modello statistico nella fase iniziale di ricerca e sviluppo, sia quelli della strategia di trading che utilizza un modello statistico ottimizzato, tenendo conto delle rispettive metriche di performance.
L’Ottimizzazione è Costosa
Con più parametri reali, il processo di ottimizzazione può diventare molto costoso. Ogni parametro aggiuntivo aumenta dimensionalmente lo spazio di ricerca. Ad esempio, in una griglia di ricerca, se si desidera variare un singolo parametro \(\alpha\) tra \big\{0.1,0.2,0.3,0.4,0.5\big\}, servono 5 simulazioni. Aggiungendo un altro parametro da testare su \big\{0.2,0.4,0.6,0.8,1\big\}, si arriva a \(5^{2} = 25\) simulazioni. Un terzo parametro porta a \(5^{3} = 125\) simulazioni. Se ogni parametro ha 10 valori possibili, il numero sale a \(10^{3} = 1000\).
In questi casi, l’ottimizzazione dei parametri nel trading può comportare costi computazionali significativi.
Occorre quindi trovare un compromesso tra una ricerca esaustiva e tempi di simulazione accettabili. Anche se il parallelismo con CPU multi-core e GPU ha ridotto il problema, introdurre nuovi parametri resta un’operazione delicata. La riduzione del numero di parametri, infatti, incide anche sull’efficacia del modello, come vedremo in seguito.
Overfitting
L’overfitting si verifica quando si ottimizza un parametro o un insieme di parametri per massimizzare o minimizzare una misura di performance su un dataset specifico, con risultati che peggiorano drasticamente su dati nuovi. Questo fenomeno è legato al bias-variance dilemma.
Il bias-variance dilemma descrive l’equilibrio tra bias e varianza: il bias rappresenta l’errore sistematico tra la stima del modello e la realtà, mentre la varianza misura la sensibilità del modello a variazioni nei dati di addestramento. L’obiettivo di ogni modello statistico è minimizzare entrambi per migliorare l’accuratezza complessiva. Tuttavia, questo può portare all’overfitting: modelli più complessi riducono l’errore sui dati in-sample, ma faticano su nuovi dati.
Ad esempio, una regressione lineare applicata a dati non lineari mostra elevato bias e bassa varianza: aggiungere dati non ne cambia l’inclinazione, ma il modello resta inadatto. Al contrario, uno spline polinomiale su dati non lineari può adattarsi troppo bene (basso bias), ma l’aggiunta di nuovi punti altera la struttura, indicando alta varianza. Questi modelli hanno scarsa capacità inferenziale.
L’overfitting non si limita al modello statistico, ma può colpire anche la strategia di trading. Ad esempio, ottimizzare lo Sharpe ratio modificando soglie operative può migliorare i risultati del backtest, ma fallire nel trading reale. Questo perché l’ottimizzazione dei parametri nel trading potrebbe adattarsi al rumore dei dati storici, compromettendo la generalizzazione. Le tecniche per ridurre l’overfitting sono molteplici, ma è fondamentale ricordare che il rischio è sempre presente, sia nel trading algoritmico che nell’analisi statistica in generale.
Selezione del Modello
Questa sezione spiega come ottimizzare il modello statistico alla base di una strategia di trading. In statistica e nel machine learning, questo processo viene chiamato selezione del modello.
L’obiettivo dell’articolo non è fornire una panoramica esaustiva di tutte le tecniche esistenti, ma presentare alcuni meccanismi fondamentali, come la Cross Validation e la Grid Search, che si rivelano efficaci nell’ambito delle strategie di trading.
Cross Validation
La Cross Validation (o convalida incrociata) rappresenta una tecnica utile per valutare la capacità di un modello statistico di generalizzare su dati nuovi, mai visti prima. Si applica comunemente a modelli predittivi, come i classificatori supervisionati utilizzati per prevedere il segno dei return nei giorni successivi a una serie di prezzi di asset finanziari. Lo scopo della convalida incrociata è ridurre l’errore sui dati di esempio, evitando al contempo il rischio di overfitting.
Questo paragrafo introduce il training/test split e la k-fold cross-validation, mostrando come utilizzare gli strumenti offerti da Scikit-Learn per applicare in modo automatico queste procedure a modelli statistici già costruiti.
Training/Test Split
Il metodo più semplice di convalida incrociata prende il nome di training/test split o convalida in due fasi. Dopo aver raccolto una serie storica di dati (ad esempio, una serie giornaliera di prezzi), si suddivide il dataset in due parti. Il rapporto tra i due segmenti varia in genere tra 0,5 e 0,8. Con un rapporto di 0,8, l’80% dei dati serve per il training, mentre il restante 20% viene riservato ai test. Le statistiche di valutazione, come tasso di successo, matrice di confusione o errore quadratico medio, vengono calcolate esclusivamente sul set di test, mai usato durante l’addestramento.
È possibile eseguire questo procedimento in Python con la libreria Scikit-Learn, sfruttando il metodo sklearn.cross_validation.train_test_split. Questo esempio amplia quanto illustrato nella lezione sull’analisi predittiva delle serie temporali. In particolare, si modifica il file forecast.py
e si crea un nuovo script chiamato train_test_split.py
, illustrando così un primo approccio pratico all’ottimizzazione dei parametri nel trading.
#!/usr/bin/python
# -*- coding: utf-8 -*-
# train_test_split.py
import datetime
import sklearn
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis as QDA
from sklearn.metrics import confusion_matrix
from sklearn.svm import LinearSVC, SVC
from forecast import create_lagged_series
forecast.py
i dati sono stati suddivisi in base a una data specifica all’interno delle serie temporali:
# forecast.py
..
# The test data is split into two parts: Before and after 1st Jan 2005.
start_test = datetime.datetime(2005,1,1)
# Create training and test sets
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]
..
train_test_split.py
questo codice è sostituito con il metodo train_test_split
di Scikit-Learn. Per completezza, il metodo principale è implementato come segue:
# train_test_split.py
if __name__ == "__main__":
# Create a lagged series of the S&P500 US stock market index
snpret = create_lagged_series(
"^GSPC", datetime.datetime(2001,1,10),
datetime.datetime(2005,12,31), lags=5
)
# Use the prior two days of returns as predictor
# values, with direction as the response
X = snpret[["Lag1","Lag2"]]
y = snpret["Direction"]
# Train/test split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.8, random_state=42
)
# Create the (parametrised) models
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='sqrt',
bootstrap=True, oob_score=False, n_jobs=1,
random_state=None, verbose=0)
)]
# Iterate through the models
for m in models:
# Train each of the models on the training set
m[1].fit(X_train, y_train)
# Make an array of predictions on the test set
pred = m[1].predict(X_test)
# Output the hit-rate and the confusion matrix for each model
print("%s:\n%0.3f" % (m[0], m[1].score(X_test, y_test)))
print("%s\n" % confusion_matrix(pred, y_test))
Risultati
In questo approccio di ottimizzazione dei parametri nel trading, abbiamo selezionato un set di training pari all’80% dell’intero dataset, riservando il restante 20% ai dati di test.
Abbiamo anche impostato un parametro random_state
per randomizzare il campionamento all’interno del dataset. Questo implica che la suddivisione dei dati non segue l’ordine cronologico, ma avviene in modo casuale.
Di seguito riportiamo i risultati della cross validation applicata al modello (potrebbero variare leggermente a causa della natura stocastica del processo di fitting):
Hit Rates/Confusion Matrices:
LR: 0.511
[[ 70 70]
[ 419 441]]
LDA: 0.513
[[ 69 67]
[420 444]]
QDA: 0.503
[[ 83 91]
[406 420]]
LSVC: 0.513
[[ 69 67]
[420 444]]
RSVM: 0.506
[[ 8 13]
[481 498]]
RF:
0.490
[[200 221]
[289 290]]
Notiamo che i tassi di successo risultano sensibilmente inferiori rispetto a quelli riportati nella lezione citata in precedenza. Questo suggerisce che una determinata scelta del rapporto tra dati di allenamento e di test possa fornire una visione eccessivamente ottimistica della capacità predittiva del classificatore.
Il passo successivo consiste nell’aumentare il numero di esecuzioni della cross validation per ridurre al minimo il rischio di overfitting. A tal fine, si utilizza la convalida incrociata k-fold.
K-Fold Cross Validation
Invece di dividere il dataset in un unico set di training e uno di test, la k-fold cross validation suddivide casualmente i dati in k sottogruppi di dimensioni uguali. Per ciascuna delle k iterazioni, uno dei sottogruppi viene usato come set di test, mentre i restanti k-1 costituiscono il set di training. Si addestra un modello statistico per ogni combinazione e si valuta la sua performance sul relativo set di test.
L’obiettivo è combinare i risultati dei vari modelli in un ensemble, mediando le previsioni (o applicando altre metriche) per generare una previsione unica. Il principale vantaggio di questa tecnica consiste nel fatto che ogni elemento del dataset originale viene utilizzato sia per il training sia per il test, almeno una volta.
Questa procedura rende importante la scelta del valore di k, che rappresenta un ulteriore parametro da ottimizzare. Solitamente si imposta k = 10, ma è possibile effettuare un’ulteriore analisi per individuare il valore ottimale. Questo rientra pienamente nel processo di ottimizzazione dei parametri nel trading.
Implementazione in Python
Nel codice, usiamo il modulo cross_validation
di Scikit-Learn per ottenere l’oggetto KFold
relativo alla convalida incrociata k-fold. Si crea quindi un nuovo file chiamato k_fold_cross_val.py
, che è una copia di train_test_split.py e modifica le importazioni aggiungendo la seguente riga:
#!/usr/bin/python
# -*- coding: utf-8 -*- # k_fold_cross_val.py
import datetime
import pandas as pd
import sklearn
from sklearn import cross_validation
from sklearn.metrics import confusion_matrix
from sklearn.svm import SVC
from create_lagged_series import create_lagged_series
Dobbiamo modificare la funzione principale main
, rimuovendo il metodo train_test_split
e sostituendolo con un’istanza di KFold
. Per farlo, sono necessari cinque parametri. Il primo è la lunghezza del set di dati, che in questo caso è pari a 1250 giorni. Il secondo parametro è K
, che rappresenta il numero di fold, ovvero sottoinsiemi, e in questo caso è 10. Il terzo parametro è indices
, impostato su False
, in modo che vengano utilizzati i valori effettivi degli indici per navigare nell’array durante l’iterazione. Il quarto e il quinto parametro servono per randomizzare l’ordine dei campioni.
Come nei file forecast.py
e train_test_split.py
, acquisiamo la serie temporale dell’S&P500. Successivamente, creiamo una serie di vettori per i predittori (X) e le risposte (y). Poi, utilizziamo l’oggetto KFold
e iteriamo su di esso. Durante ogni iterazione, generiamo un set di training e uno di testing per ciascuno dei vettori X e Y. Questi vengono poi inseriti in una Support Vector Machine (SVM) radiale, utilizzando gli stessi parametri dei file precedentemente menzionati. Infine, calcoliamo e restituiamo l’Hit Rate e la Matrice di Confusione per ogni istanza di SVM. Questa procedura, che include l’ottimizzazione dei parametri nel trading, consente di migliorare l’efficacia del modello di previsione.
# k_fold_cross_val.py
if __name__ == "__main__":
# Create a lagged series of the S&P500 US stock market index
snpret = create_lagged_series(
"^GSPC", datetime.datetime(2001,1,10), datetime.datetime(2005,12,31), lags=5
)
# Use the prior two days of returns as predictor # values, with direction as the response
X = snpret[["Lag1","Lag2"]]
y = snpret["Direction"]
# Create a k-fold cross validation object
kf = cross_validation.KFold(
len(snpret), n_folds=10, indices=False, shuffle=True, random_state=42
)
# Use the kf object to create index arrays that
# state which elements have been retained for training
# and which elements have beenr retained for testing
# for each k-element iteration
for train_index, test_index in kf:
X_train = X.ix[X.index[train_index]]
X_test = X.ix[X.index[test_index]]
y_train = y.ix[y.index[train_index]]
y_test = y.ix[y.index[test_index]]
# In this instance only use the
# Radial Support Vector Machine (SVM)
print("Hit Rate/Confusion Matrix:")
model = SVC(
C=1000000.0, cache_size=200, class_weight=None,
coef0=0.0, degree=3, gamma=0.0001, kernel='rbf',
shrinking=True, tol=0.001, verbose=False
)
# Train the model on the retained training data
model.fit(X_train, y_train)
# Make an array of predictions on the test set
pred = model.predict(X_test)
# Output the hit-rate and the confusion matrix for each model
print("%0.3f" % model.score(X_test, y_test))
print("%s\n" % confusion_matrix(pred, y_test))
Risultati
L’output del codice è il seguente:
Hit Rate/Confusion Matrix:
0.528
[[11 10]
[49 55]]
Hit Rate/Confusion Matrix:
0.400
[[ 2 5]
[70 48]]
Hit Rate/Confusion Matrix:
0.528
[[ 8 8]
[51 58]]
Hit Rate/Confusion Matrix:
0.536
[[ 6 3]
[55 61]]
Hit Rate/Confusion Matrix:
0.512
[[ 7 5]
[56 57]]
Hit Rate/Confusion Matrix:
0.480
[[11 11]
[54 49]]
Hit Rate/Confusion Matrix:
0.608
[[12 13]
[36 64]]
Hit Rate/Confusion Matrix:
0.440
[[ 8 17]
[53 47]]
Hit Rate/Confusion Matrix:
0.560
[[10 9]
[46 60]]
Hit Rate/Confusion Matrix:
0.528
[[ 9 11]
[48 57]]
È evidente che il tasso di successo e le matrici di confusione variano significativamente tra i diversi “folds”, indicando che il modello potrebbe essere soggetto a overfitting su questo specifico set di dati. Per affrontare questa problematica, è possibile aumentare notevolmente la quantità di dati, utilizzarli a una frequenza più alta o estendere il periodo di raccolta.
Per applicare questo modello a una strategia di trading, sarebbe necessario combinare ciascuno dei classificatori individualmente addestrati (ossia ogni oggetto K) in un modello complessivo e successivamente utilizzare questo modello combinato per la classificazione nella strategia. Va sottolineato che, tecnicamente, non è corretto applicare tecniche di convalida incrociata standard su dati ordinati (come le serie temporali). Esistono metodi più avanzati per analizzare l’autocorrelazione in tali contesti, ma si è scelto di utilizzare i dati delle serie temporali per semplicità.
Grid Search
Finora abbiamo descritto come il k-fold cross-validation aiuti a prevenire l’overfitting nei dati, eseguendo la convalida su ciascun elemento del campione. Ora approfondiremo come ottimizzare i parametri di un modello statistico specifico. Questi parametri, infatti, non sono appresi direttamente dalla procedura di stima del modello, come ad esempio C e γ in una SVM. In pratica, sono i parametri che vanno definiti quando si inizializza il modello statistico. Per ottimizzare questi parametri nel trading, possiamo utilizzare un approccio noto come grid search.
Il concetto fondamentale alla base di questa tecnica è esplorare un insieme di parametri e valutare le prestazioni del modello statistico per ogni combinazione all’interno di un determinato intervallo. Per implementare questa procedura, è possibile utilizzare un oggetto ParameterGrid
in Scikit-Learn, che genera una lista di dizionari Python, ognuno contenente una combinazione di parametri da applicare al modello statistico.
Di seguito è riportato un esempio di codice che crea una griglia di parametri per una SVM:
>>> from sklearn.grid_search import ParameterGrid
>>> param_grid = {’C’: [1, 10, 100, 1000], ’gamma’: [0.001, 0.0001]}
>>> list(ParameterGrid(param_grid))
[{’C’: 1, ’gamma’: 0.001},
{’C’: 1, ’gamma’: 0.0001},
{’C’: 10, ’gamma’: 0.001},
{’C’: 10, ’gamma’: 0.0001},
{’C’: 100, ’gamma’: 0.001},
{’C’: 100, ’gamma’: 0.0001},
{’C’: 1000, ’gamma’: 0.001},
{’C’: 1000, ’gamma’: 0.0001}]
Ora che disponiamo di uno strumento adatto per generare un ParameterGrid
, è necessario integrarlo in un modello statistico per ottimizzare i parametri nel trading e cercare iterativamente il punteggio di prestazione migliore. In questo caso, l’obiettivo è massimizzare il tasso di successo del classificatore.
Il metodo GridSearchCV
di Scikit-Learn permette di eseguire una vera e propria grid search. Non solo calcola una grid search standard, ma consente anche di implementare un processo di convalida incrociata.
Implementazione
Creiamo un nuovo file, grid_search.py
, che utilizza di nuovo il create_lagged_series.py
insieme a una SVM per effettuare una grid search iperparametrica con validazione incrociata. Per fare ciò, è necessario importare le librerie corrette:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# grid_search.py
import datetime
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.svm import SVC
from forecast import create_lagged_series
Come in precedenza per il k_fold_cross_val.py
, si crea una serie ritardata e quindi utilizza come predittori i returns degli ultimi due giorni precedenti. Inizialmente si crea una suddivisione di training / test in modo tale che il 50% dei dati possono essere utilizzati per il traning e la cross-validation, mentre i dati rimanenti possono essere “tenuti fuori” per la valutazione.
Successivamente si crea la lista tuned_parameters
, che contiene un dizionario dei valori che si vogliono testare per ogni singolo parametro. Questo comporta la creazione di un prodotto cartesiano delle liste di tutti i parametri, cioè un elenco di coppie di ogni possibile combinazione dei parametri. Dopo ever creato l’elenco dei parametri, questo viene passato alla classe GridSearchCV
, insieme al tipo di classificatore a cui si è interessati (ovvero una SVM radiale), con un valore k = 10 per il k-fold cross-validation.
Infine, si forma il modello e si produce la miglior stima e i relativi punteggi di hit rate associato. In questo modo non solo si sono ottimizzati i parametri del modello tramite la validazione incrociata, ma si è anche ottimizzato gli iperparametri del modello tramite una grid search parametrizzata, tutto in una classe! Tale concisione del codice consente una significativa sperimentazione senza essere impantanati da un eccessivo “conflitto di dati”.
if __name__ == "__main__":
# Create a lagged series of the S&P500 US stock market index
snpret = create_lagged_series(
"^GSPC",
datetime.datetime(2001,1,10),
datetime.datetime(2005,12,31), lags=5
)
# Use the prior two days of returns as predictor
# values, with direction as the response
X = snpret[["Lag1","Lag2"]]
y = snpret["Direction"]
# Train/test split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.5, random_state=42
)
# Set the parameters by cross-validation
tuned_parameters = [
{'kernel': ['rbf'], 'gamma': [1e-3, 1e-4], 'C': [1, 10, 100, 1000]}
]
# Perform the grid search on the tuned parameters
model = GridSearchCV(SVC(C=1), tuned_parameters, cv=10)
model.fit(X_train, y_train)
print("Optimised parameters found on training set:")
print(model.best_estimator_, "\n")
print("Grid scores calculated on training set:")
results = model.cv_results_
for mean_score, params in zip(results["mean_test_score"], results["params"]):
print("%0.3f for %r" % (mean_score, params))
Risultati
L’output della procedura di grid search cross validation procedure è il seguente:
Optimised parameters found on training set:
SVC(C=1, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.001,
kernel=’rbf’, max_iter=-1, probability=False, random_state=None,
shrinking=True, tol=0.001, verbose=False)
Grid scores calculated on training set:
0.541 for {’kernel’: ’rbf’, ’C’: 1, ’gamma’: 0.001}
0.541 for {’kernel’: ’rbf’, ’C’: 1, ’gamma’: 0.0001}
0.541 for {’kernel’: ’rbf’, ’C’: 10, ’gamma’: 0.001}
0.541 for {’kernel’: ’rbf’, ’C’: 10, ’gamma’: 0.0001}
0.541 for {’kernel’: ’rbf’, ’C’: 100, ’gamma’: 0.001}
0.541 for {’kernel’: ’rbf’, ’C’: 100, ’gamma’: 0.0001}
0.538 for {’kernel’: ’rbf’, ’C’: 1000, ’gamma’: 0.001}
0.541 for {’kernel’: ’rbf’, ’C’: 1000, ’gamma’: 0.0001}
Come possiamo vedere, γ = 0.001 e C = 1 fornisce il miglior Hit Rate, sul set di convalida, per questa particolare SVM radiale. Questo modello potrebbe ora costituire la base di una strategia di trading basata sull’analisi predittiva delle serie temporali.
Conclusione
In questa lezione di introduzione all’ottimizzazione dei parametri nel trading, abbiamo esplorato i principali concetti relativi alla definizione e ottimizzazione dei parametri in modelli predittivi e strategie di trading algoritmico. Abbiamo visto come la scelta dei parametri influenzi direttamente le prestazioni dei modelli, come nel caso dell’SVM e della strategia di crossover delle medie mobili.
Abbiamo anche evidenziato il rischio di overfitting, che può compromettere l’affidabilità dei modelli se non gestito correttamente. Inoltre, abbiamo discusso delle tecniche fondamentali per l’ottimizzazione, come la convalida incrociata e la ricerca della griglia, e come queste possano essere utilizzate per evitare che i modelli si adattino troppo ai dati storici.
Infine, è emersa l’importanza di un approccio bilanciato tra complessità computazionale e accuratezza del modello, ricordando che l’ottimizzazione dei parametri è un processo cruciale ma potenzialmente costoso, che richiede attenzione e consapevolezza nell’implementazione.
Il codice completo presentato in questa lezione è disponibile nel seguente repository GitHub: “https://github.com/tradingquant-it/TQResearch“