library(quantmod)
## Loading required package: xts
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 3.6.1
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Registered S3 method overwritten by 'xts':
## method from
## as.zoo.xts zoo
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
## Version 0.4-0 included new data defaults. See ?getSymbols.
library(dplyr)
## Warning: package 'dplyr' was built under R version 3.6.1
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:xts':
##
## first, last
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tidyr)
library(lubridate)
##
## Attaching package: 'lubridate'
## The following object is masked from 'package:base':
##
## date
library(forecast)
## Registered S3 methods overwritten by 'forecast':
## method from
## fitted.fracdiff fracdiff
## residuals.fracdiff fracdiff
library(fpp2)
## Loading required package: ggplot2
## Loading required package: fma
## Loading required package: expsmooth
fb <- getSymbols("FB", auto.assign = F)
## 'getSymbols' currently uses auto.assign=TRUE by default, but will
## use auto.assign=FALSE in 0.5-0. You will still be able to use
## 'loadSymbols' to automatically load data. getOption("getSymbols.env")
## and getOption("getSymbols.auto.assign") will still be checked for
## alternate defaults.
##
## This message is shown once per session and may be disabled by setting
## options("getSymbols.warning4.0"=FALSE). See ?getSymbols for details.
chartSeries(fb)

fbClose <- fb$FB.Close
# install.packages('rugarch')
library(rugarch)
## Warning: package 'rugarch' was built under R version 3.6.1
## Loading required package: parallel
##
## Attaching package: 'rugarch'
## The following object is masked from 'package:stats':
##
## sigma
fbClose.train <- fbClose[1:(length(fbClose)-10)]
fbClose.valid <- fbClose[(length(fbClose)-9):length(fbClose)]
# Garch ----
Garch.HParamSelect <- function(y,totLags,totLagsEr){
aic.dt <- data.frame(list(AIC = rep(0,totLags*totLagsEr),
i = rep(0,totLags*totLagsEr),
e = rep(0,totLags*totLagsEr)))
x<-1
for (i in 0:totLags){
for(e in 0:totLagsEr){
fit <- ugarchspec(mean.model = list(armaOrder = c(i,e)), distribution.model = 'std')
try({myGarch <- ugarchfit(fit, y)
aic.dt[x,1] <- infocriteria(myGarch)[1]
aic.dt[x,2] <- i
aic.dt[x,3] <- e})
x<-x+1
}
}
return(aic.dt)
}
aic.dt<-Garch.HParamSelect(fbClose.train,6,6)
## Warning in arima(data, order = c(modelinc[2], 0, modelinc[3]), include.mean
## = modelinc[1], : possible convergence problem: optim gave code = 1
## Warning in arima(data, order = c(modelinc[2], 0, modelinc[3]), include.mean
## = modelinc[1], : possible convergence problem: optim gave code = 1
## Warning in arima(data, order = c(modelinc[2], 0, modelinc[3]), include.mean
## = modelinc[1], : possible convergence problem: optim gave code = 1
## Warning in arima(data, order = c(modelinc[2], 0, modelinc[3]), include.mean
## = modelinc[1], : possible convergence problem: optim gave code = 1
## Warning in arima(data, order = c(modelinc[2], 0, modelinc[3]), include.mean
## = modelinc[1], : possible convergence problem: optim gave code = 1
## Warning in arima(data, order = c(modelinc[2], 0, modelinc[3]), include.mean
## = modelinc[1], : possible convergence problem: optim gave code = 1
## Warning in arima(data, order = c(modelinc[2], 0, modelinc[3]), include.mean
## = modelinc[1], : possible convergence problem: optim gave code = 1
## Warning in arima(data, order = c(modelinc[2], 0, modelinc[3]), include.mean
## = modelinc[1], : possible convergence problem: optim gave code = 1
try(aic.dt <- filter(aic.dt, AIC!=0))
aic.dt[which.min(aic.dt$AIC),]
## AIC i e
## 46 3.75096 6 3
fit1 <- ugarchspec(mean.model=list(armaOrder=c(6,6)), distribution.model = 'std')
fbGarch1 <- ugarchfit(spec=fit1, data = fbClose.train)
## Warning in arima(data, order = c(modelinc[2], 0, modelinc[3]), include.mean
## = modelinc[1], : possible convergence problem: optim gave code = 1
fbPredict <- ugarchboot(fbGarch1,n.ahead = 10,method=c('Partial','Full')[1])
fcast.Garch <- as.data.frame(fbPredict, which='series', type = 'summary')[3,]
fcast.Garch <- gather(fcast.Garch, "Time","Return", 1:10)
fcast.Garch$Time <- seq.Date(from = ymd("2019-07-23"), length.out = 10,by = 1)
Metrics::rmse(actual=fbClose.valid,predicted = fcast.Garch$Return)
## [1] 11.4675
#12.78
#auto.arima ----
fit2 <- auto.arima(fbClose.train)
fcast.aArima <- forecast(fit2,h=10)
Metrics::rmse(actual=fbClose.valid,predicted=fcast.aArima$mean)
## Warning in se(actual, predicted): Incompatible methods ("Ops.xts",
## "Ops.ts") for "-"
## [1] 11.01003
#Auto-arima performs better here
#Dynamic Harmonic Regression ----
inds <- seq(as.Date("2012-05-18"), as.Date("2019-08-06"), by = "day")
fbClose.train.ts <- ts(fbClose.train,start = c(2012,as.numeric(format(inds[18], "%m"))),frequency = 365)
DHR.Kselector <- function(timeSeries, maxK){
aicc.dt <- data.frame(list(aicc = rep(0,maxK),
iVal = rep(0,maxK)))
for (i in seq(maxK)) {
fit <- auto.arima(fbClose.train.ts, xreg = fourier(fbClose.train.ts, K = i),
seasonal = FALSE, lambda = 0)
aicc.dt$aicc[i] <- fit[["aicc"]]
aicc.dt$iVal[i] <- i
}
return(aicc.dt)
}
aicc.dt <- DHR.Kselector(fbclose.train.ts,10)
myK <- aicc.dt$iVal[which.min(aicc.dt$aicc)]
fit3 <- auto.arima(fbClose.train.ts, xreg = fourier(fbClose.train.ts, K = myK),
seasonal = FALSE, lambda = 0)
fcast.DHR <- forecast(fit3,h=1, xreg = fourier(fbClose.train.ts, K = myK))
Metrics::rmse(actual=fbClose.valid,predicted=fcast.DHR$mean[1:10])
## [1] 11.47824
#The regular auto.arima seemed to perform the best so far.