Capitolo 3 Stima e Previsione con i modelli GARCH
3.2 Stima e previsione sul NASDAQ
Il primo passo da fare è quello di caricare i dati scaricati da yahoo finance su MATLAB
e per fare ciò si crea un live script:
Nasdaq=readtable(‘Nasdaq.csv’) Quello che si può fare dopo è:
- Realizzare una function (come è stato fatto nel capitolo 1 per il calcolo della
volatilità giornaliera annualizzata) e caricarla nel live script;
- Procedere per passi nel live script.
38 El Jebari O., Hakmaouoi A., GARCH Family Models vs EWMA: Which is the best Model to Forecast
Volatility of the Moroccan Stock Exchange Market?, Revista De Métodos cuantitativos para la Economia
76
Per dare una piena visione della metodologia utilizzata si procederà per passi andando a
calcolare i vari modelli, o comunque i dati di cui abbiamo bisogno, nel live script.
Nel paragrafo 3.3 si riporterà la function che sarebbe stata opportuna per andare a fare gli
stessi passaggi.
Per prima cosa andiamo a calcolare i rendimenti logaritmici
N=length(Nasdaq.Date); %lunghezza della serie Rclose=zeros(N,1);
for i=2:N
Rclose(i)=(log(Nasdaq.Close(i))-log(Nasdaq.Close(i-1)));%rendimenti
end
Successivamente si procede a creare:
- una variabile numperiods che indica il numero di giorni in cui vogliamo fare la
previsione;
- due vettori colonna (aic e bic) contenenti zeri che saranno utilizzati
successivamente per i criteri di informazione;
numperiods=10;%numperiods sono il numero di giorni per cui si intende fare previsione
aic=zeros(3,1); bic=zeros(3,1);
Adesso abbiamo tutto il necessario per procedere alla stime del primo modello, ovvero l’ARCH(1):
opts = optimset(‘fmincon’); %ARCH(1)
%si stima l’ARCH(1)
Mdl1=garch(‘Offset’,NaN,’ARCHLags’,1,’Distribution’,’Gaussian’); [EstMdl1,EstParamCov1,logL1] =
estimate(Mdl1,Rclose,’Options’,opts,’Display’,’off’); vF1 = forecast(EstMdl1,numperiods,Rclose);%previsione v=infer(EstMdl1,Rclose);%stima
NumParam1=sum(any(EstParamCov1));
[aic(1),bic(1)]=aicbic(logL1,NumParam1,N) %si calcola l’Akaike e il BIC
Ciò che si va a fare con tali comandi è la stima dei parametri del modello ARCH, la stima
77
estimate abbinato a quello summarize ci fornisce in automatico, ma l’idea era quella di far vedere come calcolare tali criteri con la funzione apposita).
Dalla figura 3.1 possiamo notare 4 diverse colonne:
- Value: indica il valore del parametro stimato.
- Standard Error: indica la misura dell’imprecisione delle stime.
- Tstatistic: è dato dal rapporto tra Value e Standard Error e indica se il valore del
parametro stimato si discosta significativamente da 0.
- Pvalue: è una quantità che misura l’evidenza fornita dai dati contro l’ipotesi nulla; in particolare minore è il valore del pvalue e più forte è l’evidenza contro l’ipotesi nulla.
Adesso andiamo a vedere i risultati ottenuti:
- i parametri risultano tutti significativamente diversi da 0 per un livello di
significatività del 5%. Infatti, il pvalue risulta inferiore a 0.05;
- i criteri di informazione AIC e BIC risultano pari a -27063.2 e -27043.8 (che
dovranno essere confrontati con gli altri modelli);
Figura 3.1
Stima del modello ARCH(1).
Possiamo andare a notare come la funzione per calcolare i criteri AIC e BIC restituisca
78
Figura 3.2
Criteri di informazione AIC e BIC
Fatto ciò si procede ad operare allo stesso modo per i modelli GARCH(1,1) e
EGARCH(1,1):
%GARCH(1,1) Mdl2=
garch(‘Offset’,NaN,’GARCHLags’,1,’ARCHLags’,1,’Distribution’,’Gaussian’); [EstMdl2,EstParamCov2,logL2] =
estimate(Mdl2,Rclose,’Options’,opts,’Display’,’off’); nr=100; vF2 = forecast(EstMdl2,numperiods,Rclose); v2=infer(EstMdl2,Rclose); NumParam2=sum(any(EstParamCov2)); [aic(2),bic(2)]=aicbic(logL2,NumParam2,N) summarize(EstMdl2) %EGARCH(1,1)
Mdl3=egarch(‘Offset’,NaN,’GARCHLags’,1,’ARCHLags’,1,’LeverageLags’,1,’Dis tribution’,’Gaussian’);
[EstMdl3,EstParamCov3,logL3] =
estimate(Mdl3,Rclose,’Options’,opts,’Display’,’off’); vF3 = forecast(EstMdl3,numperiods,Rclose);
v3=infer(EstMdl3,Rclose);
NumParam3=sum(any(EstParamCov3));
[aic(3),bic(3)]=aicbic(logL3,NumParam3,N)
Quello che dobbiamo andare a fare adesso è vedere se i parametri sono statisticamente
79
Figura 3.3
Stima del modello GARCH(1,1).
Anche qua i parametri risultano significativamente diversi da 0 per un livello di
significatività del 5%, dal momento che il pvalue risulta inferiore a 0.05.
Anche qua possiamo confrontare i criteri di informazione stimati in automatico e quelli
calcolati attraverso il comando aicbic:
Figura 3.4
Criteri di informazione AIC e BIC
Dal momento che avevamo costruito due vettori di zeri (3x1) denominati aic e bic, nella prima riga abbiamo i risultati dei criteri di informazione per quanto riguarda l’ARCH(1), nella seconda riga quelli del GARCH(1,1), nella terza riga avremo successivamente quelli dell’EGARCH(1,1).
Possiamo notare come i criteri di informazione AIC e BIC del modello GARCH(1,1)
calcolati con la funzione aicbic siano essenzialmente gli stessi rispetto a quelli calcolati
in automatico da MATLAB.
80
Figura 3.5
Stima del modello EGARCH(1,1).
In questo caso, i parametri risultano tutti significativamente diversi da 0 ad eccezione di
offset che rappresenta la media. Possiamo notare come il pvalue sia “lievemente” maggiore del valore soglia fissato a 0.05 (5%).
Altro fatto da considerare è il parametro γ (leverage) che risulta < 0 come era da attendersi: infatti questo parametro coglie l’asimmetria, già descritta in precedenza, secondo cui rendimenti negativi tendano a far aumentare la volatilità.
C’è infatti da ricordarsi che:
𝜀𝑡 = 𝜎𝑡𝑧𝑡 log 𝜎𝑡2 = 𝜔 + ∑ 𝛽𝑖𝑙𝑜𝑔(𝜎𝑡−𝑖2 ) 𝑃 𝑖=1 + ∑ 𝛼𝑗[|𝜀𝑡−𝑗| 𝜎𝑡−𝑗 − 𝐸 { |𝜀𝑡−𝑗| 𝜎𝑡−𝑗 }] 𝑄 𝑗=1 + ∑ 𝛾𝑗(𝜀𝑡−1 𝜎𝑡−1) 𝑄 𝑗=1 Dove 𝐸 {|𝜀𝑡−𝑗| 𝜎𝑡−𝑗} = √ 2 𝜋 se 𝑧𝑡 è gaussiana.
Quindi se γ < 0 e 𝜀𝑡−1 è negativo, allora aumenterà la volatilità; se 𝜀𝑡−1 è positivo si avrà una volatilità minore (proprio perché il parametro γ < 0).
81
Figura 3.6
Criteri di Informazione AIC e BIC
Possiamo notare come i criteri calcolati e quelli sviluppati in automatico coincidano.
Quello che possiamo fare adesso è andarci a costruire una tabella, con il comando table,
per andare a confrontare i criteri AIC e BIC dei diversi modelli:
%Tabella con i risultati dei due criteri d’informazione Akaike e %Schwarz(BIC)
NomiRighe={‘ARCH(1)’;’GARCH(1,1)’;’EGARCH(1,1)’}; AICBIC=table(aic,bic,’RowNames’,NomiRighe)
Figura 3.7
Tabella contenente i Criteri di Informazione dei diversi modelli
Possiamo notare come l’EGARCH(1,1) abbia i valori minori rispetto a tali criteri e per questo sia da preferire.
In linea generale questo criterio viene usato molto quando si usano modelli con molti lag o comunque superiori a 1, poiché tende a penalizzare l’aumento dei parametri da stimare; possiamo ricordarci dal capitolo 2 come vengono calcolati tali criteri:
𝐴𝐼𝐶 = −2(𝑙𝑜𝑔𝐿) + 2(𝑁𝑢𝑚𝑒𝑟𝑜𝑃𝑎𝑟𝑎𝑚𝑒𝑡𝑟𝑖)
82
Quello che possiamo fare adesso è andare a plottare le stime della volatilità dei vari
modelli:
%plottaggi volatilità stimate subplot(3,1,1) plot(Nasdaq.Date,v,’k—'); grid on; grid minor; title(‘ARCH(1)’) subplot(3,1,2) plot(Nasdaq.Date,v2,’k—'); grid on; grid minor; title(‘GARCH(1,1)’) subplot(3,1,3) plot(Nasdaq.Date,v3,’k—'); grid on; grid minor; title(‘EGARCH(1,1)’)
Dalla figura 3.8 è possibile vedere i plottaggi delle volatilità stimate con i vari modelli
utilizzati.
Dai grafici vediamo in particolare due situazioni in cui l’indice è stato particolarmente volatile: attorno agli anni 2000 (bolla delle dot-com) e verso la fine del 2008 per la crisi
dei mutui subprime.
Figura 3.8
83
Quello che si può andare a fare adesso è calcolare i residui standardizzati:
𝑧̂𝑡= 𝑦𝑡− 𝜇 √𝜎̂𝑡2 %%%%%% residui standardizzati resARCH =(Rclose-EstMdl1.Offset)./sqrt(v); resGARCH =(Rclose-EstMdl2.Offset)./sqrt(vi2); resEGARCH =(Rclose-0)./sqrt(vi3);
I residui standardizzati sono calcolati come i rendimenti meno la media, tutto diviso la radice della varianza (stimata). Per quanto riguarda l’EGARCH(1,1), la stima della media (offset) ci aveva dato un valore non significativamente diverso da 0, per cui si è
tralasciata.
Una volta che abbiamo trovato i residui, possiamo andarli a plottare successivamente ad
analizzare:
%studio dei residui standardizzati %ARCH(1)
figure
subplot(4,1,1) plot(resARCH) xlim([0,N])
title(‘ARCH(1) Residui standardizzati’) subplot(4,1,2) autocorr(resARCH) subplot(4,1,3) parcorr(resARCH) subplot(4,1,4) histogram(resARCH) %GARCH(1) figure subplot(4,1,1) plot(resGARCH) xlim([0,N])
title(‘GARCH(1) Residui standardizzati’) subplot(4,1,2)
autocorr(resGARCH) subplot(4,1,3)
84 parcorr(resGARCH) subplot(4,1,4) histogram(resGARCH) %EGARCH(1) figure subplot(4,1,1) plot(resEGARCH) xlim([0,N])
title(‘EGARCH(1) Residui standardizzati’) subplot(4,1,2) autocorr(resEGARCH) subplot(4,1,3) parcorr(resEGARCH) subplot(4,1,4) histogram(resEGARCH) Figura 3.9
85
Figura 3.10
Residui standardizzati GARCH(1,1).
Figura 3.11
86
Per analizzare i residui standardizzati, si procede ad effettuare un test denominato Test di
Ljung-Box che in generale ci consente di stabilire se le osservazioni di una serie storica presentano autocorrelazione: 𝐿𝐵 = 𝑇(𝑇 + 2) ∑ ( 𝜌(𝑘) 2 (𝑇 − 𝑘)) 𝐿 𝑘=1
Dove T è l’ampiezza del campione, L il numero di lag, e 𝜌(𝑘) l’autocorrelazione al lag k L’ipotesi nulla di tale test prevede l’assenza di autocorrelazione, per cui:
{𝐻0: 𝜌1 = 𝜌2 = . .. = 𝜌𝐿 = 0 𝑎𝑠𝑠𝑒𝑛𝑧𝑎 𝑑𝑖 𝑎𝑢𝑡𝑜𝑐𝑜𝑟𝑟𝑒𝑙𝑎𝑧𝑖𝑜𝑛𝑒 𝑓𝑖𝑛𝑜 𝑎𝑙𝑙
′𝑜𝑟𝑑𝑖𝑛𝑒 𝐿
𝐻1: ∃ 𝜌𝑘≠ 0 , 𝑐𝑜𝑛 𝑘 = 1, 2, … , 𝑘 𝑝𝑟𝑒𝑠𝑒𝑛𝑧𝑎 𝑑𝑖 𝑢𝑛𝑎 𝑞𝑢𝑎𝑙𝑐ℎ𝑒 𝑎𝑢𝑡𝑜𝑐𝑜𝑟𝑟𝑒𝑙𝑎𝑧𝑖𝑜𝑛𝑒
Quello che dobbiamo fare adesso è scrivere il codice su MATLAB per calcolare tale test:
%test residui standardizzati pvalue=zeros(1,3);
[~,pvalue(1,1)]=lbqtest(resARCH); [~,pvalue(1,2)]=lbqtest(resGARCH); [~,pvalue(1,3)]=lbqtest(resEGARCH);
Inoltre, ciò che si va a fare adesso, è costruire una tabella che riporti i risultati del test per
i residui dei diversi modelli analizzati:
Test=table(pvalue’,’RowNames’,NomiRighe);
Test.Properties.VariableNames={‘pvalueLjungBox’}; Test
Figura 3.12
87
Da tale test si può facilmente intravedere come solo il GARCH(1,1) abbia i residui
standardizzati scorrelati con un livello di significatività del 5%; per l’ARCH(1) e l’EGARCH(1,1) si rifiuta l’ipotesi di assenza di autocorrelazione.
Per verificare ciò, andiamo anche a vedere per esempio il grafico che rappresenta l’autocorrelazione dei residui standardizzati del modello ARCH(1).
Figure
autocorr(resARCH,40)
title(‘Autocorrelazione residui standardizzati ARCH(1)’)
Dalla figura 3.13, infatti, possiamo notare la presenza di autocorrelazione; si può
intravederla al lag 2, 12, 13, 16, 18, 34, 36.
Figura 3.13
Autocorrelazione dei residui standardizzati del modello ARCH(1).
Quello che si può inoltre fare è andare a vedere le autocorrelazioni del GARCH(1,1) e dell’EGARCH(1,1):
figure
autocorr(resEGARCH,40)
88
Figura 3.14
Autocorrelazione dei residui standardizzati del modello EGARCH(1,1).
Figure
autocorr(resGARCH,40)
title(‘Autocorrelazione residui standardizzati GARCH(1,1)’)
Figura 3.15
89
L’EGARCH(1,1), a differenza dell’ARCH(1), non presenta segnali molto forti di autocorrelazione, tuttavia con il test effettuato precedentemente non si accetta l’ipotesi
nulla (per un livello di significatività del 5%).
Per quanto riguarda il GARCH(1,1), dove mediante il test effettuato in precedenza si accetta l’ipotesi nulla, si può intravedere una lieve forma di autocorrelazione al lag 16; tuttavia, il test non la ritiene significativa.
Un altro test che è possibile effettuare è quello di Normalità attraverso il Test di Jarque-
Bera. In linea generale, tale test stabilisce se una serie storica ha una distribuzione empirica approssimabile a una normale (ipotesi nulla) oppure no (ipotesi alternativa):
𝐽𝐵 = 𝑇 [𝛾3
2
6 +
(𝛾4− 3)2
24 ]
Dove 𝛾3 e 𝛾4 rappresentano gli indici di asimmetria e di curtosi.
Adesso scriviamo il codice per effettuare tale test; anche adesso andremo a costruire una
tabella che avrà al suo interno i risultati del test (esattamente come avevamo fatto prima):
p=zeros(1,3);
[~,p(1,1)]=jbtest(resARCH);
Warning: P is less than the smallest tabulated value, returning 0.001.
[~,p(1,2)]=jbtest(resGARCH);
Warning: P is less than the smallest tabulated value, returning 0.001.
[~,p(1,3)]=jbtest(resEGARCH);
Warning: P is less than the smallest tabulated value, returning 0.001.
TestNormal=table(p’,’RowNames’,NomiRighe);
TestNormal.Properties.VariableNames={‘pvalueJarqueBera’}; TestNormal
In questo caso MATLAB ci avverte che il pvalue non è stato trovato nell’intervallo che
comprende un range tra [0.001, 0.50]; il test, infatti, ci avverte che il valore trovato (estremamente basso) può mettere in dubbio la validità dell’ipotesi nulla.
In questo caso possiamo ricorrere al Maximum Monte Carlo Standard Error (mctol) che è l’errore dovuto alla simulazione del pvalue:
90
𝑆𝐸 = √𝑝̂ − (1 − 𝑝̂) 𝑚𝑐𝑟𝑒𝑝𝑠
Dove 𝑝̂ è il valore stimato del pvalue mentre mcreps è il numero di repliche Monte Carlo
eseguite.
Adesso, riproviamo ad effettuare il test, specificando un valore per mctol pari a 0.0001:
p=zeros(1,3);
[~,p(1,1)]=jbtest(resARCH,[],0.0001); [~,p(1,2)]=jbtest(resGARCH,[],0.0001); [~,p(1,3)]=jbtest(resEGARCH,[],0.0001); TestNormal=table(p’,’RowNames’,NomiRighe);
TestNormal.Properties.VariableNames={‘pvalueJarqueBera’}; TestNormal
Non abbiamo più l’avvertimento di MATLAB; come possiamo andare a vedere dalla tabella sottostante, l’ipotesi nulla di distribuzione normale viene rifiutata.
Figura 3.16
Test Jarque-Bera residui standardizzati
Adesso proviamo a confrontare gli istogrammi dei residui standardizzati con il
91
Figura 3.17
Distribution Fitter MATLAB, residui standardizzati ARCH(1)
Per prima cosa selezioniamo i residui del modello ARCH(1) e successivamente create
92
Figura 3.18
Distribution Fitter MATLAB, residui standardizzati ARCH(1)
Questa è la distribuzione dei residui standardizzati (figura 3.18) che adesso possiamo
confrontare con la distribuzione Normale attraverso i comandi New Fit e successivamente
su Normal (figura 3.19).
Adesso, cliccando su apply, abbiamo i nostri dati confrontati con quelli di una
93
Figura 3.19
Costruzione della distribuzione Normale
Figura 3.20
94
Come possiamo vedere (come d’altronde ci aspettavamo visto il test effettuato in precedenza), i residui standardizzati non presentano la forma di una normale.
Possiamo procedere nello stesso modo andando a confrontare i residui standardizzati dei
modelli GARCH(1,1) e EGARCH(1,1), ottenendo:
Figura 3.21
Confronto tra distribuzione dei residui standardizzati GARCH(1,1) e distribuzione Normale
Figura 3.22
95
In particolar modo, notiamo una certa asimmetria nella distribuzione dei residui standardizzati dei 3 modelli (infatti l’indice asimmetria risulta minore di 0) e, inoltre, le distribuzioni sono leptocurtiche (con curtosi maggiore di 3).
Quello che andremo a fare adesso, invece, è di rappresentare graficamente le stime e la
previsione. Sostanzialmente, abbiamo utilizzato tutto il campione a nostra disposizione
per stimare i parametri e, con questi, stimato la volatilità.
Successivamente, abbiamo fatto una previsione fino a 10 giorni. Dal momento che il
nostro campione arrivava fino al 30 agosto, abbiamo cercato di prevedere la volatilità fino
al 10 settembre.
Per prima cosa, per rendere più visibile il grafico, prendiamo un punto da cui partire:
Start=4670; %punto di partenza per costruzione del grafico dates=Nasdaq.Date(Start:N);
Quello che possiamo fare ora è plottare la volatilità stimata e quella prevista del
modello ARCH(1)
%ARCH(1) figure
plot(dates,v(Start:N),’k:’,’LineWidth’,2); hold on;
plot(dates(end):dates(end) + numperiods,[v(end);vF1],’r’,’LineWidth’,2); title(‘Varianza Condizionata prevista con ARCH(1)’);
ylabel(‘Varianza Condizionata’); xlabel(‘Date’);
legend(‘Varianza Condizionata Stimata (Insample)’,’Varianza Condizionata prevista’);
grid on; grid minor; axis tight
96
Figura 3.23
Varianza Condizionata ARCH(1)
Adesso possiamo fare la stessa cosa per il GARCH(1,1) e l’EGARCH(1,1):
%GARCH(1,1) figure
plot(dates,v2(Start:N),’k:’,’LineWidth’,2); hold on;
plot(dates(end):dates(end) + numperiods,[v2(end);vF2],’r’,’LineWidth’,2); title(‘Varianza Condizionata con GARCH(1,1)’);
ylabel(‘Varianza Condizionata’); xlabel(‘Date’);
legend(‘Varianza Condizionata Stimata (Insample)’,’Varianza Condizionata prevista’,’Location’,’Best’);
grid on; grid minor; axis tight
97
Figura 3.24
Varianza Condizionata GARCH(1,1)
Mentre per quanto riguarda l’EGARCH(1,1) %EGARCH(1,1)
figure
plot(dates,v3(Start:N),’k:’,’LineWidth’,2); hold on;
plot(dates(end):dates(end) + numperiods,[v3(end);vF3],’r’,’LineWidth’,2); title(‘Varianza Condizionata con EGARCH(1,1)’);
ylabel(‘Varianza Condizionagta’); xlabel(‘Date’);
legend(‘Varianza Condizionata Stimata (Insample)’,’Varianza Condizionata prevista’,’Location’,’Best’);
grid on; grid minor; axis tight
98
Figura 3.25
Varianza Condizionata EGARCH(1,1)
Per quanto riguarda il secondo periodo preso come riferimento (30/08/13 – 30/08/19),
seguendo gli stessi passaggi effettuati per il periodo precedente, otteniamo:
Figura 3.26 Criteri di informazione
Il modello con i minori Akaike e BIC, anche qua, è l’EGARCH(1,1). Per quanto riguarda i test sui residui:
Figura 3.27 Test residui standardizzati
99
Anche in questo caso, solo il GARCH(1,1) presenta residui standardizzati scorrelati, anche se l’ARCH(1) è “molto vicino” alla soglia di 0,05. Per quanto riguarda il secondo test, nessuno dei tre modelli analizzati ha i residui distribuiti normalmente.
Adesso ci concentreremo soltanto sulle previsioni, cercando di andare a capire, a 10, 20,
30, 40, 50 e 100 giorni quale sia il modello migliore.
Per i calcoli precedenti abbiamo utilizzato tutto il campione a nostra disposizione, mentre
adesso ci servono dei dati da tenere fuori (outofsample) per poi fare un confronto con la
proxy della volatilità realizzata e calcolare il MSE. Il procedimento iniziale è lo stesse del precedente:
Nasdaq=readtable('Nasdaq20002019.csv')
N=length(Nasdaq.Date); %lunghezza della serie Rclose=zeros(N,1);
for i=2:N
Rclose(i)=(log(Nasdaq.Close(i))-log(Nasdaq.Close(i-1)));%rendimenti
end
Ma adesso teniamo dei dati fuori dal campione
Num=(N-100); %teniamo 100 giorni fuori dal campione
Poi si stimano i parametri esattamente come prima e, successivamente, si fa le previsioni;
a seguire si calcola il MSE. Utilizzeremo come proxy della volatilità il Garman Klass
estimator che è considerato migliore in quanto i rendimenti al quadrato sono una proxy molto “rumorosa” della volatilità:
𝐺𝑎𝑟𝑚𝑎𝑛 𝑎𝑛𝑑 𝐾𝑙𝑎𝑠𝑠 → 𝜎̂𝑡2 = 0.5 ∗ (𝑙𝑛𝐻𝑡 𝐿𝑡) 2 −(2𝑙𝑛2 − 1) ∗ [ln (𝐶𝑡 𝑂𝑡)] 2
%Garman and Klass GK=zeros(N,1); for k=1:N GK(k)=0.5*(log(Nasdaq.High(k)/Nasdaq.Low(k)))^2-(2*log(2)- 1)*(log(Nasdaq.Close(k)/Nasdaq.Open(k)))^2; end R1=sqrt(GK);
100
numperiods=10;
vF1 = forecast(EstMdl1,numperiods,nr); vF2 = forecast(EstMdl2,numperiods,nr); vF3 = forecast(EstMdl3,numperiods,nr); %Calcolo Mean Squared Error (MSE)
MSEARCH=zeros(numperiods,1); MSEGARCH=zeros(numperiods,1); MSEEGARCH=zeros(numperiods,1); for j=1:numperiods MSEARCH(j)=(R1(j)-sqrt(vF1(j)))^2; MSEGARCH(j)=(R1(j)-sqrt(vF2(j)))^2; MSEEGARCH(j)=(R1(j)-sqrt(vF3(j)))^2; end
msearch=(sum(MSEARCH))/numperiods;%MSE ARCH(1)
msegarch=(sum(MSEGARCH))/numperiods;%MSE GARCH(1,1); mseegarch=(sum(MSEEGARCH))/numperiods;%MSE EGARCH(1,1) MSE=table(msearch,msegarch,mseegarch);
MSE.Properties.VariableNames={'ARCH' 'GARCH' 'EGARCH'}; MSE
Figura 3.28
MSE con previsione a 10 giorni
Per la previsione della volatilità a 20 giorni:
numperiods=20;
vF1 = forecast(EstMdl1,numperiods,nr); vF2 = forecast(EstMdl2,numperiods,nr); vF3 = forecast(EstMdl3,numperiods,nr); %Calcolo Mean Squared Error (MSE)
MSEARCH=zeros(numperiods,1); MSEGARCH=zeros(numperiods,1); MSEEGARCH=zeros(numperiods,1); for j=1:numperiods MSEARCH(j)=(R1(j)-sqrt(vF1(j)))^2; MSEGARCH(j)=(R1(j)-sqrt(vF2(j)))^2; MSEEGARCH(j)=(R1(j)-sqrt(vF3(j)))^2; end
101
msearch=(sum(MSEARCH))/numperiods;%MSE ARCH(1)
msegarch=(sum(MSEGARCH))/numperiods;%MSE GARCH(1,1); mseegarch=(sum(MSEEGARCH))/numperiods;%MSE EGARCH(1,1) MSE=table(msearch,msegarch,mseegarch);
MSE.Properties.VariableNames={'ARCH' 'GARCH' 'EGARCH'}; MSE
Figura 3.29
MSE con previsione a 20 giorni
Senza riportare il live script, in quanto basta semplicemente modificare numperiods e
facendo girare il codice, per le previsioni successive otteniamo:
Figura 3.30
MSE con previsione a 30 giorni
Figura 3.31
MSE con previsione a 40 giorni
Figura 3.32
102
Figura 3.33
MSE con previsione a 100 giorni
Confrontando le previsioni con il Garman Klass, il modello migliore risulta l’EGARCH(1,1).
In generale, quello che si va a confrontare in un orizzonte temporale sempre più esteso, è
la previsione tra il modello GARCH(1,1) e l’EGARCH(1,1); questo perché il modello
ARCH(1), come già descritto nel paragrafo 2.8, parte con un parametro α molto basso
(α < 1
√3≈ 0.577) e quindi tende molto velocemente alla varianza unconditional.
Infatti, quello che possiamo osservare dai grafici seguenti è che l’ARCH(1), partendo da un parametro α molto basso (in questo caso di 0.33075) tende alla varianza unconditional dopo 4/5 giorni:
Figura 3.34
103
Figura 3.35
Previsioni ARCH(1) 40, 50, 100 giorni
Dai grafici sottostanti, invece, possiamo intravedere come i restanti modelli impieghino
più tempo a convergere verso varianza unconditional (a 100 giorni non l’anno ancora
raggiunta):
Figura 3.36
104
Figura 3.37
Previsioni GARCH(1,1) 40, 50, 100 giorni
Figura 3.38
105
Figura 3.39
Previsioni EGARCH(1,1) 40, 50, 100 giorni
Ciò può essere spiegato dal fatto che il parametro che dà la persistenza al modello è il β che risulta 0.8988 per il GARCH(1,1) e 0.98078 per l’EGARCH(1,1).
Adesso prendiamo i dati dal 30/08/2013 al 30/08/2019 e, facendo gli stessi procedimenti
vediamo cosa succede:
Figura 3.40
MSE con previsione a 10 giorni
Figura 3.41
106
Figura 3.42
MSE con previsione a 30 giorni
Figura 3.43
MSE con previsione a 40 giorni
Figura 3.44
MSE con previsione a 50 giorni
Figura 3.45
MSE con previsione a 100 giorni
In questo caso, esattamente come i dati precedenti confrontati con il Garman Klass, il modello migliore risulta l’EGARCH(1,1).
Adesso possiamo andare a confrontare attraverso i grafici le varie previsioni; il modello
ARCH(1), in questo caso presenta un parametro 𝛼 = 0.3011 che risulta lievemente più
basso della serie precedente (dove era pari a 0.3375) e tende alla varianza unconditional
107
Figura 3.46
Previsioni ARCH(1) 10, 20, 30 giorni
Figura 3.47
Previsioni ARCH(1) 40, 50, 100 giorni
Notiamo, infatti, come dopo soli 4 giorni sia presente una linea continua: utilizzando l’ARCH(1) è come se non facessimo nessuna previsione (è come considerare solo la varianza unconditional).
108
Per quanto riguarda gli altri due modelli, il GARCH(1,1) presenta un 𝛽 = 0.77339
(molto più basso rispetto a prima) mentre nell’EGARCH (1,1) 𝛽 = 0.93627 (anche qua inferiore rispetto a prima). In questo caso, i due modelli raggiungono più velocemente la
varianza unconditional rispetto alle previsioni precedenti:
Figura 3.48
Previsioni GARCH(1,1) 10, 20, 30 giorni
Figura 3.49
109
Figura 3.50
Previsioni EGARCH(1,1) 10, 20, 30 giorni
Figura 3.51
110
Quello che faremo adesso è di andare ad effettuare delle previsioni muovendoci a 1 passo
e poi a 5 passi sempre nello stesso intervallo temporale di 100 giorni. I dati presi come
riferimento per queste ultime previsioni sono inizialmente quelli dal 30/08/2013 al
30/08/2019 e successivamente quelle dal 30/08/2000 al 30/08/2019.
Per la previsione a un passo, dal tempo 𝑡 prevediamo la volatilità al tempo 𝑡 + 1, dal
tempo 𝑡 + 1 al tempo 𝑡 + 2 e così via.
Per quanto riguarda la previsione a 5 passi, l’idea è questa (figura 3.52): siamo al tempo 𝑡 e facciamo la previsione al tempo 𝑡 + 5, poi ci spostiamo a 𝑡 + 1 prevedendo la
volatilità al tempo 𝑡 + 6 e si continua in questo modo fino alla previsione al tempo 𝑡 +
100.
Figura 3.52 Sistema di previsione
Come abbiamo fatto nel paragrafo 3.2, per prima cosa carichiamo nel live script i dati con
il comando readtable. Successivamente si attua lo stesso procedimento visto in
precedenza: si calcolano i rendimenti logaritmici, si stimano i parametri andando a vedere
la significatività ecc.
Adesso provvediamo ad effettuare una previsione a un passo:
result1=zeros(100,1);
for j=1:100
Forecast = forecast(EstMdl1,1,Rclose(1:N-101+j));%previsione ARCH(1) result1(j)=Forecast;
111
PrevisioniARCH1Passo=(result1); result2=zeros(100,1);
for j=1:100
Forecast2 = forecast(EstMdl2,1,Rclose(1:N-101+j));%previsione GARCH(1,1) result2(j)=Forecast2; end PrevisioniGARCH1Passo=(result2); result3=zeros(100,1); for j=1:100
Forecast3 = forecast(EstMdl3,1,Rclose(1:N-101+j));%previsione EGARCH(1,1) result3(j)=Forecast3;
end
PrevisioniEGARCH1Passo=(result3);
Successivamente si procede a calcolare il MSE con il procedimento già visto in
precedenza e otteniamo i seguenti risultati:
Figura 3.53
Previsione a 1 passo sul Nasdaq con dati 2013-2019
La previsione a un passo migliore è ottenuta attraverso il modello EGARCH(1,1).
Adesso proviamo a 5 passi, non considerando l’ARCH(1) in quanto a questa distanza,
come si è già detto, la previsione converge alla varianza unconditional:
result1=zeros(96,1);
for j=5:100
Forecast1 = forecast(EstMdl2,5,Rclose(1:N-105+j));%previsione Result1(j-4)=Forecast1(5); end PrevisioniGARCH5Passi=(result1); result2=zeros(96,1); for j=5:100
Forecast2 = forecast(EstMdl3,5,Rclose(1:N-105+j));%previsione Result2(j-4)=Forecast2(5);
112
end
PrevisioniEGARCH5Passi=(result2);
Figura 3.54
Previsione a 5 passi sul Nasdaq con dati 2013-2019
Anche in questo caso la previsione migliore è l’EGARCH(1,1).
Se cambiamo i dati a nostra disposizione passando a quelli dal 30/08/2000 al 30/08/2019
Otteniamo:
Figura 3.55
Previsione a 1 passo sul Nasdaq dati dal 2000 al 2019
Per la previsione a un passo il modello migliore risulta il GARCH(1,1).
Per quanto riguarda la previsione a 5 passi, sempre non considerando l’ARCH(1) per lo
stesso motivo di prima:
Figura 3.56
Previsione a 5 passo sul Nasdaq dati dal 2000 al 2019
Anche in questo caso il GARCH(1,1) risulta il migliore.
Quindi il modello EGARCH(1,1) risulta il migliore per le previsioni a 1 e 5 passi nei dati
113
C’è da notare come gli errori siano più grandi per le previsioni effettuate sui dati dal 2000- 2019 rispetto a quelle sui dati dal 2013-2019. Probabilmente ciò è dovuto alla stima dei
parametri in un orizzonte molto lungo dove due crisi importanti (Dot-com e mutui
subprime) hanno reso la volatilità alta per un certo periodo di tempo.