library(quantmod)
## Warning: package 'quantmod' was built under R version 4.0.3
## Loading required package: xts
## Warning: package 'xts' was built under R version 4.0.2
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 4.0.2
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Loading required package: TTR
## Warning: package 'TTR' was built under R version 4.0.2
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
## Version 0.4-0 included new data defaults. See ?getSymbols.
library(fpp2)
## Warning: package 'fpp2' was built under R version 4.0.3
## -- Attaching packages ------------------------------------ fpp2 2.4 --
## v ggplot2 3.3.0 v fma 2.4
## v forecast 8.12 v expsmooth 2.3
## Warning: package 'forecast' was built under R version 4.0.2
## Warning: package 'fma' was built under R version 4.0.3
## Warning: package 'expsmooth' was built under R version 4.0.3
##
library(knitr)
library(readxl)
library(fGarch)
## Warning: package 'fGarch' was built under R version 4.0.3
## Loading required package: timeDate
## Loading required package: timeSeries
## Warning: package 'timeSeries' was built under R version 4.0.3
##
## Attaching package: 'timeSeries'
## The following object is masked from 'package:zoo':
##
## time<-
## Loading required package: fBasics
## Warning: package 'fBasics' was built under R version 4.0.3
##
## Attaching package: 'fBasics'
## The following object is masked from 'package:TTR':
##
## volatility
zm <- read.csv("C:/Users/burtkb/Downloads/ZM.csv")
z = ts(zm[,2],start=c(2019,11,26),end=c(2020,11,26),frequency=250)
autoplot(z)+ggtitle("Zoom stock price - Nov 2019-Nov 2020")
ggseasonplot(z)
There is an upward trend which is to be expected as Zoom has become much more popular over the past year as more people and businesses are using it to communicate during the pandemic. There appears to be no real seasonality.
#transform the data and plot
z.bc =BoxCox(z, lambda=BoxCox.lambda(z))
autoplot(z.bc)
Create 3 models
#naive model
zn = naive(z.bc)
fzn = forecast(zn)
checkresiduals(fzn)
##
## Ljung-Box test
##
## data: Residuals from Naive method
## Q* = 122.89, df = 50, p-value = 4.514e-08
##
## Model df: 0. Total lags used: 50
#there are several lags outside of the 95% confidence interval. There is likely a better model.
#ets model
zets = ets(z.bc)
## Warning in ets(z.bc): I can't handle data with frequency greater than 24.
## Seasonality will be ignored. Try stlf() if you need seasonal forecasts.
fzets = forecast(zets)
checkresiduals(fzets)
##
## Ljung-Box test
##
## data: Residuals from ETS(M,A,N)
## Q* = 42.313, df = 46, p-value = 0.6274
##
## Model df: 4. Total lags used: 50
#there are a few lags outside of the interval, but not as many as the first.
#arima model
za = auto.arima(z.bc, seasonal=FALSE)
fza = forecast(za, h=6)
checkresiduals(fza)
##
## Ljung-Box test
##
## data: Residuals from ARIMA(1,2,1)
## Q* = 40.723, df = 48, p-value = 0.7627
##
## Model df: 2. Total lags used: 50
#this is the best model thus far.
#garch model
zg = garchFit(data = z.bc, cond.dist = "norm")
##
## Series Initialization:
## ARMA Model: arma
## Formula Mean: ~ arma(0, 0)
## GARCH Model: garch
## Formula Variance: ~ garch(1, 1)
## ARMA Order: 0 0
## Max ARMA Order: 0
## GARCH Order: 1 1
## Max GARCH Order: 1
## Maximum Order: 1
## Conditional Dist: norm
## h.start: 2
## llh.start: 1
## Length of Series: 251
## Recursion Init: mci
## Series Scale: 144.5506
##
## Parameter Initialization:
## Initial Parameters: $params
## Limits of Transformations: $U, $V
## Which Parameters are Fixed? $includes
## Parameter Matrix:
## U V params includes
## mu -15.74449014 15.74449 1.574449 TRUE
## omega 0.00000100 100.00000 0.100000 TRUE
## alpha1 0.00000001 1.00000 0.100000 TRUE
## gamma1 -0.99999999 1.00000 0.100000 FALSE
## beta1 0.00000001 1.00000 0.800000 TRUE
## delta 0.00000000 2.00000 2.000000 FALSE
## skew 0.10000000 10.00000 1.000000 FALSE
## shape 1.00000000 10.00000 4.000000 FALSE
## Index List of Parameters to be Optimized:
## mu omega alpha1 beta1
## 1 2 3 5
## Persistence: 0.9
##
##
## --- START OF TRACE ---
## Selected Algorithm: nlminb
##
## R coded nlminb Solver:
##
## 0: 311.06931: 1.57445 0.100000 0.100000 0.800000
## 1: 271.27798: 0.875154 1.00000e-06 0.411914 0.0317495
## 2: 257.23053: 0.844875 0.101843 0.424913 1.00000e-08
## 3: 255.46862: 0.935921 0.102223 0.396786 0.0934124
## 4: 240.57415: 0.892273 0.0974455 0.634335 0.00340836
## 5: 220.81363: 1.00413 1.00000e-06 0.779858 1.00000e-08
## 6: 205.97032: 1.00404 0.0152898 0.779858 3.32803e-07
## 7: 205.06804: 0.971572 0.0152125 0.799635 1.00000e-08
## 8: 204.36742: 0.966528 0.0151989 0.845363 1.00000e-08
## 9: 203.96914: 0.965638 0.0151933 0.906271 1.00000e-08
## 10: 203.94384: 0.967456 0.0151953 0.923070 1.00000e-08
## 11: 203.94166: 0.968385 0.0151955 0.926829 1.00000e-08
## 12: 203.93961: 0.969128 0.0151939 0.929000 1.00000e-08
## 13: 203.93248: 0.970885 0.0151836 0.933652 1.00000e-08
## 14: 203.91590: 0.973432 0.0151522 0.940351 1.00000e-08
## 15: 203.87026: 0.977684 0.0150528 0.952205 1.00000e-08
## 16: 203.75090: 0.984205 0.0147727 0.972724 1.00000e-08
## 17: 203.12902: 1.00211 0.0135947 1.00000 1.00000e-08
## 18: 200.84726: 1.04266 0.00966348 1.00000 1.00000e-08
## 19: 194.89538: 1.08297 1.00000e-06 1.00000 1.00000e-08
## 20: 193.32448: 1.08296 0.00191212 1.00000 7.04465e-08
## 21: 188.24409: 1.03923 0.00179453 0.954279 1.00000e-08
## 22: 186.36579: 0.787658 0.00111157 0.999795 1.00000e-08
## 23: 185.88772: 0.772231 0.00106696 0.999778 1.00000e-08
## 24: 185.86579: 0.771332 0.00106000 0.992478 1.00000e-08
## 25: 185.80078: 0.769410 0.00103354 0.978185 1.00000e-08
## 26: 185.65411: 0.766410 0.000967577 0.960021 1.00000e-08
## 27: 185.17566: 0.759157 0.000749205 0.927855 1.00000e-08
## 28: 183.97220: 0.751593 0.000455328 0.924265 0.0166397
## 29: 181.89362: 0.751598 0.000128106 0.924265 0.0166398
## 30: 181.60921: 0.751597 7.38140e-05 0.924265 0.0166398
## 31: 181.57824: 0.751596 6.26063e-05 0.924265 0.0166398
## 32: 181.56905: 0.751595 5.14169e-05 0.924265 0.0166399
## 33: 181.56806: 0.751590 5.39052e-05 0.924263 0.0166500
## 34: 181.27453: 0.748487 3.59940e-05 0.922784 0.0235127
## 35: 180.85771: 0.744943 2.68258e-05 0.921081 0.0313619
## 36: 180.84983: 0.744942 3.24624e-05 0.921081 0.0313619
## 37: 180.84898: 0.744939 3.14316e-05 0.921079 0.0313669
## 38: 180.30947: 0.738686 2.64321e-05 0.917370 0.0424400
## 39: 180.11545: 0.737090 1.66696e-05 0.927477 0.0467760
## 40: 180.03124: 0.737752 1.31322e-05 0.949560 0.0465539
## 41: 179.82935: 0.736882 1.62129e-05 0.996095 0.0358658
## 42: 179.65013: 0.735022 1.01529e-05 1.00000 0.00837603
## 43: 179.56028: 0.736751 1.32497e-05 1.00000 1.00000e-08
## 44: 179.54773: 0.736233 1.20564e-05 1.00000 1.00000e-08
## 45: 179.54734: 0.736112 1.16906e-05 1.00000 1.00000e-08
## 46: 179.54733: 0.736125 1.17725e-05 1.00000 1.00000e-08
## 47: 179.54733: 0.736126 1.17633e-05 1.00000 1.00000e-08
## 48: 179.54733: 0.736126 1.17634e-05 1.00000 1.00000e-08
##
## Final Estimate of the Negative LLH:
## LLH: 1427.928 norm LLH: 5.688958
## mu omega alpha1 beta1
## 106.40740146 0.24579551 0.99999999 0.00000001
##
## R-optimhess Difference Approximated Hessian Matrix:
## mu omega alpha1 beta1
## mu -4.81500429 -0.02820984 -0.2571304 7.0083813
## omega -0.02820984 -0.03503851 -0.2636339 -0.2812824
## alpha1 -0.25713044 -0.26363391 -130.6473239 -133.3303587
## beta1 7.00838131 -0.28128238 -133.3303587 -274.8141779
## attr(,"time")
## Time difference of 0.008978128 secs
##
## --- END OF TRACE ---
##
##
## Time to Estimate Parameters:
## Time difference of 0.07380319 secs
## Warning: Using formula(x) is deprecated when x is a character vector of length > 1.
## Consider formula(paste(x, collapse = " ")) instead.
coef(zg)
## mu omega alpha1 beta1
## 106.40740146 0.24579551 0.99999999 0.00000001
plot(residuals(zg))
fzg = predict(zg, n.ahead=12, plot=TRUE)
acf(zg@residuals)
pacf(zg@residuals)
#arima is still probably the best model to use moving forward
Even though the residual plots indicate that the arima model is best, we will look at accuracy of the three models.
accuracy(fzn)
## ME RMSE MAE MPE MAPE MASE ACF1
## Training set 1.906 3.994186 1.906 0.8533343 0.8533343 0.004 0.4356499
accuracy(fzets)
## ME RMSE MAE MPE MAPE MASE
## Training set 0.06406974 3.305614 1.622157 0.03459776 0.7288071 0.003404317
## ACF1
## Training set 0.2543346
accuracy(fza)
## ME RMSE MAE MPE MAPE MASE
## Training set 0.22327 3.138125 1.547152 0.1180489 0.691543 0.003246909
## ACF1
## Training set -0.01851844
#the accuracy numbers confirm that the arima model is the best to use as the mrmse, mape, and mase were lowest for the arima model than the others.
We will use the arima model to make final predictions.
final.fz = forecast(fza, h=1)
autoplot(final.fz, include=24)
print(summary(final.fz))
##
## Forecast method: ARIMA(1,2,1)
##
## Model Information:
## Series: z.bc
## ARIMA(1,2,1)
##
## Coefficients:
## ar1 ma1
## 0.3877 -0.9720
## s.e. 0.0625 0.0182
##
## sigma^2 estimated as 10.01: log likelihood=-640.13
## AIC=1286.26 AICc=1286.36 BIC=1296.81
##
## Error measures:
## ME RMSE MAE MPE MAPE MASE
## Training set 0.22327 3.138125 1.547152 0.1180489 0.691543 0.003246909
## ACF1
## Training set -0.01851844
##
## Forecasts:
## Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
## 2020.044 540.5886 536.5345 544.6427 534.3884 546.7888
## Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
## 2020.044 540.5886 536.5345 544.6427 534.3884 546.7888
predict(final.fz)
## Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
## 2020.044 540.5886 536.5345 544.6427 534.3884 546.7888