Finora su DataTrading abbiamo parlato dell’identificazione di strategie di trading algoritmico, il backtesting, i securities master database dei titoli e come creare un ambiente di sviluppo software. È giunto il momento di rivolgere la nostra attenzione alla creazione di strategie di trading e di come implementarle.
Uno dei concetti chiave nella cassetta degli attrezzi del trader quantitativo è quello della mean reversion. Questo concetto si riferisce ad una serie temporale che mostra una tendenza a ritornare verso valore medio. Matematicamente, una tale serie temporale (continua) viene definita processo Ornstein-Uhlenbeck. Questo è in contrasto con random walk (moto Browniano), dove non si prevede “memoria” dei valori pregressi in ogni specifica istanza di tempo. La proprietà mean-reverting di una serie temporale può essere sfruttata al fine di produrre strategie di trading redditizie.
In questo articolo verranno illustrati i test statistici necessari per identificare la mean reversion. In particolare, studieremo il concetto di stazionarietà e come testarla.
Testing per la Mean Reversion
\(\begin{eqnarray}
d x_t = \theta (\mu – x_t) dt + \sigma dW_t
\end{eqnarray}\)
Dove θ è la velocità del processo di reversion, μ è il prezzo medio di lungo periodo verso cui avviene la reversione, σ è la varianza del processo e Wt è un processo Wiener o moto browniano.
L’equazione afferma che la “tendenza” delle serie di prezzi nel prossimo periodo di tempo è proporzionale alla differenza tra il prezzo medio e il prezzo corrente, con l’aggiunta del rumore gaussiano.
Questa proprietà è dimostata del test Augmented Dickey-Fuller, che descriveremo di seguito.
Il Test Dickey-Fuller Aumentato (ADF)
Matematicamente, l’ADF si basa sulla verifica della presenza di un trend o radici unitarie a root unit in un campione di serie temporali autoregressive. Sfrutta il fatto che se una serie di prezzi possiede una mean revertion, allora il livello di prezzo successivo sarà proporzionale al livello di prezzo corrente.
Queste serie storiche sono rappresentate matimaticamente da un modello di regressione lineare di ordine p:
\(\begin{eqnarray}
\Delta y_t = \alpha + \beta t + \gamma y_{t-1} + \delta_1 \Delta y_{t-1} + \cdots + \delta_{p-1} \Delta y_{t-p+1} + \epsilon_t
\end{eqnarray}\)
Dove α è una costante, β rappresenta il coefficiente di andamento temporale e Δyt = y (t) -y (t-1).
Il test ADF prevede che il processo autogressivo di ordine p=1 abbia una media nulla, cioè γ = 0, che si traduce con α = β = 0 e quindi identifica il processo come casuale e non mean-reverting.
Se si può eliminare l’ipotesi che γ = 0, allora il movimento della serie di prezzi è proporzionale al prezzo corrente e quindi è improbabile che sia casuale.
Quindi, come viene eseguito il test ADF? Il primo compito è calcolare la statistica di prova \(DF_{\tau}\), che è data dalla costante di proporzionalità del campione \(\hat{\gamma}\) divisa per l’errore standard della costante di proporzionalità del campione:
Dickey e Fuller hanno calcolato la distribuzione di questa statistica di test, che ci consente di scartare l’ipotesi per qualsiasi specifico valore percentuale scelto. La statistica del test è un numero negativo e quindi, per essere significativo, il numero deve essere più negativo di questi valori, cioè inferiore ai valori critici.
In sostanza, per i trader è che qualsiasi deriva a lungo termine in termini di prezzo è molto probabile rispetto a qualsiasi fluttuazione a breve termine e quindi il modello approssima a zero la deriva (β = 0).
Poiché stiamo considerando un modello di regressione di ordine p, è necessario definire p con uno specifico valore. Di solito è sufficiente, per le strategie di trading, impostare p = 1 per consentirci scartare l’ipotesi nulla.
Per calcolare il test Dickey-Fuller aumentato possiamo utilizzare le librerie pandas e statsmodels. La prima ci fornisce un metodo diretto per ottenere i dati Open-High-Low-Close-Volume (OHLCV) da Yahoo Finance, mentre il secondo implementa il test ADF in una funzione facile da richiamare.
Effettueremo il test ADF su i dati storici delle azioni di Google, dal 1 ° gennaio 2000 al 1 ° gennaio 2013.
# Import the Time Series library
import statsmodels.tsa.stattools as ts
# Import Datetime and the Pandas DataReader
from datetime import datetime
from pandas.io.data import DataReader
# Download the Google OHLCV data from 1/1/2000 to 1/1/2013
goog = DataReader("GOOG", "yahoo", datetime(2000,1,1), datetime(2013,1,1))
# Output the results of the Augmented Dickey-Fuller test for Google
# with a lag order value of 1
ts.adfuller(goog['Adj Close'], 1)
(-2.1900105430326064,
0.20989101040060731,
0,
2106,
{'1%': -3.4334588739173006,
'10%': -2.5675011176676956,
'5%': -2.8629133710702983},
15436.871010333041)
Testing per la Stazionarità
Esponente Hurst
Una serie temporale può quindi essere caratterizzata nel seguente modo:
- H <0,5 – Le serie temporali sono mean reverting;
- H = 0.5 – Le serie temporali sono in un moto browniano geometric;
- H> 0,5 – Le serie temporali sono in trend
Oltre alla caratterizzazione delle serie temporali, l’esponente di Hurst descrive anche il grado in cui una serie si comporta nel modo categorizzato. Ad esempio, un valore di H vicino allo 0 vuol dire che una serie ha un’elevata mean-reverting, mentre per H vicino a 1 la serie è fortemente in trend.
Per calcolare l’esponente di Hurst per la serie di prezzi di Google, gli stessi ustati come esempio per l’ADF, possiamo usare il seguente codice Python:
from numpy import cumsum, log, polyfit, sqrt, std, subtract
from numpy.random import randn
def hurst(ts):
"""Returns the Hurst Exponent of the time series vector ts"""
# Create the range of lag values
lags = range(2, 100)
# Calculate the array of the variances of the lagged differences
tau = [sqrt(std(subtract(ts[lag:], ts[:-lag]))) for lag in lags]
# Use a linear fit to estimate the Hurst Exponent
poly = polyfit(log(lags), log(tau), 1)
# Return the Hurst exponent from the polyfit output
return poly[0]*2.0
# Create a Gometric Brownian Motion, Mean-Reverting and Trending Series
gbm = log(cumsum(randn(100000))+1000)
mr = log(randn(100000)+1000)
tr = log(cumsum(randn(100000)+1)+1000)
# Output the Hurst Exponent for each of the above series
# and the price of Google (the Adjusted Close price) for
# the ADF test given above in the article
print "Hurst(GBM): %s" % hurst(gbm)
print "Hurst(MR): %s" % hurst(mr)
print "Hurst(TR): %s" % hurst(tr)
# Assuming you have run the above code to obtain 'goog'!
print "Hurst(GOOG): %s" % hurst(goog['Adj Close'])
Hurst(GBM): 0.500606209426
Hurst(MR): 0.000313348900533
Hurst(TR): 0.947502376783
Hurst(GOOG): 0.50788012261
Da questa output si nota come il movimento browniano geometrico possiede un esponente di Hurst, H, che è quasi esattamente 0,5. La serie di mean reverting ha H quasi uguale a zero, mentre la serie in trend ha H vicino a 1.
È interessante notare che Google ha anche H quasi uguale a 0,5 che indica che è estremamente simile ad una random walk geometrica (almeno nel periodo considerato).
Ora che abbiamo un metodo per caratterizzare la natura di una serie temporale di prezzi, dobbiamo discutere quanto il valore H sia statisticamente significativo. Dobbiamo essere in grado di determinare se sia possiamo rifiutare l’ipotesi nulla che H = 0.5 in modo da valutare un comportamento mean reverting o di trend.
Negli articoli successivi descriveremo come calcolare che H è statisticamente significativa. Inoltre, prenderemo in considerazione il concetto di cointegrazione, che ci consentirà di creare le nostre serie temporali di mean-reverting da più serie di prezzi differenti. Infine, uniremo insieme queste tecniche statistiche al fine di formare una strategia di trading mean reverting di base.