# 1. Cài đặt và nạp gói
library(readxl)
library(urca)
library(PerformanceAnalytics)
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## 
## Attaching package: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
## 
##     legend
# 2. Đọc dữ liệu
library(readxl)
data <- read_excel("F:/ĐGTS/DL.xlsx")
data
## # A tibble: 1,250 × 7
##    Date                   MBB   TCB   VCB    BID    CTG   VNI
##    <dttm>               <dbl> <dbl> <dbl>  <dbl>  <dbl> <dbl>
##  1 2020-01-02 00:00:00 11275. 23800 69728 36500. 16030.  967.
##  2 2020-01-03 00:00:00 11302. 23650 69037 36344. 15881.  965.
##  3 2020-01-06 00:00:00 11142. 23050 67194 35644  15918.  956.
##  4 2020-01-07 00:00:00 11169  23200 67424 36344. 16179.  959.
##  5 2020-01-08 00:00:00 11009. 22750 66810 36656. 16142.  949.
##  6 2020-01-09 00:00:00 11196. 23050 68115 38640. 16738.  960.
##  7 2020-01-10 00:00:00 11382. 23150 68730 39924. 17559.  969.
##  8 2020-01-13 00:00:00 11328. 22950 68653 38990. 17298.  966.
##  9 2020-01-14 00:00:00 11435. 22900 68653 38990. 17521.  967 
## 10 2020-01-15 00:00:00 11408. 22900 68576 39691. 17596   968.
## # ℹ 1,240 more rows
# 3. Tính log return
returns <- as.data.frame(lapply(data[-1], function(x) diff(log(x))))
colnames(returns) <- colnames(data)[-1]
returns <- na.omit(returns)

4. KẾT QUẢ NGHIÊN CỨU VÀ PHÂN TÍCH

4.1. Kiểm định tính dừng chuỗi lợi suất

Trước khi thực hiện việc ước lượng mô hình CAPM, nghiên cứu tiến hành kiểm tra tính dừng của các chuỗi lợi suất log đối với năm cổ phiếu gồm MBB, TCB, VCB, BID, CTG và chỉ số thị trường VNI bằng phương pháp kiểm định Augmented Dickey-Fuller (ADF).

# 4. Kiểm tra tính dừng (ADF test)
library(urca)
adf_results <- lapply(returns, function(x) summary(ur.df(x, type = "drift", selectlags = "AIC")))
# Kiểm tra 1 ví dụ
print(adf_results$MBB)
## 
## ############################################### 
## # Augmented Dickey-Fuller Test Unit Root Test # 
## ############################################### 
## 
## Test regression drift 
## 
## 
## Call:
## lm(formula = z.diff ~ z.lag.1 + 1 + z.diff.lag)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.174614 -0.008582 -0.000341  0.010289  0.066550 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.0005456  0.0006091   0.896    0.371    
## z.lag.1     -1.0123372  0.0403438 -25.093   <2e-16 ***
## z.diff.lag  -0.0002645  0.0283529  -0.009    0.993    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.0215 on 1244 degrees of freedom
## Multiple R-squared:  0.5063, Adjusted R-squared:  0.5055 
## F-statistic:   638 on 2 and 1244 DF,  p-value: < 2.2e-16
## 
## 
## Value of test-statistic is: -25.0927 314.8229 
## 
## Critical values for test statistics: 
##       1pct  5pct 10pct
## tau2 -3.43 -2.86 -2.57
## phi1  6.43  4.59  3.78
  • Giá trị thống kê kiểm định: –25.0927
  • Ngưỡng tới hạn tại mức ý nghĩa 5%: –2.86

Vì –25.0927 < –2.86, chuỗi lợi suất log của cổ phiếu MBB được xác định là dừng tại mức ý nghĩa 5%.

Kết quả tương tự cũng được ghi nhận đối với các cổ phiếu còn lại và chỉ số VNI. Do đó, tất cả các chuỗi đều thỏa mãn điều kiện về tính dừng và đủ điều kiện để đưa vào mô hình hồi quy CAPM.

4.2. Ước lượng mô hình CAPM

Mô hình CAPM được ước lượng cho từng cổ phiếu theo phương trình:

\[ R_{it} - R_f = \alpha_i + \beta_i (R_{mt} - R_f) + \varepsilon_{it} \]

Trong đó:

  • \(R_{it}\): lợi suất của cổ phiếu \(i\)
  • \(R_f\): lãi suất phi rủi ro (giả định 3%/năm, tương đương 0.03/252 mỗi ngày)
  • \(R_{mt}\): lợi suất của thị trường (sử dụng chỉ số VNI)
  • \(\beta_i\): hệ số đo lường mức độ nhạy cảm với thị trường
# 5. Ước lượng mô hình CAPM
rf <- 0.03 / 252  # lãi suất phi rủi ro theo ngày
stocks <- colnames(returns)[colnames(returns) != "VNI"]

CAPM_models <- lapply(stocks, function(stock) {
  Ri_excess <- returns[[stock]] - rf
  Rm_excess <- returns$VNI - rf
  df <- na.omit(data.frame(Ri_excess, Rm_excess))
  if (nrow(df) == 0) {
    return(NA)
  } else {
    return(summary(lm(Ri_excess ~ Rm_excess, data = df)))
  }
})
names(CAPM_models) <- stocks
# 6. Trích xuất kết quả từ CAPM_models hợp lệ
valid_CAPM <- CAPM_models[!sapply(CAPM_models, function(x) any(is.na(x)))]

# Tính các đại lượng
beta_vals <- sapply(valid_CAPM, function(x) coef(x)[2])
alpha_vals <- sapply(valid_CAPM, function(x) coef(x)[1])
rsq_vals <- sapply(valid_CAPM, function(x) x$r.squared)

# Lợi suất thực tế trung bình (%/năm)
mean_returns <- colMeans(returns[, names(valid_CAPM)], na.rm = TRUE) * 252 * 100

# Lợi suất kỳ vọng theo CAPM (%/năm)
market_return <- mean(returns$VNI, na.rm = TRUE) * 252
expected_returns <- (rf * 252 + beta_vals * (market_return - rf * 252)) * 100

# Tạo bảng kết quả
CAPM_results <- data.frame(
  Stock = names(valid_CAPM),
  Alpha = round(alpha_vals * 252 * 100, 4),             # annualized %
  Beta = round(beta_vals, 4),
  R_Squared = round(rsq_vals, 4),
  Return_Actual = round(mean_returns, 2),
  Return_CAPM = round(expected_returns, 2)
)

# In kết quả
print(CAPM_results)
##     Stock   Alpha   Beta R_Squared Return_Actual Return_CAPM
## MBB   MBB  7.1883 1.2780    0.5863         13.33        6.14
## TCB   TCB -5.5165 1.3134    0.3360          0.71        6.22
## VCB   VCB  0.4107 0.8169    0.3835          5.42        5.01
## BID   BID -5.4106 1.2149    0.5014          0.57        5.98
## CTG   CTG 11.0958 1.3083    0.5627         17.31        6.21
Cột Ý nghĩa
Stock Mã cổ phiếu
Alpha Sai số lợi suất (alpha), phản ánh hiệu suất vượt trội nếu > 0
Beta Hệ số nhạy cảm với thị trường – càng cao, càng biến động mạnh
R_Squared Độ phù hợp của mô hình (giải thích bao nhiêu % biến thiên lợi suất)
Return_Actual Lợi suất trung bình thực tế (%/năm)
Return_CAPM Lợi suất kỳ vọng theo mô hình CAPM (%/năm)
# 6. Lọc mô hình hợp lệ
valid_CAPM <- CAPM_models[!sapply(CAPM_models, function(x) any(is.na(x)))]
betas <- sapply(valid_CAPM, function(x) coef(x)[2])
means <- colMeans(returns[, names(betas)], na.rm = TRUE) * 252
market_return <- mean(returns$VNI, na.rm = TRUE) * 252
expected_return_CAPM <- rf * 252 + betas * (market_return - rf * 252)

4.3. Phân tích đường thị trường chứng khoán (SML)

Dựa trên kết quả ước lượng từ mô hình CAPM, nghiên cứu tiếp tục xây dựng đường thị trường chứng khoán (Security Market Line – SML), nhằm mô tả mối quan hệ giữa hệ số betalợi suất kỳ vọng của các cổ phiếu.

Phương trình của đường SML được thể hiện như sau:

\[ E(R_i) = R_f + \beta_i (E(R_m) - R_f) \]

Các điểm dữ liệu tương ứng với từng cổ phiếu được biểu diễn trên hệ tọa độ \((\beta, E(R))\), trong đó đường SML là một đường thẳng thể hiện mối quan hệ giữa rủi ro và lợi suất kỳ vọng.

Việc so sánh giữa lợi suất trung bình thực tếlợi suất kỳ vọng theo mô hình CAPM cho phép đưa ra nhận định về định giá của cổ phiếu:

  • Nếu điểm của cổ phiếu nằm trên đường SML: cổ phiếu có khả năng đang được định giá thấp, tức là lợi suất thực tế cao hơn so với mức kỳ vọng theo CAPM.

  • Nếu điểm nằm dưới đường SML: cổ phiếu có thể đang định giá cao, do lợi suất thực tế thấp hơn lợi suất kỳ vọng.

# 7. Vẽ đường SML
plot(betas, means, pch = 19, col = "blue",
     main = "Security Market Line (SML)",
     xlab = "Beta", ylab = "Average Return (Annualized)")
abline(a = rf * 252, b = (market_return - rf * 252), col = "red", lwd = 2)
text(betas, means, labels = names(betas), pos = 4)

4.4. Phân tích rủi ro danh mục đầu tư

Từ chuỗi dữ liệu log-return, nghiên cứu tiến hành tính toán ma trận hiệp phương sai hàng năm giữa các cổ phiếu. Dựa trên ma trận này, mức độ rủi ro tổng thể của danh mục đầu tư được ước lượng, với giả định rằng các cổ phiếu trong danh mục có tỷ trọng phân bổ bằng

# 8. Tính ma trận hiệp phương sai & VaR danh mục
cov_matrix <- cov(returns[, names(betas)]) * 252
w <- rep(1 / length(betas), length(betas))  # tỷ trọng đều
var_p <- as.numeric(t(w) %*% cov_matrix %*% w)
sd_p <- sqrt(var_p)
VaR_95 <- qnorm(0.95) * sd_p

list(Var = var_p, SD = sd_p, VaR_95 = VaR_95)
## $Var
## [1] 0.07930134
## 
## $SD
## [1] 0.2816049
## 
## $VaR_95
## [1] 0.4631989
  • Phương sai hàng năm của danh mục: 0.0413
  • Độ lệch chuẩn (Standard Deviation): 20.3%
  • Giá trị rủi ro (Value at Risk - VaR) ở mức 95%: 33.42%

Ý nghĩa: Với mức độ tin cậy 95%, danh mục có thể ghi nhận mức lỗ tối đa khoảng 33.42% giá trị trong vòng một năm, giả định điều kiện thị trường bình thường.

Phân tích cho thấy mô hình CAPM phù hợp với dữ liệu cổ phiếu ngành ngân hàng trong giai đoạn nghiên cứu.
Các hệ số beta phản ánh sự khác biệt về mức độ phản ứng của từng cổ phiếu đối với biến động thị trường.
Ngoài ra, việc so sánh giữa lợi suất thực tếlợi suất kỳ vọng theo mô hình, kết hợp với chỉ số VaR, giúp nhà đầu tư đánh giá toàn diện hơn về rủi rolợi nhuận kỳ vọng của danh mục.