library(ggplot2)
library(zoo)
library(quantmod)
library(xts)
library(PerformanceAnalytics)
library(rugarch)

Firstly we need data before anything, so we get WIPRO’s stock data from # Yahoo Finance

Here we have used WIPRO as our stock for forecasting with the last 10 years of stock data.

getSymbols("WIPRO.NS",from = "2011-01-01",to = "2021-03-31")
## [1] "WIPRO.NS"
chartSeries(WIPRO.NS)

lreturn <- WIPRO.NS$WIPRO.NS.Close

Wipro Daily Closing prices

Firstly we will remove the null values from our dataset abd then convert it into returns data Then have a look at this time series

lreturn<- na.omit(lreturn)
return <- CalculateReturns(WIPRO.NS$WIPRO.NS.Close)
return <- return[-1]
return<- na.omit(return)

In the above section, we calculated the returns of closing prices, which will now be used for further modelling.

We now look at our data in the form of chart series to get a better understanding

autoplot(return)

hist(return)

chart.Histogram(return,
                methods = c('add.density', 'add.normal'),
                colorset = c('blue', 'green', 'red'))

chartSeries(return)

Before going further we will now look at the annual volatility of Wipro stock using Rolling statistics.

chart.RollingPerformance(R = return["2011::2020"],
                         width = 22,
                         FUN = "sd.annualized",
                         scale = 252,
                         main = "Wipro's yearly rolling volatility")

Before applying GARCH model, we need to find the right set of values of GARCH order and ARMA order , for this, we build a set of models using standard GARCH by tweaking the order values a bit, and trying different combinations to find the most suitable one for forecasting.

This particular model will be chosen by looking for the least AIC(Akaike Information Criterion) value in each model.

Some of these models are shown below

Firstly we use standard Garch Model here with Garch order (1,1) and ARMA values (0,0)

s1 <- ugarchspec(variance.model=list(model="sGARCH",garchOrder=c(1,1)),
                mean.model=list(armaOrder=c(0,0)),distribution.model="norm")
m1 <- ugarchfit(data = return, spec = s1)
m1
## 
## *---------------------------------*
## *          GARCH Model Fit        *
## *---------------------------------*
## 
## Conditional Variance Dynamics    
## -----------------------------------
## GARCH Model  : sGARCH(1,1)
## Mean Model   : ARFIMA(0,0,0)
## Distribution : norm 
## 
## Optimal Parameters
## ------------------------------------
##         Estimate  Std. Error  t value Pr(>|t|)
## mu      0.000246    0.000301  0.81678  0.41405
## omega   0.000004    0.000003  1.31518  0.18845
## alpha1  0.039776    0.007466  5.32749  0.00000
## beta1   0.947638    0.010889 87.02911  0.00000
## 
## Robust Standard Errors:
##         Estimate  Std. Error  t value Pr(>|t|)
## mu      0.000246    0.000310  0.79122  0.42882
## omega   0.000004    0.000021  0.17959  0.85747
## alpha1  0.039776    0.031338  1.26928  0.20434
## beta1   0.947638    0.071709 13.21509  0.00000
## 
## LogLikelihood : 6846.941 
## 
## Information Criteria
## ------------------------------------
##                     
## Akaike       -5.4482
## Bayes        -5.4389
## Shibata      -5.4482
## Hannan-Quinn -5.4448
## 
## Weighted Ljung-Box Test on Standardized Residuals
## ------------------------------------
##                         statistic p-value
## Lag[1]                     0.2968  0.5859
## Lag[2*(p+q)+(p+q)-1][2]    0.3642  0.7610
## Lag[4*(p+q)+(p+q)-1][5]    1.1286  0.8299
## d.o.f=0
## H0 : No serial correlation
## 
## Weighted Ljung-Box Test on Standardized Squared Residuals
## ------------------------------------
##                         statistic p-value
## Lag[1]                     0.3083  0.5787
## Lag[2*(p+q)+(p+q)-1][5]    2.1877  0.5748
## Lag[4*(p+q)+(p+q)-1][9]    5.4120  0.3715
## d.o.f=2
## 
## Weighted ARCH LM Tests
## ------------------------------------
##             Statistic Shape Scale P-Value
## ARCH Lag[3]    0.6391 0.500 2.000  0.4240
## ARCH Lag[5]    4.3182 1.440 1.667  0.1473
## ARCH Lag[7]    5.4247 2.315 1.543  0.1850
## 
## Nyblom stability test
## ------------------------------------
## Joint Statistic:  2.4976
## Individual Statistics:             
## mu     0.1028
## omega  0.7274
## alpha1 0.1234
## beta1  0.1220
## 
## Asymptotic Critical Values (10% 5% 1%)
## Joint Statistic:          1.07 1.24 1.6
## Individual Statistic:     0.35 0.47 0.75
## 
## Sign Bias Test
## ------------------------------------
##                    t-value   prob sig
## Sign Bias           1.1096 0.2673    
## Negative Sign Bias  0.8427 0.3995    
## Positive Sign Bias  1.0107 0.3123    
## Joint Effect        3.9612 0.2657    
## 
## 
## Adjusted Pearson Goodness-of-Fit Test:
## ------------------------------------
##   group statistic p-value(g-1)
## 1    20     134.0    2.574e-19
## 2    30     155.8    2.693e-19
## 3    40     168.4    5.145e-18
## 4    50     161.0    7.530e-14
## 
## 
## Elapsed time : 0.3229518
plot(m1, which = 'all')
## 
## please wait...calculating quantiles...

Now here with Garch order (1,1) and ARMA values (2,2)

s2 <-  ugarchspec(variance.model=list(model="sGARCH",garchOrder=c(1,1)),
                mean.model=list(armaOrder=c(2,2)),distribution.model="norm")
m2 <- ugarchfit(data = return, spec = s2)
m2
## 
## *---------------------------------*
## *          GARCH Model Fit        *
## *---------------------------------*
## 
## Conditional Variance Dynamics    
## -----------------------------------
## GARCH Model  : sGARCH(1,1)
## Mean Model   : ARFIMA(2,0,2)
## Distribution : norm 
## 
## Optimal Parameters
## ------------------------------------
##         Estimate  Std. Error    t value Pr(>|t|)
## mu      0.000246    0.000298    0.82694  0.40827
## ar1    -0.766894    0.012322  -62.23616  0.00000
## ar2    -0.964653    0.005652 -170.66838  0.00000
## ma1     0.761891    0.015086   50.50441  0.00000
## ma2     0.950692    0.008096  117.42555  0.00000
## omega   0.000004    0.000003    1.39826  0.16204
## alpha1  0.039609    0.007594    5.21560  0.00000
## beta1   0.948011    0.010726   88.38041  0.00000
## 
## Robust Standard Errors:
##         Estimate  Std. Error    t value Pr(>|t|)
## mu      0.000246    0.000303    0.81377  0.41578
## ar1    -0.766894    0.028070  -27.32124  0.00000
## ar2    -0.964653    0.009082 -106.21226  0.00000
## ma1     0.761891    0.033245   22.91734  0.00000
## ma2     0.950692    0.008374  113.52352  0.00000
## omega   0.000004    0.000018    0.20029  0.84125
## alpha1  0.039609    0.033644    1.17730  0.23908
## beta1   0.948011    0.067855   13.97115  0.00000
## 
## LogLikelihood : 6850.284 
## 
## Information Criteria
## ------------------------------------
##                     
## Akaike       -5.4477
## Bayes        -5.4291
## Shibata      -5.4477
## Hannan-Quinn -5.4409
## 
## Weighted Ljung-Box Test on Standardized Residuals
## ------------------------------------
##                          statistic p-value
## Lag[1]                     0.07318  0.7868
## Lag[2*(p+q)+(p+q)-1][11]   1.82766  1.0000
## Lag[4*(p+q)+(p+q)-1][19]   4.45344  0.9982
## d.o.f=4
## H0 : No serial correlation
## 
## Weighted Ljung-Box Test on Standardized Squared Residuals
## ------------------------------------
##                         statistic p-value
## Lag[1]                     0.2859  0.5929
## Lag[2*(p+q)+(p+q)-1][5]    2.1500  0.5834
## Lag[4*(p+q)+(p+q)-1][9]    5.4559  0.3656
## d.o.f=2
## 
## Weighted ARCH LM Tests
## ------------------------------------
##             Statistic Shape Scale P-Value
## ARCH Lag[3]    0.5373 0.500 2.000  0.4635
## ARCH Lag[5]    4.0726 1.440 1.667  0.1675
## ARCH Lag[7]    5.1652 2.315 1.543  0.2084
## 
## Nyblom stability test
## ------------------------------------
## Joint Statistic:  4.0318
## Individual Statistics:              
## mu     0.10259
## ar1    0.41531
## ar2    0.04535
## ma1    0.45309
## ma2    0.07021
## omega  0.82335
## alpha1 0.12341
## beta1  0.12196
## 
## Asymptotic Critical Values (10% 5% 1%)
## Joint Statistic:          1.89 2.11 2.59
## Individual Statistic:     0.35 0.47 0.75
## 
## Sign Bias Test
## ------------------------------------
##                    t-value   prob sig
## Sign Bias           0.9416 0.3465    
## Negative Sign Bias  0.9475 0.3435    
## Positive Sign Bias  0.9474 0.3435    
## Joint Effect        3.6348 0.3037    
## 
## 
## Adjusted Pearson Goodness-of-Fit Test:
## ------------------------------------
##   group statistic p-value(g-1)
## 1    20     118.8    1.849e-16
## 2    30     135.1    1.235e-15
## 3    40     143.1    8.448e-14
## 4    50     170.4    2.476e-15
## 
## 
## Elapsed time : 0.6558981
plot(m2, which = 'all')
## 
## please wait...calculating quantiles...

Now here with Garch order (1,2) and ARMA values (2,2)

s3 <-  ugarchspec(variance.model=list(model="sGARCH",garchOrder=c(1,2)),
                mean.model=list(armaOrder=c(2,2)),distribution.model="norm")
m3 <- ugarchfit(data = return, spec = s3)
m3
## 
## *---------------------------------*
## *          GARCH Model Fit        *
## *---------------------------------*
## 
## Conditional Variance Dynamics    
## -----------------------------------
## GARCH Model  : sGARCH(1,2)
## Mean Model   : ARFIMA(2,0,2)
## Distribution : norm 
## 
## Optimal Parameters
## ------------------------------------
##         Estimate  Std. Error   t value Pr(>|t|)
## mu      0.000390    0.000292   1.33470  0.18197
## ar1    -0.747954    0.060349 -12.39390  0.00000
## ar2    -0.954797    0.017262 -55.31070  0.00000
## ma1     0.743353    0.067960  10.93803  0.00000
## ma2     0.943195    0.020518  45.96955  0.00000
## omega   0.000008    0.000001   8.02041  0.00000
## alpha1  0.085817    0.008572  10.01087  0.00000
## beta1   0.004138    0.011709   0.35343  0.72377
## beta2   0.884351    0.014671  60.27848  0.00000
## 
## Robust Standard Errors:
##         Estimate  Std. Error   t value Pr(>|t|)
## mu      0.000390    0.000297   1.31365 0.188965
## ar1    -0.747954    0.087254  -8.57216 0.000000
## ar2    -0.954797    0.011210 -85.17065 0.000000
## ma1     0.743353    0.098300   7.56209 0.000000
## ma2     0.943195    0.011708  80.56114 0.000000
## omega   0.000008    0.000002   3.66127 0.000251
## alpha1  0.085817    0.017028   5.03968 0.000000
## beta1   0.004138    0.031292   0.13226 0.894782
## beta2   0.884351    0.047469  18.63009 0.000000
## 
## LogLikelihood : 6856.633 
## 
## Information Criteria
## ------------------------------------
##                     
## Akaike       -5.4519
## Bayes        -5.4311
## Shibata      -5.4520
## Hannan-Quinn -5.4444
## 
## Weighted Ljung-Box Test on Standardized Residuals
## ------------------------------------
##                          statistic p-value
## Lag[1]                       0.170  0.6801
## Lag[2*(p+q)+(p+q)-1][11]     2.287  1.0000
## Lag[4*(p+q)+(p+q)-1][19]     5.174  0.9920
## d.o.f=4
## H0 : No serial correlation
## 
## Weighted Ljung-Box Test on Standardized Squared Residuals
## ------------------------------------
##                          statistic p-value
## Lag[1]                     0.03653 0.84842
## Lag[2*(p+q)+(p+q)-1][8]    9.40877 0.04710
## Lag[4*(p+q)+(p+q)-1][14]  14.85688 0.02669
## d.o.f=3
## 
## Weighted ARCH LM Tests
## ------------------------------------
##             Statistic Shape Scale  P-Value
## ARCH Lag[4]     4.967 0.500 2.000 0.025840
## ARCH Lag[6]     6.628 1.461 1.711 0.048500
## ARCH Lag[8]    11.672 2.368 1.583 0.009495
## 
## Nyblom stability test
## ------------------------------------
## Joint Statistic:  6.6797
## Individual Statistics:             
## mu     0.2158
## ar1    0.7049
## ar2    0.1190
## ma1    0.7229
## ma2    0.1346
## omega  0.8468
## alpha1 0.1644
## beta1  0.1474
## beta2  0.1634
## 
## Asymptotic Critical Values (10% 5% 1%)
## Joint Statistic:          2.1 2.32 2.82
## Individual Statistic:     0.35 0.47 0.75
## 
## Sign Bias Test
## ------------------------------------
##                    t-value   prob sig
## Sign Bias           1.0143 0.3106    
## Negative Sign Bias  0.5435 0.5868    
## Positive Sign Bias  0.2980 0.7657    
## Joint Effect        2.9937 0.3926    
## 
## 
## Adjusted Pearson Goodness-of-Fit Test:
## ------------------------------------
##   group statistic p-value(g-1)
## 1    20     119.8    1.209e-16
## 2    30     129.0    1.449e-14
## 3    40     141.2    1.700e-13
## 4    50     149.9    3.730e-12
## 
## 
## Elapsed time : 0.9548478
plot(m3, which = 'all')
## 
## please wait...calculating quantiles...

Now here with Garch order (2,1) and ARMA values (1,1)

s4 <-  ugarchspec(variance.model=list(model="sGARCH",garchOrder=c(2,1)),
                mean.model=list(armaOrder=c(1,1)),distribution.model="norm")
m4 <- ugarchfit(data = return, spec = s4)
m4
## 
## *---------------------------------*
## *          GARCH Model Fit        *
## *---------------------------------*
## 
## Conditional Variance Dynamics    
## -----------------------------------
## GARCH Model  : sGARCH(2,1)
## Mean Model   : ARFIMA(1,0,1)
## Distribution : norm 
## 
## Optimal Parameters
## ------------------------------------
##         Estimate  Std. Error    t value Pr(>|t|)
## mu      0.000246    0.000292   0.840689 0.400522
## ar1     0.418984    0.621578   0.674066 0.500270
## ma1    -0.437486    0.615345  -0.710960 0.477109
## omega   0.000003    0.000002   1.620957 0.105027
## alpha1  0.037584    0.018629   2.017477 0.043646
## alpha2  0.000000    0.020910   0.000006 0.999995
## beta1   0.950938    0.009209 103.256344 0.000000
## 
## Robust Standard Errors:
##         Estimate  Std. Error   t value Pr(>|t|)
## mu      0.000246    0.000314  0.782757  0.43377
## ar1     0.418984    0.456341  0.918138  0.35855
## ma1    -0.437486    0.455087 -0.961323  0.33639
## omega   0.000003    0.000014  0.250590  0.80213
## alpha1  0.037584    0.050045  0.750996  0.45265
## alpha2  0.000000    0.076679  0.000002  1.00000
## beta1   0.950938    0.053611 17.737879  0.00000
## 
## LogLikelihood : 6847.432 
## 
## Information Criteria
## ------------------------------------
##                     
## Akaike       -5.4462
## Bayes        -5.4300
## Shibata      -5.4462
## Hannan-Quinn -5.4403
## 
## Weighted Ljung-Box Test on Standardized Residuals
## ------------------------------------
##                         statistic p-value
## Lag[1]                    0.09744  0.7549
## Lag[2*(p+q)+(p+q)-1][5]   0.97811  1.0000
## Lag[4*(p+q)+(p+q)-1][9]   1.77426  0.9921
## d.o.f=2
## H0 : No serial correlation
## 
## Weighted Ljung-Box Test on Standardized Squared Residuals
## ------------------------------------
##                          statistic p-value
## Lag[1]                      0.4284  0.5128
## Lag[2*(p+q)+(p+q)-1][8]     5.1981  0.3266
## Lag[4*(p+q)+(p+q)-1][14]    9.1088  0.2712
## d.o.f=3
## 
## Weighted ARCH LM Tests
## ------------------------------------
##             Statistic Shape Scale P-Value
## ARCH Lag[4]   0.09087 0.500 2.000 0.76307
## ARCH Lag[6]   5.53260 1.461 1.711 0.08608
## ARCH Lag[8]   7.49167 2.368 1.583 0.07953
## 
## Nyblom stability test
## ------------------------------------
## Joint Statistic:  7.383
## Individual Statistics:             
## mu     0.1050
## ar1    0.1132
## ma1    0.1172
## omega  1.2577
## alpha1 0.1198
## alpha2 0.1425
## beta1  0.1174
## 
## Asymptotic Critical Values (10% 5% 1%)
## Joint Statistic:          1.69 1.9 2.35
## Individual Statistic:     0.35 0.47 0.75
## 
## Sign Bias Test
## ------------------------------------
##                    t-value   prob sig
## Sign Bias            1.129 0.2592    
## Negative Sign Bias   0.926 0.3545    
## Positive Sign Bias   1.073 0.2833    
## Joint Effect         4.370 0.2241    
## 
## 
## Adjusted Pearson Goodness-of-Fit Test:
## ------------------------------------
##   group statistic p-value(g-1)
## 1    20     123.8    2.156e-17
## 2    30     140.1    1.679e-16
## 3    40     144.5    4.887e-14
## 4    50     165.6    1.418e-14
## 
## 
## Elapsed time : 0.384959
plot(m4, which = 'all')
## 
## please wait...calculating quantiles...

By repeating the steps above multiple times, we prepared a list of combinations with their particular AIC values that are listed below:

#GARCH order |    ARMA order  |  AIC value(Akaike)
#(1,1)       |       (0,0)    |   -5.4482
#(1,1)       |       (1,0)    |   -5.4479
#(1,1)       |       (1,1)    |   -5.4472
#(1,1)       |       (1,2)    |   -5.4471
#(1,1)       |       (2,0)    |   -5.4475
#(1,1)       |       (2,1)    |   -5.4471
#(1,1)       |       (2,2)    |   -5.4477  
#(1,2)       |       (1,1)    |   -5.4463
#(1,2)       |       (1,2)    |   -5.4455
#(1,2)       |       (2,0)    |   -5.4463
#(1,2)       |       (2,1)    |   -5.4457
#(1,2)       |       (2,2)    |   -5.4519  (Lowest AIC value)
#(2,0)       |       (1,1)    |   -5.4186
#(2,0)       |       (1,2)    |   -5.4192
#(2,0)       |       (2,0)    |   -5.4206
#(2,0)       |       (2,1)    |     NULL
#(2,0)       |       (2,2)    |   -3.9440
#(2,1)       |       (1,1)    |   -5.4462
#(2,1)       |       (1,2)    |   -5.4497

We can see that at GARCH order(1,2) and ARMA order (2,2) has the least AIC value, so we will move further with this.

With these values in hand now, we start creating our Garch model

Now we use this model to forecast values for the next 30 days

s2final <-  ugarchspec(variance.model=list(model="sGARCH",garchOrder=c(1,2)),
                mean.model=list(armaOrder=c(2,2)),distribution.model="norm")
m2final <- ugarchfit(data = return, spec = s2final)
f <- ugarchforecast(fitORspec = m2final, n.ahead = 30)
plot(fitted(f))

plot(sigma(f))

Prediction

Forecasting our predictions on actual stock price values using our model

sfinal <- s2
setfixed(sfinal) <- as.list(coef(m2))



sim <- ugarchpath(spec = sfinal,
                  m.sim = 1,
                  n.sim = 1*30,
                  rseed = 16)
plot.zoo(fitted(sim))

plot.zoo(sigma(sim))

prediction_April_Wipro<- 410.10*apply(fitted(sim), 2, 'cumsum') + 410.10
matplot(prediction_April_Wipro, type = "l", lwd = 3)

##We can see that our Wipro stock price is increasing over the month of april with Highest Closing price of around Rs468 and Lowest Closing price of around Rs409