Time Series Forecasting – How to Use ARIMA and GARCH Models for Accurate Finance Predictions

financeforecastinggarchtime seriesvolatility-forecasting

I have a time series containing the daily close price for a stock and I would like to perform a 10 days forecast of the volatility.

I'm trying to follow this tutorial: https://talksonmarkets.files.wordpress.com/2012/09/time-series-analysis-with-arima-e28093-arch013.pdf

This is my data and its autocorrelation:

> closing_price$CloseDayPriceA
 [1] 0.0610 0.0605 0.0590 0.0575 0.0590 0.0585 0.0610 0.0590 0.0615 0.0610 0.0625
[12] 0.0605 0.0600 0.0650 0.0650 0.0710 0.0740 0.0730 0.0765 0.0770 0.0755 0.0765
[23] 0.0760 0.0775 0.0850 0.0955 0.0975 0.1155 0.1365 0.1200 0.1270 0.1230 0.1210
[34] 0.1040 0.1155 0.1355 0.1315 0.1310 0.1265 0.1250 0.1230 0.1245 0.1240 0.1235
[45] 0.1225 0.1185 0.1110 0.1130 0.1170 0.1150 0.1120 0.1135 0.1135 0.1085 0.1100
[56] 0.1090 0.1075 0.1050 0.1030 0.0960 0.0955 0.0970 0.0960 0.0915 0.0910
> a = acf(closing_price$CloseDayPriceA)
> a

Autocorrelations of series ‘closing_price$CloseDayPriceA’, by lag

     0      1      2      3      4      5      6      7      8      9     10 
 1.000  0.955  0.908  0.864  0.813  0.759  0.714  0.680  0.625  0.570  0.511 
    11     12     13     14     15     16     17     18 
 0.446  0.381  0.314  0.242  0.170  0.106  0.048 -0.017 
> 

The data is clearly not stationary. I can make it stationary by differencing:

diff_price = diff(closing_price$CloseDayPriceA)

or alternatively by fitting an AR(1) model and taking the residuals:

arimaA = arima(closing_price$CloseDayPriceA, order = c(1, 0, 0))

Now the squared residuals are still autocorrelated as shown by their ACF. For this reason I apply a GARCH model:

library(fGarch)

    garchA=garchFit(formula = ~garch(2, 1), data = arimaA$residuals, trace = F)
    acf(residuals(garchA))

My questions are:

  1. Does the procedure that I am following make sense?
  2. How can I make a 10 days forecast and compute the 10 days volatility?

EDIT:
This should be the code:

A = closing_price$CloseDayPriceA
A.log = log(A)
log_rtn = diff(A.log)
A.garch = garchFit(formula = ~garch(1, 1), data = log_rtn, trace = F)
A.est = predict(A.garch, 30, plot=T)

Best Answer

When modelling stock prices, it is quite common to transform the original prices $P_{t}$ to logarithmic returns $r_t:=\ln(P_{t})-\ln(P_{t-1})$ and then employ a GARCH model.

Logarithmic returns reflect price changes relative to price levels. If the price was fluctuating at around the same level, logarithmic returns would behave similarly to simple returns (just be scaled by roughly a constant); then not taking logarithms could be justified. But since the price is roughly a random walk, it does not stay around any fixed level for too long, and hence there is a difference between logarithmic and simple returns. Simple returns have an amplitude that changes with the price level, while logarithmic returns have a roughly constant amplitude. Therefore, modelling logarithmic returns is more convenient.

Given a GARCH model for (logarithmic) returns, you can predict the volatility iteratively:

$$ \begin{aligned} \hat\sigma_{t+1}^2 &= \hat\omega + \hat\alpha r_{t}^2 + \hat\beta \sigma_{t}^2 \\ \hat r_{t+1}^2 &= \hat\sigma_{t+1}^2 \\ \hat\sigma_{t+2}^2 &= \hat\omega + \hat\alpha r_{t+1}^2 + \hat\beta \hat\sigma_{t+1}^2 \\ \hat r_{t+2}^2 &= \hat\sigma_{t+2}^2 \\ &\dotsc \end{aligned} $$

In R, use function predict on a fitted object from garchFit, in your case, garchA; see p. 30-31 of the "fGarch" manual for details.

In the above I assumed you are not using an ARMA model for the conditional mean of returns. Predictability in the level of returns via ARMA would be a little naive to expect and would be a sign of market inefficiency. Without ARMA, the point forecast of $r_{t+h}=0$ for $h>0$.
However, if you decide to use ARMA, replace $r_t$ and $\hat r_t$ with $\hat\varepsilon_t$ in the GARCH formulas above, where $\hat\varepsilon_t$ is a residual from the ARMA model. Also, the point forecast is generally nonzero and is given by the ARMA model.

Also, if you use ARMA, estimate both ARMA and GARCH simultaneously (rather than first estimating ARMA and then fitting GARCH on its residuals). This will yield consistent and efficient parameter estimates. This can be done with the same garchFit function as you are using now.