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