library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.2     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggthemes)
## Warning: package 'ggthemes' was built under R version 4.3.3
library(forecast)
## Warning: package 'forecast' was built under R version 4.3.3
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(tseries)
library(gridExtra)
## 
## Attaching package: 'gridExtra'
## 
## The following object is masked from 'package:dplyr':
## 
##     combine
library(rugarch)
## Loading required package: parallel
## 
## Attaching package: 'rugarch'
## 
## The following object is masked from 'package:purrr':
## 
##     reduce
## 
## The following object is masked from 'package:stats':
## 
##     sigma
library(readxl)
dfghjkl <- read_excel("/Users/chaua/OneDrive - UFM/TLHT/dfghjkl.xlsx")
# One column for each stock

qplot(x = 1:816, y = dfghjkl$eg , geom = 'line') + geom_line(color = 'darkblue') + 
    labs(x = '' , y = 'Price' , title = "Citigroup Inc.") + geom_hline(yintercept = mean(dfghjkl$eg) , color = 'red')
## Warning: `qplot()` was deprecated in ggplot2 3.4.0.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

rets = diff(dfghjkl$eg) / dfghjkl$eg[-length(dfghjkl$eg)]

p1 = qplot(x = 1:length(rets) , y = rets , geom = 'line') + geom_line(color = 'darkblue') + 
    geom_hline(yintercept = mean(rets) , color = 'red' , size = 1) + 
    labs(x = '' , y = 'Daily Returns')
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
p2 = qplot(rets , geom = 'density') + coord_flip() + geom_vline(xintercept = mean(rets) , color = 'red' , size = 1) +
    geom_density(fill = 'lightblue' , alpha = 0.4) + labs(x = '')

grid.arrange(p1 , p2 , ncol = 2)

adf.test(rets)
## Warning in adf.test(rets): p-value smaller than printed p-value
## 
##  Augmented Dickey-Fuller Test
## 
## data:  rets
## Dickey-Fuller = -7.8537, Lag order = 9, p-value = 0.01
## alternative hypothesis: stationary
model.arima = auto.arima(rets , max.order = c(3 , 0 ,3) , stationary = TRUE , trace = T , ic = 'aicc')
## 
##  Fitting models using approximations to speed things up...
## 
##  ARIMA(2,0,2) with non-zero mean : -4084.083
##  ARIMA(0,0,0) with non-zero mean : -4074.15
##  ARIMA(1,0,0) with non-zero mean : -4076.424
##  ARIMA(0,0,1) with non-zero mean : -4074.952
##  ARIMA(0,0,0) with zero mean     : -4074.982
##  ARIMA(1,0,2) with non-zero mean : -4080.665
##  ARIMA(2,0,1) with non-zero mean : -4078.6
##  ARIMA(3,0,2) with non-zero mean : Inf
##  ARIMA(2,0,3) with non-zero mean : -4096.436
##  ARIMA(1,0,3) with non-zero mean : -4078.671
##  ARIMA(3,0,3) with non-zero mean : Inf
##  ARIMA(2,0,4) with non-zero mean : -4095.346
##  ARIMA(1,0,4) with non-zero mean : -4097.709
##  ARIMA(0,0,4) with non-zero mean : -4082.991
##  ARIMA(1,0,5) with non-zero mean : -4096.842
##  ARIMA(0,0,3) with non-zero mean : -4079.334
##  ARIMA(0,0,5) with non-zero mean : -4089.857
##  ARIMA(2,0,5) with non-zero mean : -4095.971
##  ARIMA(1,0,4) with zero mean     : -4098.742
##  ARIMA(0,0,4) with zero mean     : -4083.974
##  ARIMA(1,0,3) with zero mean     : -4079.682
##  ARIMA(2,0,4) with zero mean     : -4096.128
##  ARIMA(1,0,5) with zero mean     : -4097.905
##  ARIMA(0,0,3) with zero mean     : -4080.451
##  ARIMA(0,0,5) with zero mean     : -4090.993
##  ARIMA(2,0,3) with zero mean     : -4097.164
##  ARIMA(2,0,5) with zero mean     : -4097.357
## 
##  Now re-fitting the best model(s) without approximations...
## 
##  ARIMA(1,0,4) with zero mean     : -4097.796
## 
##  Best model: ARIMA(1,0,4) with zero mean
model.arima
## Series: rets 
## ARIMA(1,0,4) with zero mean 
## 
## Coefficients:
##           ar1     ma1     ma2    ma3      ma4
##       -0.7341  0.8195  0.1477  0.060  -0.1112
## s.e.   0.0838  0.0875  0.0455  0.044   0.0375
## 
## sigma^2 = 0.0003802:  log likelihood = 2054.95
## AIC=-4097.9   AICc=-4097.8   BIC=-4069.68
model.arima$residuals %>% ggtsdisplay(plot.type = 'hist' , lag.max = 14)

ar.res = model.arima$residuals
Box.test(model.arima$residuals , lag = 14 , fitdf = 2 , type = 'Ljung-Box')
## 
##  Box-Ljung test
## 
## data:  model.arima$residuals
## X-squared = 7.4879, df = 12, p-value = 0.8238
tsdisplay(ar.res^2 , main = 'Squared Residuals')

# Model specification
model.spec = ugarchspec(variance.model = list(model = 'sGARCH' , garchOrder = c(1 , 1)) , 
                        mean.model = list(armaOrder = c(0 , 0)))

model.fit = ugarchfit(spec = model.spec , data = ar.res , solver = 'solnp')

options(scipen = 999)
model.fit@fit$matcoef
##             Estimate     Std. Error    t value        Pr(>|t|)
## mu     0.00046941815 0.000563885625  0.8324705 0.4051434252857
## omega  0.00002021698 0.000004842566  4.1748488 0.0000298184052
## alpha1 0.14494123637 0.028623893848  5.0636450 0.0000004113153
## beta1  0.81455638853 0.028363598562 28.7183725 0.0000000000000
quantile(rets , 0.05)
##          5% 
## -0.02566048
quantile(rets , 0.01)
##          1% 
## -0.05322639