BÀI THỰC HÀNH KIỂM TRA GIỮA KỲ MÔN QUẢN TRỊ RỦI RO TÀI CHÍNH

  1. Đọc dữ liệu từ link google sheet
library(googlesheets4)
gs4_deauth()
df <- read_sheet("https://docs.google.com/spreadsheets/d/10nZIVWn3i5djs0tRZbI--8nntNbfbGoNvYKX8yI7Eeo/edit?gid=1109581498#gid=1109581498", sheet = "hose3")
  1. Lấy dữ liệu mã cổ phiếu THG
df
# A tibble: 3,335 × 241
   Date                  AAA   AAM   ABT   ACB   ACC   ACL   ADP   AGR   ANV
   <dttm>              <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1 2012-04-11 00:00:00  4582  9448 10913  3583  2760  5507   422  7418  1115
 2 2012-04-12 00:00:00  4560  9557 10972  3681  2851  5446   461  7418  1115
 3 2012-04-13 00:00:00  4476  9557 10972  3681  2851  5446   505  7339  1094
 4 2012-04-16 00:00:00  4624  9557 11300  3681  2967  5538   477  7655  1115
 5 2012-04-17 00:00:00  4624  9703 11420  3667  2993  5660   521  7971  1126
 6 2012-04-18 00:00:00  4560  9849 11330  3611  3110  5568   532  8208  1115
 7 2012-04-19 00:00:00  4348  9849 11390  3555  3226  5844   581  7813  1061
 8 2012-04-20 00:00:00  4370  9885 11420  3569  3071  6119   581  7497  1105
 9 2012-04-23 00:00:00  4370  9885 11420  3611  3006  6241   581  7339  1159
10 2012-04-24 00:00:00  4433  9995 11539  3611  3110  6241   526  7418  1207
# ℹ 3,325 more rows
# ℹ 231 more variables: APG <dbl>, ASM <dbl>, ASP <dbl>, BCE <dbl>, BIC <dbl>,
#   BMC <dbl>, BMI <dbl>, BMP <dbl>, BRC <dbl>, BSI <dbl>, BTP <dbl>,
#   BTT <dbl>, BVH <dbl>, C32 <dbl>, C47 <dbl>, CCI <dbl>, CCL <dbl>,
#   CDC <dbl>, CHP <dbl>, CIG <dbl>, CII <dbl>, CLC <dbl>, CLW <dbl>,
#   CMG <dbl>, CMV <dbl>, CMX <dbl>, CNG <dbl>, COM <dbl>, CSM <dbl>,
#   CTD <dbl>, CTG <dbl>, CTI <dbl>, CTS <dbl>, CVT <dbl>, D2D <dbl>, …
thg <- df[, c("Date", "THG")]
  1. Kiểm tra dữ liệu
str(thg)
tibble [3,335 × 2] (S3: tbl_df/tbl/data.frame)
 $ Date: POSIXct[1:3335], format: "2012-04-11" "2012-04-12" ...
 $ THG : num [1:3335] 810 850 882 907 866 826 794 794 826 786 ...
head(thg)
# A tibble: 6 × 2
  Date                  THG
  <dttm>              <dbl>
1 2012-04-11 00:00:00   810
2 2012-04-12 00:00:00   850
3 2012-04-13 00:00:00   882
4 2012-04-16 00:00:00   907
5 2012-04-17 00:00:00   866
6 2012-04-18 00:00:00   826
tail(thg)
# A tibble: 6 × 2
  Date                  THG
  <dttm>              <dbl>
1 2026-05-15 00:00:00 43300
2 2026-05-18 00:00:00 43300
3 2026-05-19 00:00:00 43100
4 2026-05-20 00:00:00 42650
5 2026-05-21 00:00:00 43000
6 2026-05-22 00:00:00 42900
summary(thg)
      Date                          THG       
 Min.   :2012-04-11 00:00:00   Min.   :  529  
 1st Qu.:2015-09-16 12:00:00   1st Qu.: 2956  
 Median :2019-04-23 00:00:00   Median :11073  
 Mean   :2019-05-03 01:14:16   Mean   :16522  
 3rd Qu.:2022-12-27 12:00:00   3rd Qu.:26971  
 Max.   :2026-05-22 00:00:00   Max.   :55983  

4.1. Thống kê mô tả dữ liệu giá chứng khoán

library(fBasics)
basicStats(thg$THG)
               X..thg.THG
nobs         3.335000e+03
NAs          0.000000e+00
Minimum      5.290000e+02
Maximum      5.598300e+04
1. Quartile  2.956000e+03
3. Quartile  2.697100e+04
Mean         1.652163e+04
Median       1.107300e+04
Sum          5.509965e+07
SE Mean      2.520508e+02
LCL Mean     1.602744e+04
UCL Mean     1.701582e+04
Variance     2.118712e+08
Stdev        1.455580e+04
Skewness     7.832710e-01
Kurtosis    -4.388960e-01
summary(thg$THG)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    529    2956   11073   16522   26971   55983 

4.2. Thống kê mô tả dữ liệu return của giá chứng khoán

thg_return <- diff(log(thg$THG))
head(thg_return)
[1]  0.04820210  0.03695571  0.02795039 -0.04625754 -0.04729014 -0.03951131
tail(thg_return)
[1]  0.005790404  0.000000000 -0.004629638 -0.010495723  0.008172842
[6] -0.002328290
basicStats(thg_return)
             thg_return
nobs        3334.000000
NAs            0.000000
Minimum       -0.072453
Maximum        0.162045
1. Quartile   -0.007538
3. Quartile    0.010291
Mean           0.001191
Median         0.000000
Sum            3.969593
SE Mean        0.000402
LCL Mean       0.000403
UCL Mean       0.001978
Variance       0.000538
Stdev          0.023187
Skewness       0.077569
Kurtosis       2.904574

5.1. Vẽ đồ thị và hàm mật độ của giá chứng khoán

ts.plot(thg$THG)

plot(thg, type = "l")

hist(thg$THG)

d1 = density(thg$THG)
plot(d1, type = "l")

5.2 Vẽ đồ thị và hàm mật độ của giá chứng khoán

plot(thg_return, type = "l")

hist(thg_return)

d2 <- density(thg_return)
plot(d2, type = "l")

  1. Kiểm tra tính dừng, kiểm tra phân phối chuẩn
library(tseries)
adf.test(thg$THG)

    Augmented Dickey-Fuller Test

data:  thg$THG
Dickey-Fuller = -2.4302, Lag order = 14, p-value = 0.3962
alternative hypothesis: stationary
adf.test(thg_return)

    Augmented Dickey-Fuller Test

data:  thg_return
Dickey-Fuller = -16.115, Lag order = 14, p-value = 0.01
alternative hypothesis: stationary
kpss.test(thg_return) #Ho: stationary

    KPSS Test for Level Stationarity

data:  thg_return
KPSS Level = 0.20872, Truncation lag parameter = 9, p-value = 0.1
normalTest(thg$THG, method = c("jb")) #Ho:normal distribution

Title:
 Jarque-Bera Normality Test

Test Results:
  STATISTIC:
    X-squared: 367.8988
  P VALUE:
    Asymptotic p Value: < 2.2e-16 
normalTest(thg_return, method = c("jb")) #Ho:normal distribution

Title:
 Jarque-Bera Normality Test

Test Results:
  STATISTIC:
    X-squared: 1178.185
  P VALUE:
    Asymptotic p Value: < 2.2e-16 
  1. Kiểm tra tự tương quan bằng đồ thị và bằng kiểm định
acf(thg_return)

pacf(thg_return)

Box.test(thg_return, lag = 10) # H0: no autocorrelation

    Box-Pierce test

data:  thg_return
X-squared = 12.152, df = 10, p-value = 0.275
Box.test(thg_return, lag = 10, type = c("Ljung-Box")) # H0: no autocorrelation

    Box-Ljung test

data:  thg_return
X-squared = 12.184, df = 10, p-value = 0.2729
  1. Ước lượng mô hình ARIMA
# 8.1. Xây dựng mô hình AR
pacf(thg_return)

m1 <- ar(thg_return, type = c("mle"))
m1 

Call:
ar(x = thg_return, type = c("mle"))


Order selected 0  sigma^2 estimated as  0.0005376
names(m1)
 [1] "order"      "ar"         "var.pred"   "x.mean"     "aic"       
 [6] "n.used"     "n.obs"      "order.max"  "partialacf" "resid"     
[11] "method"     "series"     "frequency"  "call"      
m1$aic
        0         1         2         3         4         5         6         7 
 0.000000  1.957739  3.933965  5.429070  1.538159  3.448909  5.448518  7.415318 
        8         9        10        11        12        13        14        15 
 9.370438 10.767022  7.887608  8.128206 10.112239  9.110773 10.347335 10.953062 
       16        17        18        19        20        21        22        23 
10.438664  8.176167 10.145611 11.350266 13.117708 15.052095 14.626021 15.087983 
       24        25        26        27        28        29        30        31 
16.526684 18.453771 20.320350 21.807865 23.798609 24.632229 26.162760 27.959515 
       32        33        34        35 
29.716350 30.720615 31.955061 33.810210 
# Ước lượng AR(p)
m21 <- arima(thg_return, order = c(0, 0, 0))
m21

Call:
arima(x = thg_return, order = c(0, 0, 0))

Coefficients:
      intercept
         0.0012
s.e.     0.0004

sigma^2 estimated as 0.0005375:  log likelihood = 7819.49,  aic = -15634.97
# Hàm tính p value
coeftest <- function(model){
          coef <- model$coef
          se <- sqrt(diag(model$var.coef))
          t <- coef / se
          p <- 2 * (1 - pnorm(abs(t)))
          data.frame(coef, se, t, p)
}

coeftest(m21)
                coef           se        t           p
intercept 0.00119064 0.0004018828 2.962654 0.003049992
# Kiểm định phần dư
plot(m21$residuals, type = "l")

qqplot(m21$residuals, thg_return)

Box.test(m21$residuals, lag = 10)

    Box-Pierce test

data:  m21$residuals
X-squared = 12.152, df = 10, p-value = 0.275

9.1. Kiểm định hiệu ứng ARCH (ARCH-LM test)

library(fGarch)
m4 <- garchFit(~ arma(0,0) + garch(1,0), data = thg_return, trace = FALSE)
summary(m4)

Title:
 GARCH Modelling 

Call:
 garchFit(formula = ~arma(0, 0) + garch(1, 0), data = thg_return, 
    trace = FALSE) 

Mean and Variance Equation:
 data ~ arma(0, 0) + garch(1, 0)
<environment: 0x0000026d11c97cb8>
 [data = thg_return]

Conditional Distribution:
 norm 

Coefficient(s):
        mu       omega      alpha1  
0.00075296  0.00040365  0.25296629  

Std. Errors:
 based on Hessian 

Error Analysis:
        Estimate  Std. Error  t value Pr(>|t|)    
mu     7.530e-04   3.736e-04    2.015   0.0439 *  
omega  4.037e-04   1.214e-05   33.259   <2e-16 ***
alpha1 2.530e-01   2.528e-02   10.007   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Log Likelihood:
 7942.494    normalized:  2.382272 

Description:
 Tue Jun  9 22:07:39 2026 by user: Admin 



Standardised Residuals Tests:
                                   Statistic   p-Value
 Jarque-Bera Test   R    Chi^2  2434.6275306 0.0000000
 Shapiro-Wilk Test  R    W         0.9334399 0.0000000
 Ljung-Box Test     R    Q(10)     9.5681993 0.4791569
 Ljung-Box Test     R    Q(15)    14.5663211 0.4830827
 Ljung-Box Test     R    Q(20)    22.0398927 0.3383499
 Ljung-Box Test     R^2  Q(10)   164.7189049 0.0000000
 Ljung-Box Test     R^2  Q(15)   214.7518202 0.0000000
 Ljung-Box Test     R^2  Q(20)   249.8555175 0.0000000
 LM Arch Test       R    TR^2    121.2976047 0.0000000

Information Criterion Statistics:
      AIC       BIC       SIC      HQIC 
-4.762744 -4.757244 -4.762746 -4.760776 

9.2. Ước lương ARIMA + GARCH (chọn bậc p, q hợp lý)

m5 <-garchFit(~ arma(0,0) + garch(1,1), data = thg_return, trace = FALSE)
summary(m5)

Title:
 GARCH Modelling 

Call:
 garchFit(formula = ~arma(0, 0) + garch(1, 1), data = thg_return, 
    trace = FALSE) 

Mean and Variance Equation:
 data ~ arma(0, 0) + garch(1, 1)
<environment: 0x0000026d13a86a90>
 [data = thg_return]

Conditional Distribution:
 norm 

Coefficient(s):
        mu       omega      alpha1       beta1  
8.7747e-04  2.5689e-05  1.2517e-01  8.2955e-01  

Std. Errors:
 based on Hessian 

Error Analysis:
        Estimate  Std. Error  t value Pr(>|t|)    
mu     8.775e-04   3.279e-04    2.676  0.00745 ** 
omega  2.569e-05   4.401e-06    5.837 5.33e-09 ***
alpha1 1.252e-01   1.579e-02    7.925 2.22e-15 ***
beta1  8.295e-01   2.062e-02   40.239  < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Log Likelihood:
 8159.368    normalized:  2.447321 

Description:
 Tue Jun  9 22:07:39 2026 by user: Admin 



Standardised Residuals Tests:
                                   Statistic   p-Value
 Jarque-Bera Test   R    Chi^2  5274.8924502 0.0000000
 Shapiro-Wilk Test  R    W         0.9367452 0.0000000
 Ljung-Box Test     R    Q(10)     5.0046653 0.8908662
 Ljung-Box Test     R    Q(15)     8.1095034 0.9193175
 Ljung-Box Test     R    Q(20)    16.8429706 0.6631454
 Ljung-Box Test     R^2  Q(10)     5.5530543 0.8513132
 Ljung-Box Test     R^2  Q(15)    10.1099259 0.8127689
 Ljung-Box Test     R^2  Q(20)    13.7457721 0.8431484
 LM Arch Test       R    TR^2      9.3595705 0.6719501

Information Criterion Statistics:
      AIC       BIC       SIC      HQIC 
-4.892242 -4.884910 -4.892245 -4.889619 
predict(m5, 5)
  meanForecast  meanError standardDeviation
1 0.0008774678 0.01353233        0.01353233
2 0.0008774678 0.01416053        0.01416053
3 0.0008774678 0.01473531        0.01473531
4 0.0008774678 0.01526389        0.01526389
5 0.0008774678 0.01575198        0.01575198
  1. Tính và dự báo VaR
# Chạy hàm Loss để tính VaR

nreturn_thg <- - thg_return

# 10.1. Ước tính VaR theo Risk Metrics
# Cách 1: Tính thủ công
library(rugarch)
spec1 <- ugarchspec(mean.model = list(armaOrder=c(0,0)),
                    variance.model = list(model="iGARCH", garchOrder=c(1,1)))

m6 <- ugarchfit(spec=spec1,data = nreturn_thg)
Box.test(residuals(m6, standardize=TRUE), lag=10, type="Ljung")

    Box-Ljung test

data:  residuals(m6, standardize = TRUE)
X-squared = 5.4724, df = 10, p-value = 0.8575
# H0: no autocorrelation
# Dự báo mean và variance (1 ngày):
ugarchforecast(m6, n.ahead = 1)

*------------------------------------*
*       GARCH Model Forecast         *
*------------------------------------*
Model: iGARCH
Horizon: 1
Roll Steps: 0
Out of Sample: 0

0-roll forecast [T0=1979-02-17]:
       Series   Sigma
T+1 -0.000836 0.01234
# Tính VaR (Phương pháp của JP Morgan xem mean = 0): 
VaR1 <- 0 + qnorm(0.95) * 0.01234

# Cách 2: tính từ RMeasure.R
setwd("D:\\meeee\\Đại học\\HK2 năm 3\\QTRR TÀI CHÍNH")
source("RMeasure.R")
VaR2 <- RMeasure(0, 0.01234)

 Risk Measures for selected probabilities: 
      prob        VaR         ES
[1,] 0.950 0.02029749 0.02545388
[2,] 0.990 0.02870713 0.03288874
[3,] 0.999 0.03813347 0.04154989
# 10.2. Ước tính VaR theo ECONOMICTRICS

m7 <- garchFit(~ arma(0,0) + garch(1,1), data = nreturn_thg, trace=F)
summary(m7)

Title:
 GARCH Modelling 

Call:
 garchFit(formula = ~arma(0, 0) + garch(1, 1), data = nreturn_thg, 
    trace = F) 

Mean and Variance Equation:
 data ~ arma(0, 0) + garch(1, 1)
<environment: 0x0000026cd9d15d98>
 [data = nreturn_thg]

Conditional Distribution:
 norm 

Coefficient(s):
         mu        omega       alpha1        beta1  
-8.7747e-04   2.5689e-05   1.2517e-01   8.2955e-01  

Std. Errors:
 based on Hessian 

Error Analysis:
         Estimate  Std. Error  t value Pr(>|t|)    
mu     -8.775e-04   3.279e-04   -2.676  0.00745 ** 
omega   2.569e-05   4.401e-06    5.837 5.33e-09 ***
alpha1  1.252e-01   1.579e-02    7.925 2.22e-15 ***
beta1   8.295e-01   2.062e-02   40.239  < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Log Likelihood:
 8159.368    normalized:  2.447321 

Description:
 Tue Jun  9 22:07:40 2026 by user: Admin 



Standardised Residuals Tests:
                                   Statistic   p-Value
 Jarque-Bera Test   R    Chi^2  5274.8923886 0.0000000
 Shapiro-Wilk Test  R    W         0.9367452 0.0000000
 Ljung-Box Test     R    Q(10)     5.0046653 0.8908662
 Ljung-Box Test     R    Q(15)     8.1095034 0.9193175
 Ljung-Box Test     R    Q(20)    16.8429707 0.6631454
 Ljung-Box Test     R^2  Q(10)     5.5530543 0.8513132
 Ljung-Box Test     R^2  Q(15)    10.1099258 0.8127689
 Ljung-Box Test     R^2  Q(20)    13.7457722 0.8431484
 LM Arch Test       R    TR^2      9.3595705 0.6719501

Information Criterion Statistics:
      AIC       BIC       SIC      HQIC 
-4.892242 -4.884910 -4.892245 -4.889619 
predict(m7, 1)
   meanForecast  meanError standardDeviation
1 -0.0008774678 0.01353233        0.01353233
#Tính VaR
VaR3 <- -0.0008774678 + qnorm(0.95)*0.01353233

# 10.3. Ước lượng QUANTILE ESTIMATION
VaR4 <- quantile(nreturn_thg, 0.95)

# 10.4. Ước lượng MONTE CARLO SIMULATION
mean_thg <- mean(nreturn_thg)
sd_thg <- sd(nreturn_thg)
# Tiến hành mô phỏng Monte Carlo
set.seed(42)
sim1 <- rnorm(10000, mean = mean_thg, sd = sd_thg)
ts.plot(sim1)

VaR5 <- quantile(sim1, 0.95)
  1. VaR theo số tiền
VaR1_100 = VaR1*100000
VaR1_100
[1] 2029.749
VaR3_100 = VaR3*100000
VaR3_100
[1] 2138.123
VaR4_100 = VaR4*100000
VaR4_100
     95% 
4190.881 
VaR5_100 = VaR5*100000
VaR5_100
    95% 
3699.63