library(readxl)
library(zoo)
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(aod)
library(pdfetch)
library(lubridate)
## Loading required package: timechange
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tseries)
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
library(vars)
## Loading required package: MASS
##
## Attaching package: 'MASS'
## The following object is masked from 'package:dplyr':
##
## select
## Loading required package: strucchange
## Loading required package: sandwich
## Loading required package: urca
## Loading required package: lmtest
library(FinAna)
##
## Attaching package: 'FinAna'
## The following object is masked from 'package:dplyr':
##
## desc
library(strucchange)
library(sjPlot)
directory <- "/cloud/project/data"
gdpind <- as.data.frame(read.csv(file.path(directory,"NAEXKP01INQ652S.csv"))) # Real GDP
mktcap <- as.data.frame(read_excel(file.path(directory,"Final.xlsx"),sheet = "Market Capitalisaton"))
trnvr <- as.data.frame(read_excel(file.path(directory,"Final.xlsx"),sheet = "Turnover"))
# Real GDP
gdpind$qy=as.yearqtr(as.Date( gdpind$DATE, "%Y-%m-%d"))
gdpind.zoo <- zoo(gdpind$NAEXKP01INQ652S,order.by = gdpind$qy)
#Market Capitalization
mktcap$qy=as.yearqtr(as.Date( mktcap$DATE, "%Y-%m-%d"))
mktcap.zoo <- zoo(mktcap$MKTCAP,order.by = mktcap$qy)
#Turnover/ Trading Volume
trnvr$qy=as.yearqtr(as.Date( trnvr$DATE, "%Y-%m-%d"))
trnvr.zoo <- zoo(trnvr$TRNR,order.by = trnvr$qy)
#Stock Volatility
tickers <- c("^BSESN")
volat <- pdfetch_YAHOO(tickers,fields = "close",from="1996-01-01", to="2021-12-31")
write.zoo(x=volat,file = "Volatillity.csv",col.names = c("DATE","BESN"))
volatility <- as.data.frame(read.csv(file.path(directory,"Volatility.csv")))
data <- volatility
data$year <- strftime(data$DATE,"%Y")
data$month <- strftime(data$DATE,"%m")
data_aggr <- aggregate(BESN~month+year,data,FUN = mean) # Finding the mean of daily data for using as monthly average
data_aggr$Date <- as.yearmon(paste(data_aggr$year, data_aggr$month), "%Y %m ")
data_aggr$qy=as.yearqtr(as.yearmon(data_aggr$Date,"%m %Y"))
data_aggr.zoo <- zoo(data_aggr$BESN,order.by = data_aggr$qy)
## Warning in zoo(data_aggr$BESN, order.by = data_aggr$qy): some methods for "zoo"
## objects do not work if the index entries in 'order.by' are not unique
# Stock Market Volatility(SMV)
smv <- data_aggr
smv <- aggregate(BESN~qy,data_aggr,FUN = mean)
smv.zoo <- zoo(smv$BESN,order.by = smv$qy)
par(mfrow=c(2,2))
plot(gdpind.zoo,main="Real GDP",ylab="Real GDP",xlab="Year")
plot(mktcap.zoo,main="Market Capitalisation",ylab="Mkt Cap",xlab="Year")
plot(trnvr.zoo,main="Market Turnover",ylab="Turnover",xlab="Year")
plot(smv.zoo,main="Stock market Volatility",ylab="Volatility",xlab="Year")
par(mfrow=c(2,2))
acf(ts(gdpind.zoo, f=1),lag.max = 32, main="ACF of GDP",
xaxt="n", xlab="Lag (quarter)", ylim=c(-.2,1))
axis(1, at=seq(0, 32, 1))
acf(ts(mktcap.zoo, f=1),lag.max = 32, main="ACF of Market Capitalisation",
xaxt="n", xlab="Lag (quarter)", ylim=c(-.2,1))
axis(1, at=seq(0, 32, 1))
acf(ts(trnvr.zoo, f=1),lag.max = 32, main="ACF of Turnover",
xaxt="n", xlab="Lag (quarter)", ylim=c(-.2,1))
axis(1, at=seq(0, 32, 1))
acf(ts(smv.zoo, f=1),lag.max = 32, main="ACF of Volatility",
xaxt="n", xlab="Lag (quarter)", ylim=c(-.2,1))
axis(1, at=seq(0, 32, 1))
mtext("My Multiplot Title", # Add main title
side = 5,
line = -2,
outer = TRUE)
str.gdp <- ts(gdpind$NAEXKP01INQ652S,start=1996,frequency = 4)
dfgdp <- breakpoints(str.gdp~1)
summary(dfgdp) # potential breakpoints of real GDP
##
## Optimal (m+1)-segment partition:
##
## Call:
## breakpoints.formula(formula = str.gdp ~ 1)
##
## Breakpoints at observation number:
##
## m = 1 62
## m = 2 44 76
## m = 3 36 57 79
## m = 4 35 54 70 85
## m = 5 26 41 56 71 86
##
## Corresponding to breakdates:
##
## m = 1 2011(2)
## m = 2 2006(4) 2014(4)
## m = 3 2004(4) 2010(1) 2015(3)
## m = 4 2004(3) 2009(2) 2013(2) 2017(1)
## m = 5 2002(2) 2006(1) 2009(4) 2013(3) 2017(2)
##
## Fit:
##
## m 0 1 2 3 4 5
## RSS 9.956e+27 2.237e+27 8.718e+26 4.930e+26 3.548e+26 2.864e+26
## BIC 6.588e+03 6.440e+03 6.351e+03 6.300e+03 6.275e+03 6.262e+03
str.mcap <- ts(mktcap$MKTCAP,start = 1996,frequency = 4)
dfmcap <- breakpoints(str.mcap~1)
summary(dfmcap) # potential breakpoints of market capitalization
##
## Optimal (m+1)-segment partition:
##
## Call:
## breakpoints.formula(formula = str.mcap ~ 1)
##
## Breakpoints at observation number:
##
## m = 1 73
## m = 2 45 84
## m = 3 43 72 87
## m = 4 38 54 72 87
## m = 5 24 39 54 72 87
##
## Corresponding to breakdates:
##
## m = 1 2014(1)
## m = 2 2007(1) 2016(4)
## m = 3 2006(3) 2013(4) 2017(3)
## m = 4 2005(2) 2009(2) 2013(4) 2017(3)
## m = 5 2001(4) 2005(3) 2009(2) 2013(4) 2017(3)
##
## Fit:
##
## m 0 1 2 3 4 5
## RSS 3.824e+15 1.121e+15 5.748e+14 4.131e+14 3.779e+14 3.738e+14
## BIC 3.553e+03 3.435e+03 3.374e+03 3.349e+03 3.349e+03 3.358e+03
str.trnvr <- ts(trnvr$TRNR,start = 1996,frequency = 4)
dftrnvr <- breakpoints(str.trnvr~1)
summary(dftrnvr) # potential breakpoints of turnover or total traded value
##
## Optimal (m+1)-segment partition:
##
## Call:
## breakpoints.formula(formula = str.trnvr ~ 1)
##
## Breakpoints at observation number:
##
## m = 1 86
## m = 2 45 87
## m = 3 40 72 87
## m = 4 30 45 72 87
## m = 5 15 30 45 72 87
##
## Corresponding to breakdates:
##
## m = 1 2017(2)
## m = 2 2007(1) 2017(3)
## m = 3 2005(4) 2013(4) 2017(3)
## m = 4 2003(2) 2007(1) 2013(4) 2017(3)
## m = 5 1999(3) 2003(2) 2007(1) 2013(4) 2017(3)
##
## Fit:
##
## m 0 1 2 3 4 5
## RSS 2.582e+10 8.991e+09 4.798e+09 4.472e+09 4.238e+09 4.192e+09
## BIC 2.315e+03 2.214e+03 2.158e+03 2.160e+03 2.164e+03 2.172e+03
str.smv <- ts(smv$BESN,start = 1997,frequency = 4)
dfsmv <- breakpoints(str.smv~1)
summary(dfsmv) # potential breakpoints of stock market volatility
##
## Optimal (m+1)-segment partition:
##
## Call:
## breakpoints.formula(formula = str.smv ~ 1)
##
## Breakpoints at observation number:
##
## m = 1 67
## m = 2 37 79
## m = 3 35 67 84
## m = 4 34 49 67 84
## m = 5 20 34 49 67 84
##
## Corresponding to breakdates:
##
## m = 1 2013(3)
## m = 2 2006(1) 2016(3)
## m = 3 2005(3) 2013(3) 2017(4)
## m = 4 2005(2) 2009(1) 2013(3) 2017(4)
## m = 5 2001(4) 2005(2) 2009(1) 2013(3) 2017(4)
##
## Fit:
##
## m 0 1 2 3 4 5
## RSS 1.797e+10 5.221e+09 2.516e+09 1.442e+09 1.254e+09 1.238e+09
## BIC 2.152e+03 2.040e+03 1.978e+03 1.932e+03 1.928e+03 1.936e+03
par(mfrow=c(2,2))
ci.dfgdp <- confint(dfgdp)
ts.plot(str.gdp) #GDP
lines(ci.dfgdp)
ci.dfmcap <- confint(dfmcap)
ts.plot(str.mcap) #Market Capitalisation
lines(ci.dfmcap)
ci.dftrnvr <- confint(dftrnvr)
ts.plot(str.trnvr) #Turnover
lines(ci.dftrnvr)
ci.dfsmv <- confint(dfsmv)
ts.plot(str.smv) #Stock Volatility
lines(ci.dfsmv)
mtext("STRUCTURAL BREAKS PLOTS", side = 3, line = -1, outer = TRUE)
* Clearly there is presence of structural breaks in the variables , so
ordinary ADF (Augmented Dickey Fuller) tests are biased.
#Checking Unit root
# We'll use will use Phillips Perron Test as it is not susceptible to structural breaks like ADF test
PP.test(gdpind$NAEXKP01INQ652S)
##
## Phillips-Perron Unit Root Test
##
## data: gdpind$NAEXKP01INQ652S
## Dickey-Fuller = -3.3237, Truncation lag parameter = 4, p-value =
## 0.07095
PP.test(mktcap$MKTCAP)
##
## Phillips-Perron Unit Root Test
##
## data: mktcap$MKTCAP
## Dickey-Fuller = 0.32774, Truncation lag parameter = 4, p-value = 0.99
PP.test(trnvr$TRNR)
##
## Phillips-Perron Unit Root Test
##
## data: trnvr$TRNR
## Dickey-Fuller = -4.7199, Truncation lag parameter = 4, p-value = 0.01
PP.test(smv$BESN)
##
## Phillips-Perron Unit Root Test
##
## data: smv$BESN
## Dickey-Fuller = -0.29909, Truncation lag parameter = 3, p-value =
## 0.9891
par(mfrow=c(2,2))
pacf(ts(gdpind.zoo, f=1),lag.max = 32, main="PACF of GDP",
xaxt="n", xlab="Lag (quarter)", ylim=c(-.2,1))
axis(1, at=seq(0, 32, 1))
pacf(ts(mktcap.zoo, f=1),lag.max = 32, main="PACF of Market Capitalisation",
xaxt="n", xlab="Lag (quarter)", ylim=c(-.2,1))
axis(1, at=seq(0, 32, 1))
pacf(ts(trnvr.zoo, f=1),lag.max = 32, main="PACF of Turnover",
xaxt="n", xlab="Lag (quarter)", ylim=c(-.2,1))
axis(1, at=seq(0, 32, 1))
pacf(ts(smv.zoo, f=1),lag.max = 32, main="PACF of Stock Volatility",
xaxt="n", xlab="Lag (quarter)", ylim=c(-.2,1))
axis(1, at=seq(0, 32, 1))
model=cbind(gdpind.zoo,mktcap.zoo,trnvr.zoo,smv.zoo)
# Writing to a CSV file
write.zoo(x=model,"model.csv")
# Manually removing the NaN values and inserting new values obtained from other sources using
'fix(model)'
## [1] "fix(model)"
#Importing the updated data set
df1 <- as.data.frame(read_excel(file.path(directory,"updated_values.xlsx"),sheet = "GDP"))
df2 <- as.data.frame(read_excel(file.path(directory,"updated_values.xlsx"),sheet = "MCAP"))
df3 <- as.data.frame(read_excel(file.path(directory,"updated_values.xlsx"),sheet = "TRNVR"))
df4 <- as.data.frame(read_excel(file.path(directory,"updated_values.xlsx"),sheet = "SMV"))
# Converting to zoo series
upd_gdpind.zoo <- zoo(df1$gdpind.zoo,order.by = df1$Index)
upd_mktcap.zoo <- zoo(df2$mktcap.zoo,order.by = df2$Index)
upd_trnvr.zoo <- zoo(df3$trnvr.zoo,order.by = df3$Index)
upd_smv.zoo <- zoo(df4$smv.zoo,order.by = df4$Index)
# Binding all the data into a composite matrix
var_model <- cbind(upd_gdpind.zoo,upd_mktcap.zoo,upd_trnvr.zoo,upd_smv.zoo)
# Deciding the optimal lag value to be included by Schwartz ("SC(n)") criterion
VARselect(var_model,lag.max = 3,type="const")
## $selection
## AIC(n) HQ(n) SC(n) FPE(n)
## 3 3 2 3
##
## $criteria
## 1 2 3
## AIC(n) 1.139520e+02 1.130875e+02 1.128240e+02
## HQ(n) 1.141592e+02 1.134605e+02 1.133628e+02
## SC(n) 1.144636e+02 1.140084e+02 1.141542e+02
## FPE(n) 3.082240e+49 1.300346e+49 1.002784e+49
-Therefore we conclude that the optimal number of lagged terms to be included is : 2
$$
\[ For\ Applying\ Toda\ Yamamoto\ test\ we\ need\ to\ construct\ a\ VAR\ model\ with \ k+d_{\max }\ lagged\ terms \ equaling\ 3 \ lags \]
-where k is the number of lagged terms to be included as decided by the SIC criterion and d is the maximum order of integration.
ty <- VAR(var_model,p=3,type = "const")
ty
##
## VAR Estimation Results:
## =======================
##
## Estimated coefficients for equation upd_gdpind.zoo:
## ===================================================
## Call:
## upd_gdpind.zoo = upd_gdpind.zoo.l1 + upd_mktcap.zoo.l1 + upd_trnvr.zoo.l1 + upd_smv.zoo.l1 + upd_gdpind.zoo.l2 + upd_mktcap.zoo.l2 + upd_trnvr.zoo.l2 + upd_smv.zoo.l2 + upd_gdpind.zoo.l3 + upd_mktcap.zoo.l3 + upd_trnvr.zoo.l3 + upd_smv.zoo.l3 + const
##
## upd_gdpind.zoo.l1 upd_mktcap.zoo.l1 upd_trnvr.zoo.l1 upd_smv.zoo.l1
## 8.749651e-01 1.348220e+06 -3.723653e+07 -4.464410e+08
## upd_gdpind.zoo.l2 upd_mktcap.zoo.l2 upd_trnvr.zoo.l2 upd_smv.zoo.l2
## -1.700111e-01 -1.023550e+06 1.862855e+07 2.986756e+08
## upd_gdpind.zoo.l3 upd_mktcap.zoo.l3 upd_trnvr.zoo.l3 upd_smv.zoo.l3
## 3.337777e-01 -9.386076e+04 1.043888e+07 2.768280e+07
## const
## 3.346709e+11
##
##
## Estimated coefficients for equation upd_mktcap.zoo:
## ===================================================
## Call:
## upd_mktcap.zoo = upd_gdpind.zoo.l1 + upd_mktcap.zoo.l1 + upd_trnvr.zoo.l1 + upd_smv.zoo.l1 + upd_gdpind.zoo.l2 + upd_mktcap.zoo.l2 + upd_trnvr.zoo.l2 + upd_smv.zoo.l2 + upd_gdpind.zoo.l3 + upd_mktcap.zoo.l3 + upd_trnvr.zoo.l3 + upd_smv.zoo.l3 + const
##
## upd_gdpind.zoo.l1 upd_mktcap.zoo.l1 upd_trnvr.zoo.l1 upd_smv.zoo.l1
## -1.050027e-07 1.103332e+00 2.536259e+01 -1.225968e+02
## upd_gdpind.zoo.l2 upd_mktcap.zoo.l2 upd_trnvr.zoo.l2 upd_smv.zoo.l2
## 1.360143e-08 2.412789e-01 -1.892565e+01 1.478810e+02
## upd_gdpind.zoo.l3 upd_mktcap.zoo.l3 upd_trnvr.zoo.l3 upd_smv.zoo.l3
## 1.528581e-07 -5.298624e-01 4.112104e+01 -2.625051e+01
## const
## -6.441721e+05
##
##
## Estimated coefficients for equation upd_trnvr.zoo:
## ==================================================
## Call:
## upd_trnvr.zoo = upd_gdpind.zoo.l1 + upd_mktcap.zoo.l1 + upd_trnvr.zoo.l1 + upd_smv.zoo.l1 + upd_gdpind.zoo.l2 + upd_mktcap.zoo.l2 + upd_trnvr.zoo.l2 + upd_smv.zoo.l2 + upd_gdpind.zoo.l3 + upd_mktcap.zoo.l3 + upd_trnvr.zoo.l3 + upd_smv.zoo.l3 + const
##
## upd_gdpind.zoo.l1 upd_mktcap.zoo.l1 upd_trnvr.zoo.l1 upd_smv.zoo.l1
## -2.947596e-10 1.053096e-03 2.758066e-01 -3.053980e-01
## upd_gdpind.zoo.l2 upd_mktcap.zoo.l2 upd_trnvr.zoo.l2 upd_smv.zoo.l2
## 1.280713e-10 -1.905492e-03 4.621037e-01 1.256720e+00
## upd_gdpind.zoo.l3 upd_mktcap.zoo.l3 upd_trnvr.zoo.l3 upd_smv.zoo.l3
## 5.139362e-10 -4.454741e-04 5.226267e-02 -3.932300e-01
## const
## -3.846356e+03
##
##
## Estimated coefficients for equation upd_smv.zoo:
## ================================================
## Call:
## upd_smv.zoo = upd_gdpind.zoo.l1 + upd_mktcap.zoo.l1 + upd_trnvr.zoo.l1 + upd_smv.zoo.l1 + upd_gdpind.zoo.l2 + upd_mktcap.zoo.l2 + upd_trnvr.zoo.l2 + upd_smv.zoo.l2 + upd_gdpind.zoo.l3 + upd_mktcap.zoo.l3 + upd_trnvr.zoo.l3 + upd_smv.zoo.l3 + const
##
## upd_gdpind.zoo.l1 upd_mktcap.zoo.l1 upd_trnvr.zoo.l1 upd_smv.zoo.l1
## 8.877145e-11 1.770231e-03 7.214014e-03 4.307005e-01
## upd_gdpind.zoo.l2 upd_mktcap.zoo.l2 upd_trnvr.zoo.l2 upd_smv.zoo.l2
## -2.168320e-11 -9.224220e-04 8.258345e-04 2.701003e-01
## upd_gdpind.zoo.l3 upd_mktcap.zoo.l3 upd_trnvr.zoo.l3 upd_smv.zoo.l3
## 4.555919e-11 -5.013238e-04 4.526356e-02 2.808872e-02
## const
## -3.753348e+02
# Real GDP (GDPIND) versus Market Capitalization (MKTCAP)
# GDP does not granger cause MKTCAP
wald.test(b=coef(ty$varresult[[1]]), Sigma=vcov(ty$varresult[[1]]), Terms=c(2,6,10))
## Wald test:
## ----------
##
## Chi-squared test:
## X2 = 108.2, df = 3, P(> X2) = 0.0
# MKTCAP does not granger cause GDP
wald.test(b=coef(ty$varresult[[2]]), Sigma=vcov(ty$varresult[[2]]), Terms=c(1,5,9))
## Wald test:
## ----------
##
## Chi-squared test:
## X2 = 4.6, df = 3, P(> X2) = 0.2
# Real GDP (GDPIND) versus Value Traded (TRNVR)
# GDP does not granger cause Value Traded
wald.test(b=coef(ty$varresult[[1]]), Sigma=vcov(ty$varresult[[1]]), Terms=c(3,7,11))
## Wald test:
## ----------
##
## Chi-squared test:
## X2 = 6.7, df = 3, P(> X2) = 0.081
# Value Traded does not granger cause GDP
wald.test(b=coef(ty$varresult[[3]]), Sigma=vcov(ty$varresult[[1]]), Terms=c(1,5,9))
## Wald test:
## ----------
##
## Chi-squared test:
## X2 = 1.1e-16, df = 3, P(> X2) = 1.0
# Real GDP (GDPIND) versus Stock Market Volatility (SMV)
# GDP does not granger cause Stock Market Volatility
wald.test(b=coef(ty$varresult[[1]]), Sigma=vcov(ty$varresult[[1]]), Terms=c(4,8,12))
## Wald test:
## ----------
##
## Chi-squared test:
## X2 = 24.2, df = 3, P(> X2) = 2.3e-05
# Stock Market Volatility does not granger GDP
wald.test(b=coef(ty$varresult[[4]]), Sigma=vcov(ty$varresult[[4]]), Terms=c(1,5,9))
## Wald test:
## ----------
##
## Chi-squared test:
## X2 = 4.1, df = 3, P(> X2) = 0.25