Outline

Extended ARIMA and GARCH

Why Extended ARIMA and GARCH Models?

(Before We Proceed) Data and Library Setup

ARIMAX: Motivation

ARMAX: The Model

\[ ARMAX(p,q,r): r_t = \sum_{i=1}^p r_{t-i} + \sum_{j=1}^q \varepsilon_{t-j}+\sum_{k=1}^r \gamma_k X_{tk} + \varepsilon_t \] - where: \(\gamma_k\) are the parameters for the exogenous variables \(X_{tk}\).

ARIMAX: Model Estimation

# Hypothesis: I believe that AAPL daily volume can explain AAPL future prices
psych::describe(s1v)
psych::describe(log(s1v))

plot(s1v)
plot(log(s1v))
hist(log(s1v))

cor(s1p, log(s1v))
cor.test(s1p, log(s1v))

# Model Estimation 
arima   <- auto.arima(s1p)
arima

arima.x <- auto.arima(s1p, xreg = log(s1v) )
arima.x

Applications: Can VIX Improve Stock Index Forecastibility?

# Setting Time Parameters
tt  <- dim(mk) # Total Time Period
hh  <- 200     # Out-sample Period for Prediction 

# ARIMA
mk.arima.1 <- auto.arima(mk[1:(tt-hh),])
mk.arima.1
mk.arima.f <- forecast(mk.arima.1, h = hh)


# ARIMAX with VIX
mk.arima.2 <- auto.arima(mk[1:(tt-hh),], xreg = vix[1:(tt-hh),])
mk.arima.2
mk.arima.f2 <- forecast(mk.arima.2, h = hh, xreg = vix[(tt-hh+1):tt])

# Forecast Plot
par(mfrow=c(1,3))
plot(mk.arima.f)
plot(mk.arima.f2)
plot(mk)

Applications: Can AAPL Volume Improve AAPL Price Forecastibity?

# Setting Time Parameters
tt  <- dim(s1p) # Total Time Period
hh  <- 100     # Out-sample Period for Prediction 

# ARIMA
s1p.arima.1 <- auto.arima(s1p[1:(tt-hh),])
s1p.arima.1
s1p.arima.f <- forecast(s1p.arima.1, h = hh)


# ARIMAX with VIX
s1p.arima.2 <- auto.arima(s1p[1:(tt-hh),], xreg = log(s1v)[1:(tt-hh),])
s1p.arima.2
s1p.arima.f2 <- forecast(s1p.arima.2, h = hh, xreg = log(s1v)[(tt-hh+1):tt])

# Forecast Plot
par(mfrow=c(1,2))
plot(s1p.arima.f)
plot(s1p.arima.f2)

Paper on VIX

  1. “The Predictive Power of Implied Volatility: Evidence from 35 Futures Markets”1 This paper examines the predictive power of the VIX index for futures prices in various markets and finds that it is a significant predictor in many cases.
  2. “The VIX, the Variance Premium and Stock Market Volatility”2 This paper studies the relationship between the VIX index, the variance premium, and stock market volatility and finds that they are closely related.
  3. “The Information Content of Implied Volatility in Agricultural Commodity Markets”3. This paper examines the information content of the VIX index in agricultural commodity markets and finds that it is a significant predictor of futures prices in these markets.

GARCH with Exogenous Variables: Motivation

GARCH with Exogenous Variables: The Model

\[ r_t = ARMA/ARMAX + \sigma_t Z_t \\ GARCH(p, q, r) : \sigma_t^2 = \omega + \sum_{i=1}^p \alpha_i \epsilon_{t-i}^2 + \sum_{j=1}^q \beta_j \sigma_{t-j}^2 + \sum_{k = 1}^r \gamma_k X{tk} \]

GARCH with Exogenous Variables: Estimation

plot(vix)
dim(vix)
dim(vix)

?ugarchspec
?ugarchfit

garchs <- ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(1, 1)), 
                     mean.model = list(armaOrder = c(0, 0), include.mean = TRUE))

garchs.res <- ugarchfit(garchs, mkr)  

garchx <- ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(1, 1), 
                                           external.regressors = vix),
                     mean.model = list(armaOrder = c(0, 0), include.mean = TRUE))

garchx.res <- ugarchfit(garchx, mkr, xreg = vix)  

print(garchs.res)
print(garchx.res)

GARCH with Exogenous Variables: Interpretation and Diagnostics

err <- garchx.res@fit[["residuals"]]

# Residual Visualization
par(mfrow = c(2,3))
plot(err)
hist(err, breaks = 50)
qqnorm(err)
acf(err)
pacf(err)

# Ljung-Box Test -> H1: Error is not stationary 
Box.test(err, lag = 16, type = "Ljung")

# ADF Test -> H1: Error has no unit root 
adf.test(err)

# Jarque-Bera Test -> H1: Error is not normal 
jarque.bera.test(err)

Can We Try GARCH with Heavy Tail Distributions?

\[ CME(x)=\mathbb{E}[X-x|X \geq x] \] - Examples of the heavy tail distribution according to this definition include Pareto distribution, Weibull distribution, Cauchy distribution etc.

Can We Try GARCH with Heavy Tail Distributions?

Quick Notes on the Heavy Tail Distributions

Can We Try GARCH with Heavy Tail Distributions?

garchs.n <- ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(1, 1)), 
                     mean.model = list(armaOrder = c(0, 0), include.mean = TRUE), 
                     distribution.model = "norm")

garchs.sn <- ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(1, 1)), 
                     mean.model = list(armaOrder = c(0, 0), include.mean = TRUE), 
                     distribution.model = "snorm")

garchs.t <- ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(1, 1)), 
                     mean.model = list(armaOrder = c(0, 0), include.mean = TRUE), 
                     distribution.model = "std")

garchs.st <- ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(1, 1)), 
                     mean.model = list(armaOrder = c(0, 0), include.mean = TRUE), 
                     distribution.model = "sstd")

garchs.g <- ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(1, 1)), 
                     mean.model = list(armaOrder = c(0, 0), include.mean = TRUE), 
                     distribution.model = "ged")

garchs.sg <- ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(1, 1)), 
                     mean.model = list(armaOrder = c(0, 0), include.mean = TRUE), 
                     distribution.model = "sged")

garchs.h <- ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(1, 1)), 
                     mean.model = list(armaOrder = c(0, 0), include.mean = TRUE), 
                     distribution.model = "ghyp")

garchs.n  <- ugarchfit(garchs.n, s1r)
garchs.sn <- ugarchfit(garchs.sn, s1r)
garchs.t  <- ugarchfit(garchs.t, s1r)
garchs.st <- ugarchfit(garchs.st, s1r)
garchs.g  <- ugarchfit(garchs.g, s1r)
garchs.sg <- ugarchfit(garchs.sg, s1r)
garchs.h  <- ugarchfit(garchs.h, s1r)

garchs.n@fit[["coef"]]
garchs.sn@fit[["coef"]]
garchs.t@fit[["coef"]]
garchs.st@fit[["coef"]]
garchs.g@fit[["coef"]]
garchs.sg@fit[["coef"]]
garchs.h@fit[["coef"]]

### Remarks ###
# This is how they compute the information criteria in R
# Check this out -> rugarch:::.information.test
info.test <- function (LLH, nObs, nPars) 
{
    AIC = (-2 * LLH)/nObs + 2 * nPars/nObs
    BIC = (-2 * LLH)/nObs + nPars * log(nObs)/nObs
    SIC = (-2 * LLH)/nObs + log((nObs + 2 * nPars)/nObs)
    HQIC = (-2 * LLH)/nObs + (2 * nPars * log(log(nObs)))/nObs
    informationTests = list(AIC = AIC, BIC = BIC, SIC = SIC, HQIC = HQIC)
    return(informationTests)
}

EGARCH: Motivation

EGARCH: The Model

\[ r_t = \mu + \sigma_t z_t \]

\[ ln(\sigma^2_t) = \omega + \Sigma_{i=1}^p \alpha_i (|z_{t-i}|-\mathbb{E}[|z_{t-i}|] + \gamma z_{t-i}) + \Sigma_{j=1}^q \beta_j ln (\sigma^2_{t-j}) \]

EGARCH: Estimation

eg1 <- ugarchspec(variance.model = list(model = "eGARCH", garchOrder = c(1, 1)), 
                  mean.model = list(armaOrder = c(0,0)), 
                  distribution.model = "norm")
eg1fit <- ugarchfit(eg1,s1r)
eg1fit

EGARCH: Interpretation and Diagnostics

err <- eg1fit@fit[["residuals"]] 

par(mfrow = c(2,3))
plot(err)
hist(err, breaks = 50)
qqnorm(err)
acf(err)
pacf(err)

Box.test(err, lag = 16, type = "Ljung")
adf.test(err) # make sure you have the tseries package to use this function 
jarque.bera.test(err)

gjrGARCH: Motivation

gjrGARCH: Model

\[ r_t = \mu + \sigma_t z_t \]

\[ \sigma^2_t = \omega + \Sigma_{i=1}^p (\alpha_i + \gamma_i N_{t-i})z_{t-i}^2 + \Sigma_{j=1}^q \beta_j \sigma_{t-j}^2 \]- Where \(N_{t-i} = 1; z_{t-i}< 0\) and 0 otherwise.

- Again, you can use normal distribution or other fatter-tailed distributions for \(z_t\).

gjrGARCH: Estimation

tg1 <- ugarchspec(variance.model = list(model = "gjrGARCH", garchOrder = c(1, 1)),
                  mean.model = list(armaOrder = c(0,0)), 
                  distribution.model = "norm")
tg1fit <- ugarchfit(tg1,s1r)
tg1fit

gjrGARCH: Interpretation and Diagnostics

err <- tg1fit@fit[["residuals"]] 

par(mfrow = c(2,3))
plot(err)
hist(err, breaks = 50)
qqnorm(err)
acf(err)
pacf(err)

Box.test(err, lag = 16, type = "Ljung")
adf.test(err) # make sure you have the tseries package to use this function 
jarque.bera.test(err)

APARCH: Motivation

APARCH: Model

\[ \sigma_t^\delta = \omega + \Sigma_{i=1}^p \alpha_i (|\varepsilon_{t-i}| - \gamma_i \varepsilon_{t-i} )^\delta + \Sigma_{j=1}^q \beta_j \sigma_{t-j}^\delta \]

APARCH: Estimation

ag1 <- ugarchspec(variance.model = list(model = "apARCH", garchOrder = c(1, 1)),
                  mean.model = list(armaOrder = c(0,0)), 
                  distribution.model = "norm")
ag1fit <- ugarchfit(ag1,s1r)
ag1fit

APARCH: Interpretation and Diagnostics

err <- ag1fit@fit[["residuals"]] 

par(mfrow = c(2,3))
plot(err)
hist(err, breaks = 50)
qqnorm(err)
acf(err)
pacf(err)

Box.test(err, lag = 16, type = "Ljung")
adf.test(err) # make sure you have the tseries package to use this function 
jarque.bera.test(err)

Forecast with GARCH: ugarchforecast

Forecast with GARCH: ugarchforecast

?ugarchforecast
garchs.n.f <- ugarchforecast(garchs.n, n.ahead = 100)
plot(garchs.n.f)

garchs.sn.f <- ugarchforecast(garchs.sn, n.ahead = 100)
plot(garchs.sn.f)

Forecast with GARCH: ugarchboot

Quick In-class Exercises

  1. Let’s find the best model for TSLA stock price with ARIMA using auto.arima
  2. Let’s find the best model for TSLA stock price with ARIMAX using auto.arima + exo. variable = TSLA daily volume
  3. Let’s find the best model for TSLA stock return volatility.
    • Let’s use ARMA(0,0) for the mean model
    • Compare GARCH(1,1), EGARCH(1,1), gjrGARCH(1,1), APARCH(1,1)
    • Compare the results above when switch from normal distribution to student-t distribution (std)… so there are 8 models total
    • Report coefficients’ p-values and the AICs
    • Use the “best model” to forecast returns and volatility in the next 10 days using the ugarchforecast and/or ugarchboot function

MSGARCH: Motivation

MSGARCH: Motivation

par(mfrow = c(1,2))
plot(mk)
plot(mkr)

MSGARCH: The Model Estimation

library(MSGARCH)
dat <- mkr

spec <- CreateSpec(variance.spec = list(model = c("eGARCH","eGARCH")),
                   distribution.spec = list(distribution = c("std","std")),
                   switch.spec = list(do.mix = FALSE))

msg.res <- FitML(spec, dat)
print(msg.res)

msg.sprob <- State(msg.res)
msg.state <- msg.sprob[["Viterbi"]]

plot(msg.state, type = "l")

Application: VaR and ES Estimation with GARCH vs MSGARCH

Summary


  1. Szakmary, A., Ors, E., Kim, J. K., & Davidson III, W. N. (2003). The predictive power of implied volatility: Evidence from 35 futures markets. Journal of Banking & Finance, 27(11), 2151-2175.↩︎

  2. Bekaert, G., & Hoerova, M. (2014). The VIX, the variance premium and stock market volatility. Journal of econometrics, 183(2), 181-192.↩︎

  3. Giot, P. (2003). The information content of implied volatility in agricultural commodity markets. Journal of Futures Markets: Futures, Options, and Other Derivative Products, 23(5), 441-454.↩︎

  4. https://cran.r-project.org/web/packages/evd/index.html↩︎

  5. https://cran.r-project.org/web/packages/ghyp/index.html↩︎

  6. Fernández, C., & Steel, M. F. (1998). On Bayesian modeling of fat tails and skewness. Journal of the american statistical association, 93(441), 359-371. https://www.jstor.org/stable/2669632↩︎

  7. See Nelson, D. B. (1991). Conditional heteroskedasticity in asset returns: A new approach. Econometrica: Journal of the econometric society, 347-370.↩︎

  8. https://vlab.stern.nyu.edu/docs/volatility/EGARCH↩︎

  9. Glosten, L. R., R. Jagannathan, and D. E. Runkle, 1993. On The Relation between The Expected Value and The Volatility of Nominal Excess Return on stocks. Journal of Finance 48: 1779-1801. https://www.jstor.org/stable/2329067↩︎

  10. Zakoian, J. M., 1994. Threshold Heteroscedastic Models. Journal of Economic Dynamics and Control 18: 931-955. https://doi.org/10.1016/0165-1889(94)90039-6↩︎

  11. Ding, Z., Granger C.W., Engle R.F., 1991. A Long Memory Property of Stock Market Returns and a New Model. Journal of Empirical Finance 1 (1993) 83-106. https://doi.org/10.1016/S0304-4076(97)00072-9↩︎

  12. Haas, M., Mittnik, S., & Paolella, M. S. (2004). A new approach to Markov-switching GARCH models. Journal of financial Econometrics, 2(4), 493-530.↩︎

  13. https://www.weforum.org/agenda/2023/03/charted-the-link-between-unemployment-and-recessions/↩︎