Modello autoregressivo a media mobile (ARMA) di ordine p, q

Modello autoregressivo a media mobile (ARMA)

In questa lezione descriviamo il modello autoregressivo a media mobile (ARMA) di ordine p,q. Nelle precedenti lezioni abbiamo introdotto i modelli autoregressivi e i modelli a media mobile. Ora combiniamo entrambi per ottenere un modello più sofisticato.

In definitiva, arriviamo ai modelli ARIMA e GARCH che ci aiutano a prevedere i rendimenti degli asset e a stimare la volatilità. Usiamo questi modelli come base per costruire segnali di trading e strategie di gestione del rischio.

Applichiamo il seguente schema per analizzare un modello di serie temporali:

  • Motivazione – Spieghiamo perché ci interessa questo particolare modello.
  • Definizione – Forniamo una definizione matematica per evitare ambiguità.
  • Correlogramma – Disegniamo un correlogramma di esempio per osservare il comportamento del modello.
  • Simulazione e adattamento – Adattiamo il modello alle simulazioni per comprenderlo a fondo.
  • Dati finanziari reali – Applichiamo il modello ai dati storici reali degli asset.
  • Predizione – Prevediamo i valori futuri per generare segnali o filtri di trading.

Criterio di informazione bayesiano

Nelle lezioni precedenti abbiamo descritto il Criterio di Informazione di Akaike (AIC) come strumento per scegliere tra i migliori modelli di serie temporali.

Utilizziamo anche il Bayesian Information Criterion (BIC), uno strumento strettamente correlato. Il BIC si comporta in modo simile all’AIC, poiché penalizza i modelli con troppi parametri, riducendo così il rischio di sovra-adattamento. Tuttavia, il BIC applica una penalizzazione più rigorosa ai parametri aggiuntivi.

Criterio di informazione bayesiano

Consideriamo la funzione di verosimiglianza per un modello statistico con K parametri e L che massimizza la verosimiglianza. Allora, il criterio di informazione bayesiano si calcola come:

\(\begin{eqnarray}BIC = -2 \text{log} (L) + k \text{log}(n)\end{eqnarray}\)

Dove \(n\) rappresenta il numero di punti dati nella serie temporale.

Utilizziamo AIC e BIC per selezionare i modelli ARMA(p,q) più adatti all’analisi delle serie storiche finanziarie.

Test Ljung-Box

Il test di Ljung-Box rappresenta un test di ipotesi fondamentale per verificare se un gruppo di autocorrelazioni associate a un modello di serie temporali differisce significativamente da zero. Il test non analizza la casualità di ogni singolo ritardo, ma valuta l’insieme dei ritardi.

Formalmente:

Test Ljung-Box

Definiamo l’ipotesi nulla \({\bf H_0}\) come: i dati delle serie temporali a ogni ritardo risultano iid, ovvero senza correlazioni seriali nella popolazione.

Definiamo l’ipotesi alternativa \({\bf H_a}\) come: i dati delle serie temporali non risultano iid e mostrano correlazione seriale.

Calcoliamo il seguente test statistico, \(Q\):

\(\begin{eqnarray}Q = n (n+2) \sum_{k=1}^{h} \frac{\hat{\rho}^2_k}{n-k}\end{eqnarray}\)

Dove n rappresenta la lunghezza del campione, \(\hat{\rho}_k\) l’autocorrelazione campionaria al ritardo k e h il numero di ritardi considerati.

Applichiamo la regola: rifiutiamo l’ipotesi nulla \({\bf H_0}\) se \(Q > \chi^2_{\alpha,h}\), con riferimento alla distribuzione chi quadrato con h gradi di libertà al percentile \(100(1-\alpha)\).

Nonostante i calcoli del test appaiano complessi, sfruttiamo Python per eseguire il test, rendendo la procedura più accessibile.

Modello autoregressivo a media mobile (ARMA) di ordine p, q

Ora che abbiamo analizzato il BIC e il test Ljung-Box, possiamo descrivere il nostro primo modello misto: il modello autoregressivo a media mobile (ARMA) di ordine p, q.

Fondamento logico

Fino ad ora abbiamo esplorato i processi autoregressivi e quelli a media mobile.

Nel primo caso, utilizziamo il comportamento passato della serie come input per catturare gli effetti dei partecipanti al mercato, come il momentum e il mean-reverting nel trading azionario.

Nel secondo, impieghiamo il modello per descrivere le informazioni di tipo “shock” presenti nella serie, come un annuncio di utili a sorpresa o un evento inatteso (ad esempio, la fuoriuscita di petrolio della BP Deepwater Horizon).

Un modello ARMA consente di includere entrambi gli aspetti durante la modellazione delle serie temporali finanziarie.

Dobbiamo ricordare che il modello autoregressivo a media mobile (ARMA) non rappresenta il clustering della volatilità, un fenomeno empirico chiave nelle serie finanziarie. Non consideriamo l’eteroscedasticità condizionata. Per modellarla, ci affideremo ai modelli ARCH e GARCH.

Definizione

Costruiamo il modello ARMA(p,q) come combinazione lineare di due modelli lineari; di conseguenza, anche esso risulta lineare:

Modello autoregressivo a media mobile (ARMA) di ordine p, q

Definiamo un modello per la serie storica \(\{ x_t \}\) come ARMA(p,q) se:

\(\begin{eqnarray}x_t = \alpha_1 x_{t-1} + \alpha_2 x_{t-2} + \ldots + w_t + \beta_1 w_{t-1} + \beta_2 w_{t-2} \ldots + \beta_q w_{t-q}\end{eqnarray}\)

Qui \(\{ w_t \}\) rappresenta il rumore bianco con \(E(w_t) = 0\) e varianza \(\sigma^2\).

Utilizziamo l’operatore di ritardo B e riscriviamo l’equazione come funzione di \(\theta\) e \(\phi\) in B:

\(\begin{eqnarray}\theta_p ({\bf B}) x_t = \phi_q ({\bf B}) w_t\end{eqnarray}\)

Quando impostiamo \(p \neq 0\) e \(q=0\), otteniamo il modello AR(p). Se invece poniamo \(p=0\) e \(q \neq 0\), otteniamo il modello MA(q).

Le caratteristiche principali del modello ARMA includono moderazione e ridondanza nei parametri. Infatti, spesso possiamo usare meno parametri rispetto ai modelli AR(p) o MA(q) separatamente. Inoltre, se riscriviamo l’equazione usando BSO, i polinomi \(\theta\) e \(\phi\) possono condividere un fattore comune, semplificando così il modello.

Simulazioni e Correlogrammi

Come abbiamo fatto per i modelli autoregressivi e a media mobile, ora simuliamo diverse serie ARMA e applichiamo i relativi modelli a queste realizzazioni. In questo modo esploriamo la procedura di adattamento, includendo il calcolo degli intervalli di confidenza e verificando se la procedura riesce a stimare correttamente i parametri ARMA originari.

Nella parte 1 e nella parte 2, abbiamo generato manualmente le serie AR e MA estraendo \(N\) campioni da una distribuzione normale e costruito i modelli applicando i ritardi a tali campioni.

ARMA(1,1)

Partiamo dal modello autoregressivo a media mobile (ARMA) più semplice non banale: il modello ARMA(1,1). In questo caso combiniamo un modello autoregressivo di ordine uno con un modello a media mobile di ordine uno. Il modello presenta solo due coefficienti, \(\alpha\) e \(\beta\), che rappresentano rispettivamente il primo ritardo della serie storica e il termine “shock” derivante dal rumore bianco. La forma del modello è:

\(\begin{eqnarray}x_t = \alpha x_{t-1} + w_t + \beta w_{t-1}\end{eqnarray}\)

Prima di avviare la simulazione, definiamo i coefficienti. Impostiamo \(\alpha = 0.5\) e \(\beta = 0.5\).

				
					import numpy as np
import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_acf
from statsmodels.tsa.arima_process import ArmaProcess

# Imposta il seed per la riproducibilità
np.random.seed(1)

# Definizione dei parametri ARMA(1,1)
phi = 0.5   # coefficiente AR
theta = -0.5  # coefficiente MA

# Definizione del modello (attenzione al segno)
ar = np.array([1, -phi])     # coefficiente AR in forma caratteristica
ma = np.array([1, theta])    # coefficiente MA

# Simulazione
np.random.seed(1)
arma_process = ArmaProcess(ar, ma)
x = arma_process.generate_sample(nsample=1000)

# Plot della serie simulata
plt.plot(x)
plot_acf(x, lags=30)
plt.show()
				
			
Modello Autoregressivo a Media Mobile (ARMA)

Dal correlogramma possiamo vedere che non c’è un’autocorrelazione significativa, come prevedibile da un modello ARMA(1,1).

Infine, proviamo a determinare i coefficienti e i loro errori standard utilizzando la  funzione ARIMA della libreria Statsmodels:

				
					from statsmodels.tsa.arima.model import ARIMA

model = ARIMA(x, order=(1, 0, 1))
result = model.fit()
print(result.summary())

				
			
				
					                               SARIMAX Results                                
==============================================================================
Dep. Variable:                      y   No. Observations:                 1000
Model:                 ARIMA(1, 0, 1)   Log Likelihood               -1397.793
Date:                                   AIC                           2803.586
Time:                        10:17:02   BIC                           2823.217
Sample:                             0   HQIC                          2811.048
                               - 1000                                         
Covariance Type:                  opg                                         
==============================================================================
                 coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
const          0.0387      0.030      1.274      0.203      -0.021       0.098
ar.L1         -0.7935      0.202     -3.934      0.000      -1.189      -0.398
ma.L1          0.7551      0.218      3.459      0.001       0.327       1.183
sigma2         0.9585      0.041     23.657      0.000       0.879       1.038
===================================================================================
Ljung-Box (L1) (Q):                   0.16   Jarque-Bera (JB):                 3.61
Prob(Q):                              0.69   Prob(JB):                         0.16
Heteroskedasticity (H):               1.00   Skew:                            -0.08
Prob(H) (two-sided):                  0.96   Kurtosis:                         3.25
===================================================================================

				
			

Possiamo calcolare gli intervalli di confidenza al 95% per ciascun parametro utilizzando gli errori standard:

				
					ar1 = result.params[1]
ma1 = result.params[2]

se_ar1 = result.bse[1]
se_ma1 = result.bse[2]

# Intervalli di confidenza 95%
ci_ar1 = ar1 + np.array([-1.96, 1.96]) * se_ar1
ci_ma1 = ma1 + np.array([-1.96, 1.96]) * se_ma1

print("IC 95% AR(1):", ci_ar1)
print("IC 95% MA(1):", ci_ma1)

				
			
				
					IC 95% AR(1): [-1.18888368 -0.39813188]
IC 95% MA(1): [0.32724963 1.18288939]
				
			

Gli intervalli di confidenza contengono i valori veri dei parametri in entrambi i casi, ma è importante notare che sono piuttosto ampi, a causa degli errori standard relativamente grandi.

ARMA(2,2)

Proviamo ora un modello ARMA(2,2). Ovvero, un modello AR(2) combinato con un modello MA(2). Dobbiamo specificare quattro parametri per questo modello \(\alpha_1\), \(\alpha_2\), \(\beta_1\), \(\beta_2\).

Consideriamo \(\alpha_1 = 0.5\), \(\alpha_1 = -0.25\), \(\beta_1 = 0.5\) e \(\beta_2 = -0.3\):

				
					import matplotlib.pyplot as plt
import numpy as np
from statsmodels.tsa.arima_process import ArmaProcess
from statsmodels.graphics.tsaplots import plot_acf

ar1 = np.array([1, -0.5, 0.25])
ma1 = np.array([1, 0.5, -0.3])
simulated_ARMA_data = ArmaProcess(ar1, ma1).generate_sample(nsample=1000)

plt.plot(simulated_ARMA_data)
plot_acf(simulated_ARMA_data, alpha=1, lags=30)
plt.show()
				
			
L’output del nostro modello ARMA(2,2) è il seguente:
Modello Autoregressivo a Media Mobile (ARMA)
Ora possiamo provare ad adattare un modello ARMA(2,2) ai dati e calcolare gli intervalli di confidenza per ogni parametro:
				
					from statsmodels.tsa.arima.model import ARIMA

# Stima del modello ARMA(2,2)
model = ARIMA(x, order=(2, 0, 2))
results = model.fit()
print(results.summary())

				
			
				
					                               SARIMAX Results                                
==============================================================================
Dep. Variable:                      y   No. Observations:                 1000
Model:                 ARIMA(2, 0, 2)   Log Likelihood               -1395.703
Date:                                   AIC                           2803.407
Time:                        12:21:43   BIC                           2832.853
Sample:                             0   HQIC                          2814.598
                               - 1000                                         
Covariance Type:                  opg                                         
==============================================================================
                 coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
const          0.0625      0.048      1.292      0.196      -0.032       0.157
ar.L1          0.4891      0.122      4.017      0.000       0.250       0.728
ar.L2         -0.2702      0.033     -8.190      0.000      -0.335      -0.206
ma.L1          0.4905      0.126      3.877      0.000       0.243       0.738
ma.L2         -0.2717      0.116     -2.350      0.019      -0.498      -0.045
sigma2         0.9530      0.041     23.403      0.000       0.873       1.033
===================================================================================
Ljung-Box (L1) (Q):                   0.00   Jarque-Bera (JB):                 4.01
Prob(Q):                              0.98   Prob(JB):                         0.13
Heteroskedasticity (H):               1.02   Skew:                            -0.07
Prob(H) (two-sided):                  0.83   Kurtosis:                         3.27
===================================================================================
				
			
Utilizziamo ora gli errori standard per calcolare gli intervalli di confidenza:
				
					
ar1 = result.params[1]
ar2 = result.params[2]
ma1 = result.params[3]
ma2 = result.params[4]

se_ar1 = result.bse[1]
se_ar2 = result.bse[2]
se_ma1 = result.bse[3]
se_ma2 = result.bse[4]

# Intervalli di confidenza 95%
ci_ar1 = ar1 + np.array([-1.96, 1.96]) * se_ar1
ci_ar2 = ar2 + np.array([-1.96, 1.96]) * se_ar2
ci_ma1 = ma1 + np.array([-1.96, 1.96]) * se_ma1
ci_ma2 = ma2 + np.array([-1.96, 1.96]) * se_ma2

print("IC 95% AR(1):", ci_ar1)
print("IC 95% AR(2):", ci_ar2)
print("IC 95% MA(1):", ci_ma1)
print("IC 95% MA(2):", ci_ma2)


				
			
				
					IC 95% AR(1): [0.25041264 0.72771175]
IC 95% AR(2): [-0.33481549 -0.20550619]
IC 95% MA(1): [0.24252497 0.73838166]
IC 95% MA(2): [-0.49834463 -0.04504921]
				
			
Esiste una reale possibilità che gli intervalli di confidenza per i coefficienti delle due componenti non includano i valori originali dei parametri. Questo ci mostra il rischio concreto di adattare i modelli ai dati, anche quando conosciamo i veri parametri!

Tuttavia, per fare trading, ci basta disporre di un potere predittivo che superi la casualità (come il lancio di una moneta) e ci garantisca un profitto sufficiente, al netto dei costi di transazione, per risultare redditizi nel lungo periodo.

Ora che abbiamo esplorato alcuni esempi di modelli ARMA simulati, dobbiamo definire un metodo che ci consenta di scegliere i valori di p e q quando adattiamo i modelli ai dati finanziari reali.

Scegliere il miglior modello ARMA(p,q)

Per stabilire quale ordine \(p,q\) del modello autoregressivo a media mobile (ARMA) risulti adeguato per una serie, utilizziamo l’AIC (oppure il BIC) su un sottoinsieme di valori per \(p,q\) e applichiamo il test di Ljung-Box per verificare se otteniamo un buon adattamento con specifici valori di \(p,q\).

Per spiegare questo approccio, simuliamo prima un particolare processo ARMA(p,q). Poi eseguiamo un ciclo su tutte le coppie \(p \in \{ 0,1,2,3,4 \}\) e \(q \in \{ 0,1,2,3,4 \}\), calcolando l’AIC per ciascuna. Scegliamo il modello con l’AIC più basso ed eseguiamo il test di Ljung-Box sui residui per confermare se abbiamo ottenuto un buon adattamento.

Iniziamo simulando una serie ARMA(3,2):

				
					import numpy as np
import statsmodels.api as sm
import itertools
import matplotlib.pyplot as plt

np.random.seed(2)

# Simuliamo un processo ARMA(3,2) con coefficienti specificati
arparams = np.array([0.5, -0.25, 0.4])
maparams = np.array([0.5, -0.3])
ar = np.r_[1, -arparams]  # statsmodels usa coefficenti negativi per AR
ma = np.r_[1, maparams]
x = sm.tsa.arma_generate_sample(ar, ma, nsample=1000)
				
			

Ora esaminiamo diversi valori di p e q e scegliamo i valori che puntano a AIC e/o BIC più piccoli.

Creiamo ora un oggetto best_model per memorizzare il miglior modello adattato e il valore più basso dell’AIC. Eseguiamo un ciclo su tutte le combinazioni possibili di p e q, utilizzando un oggetto temporaneo per salvare l’adattamento del modello ARMA(i,j), dove i e j sono le variabili del ciclo.

Se l’AIC corrente risulta inferiore a qualsiasi AIC calcolato in precedenza, aggiorniamo il valore finale dell’AIC con quello corrente e selezioniamo quell’ordine. Al termine del ciclo, l’ordine del modello ARMA sarà memorizzato in best_order, mentre l’adattamento ARIMA(p,d,q) (con il componente “Integrato” d impostato a 0) sarà memorizzato in best_model.

Formalmente, stiamo cercando di minimizzare l’AIC tra i modelli ARMA(p,q), ovvero:

\( \text{AIC} = -2 \log L + 2k \)

dove \( L \) è la verosimiglianza massima del modello e \( k \) è il numero di parametri stimati.

				
					# Ora cerchiamo l'ordine ottimale (p, q) per un modello ARMA utilizzando il criterio AIC
best_aic = np.inf
best_order = None
best_model = None

# Proviamo tutte le combinazioni (p, q) con p e q da 0 a 4
for p, q in itertools.product(range(5), range(5)):
    try:
        model = sm.tsa.ARIMA(x, order=(p, 0, q)).fit()
        current_aic = model.aic
        if current_aic < best_aic:
            best_aic = current_aic
            best_order = (p, 0, q)
            best_model = model
    except:
        continue
        
# Stampiamo i risultati finali
print("AIC finale:", best_aic)
print("Ordine ARMA trovato:", best_order)
print(best_model.summary())


				
			

Dopo aver eseguito il fitting dei modelli su diversi ordini p e q, possiamo valutare i risultati e ricavare l’ordine del modello migliore in base all’AIC minore.

				
					
AIC finale: 2856.0201478738413

Ordine ARMA trovato: (3, 0, 2)
     


				
			

Possiamo vedere che è l’ordine originale del modello ARMA simulato è stato selezionato come ordine migliore, cioè \(p=3\) e \(q=2\).

A conferma della bontà della nostra selezione, possiamo stampare il report prodotto dalla funzione ARMA dove si evidenzia che parametri stimati sono molto vicini ai valore reali. Inoltre l’intervallo di confidenza al 95% contiene i valori dei parametri veri e quindi possiamo giudicare il modello adatto.

				
					      SARIMAX Results                                
==============================================================================
Dep. Variable:                      y   No. Observations:                 1000
Model:                 ARIMA(3, 0, 2)   Log Likelihood               -1421.010
Date:                                   AIC                           2856.020
Time:                        12:52:23   BIC                           2890.374
Sample:                             0   HQIC                          2869.077
                               - 1000                                         
Covariance Type:                  opg                                         
==============================================================================
                 coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
const         -0.1667      0.101     -1.644      0.100      -0.365       0.032
ar.L1          0.5543      0.075      7.353      0.000       0.407       0.702
ar.L2         -0.2566      0.040     -6.438      0.000      -0.335      -0.179
ar.L3          0.3659      0.034     10.904      0.000       0.300       0.432
ma.L1          0.4216      0.077      5.498      0.000       0.271       0.572
ma.L2         -0.3547      0.073     -4.861      0.000      -0.498      -0.212
sigma2         1.0018      0.043     23.319      0.000       0.918       1.086
===================================================================================
Ljung-Box (L1) (Q):                   0.00   Jarque-Bera (JB):                 7.27
Prob(Q):                              0.95   Prob(JB):                         0.03
Heteroskedasticity (H):               0.83   Skew:                             0.18
Prob(H) (two-sided):                  0.09   Kurtosis:                         3.22
===================================================================================
				
			
Possiamo stampare il corelogramma dei residui del modello per verificare se corrisponde ad una realizzazione di rumore bianco discreto (DWN):
				
					from statsmodels.graphics.tsaplots import plot_acf

# Get residuals of the model
resid = res.resid
# Plot ACF of residuals
plot_acf(resid, alpha=1, lags=30)

				
			
Autocorrelazione residui modello
Il corelogramma sembra davvero una realizzazione di DWN. Per conferma possiamo eseguire il test Ljung-Box per 20 ritardi:
				
					from statsmodels.stats.diagnostic import acorr_ljungbox

# Ljung-Box test
resid = best_model.resid
ljung_box_result = acorr_ljungbox(resid, lags=[20], return_df=True)
print(ljung_box_result)
				
			
				
					lb_stat     lb_pvalue
15.390138   0.753666
				
			
Dato che il p-value è maggiore di 0,05, non possiamo rifiutare l’ipotesi nulla di indipendenza seriale. I residui non mostrano autocorrelazione significativa e sono indipendenti al livello del 95%. Possiamo concludere che un modello ARMA(3,2) fornisce un buon adattamento del modello. Chiaramente questo dovrebbe essere banale poiché abbiamo simulato i dati! Tuttavia, questa è esattamente la procedura che useremo quando arriveremo ad adattare il modello autoregressivo a media mobile (ARMA) all’indice S&P500 nel seguente paragrafo.

Analisi del modello per l’indice S&P500

Ora che abbiamo delineato la procedura per scegliere il modello di serie temporale ottimale per una serie simulata, è piuttosto semplice applicarlo ai dati finanziari. Per questo esempio scegliamo l’indice S&P500 dell’azionariato statunitenze. Scarichiamo i prezzi di chiusura giornalieri utilizzando yfinance e quindi creiamo il flusso dei  ritorni logaritmici:
				
					import numpy as np
import pandas as pd

import yfinance as yf
data = yf.download("^GSPC", period="max")

sp500 = np.log(data['Adj Close'] / data['Adj Close'].shift(1)).dropna()
				
			
Eseguiamo la stessa procedura di adattamento della serie ARMA(3,2) simulata sulla serie dei ritorni logaritmici dell’S&P500 utilizzando l’AIC:
				
					
import statsmodels.api as sm
import itertools

# Ricerca del modello ARMA(p,q) ottimale (con d=0) usando l'AIC
best_aic = np.inf
best_order = None
best_model = None

# Proviamo tutte le combinazioni (p, q) con p e q da 0 a 4
for p, q in itertools.product(range(5), range(5)):
    for q in range(5):
        try:
            model = sm.tsa.ARIMA(log_returns, order=(p, 0, q)).fit()
            current_aic = model.aic
            if current_aic < best_aic:
                best_aic = current_aic
                best_order = (p, 0, q)
                best_model = model
        except:
            continue

print("Ordine migliore:", best_order)
				
			
Il modello più adatto ha l’ordine ARMA(4,3):
				
					p =  4
q =  3
				
			
Tracciamo il grafico dei residui del modello adattato relativo al flusso dei ritorni logaritmici dei prezzi giornalieri dell’S&P500:
				
					# Plot dell'ACF dei residui del modello ottimale
residuals = best_model.resid
sm.graphics.tsa.plot_acf(residuals.dropna(), lags=30)
plt.show()
				
			
Modello Autoregressivo a Media Mobile ARMA 2 - sp500
Si noti che ci sono alcuni picchi significativi, specialmente a ritardi più elevati. Questo è indicativo di una scarsa vestibilità. Eseguiamo un test Ljung-Box per vedere se abbiamo prove statistiche per questo:
				
					from statsmodels.stats.diagnostic import acorr_ljungbox

# Ljung-Box test
resid = best_model.resid
ljung_box_result = acorr_ljungbox(resid, lags=[20], return_df=True)
print(ljung_box_result)
				
			
				
					Ljung-Box test: 40.390954304955045
p-value: 0.0044565024322041746
				
			

Come avevamo previsto, il p-value risulta inferiore a 0,05, quindi non possiamo affermare che i residui rappresentino una realizzazione di rumore bianco discreto. Di conseguenza, rileviamo ancora autocorrelazione nei residui, non spiegata dal modello ARMA(4,3) che abbiamo adattato.

Conclusioni

Durante l’analisi delle serie temporali con il modello autoregressivo a media mobile (ARMA), abbiamo identificato segni evidenti di eteroschedasticità condizionale (cluster di volatilità) nella serie S&P500, soprattutto nei periodi intorno al 2007-2008. Nelle prossime lezioni, quando introdurremo il modello GARCH, impareremo a rimuovere queste autocorrelazioni residui.

In generale, riteniamo che i modelli ARMA non offrano un’adeguata rappresentazione dei rendimenti logaritmici azionari. Per questo motivo, teniamo conto dell’eteroschedasticità condizionale e combiniamo i modelli ARIMA e GARCH. Nella prossima lezione descriveremo il modello ARIMA e chiariremo come il componente “Integrato” si differenzi dal modello ARMA che abbiamo studiato in questa lezione.

Il codice completo presentato in questa lezione è disponibile nel seguente repository GitHub: “https://github.com/tradingquant-it/TQResearch

Torna in alto