Simulating GARCH
Let’s simulate a GARCH(1,1) process over time
library(fGarch)
rm(list = ls())
seed <- 17
# set the number simulated returns
n <- 10^2
# set the model parameters
con <- 0
w <- 0.1
a <- 0.2
b <- 0.5
par_0 <- c(con,w,a,b)
sigma_t <- sqrt(w/(1-a-b)) # start with initial volatility
ht_seq <- numeric()
R_seq <- numeric()
set.seed(seed)
for(i in 1:n) {
R_t1 <- rnorm(1,con,sigma_t)
R_seq <- c(R_seq,R_t1)
ht1 <- w + a*(R_t1^2) + b*sigma_t^2
ht_seq <- c(ht_seq,ht1)
sigma_t <- sqrt(ht1)
}
plot(sqrt(ht_seq), type = "l")

To make sure the simulation is correct, let’s try to estimate the coefficients using the data given by R_seq:
g <- garchFit(formula = ~ garch(1,1), data = R_seq,trace = F)
coef_hat <- g@fit$matcoef
coef_hat[,1]
mu omega alpha1 beta1
0.05969198 0.09070289 0.37858626 0.44038373
The above is based on 100 observations. One of the properties of MLE is consistency, for this reason, we expect the estimated parameters to converge to the true ones as the sample increases. To demonstrate this, consider the following:
sim_garch_f <- function(n) {
set.seed(seed)
sigma_t <- sqrt(w/(1-a-b))
ht_seq <- numeric()
R_seq <- numeric()
for(i in 1:n) {
R_t1 <- rnorm(1,con,sigma_t)
R_seq <- c(R_seq,R_t1)
ht1 <- w + a*(R_t1^2) + b*sigma_t^2
ht_seq <- c(ht_seq,ht1)
sigma_t <- sqrt(ht1)
}
return(R_seq)
}
n_seq <- 10^(2:4)
R_list <- lapply(n_seq, sim_garch_f)
The above simulates the R_seq for different n values. For each sample size, we can check the difference between the estimated parameters and the true ones
garch_list <- lapply(R_list, function(R) garchFit(formula = ~ garch(1,1), data = R,trace = F))
coef_hat <- sapply(garch_list, function(g) g@fit$matcoef[,1])
colnames(coef_hat) <- paste("n",n_seq,sep = "_")
data.frame(coef_hat)
As we can see, the larger the sample is the more the closer the estimates approximates the true parameters. The mu parameter denotes the average mean return, which by construction we set to zero. As a result, its estimate should converge to zero as \(n \rightarrow \infty\).
Note that the above example is rather a reverse engineering problem. We ``cook’’ the data that imposing it is generated from a GARCH model. After doing so, we estimate a GARCH model using the cooked data. Note that if the simulation is well executed, consistency should hold true. Otherwise, you need to double check your simulation procedure.
Forecasting Volatility
Let’s stick with our cooked data to demonstrate volatility forecasting. As discussed in the slides, the volatility forecast is given by
w <- 0.1
gamma <- 0.7
k <- 20 # number of days ahead
h_for <- last(ht_seq)
h_seq <- ht_seq
for(i in 1:k){
h_for <- w + gamma*h_for
h_seq <- c(h_seq,h_for)
}
in_index <- 1:n
out_index <- (n+1):(n+k)
plot(h_seq,col = 1,type = "l")
lines(h_seq[out_index] ~ out_index,col = 2,lwd = 2)
abline(h = w/(1-gamma),lty = 2)
# now add forecast for a different gamma
gamma <- 0.9
w <- 0.1/3
h_for <- last(ht_seq)
h_seq <- ht_seq
for(i in 1:k){
h_for <- w + gamma*h_for
h_seq <- c(h_seq,h_for)
}
lines(h_seq,col = 1,type = "l")
lines(h_seq[out_index] ~ out_index,col = 3,lwd = 2)
# finally, add legend
legend("topleft",c("Fitted","Forecast Gamma = 0.7","Forecast Gamma = 0.9","Long Term Variance"),col = 1:3,lwd = c(1,2,2,1),lty = c(1,1,1,2))

In fact, the red and green curves are commonly referred to as the volatility term structure. This indicates how far the current volatility is deviating from its long-term mean and how long it will take to revert back to. As demonstrated above, the green line takes longer to revert since its \(\gamma\) is larger. This means that the persistence of recent shocks (large squared returns) will last longer. On the other hand, the red line has \(\gamma = 0.7\) and, as a result, recent shocks will be less persistence, i.e. it will take the process shorter time period to revert back to its long-term mean.
Let’s repeat the above for a different simulation, however, in which the recent volatility is above the long-term average volatility
seed <- 1713134
# set the number simulated returns
n <- 10^2
# set the model parameters
con <- 0
w <- 0.1
a <- 0.2
b <- 0.5
par_0 <- c(con,w,a,b)
sigma_t <- sqrt(w/(1-a-b)) # start with initial volatility
ht_seq <- numeric()
R_seq <- numeric()
set.seed(seed)
for(i in 1:n) {
R_t1 <- rnorm(1,con,sigma_t)
R_seq <- c(R_seq,R_t1)
ht1 <- w + a*(R_t1^2) + b*sigma_t^2
ht_seq <- c(ht_seq,ht1)
sigma_t <- sqrt(ht1)
}
w <- 0.1
gamma <- 0.7
k <- 20 # number of days ahead
h_for <- last(ht_seq)
h_seq <- ht_seq
for(i in 1:k){
h_for <- w + gamma*h_for
h_seq <- c(h_seq,h_for)
}
in_index <- 1:n
out_index <- (n+1):(n+k)
plot(h_seq,col = 1,type = "l")
lines(h_seq[out_index] ~ out_index,col = 2,lwd = 2)
abline(h = w/(1-gamma),lty = 2)
# now add forecast for a different gamma
gamma <- 0.9
w <- 0.1/3
h_for <- last(ht_seq)
h_seq <- ht_seq
for(i in 1:k){
h_for <- w + gamma*h_for
h_seq <- c(h_seq,h_for)
}
lines(h_seq,col = 1,type = "l")
lines(h_seq[out_index] ~ out_index,col = 3,lwd = 2)
# finally, add legend
legend("topleft",c("Fitted","Forecast Gamma = 0.7","Forecast Gamma = 0.9","Long Term Variance"),col = 1:3,lwd = c(1,2,2,1),lty = c(1,1,1,2))

We observe a similar trend, however, now the volatility term structure is down sloping. The reason is the recent volatility is above the long-term mean average and, hence, the forecast should eventually converge to the long-term level, which is lower than the current level.
LS0tCnRpdGxlOiAiTm90ZXMgb24gR0FSQ0giCiNvdXRwdXQ6IHJtYXJrZG93bjo6Z2l0aHViX2RvY3VtZW50Cm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0CmF1dGhvcjogTWFqZWVkIFNpbWFhbgpkYXRlOiBGZWIgMTEsIDIwMTkKZmlnX3dpZHRoOiA1MAotLS0KCgojIFNpbXVsYXRpbmcgR0FSQ0gKTGV0J3Mgc2ltdWxhdGUgYSBHQVJDSCgxLDEpIHByb2Nlc3Mgb3ZlciB0aW1lIAoKYGBge3IsZmlnLmFsaWduPSdjZW50ZXInfQpsaWJyYXJ5KGZHYXJjaCkKCnJtKGxpc3QgPSBscygpKQpzZWVkIDwtIDE3CgoKIyBzZXQgdGhlIG51bWJlciBzaW11bGF0ZWQgcmV0dXJucwpuIDwtIDEwXjIKCiMgc2V0IHRoZSBtb2RlbCBwYXJhbWV0ZXJzCmNvbiA8LSAwCncgPC0gMC4xCmEgPC0gMC4yCmIgPC0gMC41CgpwYXJfMCA8LSBjKGNvbix3LGEsYikKCnNpZ21hX3QgPC0gc3FydCh3LygxLWEtYikpICMgc3RhcnQgd2l0aCBpbml0aWFsIHZvbGF0aWxpdHkgCmh0X3NlcSA8LSBudW1lcmljKCkKUl9zZXEgPC0gbnVtZXJpYygpCgpzZXQuc2VlZChzZWVkKQoKZm9yKGkgaW4gMTpuKSB7CiAgUl90MSA8LSBybm9ybSgxLGNvbixzaWdtYV90KQogIFJfc2VxIDwtIGMoUl9zZXEsUl90MSkKICBodDEgPC0gdyArIGEqKFJfdDFeMikgKyBiKnNpZ21hX3ReMgogIGh0X3NlcSA8LSBjKGh0X3NlcSxodDEpCiAgc2lnbWFfdCA8LSBzcXJ0KGh0MSkKICB9CgpwbG90KHNxcnQoaHRfc2VxKSwgdHlwZSA9ICJsIikKYGBgClRvIG1ha2Ugc3VyZSB0aGUgc2ltdWxhdGlvbiBpcyBjb3JyZWN0LCBsZXQncyB0cnkgdG8gZXN0aW1hdGUgdGhlIGNvZWZmaWNpZW50cyB1c2luZyB0aGUgZGF0YSBnaXZlbiBieSBgUl9zZXFgOiAKCmBgYHtyfQpnIDwtIGdhcmNoRml0KGZvcm11bGEgPSB+IGdhcmNoKDEsMSksIGRhdGEgPSBSX3NlcSx0cmFjZSA9IEYpCmNvZWZfaGF0IDwtIGdAZml0JG1hdGNvZWYKY29lZl9oYXRbLDFdCgpgYGAKClRoZSBhYm92ZSBpcyBiYXNlZCBvbiBgMTAwYCBvYnNlcnZhdGlvbnMuIE9uZSBvZiB0aGUgcHJvcGVydGllcyBvZiBNTEUgaXMgY29uc2lzdGVuY3ksIGZvciB0aGlzIHJlYXNvbiwgd2UgZXhwZWN0IHRoZSBlc3RpbWF0ZWQgcGFyYW1ldGVycyB0byBjb252ZXJnZSB0byB0aGUgdHJ1ZSBvbmVzIGFzIHRoZSBzYW1wbGUgaW5jcmVhc2VzLiBUbyBkZW1vbnN0cmF0ZSB0aGlzLCBjb25zaWRlciB0aGUgZm9sbG93aW5nOgoKCmBgYHtyfQpzaW1fZ2FyY2hfZiA8LSBmdW5jdGlvbihuKSB7CiAgc2V0LnNlZWQoc2VlZCkKICBzaWdtYV90IDwtIHNxcnQody8oMS1hLWIpKSAKICBodF9zZXEgPC0gbnVtZXJpYygpCiAgUl9zZXEgPC0gbnVtZXJpYygpCgogIGZvcihpIGluIDE6bikgewogICAgUl90MSA8LSBybm9ybSgxLGNvbixzaWdtYV90KQogICAgUl9zZXEgPC0gYyhSX3NlcSxSX3QxKQogICAgaHQxIDwtIHcgKyBhKihSX3QxXjIpICsgYipzaWdtYV90XjIKICAgIGh0X3NlcSA8LSBjKGh0X3NlcSxodDEpCiAgICBzaWdtYV90IDwtIHNxcnQoaHQxKQogIH0KICAKcmV0dXJuKFJfc2VxKQp9CgpuX3NlcSA8LSAxMF4oMjo0KQpSX2xpc3QgPC0gbGFwcGx5KG5fc2VxLCBzaW1fZ2FyY2hfZikKYGBgClRoZSBhYm92ZSBzaW11bGF0ZXMgdGhlIGBSX3NlcWAgZm9yIGRpZmZlcmVudCBgbmAgdmFsdWVzLiBGb3IgZWFjaCBzYW1wbGUgc2l6ZSwgd2UgY2FuIGNoZWNrIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGVzdGltYXRlZCBwYXJhbWV0ZXJzIGFuZCB0aGUgdHJ1ZSBvbmVzCgoKCmBgYHtyfQpnYXJjaF9saXN0IDwtIGxhcHBseShSX2xpc3QsIGZ1bmN0aW9uKFIpIGdhcmNoRml0KGZvcm11bGEgPSB+IGdhcmNoKDEsMSksIGRhdGEgPSBSLHRyYWNlID0gRikpCmNvZWZfaGF0IDwtIHNhcHBseShnYXJjaF9saXN0LCBmdW5jdGlvbihnKSBnQGZpdCRtYXRjb2VmWywxXSkKY29sbmFtZXMoY29lZl9oYXQpIDwtIHBhc3RlKCJuIixuX3NlcSxzZXAgPSAiXyIpCmRhdGEuZnJhbWUoY29lZl9oYXQpCmBgYAoKQXMgd2UgY2FuIHNlZSwgdGhlIGxhcmdlciB0aGUgc2FtcGxlIGlzIHRoZSBtb3JlIHRoZSBjbG9zZXIgdGhlIGVzdGltYXRlcyBhcHByb3hpbWF0ZXMgdGhlIHRydWUgcGFyYW1ldGVycy4gVGhlIG11IHBhcmFtZXRlciBkZW5vdGVzIHRoZSBhdmVyYWdlIG1lYW4gcmV0dXJuLCB3aGljaCBieSBjb25zdHJ1Y3Rpb24gd2Ugc2V0IHRvIHplcm8uIEFzIGEgcmVzdWx0LCBpdHMgZXN0aW1hdGUgc2hvdWxkIGNvbnZlcmdlIHRvIHplcm8gYXMgJG4gXHJpZ2h0YXJyb3cgIFxpbmZ0eSQuIAoKTm90ZSB0aGF0IHRoZSBhYm92ZSBleGFtcGxlIGlzIHJhdGhlciBhIHJldmVyc2UgZW5naW5lZXJpbmcgcHJvYmxlbS4gV2UgYGBjb29rJycgdGhlIGRhdGEgdGhhdCBpbXBvc2luZyBpdCBpcyBnZW5lcmF0ZWQgZnJvbSBhIEdBUkNIIG1vZGVsLiBBZnRlciBkb2luZyBzbywgd2UgZXN0aW1hdGUgYSBHQVJDSCBtb2RlbCB1c2luZyB0aGUgY29va2VkIGRhdGEuIE5vdGUgdGhhdCBpZiB0aGUgc2ltdWxhdGlvbiBpcyB3ZWxsIGV4ZWN1dGVkLCBjb25zaXN0ZW5jeSBzaG91bGQgaG9sZCB0cnVlLiBPdGhlcndpc2UsIHlvdSBuZWVkIHRvIGRvdWJsZSBjaGVjayB5b3VyIHNpbXVsYXRpb24gcHJvY2VkdXJlLiAKCiMgRm9yZWNhc3RpbmcgVm9sYXRpbGl0eQpMZXQncyBzdGljayB3aXRoIG91ciBjb29rZWQgZGF0YSB0byBkZW1vbnN0cmF0ZSB2b2xhdGlsaXR5IGZvcmVjYXN0aW5nLiBBcyBkaXNjdXNzZWQgaW4gdGhlIHNsaWRlcywgdGhlIHZvbGF0aWxpdHkgZm9yZWNhc3QgaXMgZ2l2ZW4gYnkgCmBgYHtyLGZpZy5hbGlnbj0iY2VudGVyIn0KdyA8LSAwLjEKZ2FtbWEgPC0gMC43CmsgPC0gMjAgIyBudW1iZXIgb2YgZGF5cyBhaGVhZApoX2ZvciA8LSAgbGFzdChodF9zZXEpCmhfc2VxIDwtIGh0X3NlcQpmb3IoaSBpbiAxOmspeyAKICBoX2ZvciA8LSB3ICsgZ2FtbWEqaF9mb3IKICBoX3NlcSA8LSBjKGhfc2VxLGhfZm9yKQp9Cgppbl9pbmRleCA8LSAxOm4Kb3V0X2luZGV4IDwtIChuKzEpOihuK2spCnBsb3QoaF9zZXEsY29sID0gMSx0eXBlID0gImwiKQpsaW5lcyhoX3NlcVtvdXRfaW5kZXhdIH4gb3V0X2luZGV4LGNvbCA9IDIsbHdkID0gMikKYWJsaW5lKGggPSB3LygxLWdhbW1hKSxsdHkgPSAyKQoKCiMgbm93IGFkZCBmb3JlY2FzdCBmb3IgYSBkaWZmZXJlbnQgZ2FtbWEKZ2FtbWEgPC0gMC45CncgPC0gMC4xLzMKaF9mb3IgPC0gIGxhc3QoaHRfc2VxKQpoX3NlcSA8LSBodF9zZXEKZm9yKGkgaW4gMTprKXsgCiAgaF9mb3IgPC0gdyArIGdhbW1hKmhfZm9yCiAgaF9zZXEgPC0gYyhoX3NlcSxoX2ZvcikKfQoKbGluZXMoaF9zZXEsY29sID0gMSx0eXBlID0gImwiKQpsaW5lcyhoX3NlcVtvdXRfaW5kZXhdIH4gb3V0X2luZGV4LGNvbCA9IDMsbHdkID0gMikKCiMgZmluYWxseSwgYWRkIGxlZ2VuZApsZWdlbmQoInRvcGxlZnQiLGMoIkZpdHRlZCIsIkZvcmVjYXN0IEdhbW1hID0gMC43IiwiRm9yZWNhc3QgR2FtbWEgPSAwLjkiLCJMb25nIFRlcm0gVmFyaWFuY2UiKSxjb2wgPSAxOjMsbHdkID0gYygxLDIsMiwxKSxsdHkgPSBjKDEsMSwxLDIpKQoKCmBgYApJbiBmYWN0LCB0aGUgcmVkIGFuZCBncmVlbiBjdXJ2ZXMgYXJlIGNvbW1vbmx5IHJlZmVycmVkIHRvIGFzIHRoZSB2b2xhdGlsaXR5IHRlcm0gc3RydWN0dXJlLiBUaGlzIGluZGljYXRlcyBob3cgZmFyIHRoZSBjdXJyZW50IHZvbGF0aWxpdHkgaXMgZGV2aWF0aW5nIGZyb20gaXRzIGxvbmctdGVybSBtZWFuIGFuZCBob3cgbG9uZyBpdCB3aWxsIHRha2UgdG8gcmV2ZXJ0IGJhY2sgdG8uIEFzIGRlbW9uc3RyYXRlZCBhYm92ZSwgdGhlIGdyZWVuIGxpbmUgdGFrZXMgbG9uZ2VyIHRvIHJldmVydCBzaW5jZSBpdHMgJFxnYW1tYSQgaXMgbGFyZ2VyLiBUaGlzIG1lYW5zIHRoYXQgdGhlIHBlcnNpc3RlbmNlIG9mIHJlY2VudCBzaG9ja3MgKGxhcmdlIHNxdWFyZWQgcmV0dXJucykgd2lsbCBsYXN0IGxvbmdlci4gT24gdGhlIG90aGVyIGhhbmQsIHRoZSByZWQgbGluZSBoYXMgJFxnYW1tYSA9IDAuNyQgYW5kLCBhcyBhIHJlc3VsdCwgcmVjZW50IHNob2NrcyB3aWxsIGJlIGxlc3MgcGVyc2lzdGVuY2UsIGkuZS4gaXQgd2lsbCB0YWtlIHRoZSBwcm9jZXNzIHNob3J0ZXIgdGltZSBwZXJpb2QgdG8gcmV2ZXJ0IGJhY2sgdG8gaXRzIGxvbmctdGVybSBtZWFuLiAKCkxldCdzIHJlcGVhdCB0aGUgYWJvdmUgZm9yIGEgZGlmZmVyZW50IHNpbXVsYXRpb24sIGhvd2V2ZXIsIGluIHdoaWNoIHRoZSByZWNlbnQgdm9sYXRpbGl0eSBpcyBhYm92ZSB0aGUgbG9uZy10ZXJtIGF2ZXJhZ2Ugdm9sYXRpbGl0eQpgYGB7cixmaWcuYWxpZ249ImNlbnRlciJ9CnNlZWQgPC0gMTcxMzEzNAoKIyBzZXQgdGhlIG51bWJlciBzaW11bGF0ZWQgcmV0dXJucwpuIDwtIDEwXjIKCiMgc2V0IHRoZSBtb2RlbCBwYXJhbWV0ZXJzCmNvbiA8LSAwCncgPC0gMC4xCmEgPC0gMC4yCmIgPC0gMC41CgpwYXJfMCA8LSBjKGNvbix3LGEsYikKCnNpZ21hX3QgPC0gc3FydCh3LygxLWEtYikpICMgc3RhcnQgd2l0aCBpbml0aWFsIHZvbGF0aWxpdHkgCmh0X3NlcSA8LSBudW1lcmljKCkKUl9zZXEgPC0gbnVtZXJpYygpCgoKc2V0LnNlZWQoc2VlZCkKCmZvcihpIGluIDE6bikgewogIFJfdDEgPC0gcm5vcm0oMSxjb24sc2lnbWFfdCkKICBSX3NlcSA8LSBjKFJfc2VxLFJfdDEpCiAgaHQxIDwtIHcgKyBhKihSX3QxXjIpICsgYipzaWdtYV90XjIKICBodF9zZXEgPC0gYyhodF9zZXEsaHQxKQogIHNpZ21hX3QgPC0gc3FydChodDEpCiAgfQoKdyA8LSAwLjEKZ2FtbWEgPC0gMC43CmsgPC0gMjAgIyBudW1iZXIgb2YgZGF5cyBhaGVhZApoX2ZvciA8LSAgbGFzdChodF9zZXEpCmhfc2VxIDwtIGh0X3NlcQpmb3IoaSBpbiAxOmspeyAKICBoX2ZvciA8LSB3ICsgZ2FtbWEqaF9mb3IKICBoX3NlcSA8LSBjKGhfc2VxLGhfZm9yKQp9Cgppbl9pbmRleCA8LSAxOm4Kb3V0X2luZGV4IDwtIChuKzEpOihuK2spCnBsb3QoaF9zZXEsY29sID0gMSx0eXBlID0gImwiKQpsaW5lcyhoX3NlcVtvdXRfaW5kZXhdIH4gb3V0X2luZGV4LGNvbCA9IDIsbHdkID0gMikKYWJsaW5lKGggPSB3LygxLWdhbW1hKSxsdHkgPSAyKQoKCiMgbm93IGFkZCBmb3JlY2FzdCBmb3IgYSBkaWZmZXJlbnQgZ2FtbWEKZ2FtbWEgPC0gMC45CncgPC0gMC4xLzMKaF9mb3IgPC0gIGxhc3QoaHRfc2VxKQpoX3NlcSA8LSBodF9zZXEKZm9yKGkgaW4gMTprKXsgCiAgaF9mb3IgPC0gdyArIGdhbW1hKmhfZm9yCiAgaF9zZXEgPC0gYyhoX3NlcSxoX2ZvcikKfQoKbGluZXMoaF9zZXEsY29sID0gMSx0eXBlID0gImwiKQpsaW5lcyhoX3NlcVtvdXRfaW5kZXhdIH4gb3V0X2luZGV4LGNvbCA9IDMsbHdkID0gMikKCiMgZmluYWxseSwgYWRkIGxlZ2VuZApsZWdlbmQoInRvcGxlZnQiLGMoIkZpdHRlZCIsIkZvcmVjYXN0IEdhbW1hID0gMC43IiwiRm9yZWNhc3QgR2FtbWEgPSAwLjkiLCJMb25nIFRlcm0gVmFyaWFuY2UiKSxjb2wgPSAxOjMsbHdkID0gYygxLDIsMiwxKSxsdHkgPSBjKDEsMSwxLDIpKQoKYGBgCgoKV2Ugb2JzZXJ2ZSBhIHNpbWlsYXIgdHJlbmQsIGhvd2V2ZXIsIG5vdyB0aGUgdm9sYXRpbGl0eSB0ZXJtIHN0cnVjdHVyZSBpcyBkb3duIHNsb3BpbmcuIFRoZSByZWFzb24gaXMgdGhlIHJlY2VudCB2b2xhdGlsaXR5IGlzIGFib3ZlIHRoZSBsb25nLXRlcm0gbWVhbiBhdmVyYWdlIGFuZCwgaGVuY2UsIHRoZSBmb3JlY2FzdCBzaG91bGQgZXZlbnR1YWxseSBjb252ZXJnZSB0byB0aGUgbG9uZy10ZXJtIGxldmVsLCB3aGljaCBpcyBsb3dlciB0aGFuIHRoZSBjdXJyZW50IGxldmVsLiAKCgoKCgoKCgoKCgoKCg==