0

my colleagues and I have an assignment to submit with the following directions:

  • Without using any built-in R functions, write a general function that estimates a GARCH(1,1) for a time series, and that returns the parameters, standard errors and the filtered variance process.

  • Download 15 years of daily SP500 data and estimate the GARCH model.

  • Use the estimated parameters and the filtered volatility to simulate a 95% confidence interval for a 30-days prediction period. Do this for every day in your sample.

  • Verify how often the realizations 30 days ahead violate the confidence interval. Makeanice plot.

The main issue in our code is that it appears that there is an error in the optim function and we can't figure out how to fix it. Due to this problem, we can't find the standard error (since it would derive from the hessian in the optim function). We hope you'll be able to help us. Thank you. Note that with "h" we are referring to the variance. And with "ster" we mean "standard error".

Please, find attach the code below:

#R PROJECT GARCH(1,1) MODEL written by Alice, Christian and Diana



#S&P 500 data from 01.01.2005 to 31.12.2021
library(xts)
library(ggplot2)
library(readr)
library(quantmod)
library(cvar)



SPX1 <- getSymbols("^GSPC",auto.assign = FALSE, from = "2005-01-01", to="2021-12-31")
SPX_Adj <- SPX1$GSPC.Adjusted



#SP500 <- read_csv("SP500.csv", col_types = cols(Close = col_number(), Date = col_character()))
#View(SP500)



#BETTER FITTING THE DATA FOR OUR WORK
SP500log <- as.data.frame(log10(SPX_Adj[,1]))
N <- length(SP500log[,1])
SP500_ret <- ((SP500log[2:N,]-SP500log[1:N-1,]))
x <- SP500_ret



#WRITING THE GARCH (1,1) FUNCTION



GARCH <-function(para,x){
# Volatility and loglik initialisation
mu <- mean(x)
para <- c(0.2,0.8,0.15)
Beta0 <- para[1]
Beta1 <- para[2]
Beta2 <- para[3]
e <- x - mean(x)
e2 <- e^2
h <- c(0)
loglik=c(0)
# Start of the loop
vol=c()
for (t in 2:length(x)){
h[t]=Beta0+Beta1*e2[t-1]+Beta2*h[t-1]
ster <- sqrt(h[t]/N)
loglik[t]=loglik[t-1]+log(dnorm(x[t],mean(x[1:t]),sqrt(h[t])))
}
Ster <<- ster
H <<- h
return(tail(loglik,1))
}



paraoptim <- optim(para, GARCH, gr=NULL, method=c("BFGS"),lower = 0, upper = Inf, control = list(), hessian = FALSE, SP500_ret)



paraoptim$par
Beta0 <- paraoptim$par[1]
Beta1 <- paraoptim$par[2]
Beta2 <- paraoptim$par[3]



GARCH(para,SP500_ret)



#CONFIDENCE INTERVAL



data <- diff(h, lag=29)
ConfInt <- function(data, alpha=0.05) {
x <- x[!is.na(data)]
m <- mean(x)
z <- qnorm(1-alpha/2)
s <- sd(x)/sqrt(length(x))
CONFIDENCE <- c("inf"=m-z*s, "sup"=m+z*s)
return(CONFIDENCE)
}



ConfInt(data)
bounds <- ConfInt(data)

#
ValueAtRisk <- function(x){
VaR = c()
for (t in 1:length(x)) {
VaR[t] <- as.numeric(VaR(H[1:t], p=0.95, method=c("historical")))
}
return(VaR)
}



ValueAtRisk(SP500_ret)
VaRline <- (h/ValueAtRisk(SP500_ret))/1000
#



#PLOT
plot(SP500_ret, type = "l", col="blue", ylim = c(-0.08,0.05))
lines(VaRline)
fcm
  • 1
  • 1
  • 2
    We can't run this because para (passed to optim) is not defined. Please test this in a fresh instance of R to ensure that it can be reproduced. – G. Grothendieck Jan 16 '22 at 14:44
  • @G.Grothendieck thank you for noticing that, I have fixed the parameters. Are you able to see them now? – fcm Jan 16 '22 at 15:10

1 Answers1

0

I you replace

paraoptim <- optim(para, GARCH, gr=NULL, method=c("BFGS"),lower = 0, upper = Inf, control = list(), hessian = FALSE, SP500_ret)

with

para <- c(0.2,0.8,0.15)
paraoptim <- optim(para, GARCH, gr=NULL, method=c("BFGS"),lower = 0, upper = Inf, control = list(), hessian = FALSE, SP500_ret)
h<-H

your code will run.

enter image description here

If believe your 2 issues are

  1. As pointed out by @G.Grothendieck, you are defining the para parameter within the GARCH function. Therefore its not global, and the garch call cannot see para.
  2. GARCH create H, but your subsequent calls use h.
Joe Erinjeri
  • 1,200
  • 1
  • 7
  • 15
  • Perfect! @JoeErinjeri do you know how to "frame" the x-axis? Basically I wanna display above "Index" all the years in order to display the variance for each year.. However, the thing is that if I click on the csv file related to the GSPC the system doesn't classify the column "date" as a column itself, so it's like it is not readable... – fcm Jan 16 '22 at 22:49
  • I don't use plot very much, so i don't know the syntax. but with ggplot, try. Also please mark the questions as answered. library(lubridate) library(ggplot) plot_data<-as_tibble(SP500log, rownames = "dates") %>% select(dates) %>% mutate(dates=ymd(dates)) %>% mutate(SP500_ret=SP500_ret[row_number()]) ggplot(data=plot_data, aes(x=dates, y=SP500_ret, group=1)) + geom_line() – Joe Erinjeri Jan 16 '22 at 23:08
  • @fcm Since the class of SPX1 is "numeric", the call to `plot` is going to be handled by `plot.default` so you would suppress the Index being plotted with xaxt and then call the `axis` function. I'm guessing you would want to use the index of `SP500` as the `labels` argument. See `?plot.default` and `?axis` and any of the "See also" items needed to further educate yourself on base plotting. – IRTFM Jan 17 '22 at 07:08