Financial Econometrics - Mini Project

Instructor: Dr. Nguyen Phuong Anh

1 Group Members

  1. Nguyen Minh Quan - MAMAIU19036
  2. Lam Hue Dung - MAMAIU18060
  3. Le Nguyen Dang Khoa - MAMAIU19008

2 Input Data

url = 'https://raw.githubusercontent.com/QuanNguyenIU/Res_Med_Fin/main/VnIndex.csv'
df = read.csv(url)[,1:2]
names(df)[1] = 'Date'
invisible(apply(df, 2, function(x) gsub(',', '', x)))
class(df$Price) = 'numeric'
df$Date = as.POSIXct(df$Date, format = "%m/%d/%Y")
glimpse(df)
## Rows: 2,101
## Columns: 2
## $ Date  <dttm> 2022-06-08, 2022-06-07, 2022-06-06, 2022-06-03, 2022-06-02, 202~
## $ Price <dbl> 1307.91, 1291.35, 1290.01, 1287.98, 1288.62, 1299.52, 1292.68, 1~
ggplot(df, aes(x = Date, y = Price)) + geom_line()

df$Returns = c(0, diff(log(df$Price)))
ggplot(df, aes(x = Date, y = Returns)) + geom_line()

describe(df$Returns)
##    vars    n mean   sd median trimmed  mad   min  max range skew kurtosis se
## X1    1 2101    0 0.01      0       0 0.01 -0.05 0.07  0.12 1.03      5.1  0

3 Non-Normality

ggplot(df, aes(x = Returns)) + 
  geom_histogram(binwidth = 0.001) + ylab('Count') +
  stat_function(fun = dnorm, colour = 'red',
                args = list(mean = mean(df$Returns), 
                            sd = sd(df$Returns)))

qqPlot(df$Returns, xlab = 'Normal Quantiles',
       ylab = 'Sample Quantiles')

## [1] 337 565
jarque.bera.test(df$Returns)
## 
##  Jarque Bera Test
## 
## data:  df$Returns
## X-squared = 2654.2, df = 2, p-value < 2.2e-16

4 Non-Stationarity

plot(acf(df$Returns, plot = F)[1:24], main = 'ACF of Returns')

plot(pacf(df$Returns, lag = 24, plot = F), main = 'PACF of Returns')

Box.test(df$Returns, lag = 7, type = "Ljung")
## 
##  Box-Ljung test
## 
## data:  df$Returns
## X-squared = 23.936, df = 7, p-value = 0.001169
final_AIC = Inf
final_order = c(0, 0, 0)
for (p in 0:4) for (q in 0:4) {
  current_order = c(p, 0, q)
  model = arima(df$Returns, order = current_order)
  current_AIC = AIC(model)
  if (current_AIC < final_AIC) {
    final_order = current_order
    final_AIC = current_AIC
  }
}
print(final_AIC)
## [1] -12874.22
final_arima = arima(df$Returns, order = final_order)
checkresiduals(final_arima)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(4,0,2) with non-zero mean
## Q* = 8.7606, df = 3, p-value = 0.03265
## 
## Model df: 7.   Total lags used: 10
coeftest(final_arima)
## 
## z test of coefficients:
## 
##              Estimate  Std. Error  z value  Pr(>|z|)    
## ar1       -1.15277465  0.09425090 -12.2309 < 2.2e-16 ***
## ar2       -0.74346238  0.08444456  -8.8041 < 2.2e-16 ***
## ar3        0.10382907  0.03865689   2.6859  0.007233 ** 
## ar4        0.02169635  0.02707627   0.8013  0.422955    
## ma1        1.20530657  0.09133212  13.1970 < 2.2e-16 ***
## ma2        0.87387189  0.08036251  10.8741 < 2.2e-16 ***
## intercept -0.00045438  0.00027383  -1.6594  0.097041 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

5 Volatility Clustering

resid = final_arima$residuals
plot(resid ^ 2, ylab = 'Squared Residuals')

plot(acf(resid ^ 2, plot = F)[1:24], main = 'ACF of Squared Residuals')

plot(pacf(resid ^ 2, lag = 24, plot = F), main = 'PACF of Squared Residuals')

arch.test(final_arima)
## ARCH heteroscedasticity test for residuals 
## alternative: heteroscedastic 
## 
## Portmanteau-Q test: 
##      order  PQ p.value
## [1,]     4 321       0
## [2,]     8 478       0
## [3,]    12 591       0
## [4,]    16 620       0
## [5,]    20 630       0
## [6,]    24 630       0
## Lagrange-Multiplier test: 
##      order   LM p.value
## [1,]     4 1700       0
## [2,]     8  752       0
## [3,]    12  484       0
## [4,]    16  354       0
## [5,]    20  271       0
## [6,]    24  224       0