PHẦN 1. PHÂN TÍCH CHỈ SỐ TÀI CHÍNH, ĐỊNH GIÁ VÀ YẾU TỐ ESG ẢNH HƯỞNG ĐẾN HIỆU SUẤT ĐẦU TƯ NYSE

1.1: GIỚI THIỆU VÀ MỤC TIÊU PHÂN TÍCH

1.1.1. Lý do chọn đề tài

Trong kỷ nguyên tài chính định lượng, các quyết định đầu tư ngày càng được dẫn dắt bởi sự phân tích chặt chẽ các chỉ số hiệu suất, định giá và yếu tố rủi ro. Nghiên cứu này tập trung vào việc áp dụng ngôn ngữ lập trình R để thực hiện phân tích chuyên sâu về mối liên hệ giữa các Chỉ số tài chính, định giá, và yếu tố môi trường, xã hội và quản trị (ESG) với hiệu suất đầu tư thực tế.

Bộ dữ liệu nền tảng là “400K NYSE Random Investments + Financial Ratios” (thu thập từ Kaggle), mô phỏng hơn 400.000 giao dịch đầu tư ngẫu nhiên vào các cổ phiếu niêm yết trên sàn giao dịch chứng khoán New York (NYSE) trong giai đoạn 2013-2018. Khác với các phân tích tập trung vào Hành vi Giao dịch, nghiên cứu này khai thác Nhóm Biến 2 (Chỉ số Công ty, Định giá, ESG), bao gồm các chỉ số trọng yếu như tỷ số giá/thu nhập (PE), tỷ suất sinh lời trên vốn chủ sở hữu (ROE), đòn bẩy tài chính (Leverage_Ratio), và xếp hạng ESG.

1.1.2. Mục tiêu Nghiên cứu

Nghiên cứu này được thực hiện với các mục tiêu định lượng và khám phá cụ thể như sau:

  1. Lượng hóa đặc trưng phân bố: Thực hiện các tiêu chí như thống kê mô tả, tương quan, và kiểm định giả thuyết) để lượng hóa độ tập trung, độ phân tán và hình dạng phân bố của các chỉ số tài chính và lợi suất thực tế (Real_Return).

  2. Trực quan hóa khám phá: Xây dựng tối thiểu các biểu đồ để trực quan hóa mối quan hệ giữa các chỉ số (Log_PE, ROE, ESG) và hiệu suất đầu tư.

  3. Kiểm định Giả thuyết: Kiểm tra sự khác biệt có ý nghĩa thống kê về hiệu suất đầu tư (Real_Return) và đặc điểm tài chính (ví dụ: Log_PE) giữa các nhóm ngành (sector) và nhóm kết quả đầu tư (investment GOOD/BAD) thông qua các kiểm định như \(t\)-test và ANOVA.

  4. Kiểm soát Độ tin cậy: Thực hiện nhận diện và xử lý Outlier trong các biến số quan trọng (như Real_Return, PE_ratio) để đảm bảo các kết quả thống kê và kiểm định là đáng tin cậy.

1.1.3. Phạm vi phân tích

Phạm vi phân tích sẽ giới hạn trong các biến thuộc Nhóm 2, bao gồm: Real_Return (Biến phụ thuộc), Log_PE, PB, PS, ROE, ROA, EPS, NetProfitMargin, Current_Ratio, Leverage_Ratio, ESG, và các biến phân loại liên quan (sector, investment).

1.1.4. Lý thuyết nền tảng:ESG và hiệu suất doanh nghiệp

Lý thuyết ESG bắt nguồn từ các nền tảng của Thuyết các bên liên quan (Stakeholder Theory – Freeman, 1984)Thuyết hợp pháp hóa (Legitimacy Theory), cho rằng doanh nghiệp không chỉ chịu trách nhiệm với cổ đông mà còn với toàn bộ các bên liên quan bao gồm nhân viên, khách hàng, cộng đồng và môi trường. Thực hiện tốt các tiêu chí về môi trường (E), xã hội (S), và quản trị (G) giúp doanh nghiệp giảm thiểu rủi ro pháp lý, nâng cao uy tín, tăng cường niềm tin của nhà đầu tư, đồng thời cải thiện hiệu quả tài chính dài hạn (Eccles, Ioannou & Serafeim, 2014; Fatemi et al., 2018).

Theo hướng tiếp cận này, điểm số ESG (ESG) phản ánh chất lượng quản trị và cam kết phát triển bền vững của doanh nghiệp, từ đó ảnh hưởng tích cực đến tỷ suất sinh lời (ROE, ROA)hiệu suất đầu tư thực tế (Real_Return). Các nghiên cứu gần đây cũng chỉ ra rằng doanh nghiệp có điểm ESG cao thường có chi phí vốn thấp hơn, dễ thu hút dòng vốn đầu tư bền vững và đạt mức lợi nhuận điều chỉnh rủi ro cao hơn so với nhóm còn lại. Trong nghiên cứu này, biến ESG được dùng để kiểm định vai trò của hiệu suất bền vững trong việc giải thích sự khác biệt về lợi suất đầu tư giữa các công ty niêm yết.

1.2. KIỂM TRA CẤU TRÚC DỮ LIỆU

1.2.1. Đọc dữ liệu và tạo biến phái sinh

Trước khi đi vào phân tích chuyên sâu nhóm biến 2, ta cần làm sạch, chuẩn hóa và tạo biến phái sinh đã được thực hiện trên dữ liệu gốc (nyse_raw). Quá trình này bao gồm việc loại bỏ cột thừa (...1, date_SELL_fix), chuẩn hóa tên biến, chuyển đổi kiểu dữ liệu (từ character sang factor cho sector, investment), và tạo ra các biến mới có ý nghĩa tài chính/thống kê như sau:

  • Real_Return: Lợi suất thực tế (sau khi điều chỉnh lạm phát).
  • Log_PE: Logarit tự nhiên của Tỷ số P/E (nhằm chuẩn hóa phân bố lệch phải nặng).
  • Leverage_Ratio: Tỷ số Đòn bẩy Tài chính.
1. # KHỐI NÀY GIẢ ĐỊNH QUÁ TRÌNH TIỀN XỬ LÝ ĐÃ HOÀN TẤT
2. # nyse_processed <- nyse_raw %>%
3. #   select(-c("...1", "date_SELL_fix")) %>%
4. #   rename(Horizon_Days = `horizon (days)`, Nominal_Return = nominal_return, 
5. #          Expected_Return_Yr = `expected_return (yearly)`, ESG = ESG_ranking,
6. #          PE = PE_ratio, EPS = EPS_ratio, PS = PS_ratio, PB = PB_ratio,
7. #          NetProfitMargin = NetProfitMargin_ratio, Current_Ratio = current_ratio,
8. #          ROA = roa_ratio, ROE = roe_ratio) %>%
9. #   mutate(
10. #     sector = as.factor(sector),
11. #     investment = as.factor(investment),
12. #     Date_Buy = as.Date(date_BUY_fix),
13. #     # Feature Engineering
14. #     Real_Return = Nominal_Return - inflation,
15. #     Log_PE = log(PE),
16. #     Leverage_Ratio = 1 / (1 - (PB / (ROE/100))), 
17. )
18. # # TẠO BỘ DỮ LIỆU NHÓM 2 CỐT LÕI
19. # nyse_group2_data <- nyse_processed %>%
20. #   select(company, sector, Date_Buy, Buy_Year, Buy_Quarter, investment, Real_Return, 
21. #          Log_PE, PB, PS, ROE, ROA, EPS, NetProfitMargin, Current_Ratio, Leverage_Ratio, ESG)
22. # # Lưu bộ dữ liệu (giả định đã lưu)
23. # # save(nyse_group2_data, file = "nyse_group2_data.RData") 

1.2.2. Kiểm tra cấu trúc

1.2.2.1 Kiểm tra kích thước và kiểu dữ liệu

1. if (!exists("nyse_group2_data")) {
2.   nyse_group2_data <- nyse_raw %>%
3.     select(-c("...1", "date_SELL_fix")) %>%
4.     rename(Horizon_Days = `horizon (days)`, Nominal_Return = nominal_return, 
5.            Expected_Return_Yr = `expected_return (yearly)`, ESG = ESG_ranking,
6.            PE = PE_ratio, EPS = EPS_ratio, PS = PS_ratio, PB = PB_ratio,
7.            NetProfitMargin = NetProfitMargin_ratio, Current_Ratio = current_ratio,
8.            ROA = roa_ratio, ROE = roe_ratio,
9.            Date_Buy = date_BUY_fix, investment = investment) %>%
10.     mutate(
11.       sector = as.factor(sector), 
12.       investment = as.factor(investment), 
13.       Buy_Year = factor(year(Date_Buy)),
14.       Buy_Quarter = factor(quarter(Date_Buy, with_year = TRUE)),
15.       Real_Return = Nominal_Return - inflation,
16.       Log_PE = ifelse(PE > 0, log(PE), NA), 
17.       Leverage_Ratio = ifelse(ROE != 0 & PB != 0, abs(PB / (ROE/100)), NA) 
18.     ) %>%
19.     select(company, sector, Date_Buy, Buy_Year, Buy_Quarter, investment, Real_Return, 
20.            Log_PE, PB, PS, ROE, ROA, EPS, NetProfitMargin, Current_Ratio, Leverage_Ratio, ESG)
21. }

Giả thích kĩ thuật

Dòng code Giải thích ngắn gọn
1 Kiểm tra nếu chưa tồn tại nyse_group2_data thì mới chạy khối code bên dưới.
2-3 Tạo dữ liệu từ nyse_raw, loại bỏ cột thừa (...1, date_SELL_fix) bằng select().
4-9 Đổi tên các cột cho dễ hiểu và thống nhất (ví dụ: horizon (days)Horizon_Days, PE_ratioPE, roa_ratioROA, …).
10 Bắt đầu khối mutate() để tạo hoặc chuyển đổi biến.
11-12 Chuyển sectorinvestment sang dạng factor.
13-14 Tạo biến thời gian: Buy_Year (năm mua) và Buy_Quarter (quý mua).
15-17 Tính các biến mới: lợi nhuận thực (Real_Return), log(P/E) có điều kiện, và tỷ lệ đòn bẩy (Leverage_Ratio) tránh chia cho 0.
19-20 Chọn các cột chính để tạo bộ dữ liệu hoàn chỉnh nyse_group2_data.

Kiểm tra kích thước

1. print(dim(nyse_group2_data)) 
[1] 405258     17

Nhận xét: Lệnh print(dim(nyse_group2_data)) dùng để in ra kích thước của bộ dữ liệu. Qua đó có thể thấy bộ dữ liệu gồm 405258 quan sát với 17 biến

Kiểm tra kiểu dữ liệu (str)

1. nyse_group2_data %>%
2.   select(Real_Return, Log_PE, ROE, ESG, sector, investment) %>%
3.   str()
tibble [405,258 × 6] (S3: tbl_df/tbl/data.frame)
 $ Real_Return: num [1:405258] -1.997 0.524 0.194 0.142 0.503 ...
 $ Log_PE     : num [1:405258] 2.53 2.43 2.36 2.41 2.24 ...
 $ ROE        : num [1:405258] 26.69 5.54 25.78 11.35 8.91 ...
 $ ESG        : num [1:405258] 12 26.3 19.8 12.9 27.9 17.6 31.6 24.8 26.3 27.9 ...
 $ sector     : Factor w/ 5 levels "AUTO","BANK",..: 4 2 2 4 2 3 5 2 2 2 ...
 $ investment : Factor w/ 2 levels "BAD","GOOD": 1 2 1 1 2 2 2 2 1 2 ...

Nhận xét:

Code 1 -3 thể lấy dữ liệu nyse_group2_data, chọn các biến quan trọng (Real_Return, Log_PE, ROE, ESG, sector, investment) bằng select(), sau đó dùng str() để xem cấu trúc chi tiết

Kết quả cho thấy các biến (Real_Return, Log_PE, ROE, ESG) đều có kiểu numeric, trong khi các biến phân loại (sector, investment) đã được chuẩn hóa sang kiểu factor.

1.2.2.2: Tóm tắt tổng quan và giá trị NA trong biến phái sinh

Tóm tắt tổng quan

1. summary(nyse_group2_data %>% select(Real_Return, Log_PE, ROE, ESG, Leverage_Ratio))
  Real_Return        Log_PE           ROE             ESG       Leverage_Ratio
 Min.   :-2.61   Min.   :1       Min.   :-99.5   Min.   :12.0   Min.   :   2  
 1st Qu.:-1.69   1st Qu.:2       1st Qu.:  8.8   1st Qu.:16.3   1st Qu.:  11  
 Median : 0.14   Median :3       Median : 16.1   Median :25.1   Median :  16  
 Mean   :-0.51   Mean   :3       Mean   : 15.6   Mean   :22.6   Mean   :  46  
 3rd Qu.: 0.35   3rd Qu.:3       3rd Qu.: 26.0   3rd Qu.:27.9   3rd Qu.:  27  
 Max.   : 9.05   Max.   :7       Max.   : 57.2   Max.   :31.6   Max.   :2800  
                 NA's   :39751                                  NA's   :9158  

Nhận xét

Lệnh summary() áp dụng cho các cột được chọn (Real_Return, Log_PE, ROE, ESG, Leverage_Ratio) để tóm tắt thống kê mô tả.

Kết quả cho thấy biến Real_Return dao động từ –2.61 đến 9.05, tức lợi suất thực tế vẫn tồn tại trường hợp lỗ. Biến Log_PE có giá trị nhỏ (0.1–0.7) và thiếu dữ liệu khá nhiều với 39.751 giá trị NA. Chỉ số ROE biến động rất lớn, từ –99.5 đến 57.2, điều này thể hiện sự khác biệt đáng kể về hiệu quả sinh lời giữa các doanh nghiệp.Điểm ESG nằm trong khoảng –12.0 đến 31.6, trung bình khoảng 22.6, cho thấy phần lớn doanh nghiệp đạt mức đánh giá trung bình đến khá. Cuối cùng, Leverage_Ratio trải rộng từ 0.2 đến 2800 và có 9.158 giá trị thiếu, cho thấy sự chênh lệch lớn về đòn bẩy tài chính. Ở đây không nhận xét về hình dạng phân phối vì chưa đảm bảo các biến tuân theo phân phối chuẩn.

Giá trị thiếu trong biến phái sinh

1. nyse_group2_data %>% 
2.   summarise_all(list(n_NA = ~sum(is.na(.)))) %>%
3.   pivot_longer(cols = everything(), names_to = "Variable", values_to = "NA_Count") %>%
4.   filter(NA_Count > 0) %>%
5.   arrange(desc(NA_Count)) %>%
6.   kable(caption = "Bảng 1.2.1: Số lượng NA trong các biến phái sinh")
Bảng 1.2.1: Số lượng NA trong các biến phái sinh
Variable NA_Count
Log_PE_n_NA 39751
Leverage_Ratio_n_NA 9158

Giải thích kĩ thuật

Dòng code Giải thích ngắn gọn
1 Gọi dữ liệu nyse_group2_data.
2 Dùng summarise_all() để đếm số lượng giá trị thiếu (NA) bằng sum(is.na(.)).
3 Dùng pivot_longer() để chuyển dữ liệu cột thành hàng, tạo hai cột: Variable (tên biến) và NA_Count (số lượng NA).
4 Lọc ra chỉ các biến có giá trị NA (NA_Count > 0).
5 Sắp xếp giảm dần theo số lượng NA để xem biến nào thiếu nhiều nhất.
6 Dùng kable() để hiện thị bảng.

Nhận xét

  • Log_PE có số lượng NA rất lớn (39.751) điều này xuất phát từ các trường hợp tỷ số P/E không xác định hoặc không hợp lệ (PE \(\le\) 0)

  • Leverage_Ratio cũng có nhiều NA ( 9158 NA),do các trường hợp ROE \(\approx\) 0 hoặc PB \(\approx\) 0, hoặc mẫu số trong công thức đòn bẩy bằng 0.

1.2.2.3: Xử lý NA trong biến phái sinh

1. nyse_group2_clean <- nyse_group2_data %>%
2.   drop_na(Real_Return, Log_PE, Leverage_Ratio)
3. na_removed_count <- nrow(nyse_group2_data) - nrow(nyse_group2_clean)
4. na_removed_ratio <- (na_removed_count / nrow(nyse_group2_data)) * 100
5. cat("Số quan sát bị loại bỏ do NA trong biến tạo sinh:", na_removed_count, "\n")
Số quan sát bị loại bỏ do NA trong biến tạo sinh: 48909 
1. cat(sprintf("Tỷ lệ dữ liệu bị loại bỏ: %.2f%%", na_removed_ratio), "\n")
Tỷ lệ dữ liệu bị loại bỏ: 12.07% 
1. # Kiểm tra lại kích thước bộ dữ liệu cuối cùng
2. cat("\nKích thước bộ dữ liệu đã làm sạch cuối cùng (nyse_group2_clean) sau khi loại bỏ NA:\n")

Kích thước bộ dữ liệu đã làm sạch cuối cùng (nyse_group2_clean) sau khi loại bỏ NA:
1. print(dim(nyse_group2_clean))
[1] 356349     17

Giải thích kĩ thuật

Dòng code Giải thích ngắn gọn
2 Dùng drop_na() để loại bỏ các hàng có giá trị thiếu (NA) ở ba biến: Real_Return, Log_PE, Leverage_Ratio.
3 Tính số lượng quan sát bị loại bỏ bằng cách lấy chênh lệch số hàng trước và sau khi làm sạch.
4 Tính tỷ lệ phần trăm dữ liệu bị loại bỏ so với tổng số hàng ban đầu.

Nhận xét: Sau khi loại bỏ các quan sát có giá trị NA trong các biến Real_Return, Log_PE, và Leverage_Ratio, 48909 quan sát đã bị loại, tương đương với 12.07% tổng số dữ liệu. Bộ dữ liệu cuối cùng, nyse_group2_clean, có 356349 quan sát.

1.3. Kiểm soát giá trị cực đoan trong biến tài chính

Các giá trị ngoại lai (Outlier) có thể làm sai lệch nghiêm trọng các thống kê mô tả và ảnh hưởng đến kết quả phân tích. Mục tiêu của phần này là nhận diện và kiểm soát các giá trị cực đoan trong các biến định lượng cốt lõi như Real_Return, PE (trước khi Log), và ROE.

1.3.1. Xem xét các giá trị ngoại lai(outlier)

Sử dụng phương pháp Interquartile Range (IQR) để xác định Outlier (các giá trị nằm ngoài khoảng \([Q_1 - 1.5 \times IQR, Q_3 + 1.5 \times IQR]\)).

1.3.1.1. Định lượng số lượng và tỷ lệ Outlier

1. # Hàm tính số lượng outlier
2. get_outlier_count <- function(data, var_name) {
3.   x <- data[[var_name]]
4.   Q1 <- quantile(x, 0.25, na.rm = TRUE)
5.   Q3 <- quantile(x, 0.75, na.rm = TRUE)
6.   IQR_val <- Q3 - Q1
7.   lower_bound <- Q1 - 1.5 * IQR_val
8.   upper_bound <- Q3 + 1.5 * IQR_val
9.   outliers <- sum(x < lower_bound | x > upper_bound, na.rm = TRUE)
10.   return(outliers)
11. }
12. vars_to_check <- c("Real_Return", "PE", "ROE")
13. outlier_counts <- data.frame(
14.   Variable = vars_to_check,
15.   Outlier_Count = sapply(vars_to_check, function(v) get_outlier_count(nyse_raw, v)), 
16.   Total_Count = nrow(nyse_raw)
17. )
18. outlier_counts <- outlier_counts %>%
19.   mutate(Outlier_Ratio = (Outlier_Count / Total_Count) * 100)
20. # Chuyển PE_ratio về nyse_group2_clean 
21. outlier_counts_clean <- data.frame(
22.   Variable = c("Real_Return", "ROE"),
23.   Outlier_Count = sapply(c("Real_Return", "ROE"), function(v) get_outlier_count(nyse_group2_clean, v)),
24.   Total_Count = nrow(nyse_group2_clean)
25. ) %>%
26.   mutate(Outlier_Ratio = (Outlier_Count / Total_Count) * 100)
27. knitr::kable(outlier_counts_clean, caption = "Bảng 1.3.1: Định lượng Outlier trong dữ liệu đã làm sạch NA")
Bảng 1.3.1: Định lượng Outlier trong dữ liệu đã làm sạch NA
Variable Outlier_Count Total_Count Outlier_Ratio
Real_Return Real_Return 616 356349 0.173
ROE ROE 7678 356349 2.155

Giải thích kĩ thuật

Dòng code Giải thích
1-11 Sử dụng hàm get_outlier_count()để tính số lượng giá trị ngoại lai cho từng biến. Hàm lấy dữ liệu cột var_name, tính Q1Q3, xác định IQR = Q3 - Q1, rồi đặt ngưỡng dưới/trên lần lượt là Q1 - 1.5*IQRQ3 + 1.5*IQR. Đếm các giá trị nằm ngoài bằng sum().
12-17 Tạo vector vars_to_check gồm Real_Return, PE, ROE). Sau đó dùng sapply() để áp dụng hàm get_outlier_count() cho từng biến, tạo bảng outlier_counts được tính trong nyse_raw.
18-19 Dùng mutate() để thêm biến mới Outlier_Ratio, tính tỷ lệ % outlier = (Outlier_Count / Total_Count) * 100.
20-26 Thực hiện lại bước tính outlier cho dữ liệu đã làm sạch NA (nyse_group2_clean) cho hai biến Real_ReturnROE, rồi thêm tỷ lệ outlier (%).
27 Dùng knitr::kable() để hiển thị bảng kết quả với tiêu đề “Bảng 1.3.1: Định lượng Outlier trong dữ liệu đã làm sạch NA”.

Nhận xét:

Real_Return: Mặc dù đã loại bỏ NA, biến này vẫn có tỷ lệ ngoại lai cao là 0.17%. Điều này phản ánh sự biến động cực đoan của lợi suất trong thị trường chứng khoán.

ROE: Biến này cũng có tỷ lệ ngoại lai đáng kể là rsprintf("%.2f", outlier_counts_clean$Outlier_Ratio[2])%, có thể do các trường hợp sinh lời quá cao hoặc thua lỗ nghiêm trọng.

1.3.1.2 Trực quan hóa outlier các biến

1. outlier_viz_data <- nyse_group2_clean %>%
2.   select(Real_Return, ROE, Log_PE) %>%
3.   pivot_longer(cols = everything(), names_to = "Variable", values_to = "Value")
4. ggplot(outlier_viz_data, aes(x = Variable, y = Value)) +
5.   geom_boxplot(fill = "#1E90FF", color = "#1E90FF", alpha = 0.7, outlier.colour = "red", outlier.shape = 1) +
6.   facet_wrap(~Variable, scales = "free_y") +
7.   labs(
8.     title = "Hình 1.3.1: Nhận diện Outlier trong các biến cốt lõi",
9.     y = "Giá trị"
10.   ) +
11.   theme_minimal() +
12.   theme(plot.title = element_text(face = "bold", size = 12), axis.title.x = element_blank())

Nhận xét kĩ thuật

Phần / Dòng code Giải thích
Tiền xử lý (dòng 1–3) chọn các biến Real_Return, ROE, Log_PE từ nyse_group2_clean, sau đó dùng pivot_longer() để chuyển đổi dữ liệu với hai cột Variable (tên biến) và Value (giá trị).
Layer 1 (dòng 4) Khởi tạo biểu đồ bằng ggplot(), ánh xạ (mapping) trục hoành là Variable, trục tung là Value
Layer 2 (dòng 5) geom_boxplot() để vẽ biểu đồ hộp, hiển thị outlier bằng chấm đỏ rỗng (outlier.shape = 1) và tô màu xanh dương (#1E90FF).
Layer 3 (dòng 6) facet_wrap(~Variable) để **tạo nhiều biểu đồ con hiển thị mỗi ô riêng biệt, scales = "free_y" nhằm cho mỗi biểu đồ có trục tung riêng
Layer 4 (dòng 7–9) labs() để đặt tiêu đề và nhãn trục tung cho biểu đồ.
Layer 5 (dòng 11–12) theme_minimal(), chỉnh lại tiêu đề in đậm, cỡ chữ 12 và ẩn nhãn trục hoành.

Nhận xét

  • Biến Log_PE: Phần hộp (IQR) tập trung quanh giá trị 2–3, có một số lượng nhỏ outlier nằm phía trên hộp ( trên mức 6), cho thấy chỉ số P/E của một vài công ty cao bất thường so với phần lớn còn lại.

  • Biến Real_Return: Xuất hiện rất nhiều outlier ở phía trên ( khoảng từ 3 - 9), phản ánh nhiều công ty đạt mức lợi nhuận thực cao vượt trội, trong khi phần lớn dữ liệu tập trung quanh mức lợi nhuận gần 0.

  • Biến ROE: Có một vài outlier ở giá trị cao vượt ngưỡng 50–60 so với phần hộp tập trung trong khoảng 10–30, thể hiện một số công ty có khả năng sinh lời trên vốn chủ sở hữu vượt trội so với trung bình.

1.3.2. Điều chỉnh giá trị cực đoan của các biến tài chính

Có thể thấy giá trị outlier ở các biến Real_Return, ROE, Log_PE có nhiều giá trị cực đoan, nên áp dụng kỹ thuật Winsorizing ở ngưỡng 1% và 99% để giới hạn các giá trị bất thường thay vì loại bỏ chúng.

1. winsorize <- function(x, lower = 0.01, upper = 0.99) {
2.   quantiles <- quantile(x, c(lower, upper), na.rm = TRUE)
3.   x[x < quantiles[1]] <- quantiles[1]
4.   x[x > quantiles[2]] <- quantiles[2]
5.   return(x)
6. }
7. nyse_final_data <- nyse_group2_clean %>%
8.   mutate(
9.     Real_Return_Winsorized = winsorize(Real_Return, 0.01, 0.99),
10.     ROE_Winsorized = winsorize(ROE, 0.01, 0.99),
11.     Log_PE_Winsorized = winsorize(Log_PE, 0.01, 0.99) 
12.   )
13. cat("Đã tạo bộ dữ liệu cuối cùng 'nyse_final_data' với các biến Winsorized.\n")
Đã tạo bộ dữ liệu cuối cùng 'nyse_final_data' với các biến Winsorized.

Giải thích kĩ thuật

Dòng code Giải thích
1-6 Hàm winsorize() tính hai phân vị (quantiles) ở mức 1% và 99%, rồi thay giá trị nhỏ hơn phân vị 1% và lớn hơn phân vị 99% bằng chính hai ngưỡng đó.
7 Khởi tạo bộ dữ liệu mới nyse_final_data dựa trên nyse_group2_clean sau thực hiện Winsorization.
8–11 Dùng mutate() để tạo ba biến mới: Real_Return_Winsorized, ROE_Winsorized, và Log_PE_Winsorized

1.3.2.1. Thống kê so sánh Return và ROE sau xử lý

1. comparison_stats <- nyse_final_data %>%
2.   summarise(
3.     Mean_Return_Raw = mean(Real_Return, na.rm = TRUE),
4.     Mean_Return_Win = mean(Real_Return_Winsorized, na.rm = TRUE),
5.     SD_Return_Raw = sd(Real_Return, na.rm = TRUE),
6.     SD_Return_Win = sd(Real_Return_Winsorized, na.rm = TRUE),
7.     Skew_Return_Raw = moments::skewness(Real_Return, na.rm = TRUE),
8.     Skew_Return_Win = moments::skewness(Real_Return_Winsorized, na.rm = TRUE),
9.     Mean_ROE_Raw = mean(ROE, na.rm = TRUE),
10.     Mean_ROE_Win = mean(ROE_Winsorized, na.rm = TRUE),
11.     Skew_ROE_Raw = moments::skewness(ROE, na.rm = TRUE),
12.     Skew_ROE_Win = moments::skewness(ROE_Winsorized, na.rm = TRUE)
13.   ) %>%
14.   tidyr::pivot_longer(cols = everything(), names_to = "Statistic", values_to = "Value") %>%
15.   separate(Statistic, into = c("Statistic_Type", "Variable", "Adjustment"), sep = "_") %>%
16.   mutate(Adjustment = replace_na(Adjustment, "Raw")) %>%
17.   pivot_wider(names_from = Adjustment, values_from = Value)
18. knitr::kable(comparison_stats, caption = "Bảng 1.3.2: So sánh thống kê trước và sau Winsorizing")
Bảng 1.3.2: So sánh thống kê trước và sau Winsorizing
Statistic_Type Variable Raw Win
Mean Return -0.492 -0.502
SD Return 1.079 1.047
Skew Return -0.048 -0.327
Mean ROE 19.773 19.772
Skew ROE 0.774 0.763

Nhận xét kĩ thuật

Dòng code Giải thích
1 Lấy comparison_stats từ dữ liệu nyse_final_data.
2–12 Tính các thống kê mô tả cho biến Real_ReturnROE trước và sau Winsorizing, gồm: giá trị trung bình (mean), độ lệch chuẩn (sd), và độ lệch (skewness).
14 Dùng pivot_longer()để chyển dữ liệu và gom các chỉ số thống kê vào hai cột: StatisticValue.
15 Dùng separate() để tách tên cột trong Statistic thành ba phần: (Statistic_Type), (Variable), (Adjustment).
16 Hàm mutate thay các giá trị thiếu trong Adjustment bằng “Raw” _ dữ liệu gốc
17 Dùng pivot_wider()để hiển thị song song giá trị “Raw” và “Winsorized”.

Nhận xét

  • Biến Return: Giá trị (Mean) thay đổi không đáng kể, Tuy nhiên, độ lệch chuẩn (SD) giảm nhẹ từ 1.079 xuống 1.047 nghĩa là mức độ phân tán dữ liệu giảm sau khi loại bỏ ảnh hưởng của các giá trị cực đoan. Hệ số (Skew) thay đổi từ -0.048 sang -0.327 cũng phản ánh rằng phân phối lợi suất trở nên cân đối hơn.

  • Biến ROE: Giá trị trung bình (Mean) chỉ thay đổi nhỏ(19.773 → 19.772), hệ số (Skew) giảm nhẹ từ 0.774 xuống 0.763, ít bị thay đổi.

1.3.2.2. Trực quan hóa lợi suất thực tế (Real_Return) sau xử lý

1. viz_data_final <- nyse_final_data %>%
2.   select(Real_Return, Real_Return_Winsorized) %>%
3.   pivot_longer(cols = everything(), names_to = "Version", values_to = "Value") %>%
4.   mutate(Version = factor(Version, levels = c("Real_Return", "Real_Return_Winsorized"), 
5.                           labels = c("1. Ban đầu (Raw)", "2. Đã Winsorized (1%-99%)")))
6. ggplot(viz_data_final, aes(x = Version, y = Value, fill = Version)) +
7.   geom_boxplot(outlier.shape = NA) + 
8.   scale_fill_manual(values = c("1. Ban đầu (Raw)" = "#FF7F50", "2. Đã Winsorized (1%-99%)" = "#1E90FF")) +
9.   labs(
10.     title = "Hình 1.3.2: Trực quan hóa lợi suất thực tế (Real_Return) trước và sau Winsorizing",
11.     y = "Lợi suất thực tế",
12.     fill = "Phiên bản dữ liệu"
13.   ) +
14.   theme_minimal() +
15.   theme(plot.title = element_text(face = "bold", size = 12), axis.title.x = element_blank(), legend.position = "bottom")

Giải thích kĩ thuật

Phần / Dòng code Giải thích
Layer 1 (dòng 6) ggplot(), ánh xạ (mapping) trục hoành là Version, trục tung là Value.
Layer 2 (dòng 7) geom_boxplot() để vẽ biểu đồ hộp, outlier.shape = NA ẩn các điểm outlier để đồ thị gọn hơn.
Layer 3 (dòng 8) scale_fill_manual() để quy định màu riêng cho từng nhóm: cam(#FF7F50) cho dữ liệu gốc và xanh dương(#1E90FF) cho dữ liệu Winsorized.
Layer 4 (dòng 9–12) labs() gồm tiêu đề, tên trục tung và chú thích của biến fill.
Layer 5 (dòng 14–15) theme_minimal(), định dạng tiêu đề và đặt chú thích (legend) ở phía dưới

Nhận xét: Biểu đồ cho thấy lợi suất thực tế (Real_Return) trước và sau Winsorizing có hình dạng tương tự nhau. Giá trị trung vị của cả hai biểu đồ đều gần 0 nghĩa là xu hướng lợi suất không thay đổi. Tuy nhiên, pahmj vi phân tán ở phiên bản đã Winsorized (1%-99%) hẹp hơn phản ánh mức độ biến động giảm nhẹ sau khi điều chỉnh các giá trị cực đoan, điều này phù hợp với nhận định độ lệch chuẩn giảm từ 1.079 xuống 1.047, chứng tỏ dữ liệu ổn định hơn và ít bị ảnh hưởng bởi ngoại lai.

1.2. THỐNG KÊ MÔ TẢ

1.2.1. Thống kê mô tả tổng quan

1. vars_desc_fixed <- c("Real_Return_Winsorized", "Log_PE_Winsorized", "ROE_Winsorized", "Leverage_Ratio", "ESG")
2. get_desc_stats <- function(df, vars) {
3.   df_stats <- data.frame(Variable = vars)
4.   for (var in vars) {
5.     x <- df[[var]]
6.     x <- x[!is.na(x)]
7.     n_obs <- length(x)
8.     stats_row <- data.frame(
9.       Variable = var,
10.       N = n_obs,
11.       Mean = mean(x),
12.       Median = median(x),
13.       SD = sd(x),
14.       SE = sd(x) / sqrt(n_obs),
15.       Min = min(x),
16.       Q1 = quantile(x, 0.25),
17.       Q3 = quantile(x, 0.75),
18.       Max = max(x)
19.     )
20.     if (var == vars[1]) {
21.       result_df <- stats_row
22.     } else {
23.       result_df <- rbind(result_df, stats_row)
24.     }
25.   }
26.   return(result_df)
27. }
28. desc_table_fixed <- get_desc_stats(nyse_final_data, vars_desc_fixed)
29. desc_table_fixed %>%
30.   knitr::kable(caption = "Bảng 1.2.1: Thống kê mô tả các biến chính")
Bảng 1.2.1: Thống kê mô tả các biến chính
Variable N Mean Median SD SE Min Q1 Q3 Max
25% Real_Return_Winsorized 356349 -0.502 0.143 1.047 0.002 -2.11 -1.68 0.348 1.16
25%1 Log_PE_Winsorized 356349 2.896 2.717 0.833 0.001 1.47 2.40 3.224 6.40
25%2 ROE_Winsorized 356349 19.772 18.660 11.001 0.018 1.19 11.66 26.400 55.99
25%3 Leverage_Ratio 356349 38.284 14.887 155.899 0.261 2.83 10.79 24.864 2800.00
25%4 ESG 356349 21.815 22.800 6.349 0.011 12.00 14.80 27.300 31.60

Giải thích kĩ thuật

Dòng code Giải thích
1 Tạo vector vars_desc_fixed gồm các biến đã Winsorized và Leverage_RatioESG.
3–6 Tạo df_stats và xử lý bằng vòng lặp forloại bỏ giá trị thiếu (NA).
7–19 Tính các thống kê cho từng biến bằng các chỉ tiêu thông thường: mean, medium,…
20–24 Ghép từng dòng thống kê vào bảng kết quả result_df thông qua rbind().
28 Gọi hàm get_desc_stats() trên dữ liệu nyse_final_data để tạo bảng thống kê mô tả desc_table_fixed.

Nhận xét

1. Lợi suất Thực tế (Real_Return_Winsorized): Lợi suất thực tế có trung bình -0.502 và trung vị 0.143, nghĩa là phần lớn giao dịch có lợi nhuận dương. Độ lệch chuẩn 1.047 cho thấy mức biến động cao, phản ánh rủi ro lớn ngay cả sau khi đã Winsorizing dữ liệu.

2. Hiệu suất Vốn (ROE_Winsorized): ROE có trung bình 19.77% và trung vị 18.66%, phản ánh phân phối lệch phải nhẹ.Giá trị trung vị 18.7% cho thấy các doanh nghiệp trong mẫu có khả năng sinh lời trên vốn mạnh

3. Định giá (Log_PE_Winsorized): Chỉ số Log_PE có giá trị trung bình 2.896 (tương đương P/E ≈ 18.1) và trung vị 2.717 (P/E ≈ 15.1), cho thấy các công ty trong mẫu nhìn chung được định giá ở mức hợp lý đến hơi cao. Điều này phản ánh sự tích cực của thị trường vào hiệu quả hoạt động và tiềm năng tăng trưởng của phần lớn doanh nghiệp.

4. Đòn bẩy (Leverage_Ratio): Đây là biến có độ lệch nghiêm trọng nhất. Trung bình (Mean = 38.284) lớn hơn gấp 2.5 lần so với trung vị (Median = 14.887), và độ lệch chuẩn (SD = 155.899) là cực kỳ cao.Điều này cho thấy một tỷ lệ rất nhỏ các công ty trong mẫu có mức đòn bẩy cực kỳ lớn.

5. Yếu tố ESG (ESG): Trung bình (Mean = \(21.815\)) thấp hơn Trung vị (Median = \(22.800\)), cho thấy phân bố hơi lệch trái âm. Điều này ngụ ý rằng đa số các giao dịch tập trung vào các công ty có xếp hạng ESG tương đối cao. Phạm vi hẹp (Min=12.00, Max=31.60) và SD thấp (\(6.349\)) cho thấy xếp hạng ESG là một biến số ổn định và ít biến động hơn so với các chỉ số tài chính khác.

1.2.2. Phân tích đặc trưng thống kê

1. vars_shape_fixed <- c("Real_Return_Winsorized", "Log_PE_Winsorized", "ROE_Winsorized", "Leverage_Ratio")
2. get_desc_stats_shape <- function(df, vars) {
3.   # Khởi tạo data frame kết quả
4.   result_df <- data.frame(Variable = vars)
5.   for (var in vars) {
6.     x <- df[[var]]
7.     x <- x[!is.na(x)]
8.     mean_val <- mean(x)
9.     sd_val <- sd(x)
10.     stats_row <- data.frame(
11.       Variable = var,
12.       CV = sd_val / mean_val, # Coefficient of Variation
13.       Skewness = moments::skewness(x),
14.       Kurtosis = moments::kurtosis(x)
15.     )
16.     if (var == vars[1]) {
17.       result_df <- stats_row
18.     } else {
19.       result_df <- rbind(result_df, stats_row)
20.     }
21.   }
22.   return(result_df)
23. }
24. shape_table_fixed <- get_desc_stats_shape(nyse_final_data, vars_shape_fixed)
25. shape_table_fixed %>%
26.   knitr::kable(caption = "Bảng 1.2.2: Đặc trưng thống kê biến")
Bảng 1.2.2: Đặc trưng thống kê biến
Variable CV Skewness Kurtosis
Real_Return_Winsorized -2.085 -0.327 1.34
Log_PE_Winsorized 0.288 1.596 7.02
ROE_Winsorized 0.556 0.763 3.74
Leverage_Ratio 4.072 14.141 238.06

Giải thích kĩ thuật

Dòng code Giải thích
1 vector vars_shape_fixed tạo gồm Real_Return_Winsorized, Log_PE_Winsorized, ROE_Winsorized, Leverage_Ratio.
4–7 tạo bảng kết quả và loại bỏ (NA) và dùng vòng lặp for để lần lượt tính CV, Skewness, Kurtosis cho từng biến
8–9 Tính giá trị trung bình (mean)độ lệch chuẩn (sd) của biến hiện tại.
10–15 Tính ba chỉ tiêu: CV (mức biến động), Skewness (độ lệch), Kurtosis (độ nhọn).
16–20 Lệnh ifđể kiểm tra nếu là biến đầu tiên thì khởi tạo result_df, còn nếu không thì ghép thêm dòng kết quả vào bảng bằng rbind().
24 get_desc_stats_shape() để tính toán cho toàn bộ các biến trong nyse_final_data.

Nhận xét về Độ Lệch, Độ Nhọn và Hệ số Biến thiên

  • Real_Return_Winsorized: Có hệ số biến thiên (CV = -2.085) và độ lệch (Skewness = -0.327) nhỏ, cho thấy lợi suất thực tế khá ổn định và phân bố gần đối xứng,tuy nhiên độ biến động lợi suất vẫn cao

  • Log_PE_Winsorized:CV = 0.288, độ lệch dương (Skewness = 1.596) và độ nhọn cao (Kurtosis = 7.02), phản ánh một số cổ phiếu vẫn được định giá cao vượt trội so với phần lớn còn lại.

  • ROE_Winsorized: Với CV = 0.556, Skewness = 0.763, phân phối hơi lệch phải, cho thấy một nhóm nhỏ có ROE vượt trội.

  • Leverage_Ratio: Biến động cực lớn (CV = 4.072) và (Skewness = 14.141, Kurtosis = 238.06), thể hiện sự chênh lệch đòn bẩy tài chính rất cao một số có mức nợ vượt trội bất thường.

1.2.3. Kiểm định và tần số phân bố

1.2.3.1. Kiểm định chuẩn tắc lợi suất thực tế

1. sample_size <- 5000
2. set.seed(42) 
3. sample_real_return <- nyse_final_data$Real_Return_Winsorized %>%
4.   sample(size = sample_size, replace = FALSE)
5. current_scipen <- options(scipen = 0)
6. shapiro_test <- shapiro.test(sample_real_return)
7. test_output <- broom::tidy(shapiro_test) %>%
8.     mutate(
9.         statistic = format(statistic, digits = 3),
10.         p.value = format(p.value, scientific = TRUE, digits = 3)
11.     )
12. options(scipen = current_scipen$scipen) 
13. print(test_output)
# A tibble: 1 × 3
  statistic p.value  method                     
  <chr>     <chr>    <chr>                      
1 0.816     4.95e-60 Shapiro-Wilk normality test

Giải thích kĩ thuật

Dòng code Giải thích ngắn gọn
1–2 Xác định kích thước mẫu (5000) và đặt seed = 42
3–4 Lấy mẫu gồm 5000 giá trị từ biến Real_Return_Winsorized trong nyse_final_data không lặp lại (replace = FALSE).
5 Lưu hiển thị số học (scipen) sau khi kiểm định
6 Thực hiện kiểm định Shapiro–Wilk

Nhận xét

Statistic p.value
W \(\approx 0.816\)
p-value \(\approx 4.95 \times 10^{-60}\)

Giá trị thống kê W ≈ 0.816 cùng p-value ≈ 4.95 × 10⁻⁶⁰ (rất nhỏ, < 0.05) điều này có nghĩa là biến Real_Return_Winsorized không tuân theo phân phối chuẩn dù đã được Winsorizing.

1.2.3.2. Phân bố kết quả đầu tư

1. nyse_final_data %>%
2.   count(investment) %>%
3.   mutate(
4.     Percentage = (n / sum(n)) * 100
5.   ) %>%
6.   knitr::kable(
7.     col.names = c("Kết quả Đầu tư", "Số lượng (Count)", "Tỷ lệ (%)"),
8.     digits = c(0, 0, 2), 
9.     caption = "Bảng 1.2.3: Phân bố kết quả đầu tư (GOOD/BAD)"
10.   )
Bảng 1.2.3: Phân bố kết quả đầu tư (GOOD/BAD)
Kết quả Đầu tư Số lượng (Count) Tỷ lệ (%)
BAD 229328 64.3
GOOD 127021 35.6

Giải thích kĩ thuật

Dòng code Giải thích ngắn gọn
1–2 count(investment) để đếm số lượng quan sát trong từng nhóm kết quả đầu tư (GOOD hoặc BAD).
3–5 Thêm cột tỷ lệ phần trăm (%)

Nhận xét: Kết quả cho thấy nhóm BAD (thua lỗ/lợi suất thấp) chiếm đa số với 64.3% tổng số quan sát, tương ứng 229,328 giao dịch.
Trong khi đó, nhóm GOOD (sinh lời/lợi suất cao) chỉ chiếm 35.7% với 127,021 giao dịch.
Điều này cho thấy phần lớn các khoản đầu tư trong mẫu có hiệu quả thấp, phản ánh mức độ rủi ro và khả năng sinh lời chưa ổn định trên thị trường.

1.2.4. Phân tích tương quan các biến

1.2.4.1. Ma trận tương quan

1. vars_corr <- c("Real_Return_Winsorized", "Log_PE_Winsorized", "ROE_Winsorized", "Leverage_Ratio", "ESG")
2. corr_matrix <- nyse_final_data %>%
3.   select(all_of(vars_corr)) %>%
4.   cor(use = "pairwise.complete.obs")
5. corr_matrix %>%
6.   knitr::kable(digits = 3, caption = "Bảng 1.2.4: Ma trận tương quan giữa các biến")
Bảng 1.2.4: Ma trận tương quan giữa các biến
Real_Return_Winsorized Log_PE_Winsorized ROE_Winsorized Leverage_Ratio ESG
Real_Return_Winsorized 1.000 -0.056 -0.090 -0.048 -0.001
Log_PE_Winsorized -0.056 1.000 -0.224 0.398 0.150
ROE_Winsorized -0.090 -0.224 1.000 -0.193 -0.427
Leverage_Ratio -0.048 0.398 -0.193 1.000 0.104
ESG -0.001 0.150 -0.427 0.104 1.000

Giải thích kĩ thuật

Dòng code Giải thích ngắn gọn
1 tạo ma trận gồm các biến Real_Return_Winsorized, Log_PE_Winsorized, ROE_Winsorized, Leverage_Ratio, và ESG.
2–4 tính ma trận hệ số tương quan (correlation matrix) bằng hàm cor(), với tùy chọn pairwise.complete.obs để NA.

Nhận xét

1. Mối quan hệ với Lợi suất Thực tế (Real_Return_Winsorized): Lợi suất thực tế có mối tương quan rất yếu và âm với các biến tài chính: ROE (r = -0.090), Log_PE (r = -0.056)Leverage_Ratio (r ≈ -0.048). Điều này cho thấy các chỉ tiêu hiệu quả và định giá chưa dự báo mạnh mẽ lợi suất , thậm chí các công ty có ROE hoặc P/E cao lại có xu hướng đạt lợi suất thấp hơn nhẹ. Ngoài ra, yếu tố ESG (r ≈ -0.001) gần như không ảnh hưởng đáng kể đến hiệu quả đầu tư**.

2. Mối quan hệ giữa các chỉ số chất lượng/định giá/đòn bẩy):

  • ROE và ESG (r = -0.427): Hệ số tương quan âm trung bình-mạnh cho thấy công ty có ROE cao hơn (hiệu suất tài chính tốt) lại có xu hướng có xếp hạng ESG thấp hơn (ESG thấp).

  • Leverage và Log_PE (r = 0.398): Mối tương quan dương trung bình cho thấy các công ty sử dụng đòn bẩy cao hơn cũng có xu hướng được thị trường định giá cao hơn (Log_PE cao hơn). Nghĩa là đòn bẩy cao có thể được xem là các doanh nghiệp tăng trưởng, chấp nhận rủi ro cao để tối ưu hóa hiệu suất vốn.

  • ROE và Log_PE (r = -0.224): Mối tương quan âm yếu cho thấy các công ty được định giá cao hơn (Log_PE cao) lại có xu hướng có ROE thấp hơn.

1.2.4.2. Đánh giá mức ý nghĩa của tương quan

Kiểm định giả thuyết \(H_0: \rho = 0\) cho các cặp tương quan quan trọng.

Tương quan giữa Real_Return và ROE

1. current_scipen <- options(scipen = 0)
2. test_corr_return_roe <- cor.test(nyse_final_data$Real_Return_Winsorized, nyse_final_data$ROE_Winsorized)
3. broom::tidy(test_corr_return_roe) %>%
4.     mutate(
5.         p.value = format(p.value, scientific = TRUE, digits = 3),
6.         statistic = round(statistic, 2),
7.         estimate = round(estimate, 4)
8.     ) %>%
9.     print()
# A tibble: 1 × 8
  estimate statistic p.value parameter conf.low conf.high method     alternative
     <dbl>     <dbl> <chr>       <int>    <dbl>     <dbl> <chr>      <chr>      
1  -0.0904     -54.2 0e+00      356347  -0.0936   -0.0871 Pearson's… two.sided  

Nhận xét

estimate (\(\rho\)) statistic (\(t\)) p.value conf.low conf.high
-0.0904 -54.2 \(\approx 0\) -0.0936 -0.0871

Giá trị p - value rất nhỏ nên ~ 0, Khoảng tin cậy 95% (-0.0936 đến -0.0871) nên cặp biến có ý nghĩa thống kê mạnh mẽ. Hệ số tương quan giữa ROElợi suất thực tế-0.0904, cho thấy mối quan hệ âm rất yếu nên ROE rất có khả năng giải thích được biến động lợi suất.

Tương quan giữa Real_Return và Log_PE

1. test_corr_return_logpe <- cor.test(nyse_final_data$Real_Return_Winsorized, nyse_final_data$Log_PE_Winsorized)
2. broom::tidy(test_corr_return_logpe) %>%
3.     mutate(
4.         p.value = format(p.value, scientific = TRUE, digits = 3),
5.         statistic = round(statistic, 2),
6.         estimate = round(estimate, 4)
7.     ) %>%
8.     print()
# A tibble: 1 × 8
  estimate statistic p.value   parameter conf.low conf.high method   alternative
     <dbl>     <dbl> <chr>         <int>    <dbl>     <dbl> <chr>    <chr>      
1   -0.056     -33.5 2.34e-245    356347  -0.0593   -0.0527 Pearson… two.sided  
1. options(scipen = current_scipen$scipen)

Nhận xét

estimate (\(\rho\)) statistic (\(t\)) p.value conf.low conf.high
-0.0560 -33.5 \(\approx 0\) -0.0593 -0.0527

Giá trị \(p\)-value cực kỳ nhỏ (cũng \(\approx 0\)), nên mối tương quan này cũng có ý nghĩa thống kê. Tuy nhiên hệ số tương quan ước tính là \(-0.0560\), là một mối tương quan âm và cực kỳ yếu. Mức độ giải thích của biến định giá Log_PE đối với lợi suất thực tế thậm chí còn thấp hơn cả ROE.

Giải thích kĩ thuật (tương tự ở hai cặp)

Dòng code Giải thích ngắn gọn
1 Lưu thiết lập hiển thị số (scipen) dạng khoa học
2 Thực hiện kiểm định tương quan Pearson giữa các cặp cor.test()
3–8 Dùng broom::tidy() chuyển kết quả kiểm định thành dạng bảng

1.2.5. Thống kê so sánh theo nhóm ngành

1.2.5.1. Thống kê Real_Return theo Sector

1. nyse_final_data %>%
2.   group_by(sector) %>%
3.   summarise(
4.     N = n(),
5.     Mean_Return = mean(Real_Return_Winsorized, na.rm = TRUE),
6.     SD_Return = sd(Real_Return_Winsorized, na.rm = TRUE),
7.     Median_Return = median(Real_Return_Winsorized, na.rm = TRUE)
8.   ) %>%
9.   arrange(desc(Mean_Return)) %>%
10.   knitr::kable(caption = "Bảng 1.2.5: Thống kê lợi suất thực tế theo ngành nghề")
Bảng 1.2.5: Thống kê lợi suất thực tế theo ngành nghề
sector N Mean_Return SD_Return Median_Return
TECH 89107 -0.441 1.09 0.169
AUTO 53098 -0.473 1.02 0.137
RETAIL 92346 -0.510 1.01 0.135
FMCG 49273 -0.546 1.04 0.156
BANK 72525 -0.559 1.05 0.103

Nhận xét

Ngành TECH (0.169)FMCG (0.156) có lợi suất trung vị cao nhất, cho thấy phần lớn giao dịch trong hai ngành này mang lại hiệu quả đầu tư tốt hơn so với các ngành khác. Ngược lại, BANK (0.103) có lợi suất trung vị thấp nhất, thể hiện mức sinh lời thấp nhưng rủi ro cũng thấp hơn, phản ánh đặc trưng ổn định của nhóm ngành tài chính – ngân hàng.

Ngành TECH có lợi suất trung vị cao nhưng độ biến động lớn (SD = 1.09), phản ánh rõ nguyên lý đánh đổi giữa rủi ro và lợi nhuận.
Ngược lại, ngành BANK cho thấy Mean âm (-0.559) trong khi Median dương (0.103), chứng tỏ chịu ảnh hưởng mạnh từ một số giao dịch thua lỗ cực đoan

1.2.5.2. Thống kê Chỉ số định giá, hiệu suất theo investment

1. nyse_final_data %>%
2.   group_by(investment) %>%
3.   summarise(
4.     N = n(),
5.     Median_LogPE = median(Log_PE_Winsorized, na.rm = TRUE),
6.     Median_ROE = median(ROE_Winsorized, na.rm = TRUE),
7.     Mean_Leverage = mean(Leverage_Ratio, na.rm = TRUE)
8.   ) %>%
9.   knitr::kable(caption = "Bảng 1.2.6: Thống kê chỉ số định giá/hiệu suất theo kết quả đầu tư")
Bảng 1.2.6: Thống kê chỉ số định giá/hiệu suất theo kết quả đầu tư
investment N Median_LogPE Median_ROE Mean_Leverage
BAD 229328 2.69 19.4 41.5
GOOD 127021 2.74 17.4 32.5

Nhận xét

  • Định giá (Median_LogPE): Nhóm GOOD có định giá trung vị cao hơn một chút (2.74 so 2.69), cho thấy cổ phiếu được thị trường định giá cao hơn thường mang lại kết quả đầu tư tốt hơn.

  • Hiệu suất (Median_ROE): Nhóm BAD lại có ROE trung vị cao hơn (19.4% so với 17.4%), tạo nên nghịch lý “các công ty có hiệu suất tài chính tốt hơn chưa chắc mang lại lợi suất thực tế cao hơn”, có thể được giải thích bằng giả thuyết thị trường hiệu quả.

  • Đòn bẩy (Mean_Leverage): Nhóm BAD có đòn bẩy trung bình cao hơn (41.5 so với 32.5), cho thấy rủi ro tài chính lớn hơn thường đi kèm với kết quả đầu tư kém hơn.

1.2.5.3. Thống kê ESG theo Sector

1. nyse_final_data %>%
2.   group_by(sector) %>%
3.   summarise(
4.     N = n(),
5.     Mean_ESG = mean(ESG, na.rm = TRUE),
6.     Median_ESG = median(ESG, na.rm = TRUE),
7.     SD_ESG = sd(ESG, na.rm = TRUE)
8.   ) %>%
9.   arrange(desc(Mean_ESG)) %>%
10.   knitr::kable(caption = "Bảng 1.2.7: Thống kê xếp hạng ESG theo ngành nghề")
Bảng 1.2.7: Thống kê xếp hạng ESG theo ngành nghề
sector N Mean_ESG Median_ESG SD_ESG
AUTO 53098 25.7 29.7 6.20
BANK 72525 25.4 26.3 3.19
FMCG 49273 22.6 25.1 3.50
TECH 89107 20.7 16.5 7.00
RETAIL 92346 17.4 14.5 5.65

Nhận xét

Ngành AUTO và BANK có điểm ESG cao cụ thể AUTO (Mean: \(25.7\), Median: \(29.7\)) và BANK (Mean: \(25.4\), Median: \(26.3\)) điều này phản ánh mức tuân thủ tốt các quy định về môi trường và quản trị. Ngược lại ngành RETAIL (Mean: \(17.4\), Median: \(14.5\)) và TECH (Mean: \(20.7\), Median: \(16.5\)) có điểm ESG trung bình thấp nhất. Tuy nhiên đáng chú ngành TECH có độ biến động ESG (SD_ESG = \(7.00\)) cao nhất, thể hiện sự chênh lệch lớn giữa các doanh nghiệp trong ngành trong khi ngành BANK có độ biến động thấp nhất (SD_ESG = \(3.19\)).

Giải thích kĩ thuật ba thống kê

Dòng code Giải thích ngắn gọn
1–2 Nhóm dữ liệu nyse_final_data theo chỉ tiêu cần bằng group_by().
3–7 Tính các thống kê mô tả: số lượng quan sát, trung bình, độ lệch chuẩn ..
9 Sắp xếp kết quả theo lợi suất trung bình giảm dầnở mục 1.2.5.1. và 1.2.5.3

1.3. TRỰC QUAN HÓA DỮ LIỆU

1.3.1. Trực quan hóa phân bố dữ liệu

1.3.1.1. Biểu đồ mật độ cho các biến Winsorized

1. viz_data_density <- nyse_final_data %>%
2.   select(Real_Return_Winsorized, Log_PE_Winsorized, ROE_Winsorized, Leverage_Ratio) %>%
3.   pivot_longer(cols = everything(), names_to = "Variable", values_to = "Value") %>%
4.   mutate(Variable = factor(Variable, levels = c("Real_Return_Winsorized", "Log_PE_Winsorized", "ROE_Winsorized", "Leverage_Ratio"),
5.                            labels = c("Lợi suất Thực tế (Winsorized)", "Log(PE) (Winsorized)", "ROE (Winsorized)", "Tỷ lệ Đòn bẩy")))
6. ggplot(viz_data_density, aes(x = Value, fill = Variable)) +
7.   geom_density(alpha = 0.6) +
8.   facet_wrap(~Variable, scales = "free", ncol = 2) +
9.   labs(
10.     title = "Hình 1.3.1: Phân bố mật độ của các chỉ số định lượng chính",
11.     x = "Giá trị",
12.     y = "Mật độ"
13.   ) +
14.   theme_minimal() +
15.   theme(legend.position = "none", plot.title = element_text(face = "bold", size = 12))

Giải thích kĩ thuật:

Phần / Dòng code Giải thích
Tiền xử lý (dòng 1–5) chọn dữ liệu, chuyển theo kiểu pivot_longer() và gán nhãn bằng mutate().
Layer 1 (dòng 6) ggplot(), ánh xạ (mapping) trục hoành là Value và màu tô (fill) theo Variable (tên biến)
Layer 2 (dòng 7) geom_density() để vẽ đường mật độ, alpha = 0.6 làm màu trong suốt giúp dễ so sánh
Layer 3 (dòng 8) facet_wrap(~Variable) để chia biểu đồ thành các ô nhỏ và so sánh độc lập bằng (scales = "free").
Layer 4 (dòng 9–13) labs(), gồm tiêu đề biểu đồ, tên trục X (“Giá trị”) và trục Y (“Mật độ”).
Layer 5 (dòng 14–15) theme_minimal() tạo giao diện

Nhận xét

  • Lợi suất Thực tế: Phân bố lưỡng cực rõ rệt với hai đỉnh — một ở vùng thua lỗ (~-2.0) và một ở vùng sinh lời nhẹ (~0.1–0.3), phản ánh sự phân hóa mạnh giữa các khoản đầu tư tốt và xấu.

  • Định giá (Log(PE)): Phân bố lệch phải, tập trung quanh khoảng 2.5–2.8 với đuôi dài sang phải, cho thấy có một số cổ phiếu được định giá rất cao.

  • Hiệu suất Vốn (ROE): Có dạng đa đỉnh, nổi bật ở khoảng 10–20% và 25–35%, phản ánh sự tồn tại của hai nhóm hiệu suât là ổn định và tăng trưởng.

  • Tỷ lệ Đòn bẩy: Phân bố rất lệch phải và nhọn, tập trung gần 0, với vài giá trị cực lớn (>1000), cho thấy đa số doanh nghiệp có đòn bẩy thấp nhưng một số ít có rủi ro tài chính rất cao.

1.3.1.2. Biểu đồ phân bố kết quả đầu tư (GOOD/BAD)

1. nyse_final_data %>%
2.   ggplot(aes(x = investment, fill = investment)) +
3.   geom_bar() +
4.   geom_text(stat = 'count', aes(label = after_stat(count)), vjust = -0.5) +
5.   labs(
6.     title = "Hình 1.3.2: Phân bố kết quả Đầu tư (GOOD/BAD)",
7.     x = "Kết quả đầu tư",
8.     y = "Số lượng giao dịch"
9.   ) +
10.   scale_fill_manual(values = c("GOOD" = "#28a745", "BAD" = "#dc3545")) +
11.   theme_minimal() +
12.   theme(legend.position = "none", plot.title = element_text(face = "bold", size = 10))

Giải thích kĩ thuật

Phần/ Dòng code Giải thích
Layer 1 (dòng 2) ggplot(), ánh xạ (mapping) trục hoành là investment (GOOD/BAD) và màu tô (fill) theo cùng biến này.
Layer 2 (dòng 3) geom_bar() để vẽ biểu đồ cột
Layer 3 (dòng 4) Thêm nhãn số liệu trên cột bằng geom_text(stat = "count") và căn chỉnh nhãn (vjust = -0.5).
Layer 4 (dòng 5–8) labs(): tiêu đề, tên trục X và trục Y
Layer 5 (dòng 10) chỉnh màu scale_fill_manual(): xanh lá (#28a745) cho GOOD và đỏ (#dc3545) cho BAD.
Layer 6 (dòng 11–12) Áp dụng (theme_minimal)** ẩn chú thích (legend.position = "none")

Nhận xét: Số lượng giao dịch BAD\(229,328\) (Tỷ lệ \(64.3\%\)) Trong khi đó lượng giao dịch GOOD\(127,021\) (Tỷ lệ \(35.7\%\)). Vậy có thể nói để một khoản đầu tư ngẫu nhiên vào NYSE rơi vào nhóm hiệu suất thấp (BAD) là \(1.8\) lần cao hơn so với rơi vào nhóm hiệu suất cao (GOOD).

1.3.2. Trực quan hóa mối quan hệ tương quan

1.3.2.1 Trực quan ma trận tương quan

1. # Heatmap của Ma trận Tương quan
2. corr_long <- reshape2::melt(corr_matrix)
3. ggplot(corr_long, aes(x = Var1, y = Var2, fill = value)) +
4.   geom_tile(color = "white") +
5.   scale_fill_gradient2(low = "blue", high = "red", mid = "white", midpoint = 0, limit = c(-1, 1), space = "Lab", name = "Hệ số tương quan") +
6.   geom_text(aes(label = round(value, 2)), color = "black", size = 3) +
7.   labs(
8.     title = "Hình 1.3.3: Ma trận tương quan giữa các chỉ số chính",
9.     x = "Biến",
10.     y = "Biến"
11.   ) +
12.   theme_minimal() +
13.   theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1), plot.title = element_text(face = "bold", size = 12))

Giải thích kĩ thuật

Phần / Dòng code Giải thích
Tiền xử lý (dòng 2) Sử dụng reshape2::melt() để chuyển ma trận tương quan corr_matrix sang dạng dài (long format)
Layer 1 (dòng 3) ggplot()ánh xạ (mapping) trục X, Y là các biến (Var1, Var2)
Layer 2 (dòng 4) Thêm ô màu (heatmap) bằng geom_tile(), mỗi ô biểu diễn cặp tương quan giữa hai biến; color = "white" tạo đường viền phân cách rõ ràng.
Layer 3 (dòng 5) Áp dụng thang màu hai chiều với scale_fill_gradient2(): màu xanh (tương quan âm), trắng (0), đỏ (tương quan dương). Giới hạn trong khoảng (-1, 1).
Layer 4 (dòng 6) Thêm giá trị số lên ô bằng geom_text(), làm tròn số
Layer 5 (dòng 7–10) Dùng labs() để đặt tiêu đề biểu đồ và nhãn trục X/Y**.
Layer 6 (dòng 12–13) (theme_minimal), xoay nhãn trục X 45° để dễ đọc và in đậm tiêu đề (plot.title).

Nhận xét

Lưu ý Cường độ tương quan được thể hiện bằng độ đậm của màu: Đỏ (Dương)Xanh Tím (Âm). Giá trị gần 0 (tương quan yếu) được thể hiện bằng màu trắng hoặc màu nhạt.

  • Với Lợi suất Thực tế (Real_Return_Winsorized): tương quan yếu gần bằng 0 với các biến khác (dao động từ -0.09 đến -0.001). Điều này nghĩa là hiệu suất đầu tư không bị ảnh hưởng đáng kể bởi các chỉ số tài chính.

  • Quan hệ giữa các chỉ số độc lập:

    • ROE – ESG: Mối tương quan âm mạnh nhất (r = -0.43, màu xanh đậm), phản ánh rằng doanh nghiệp ROE cao thường có điểm ESG thấp.

    • Leverage – Log(PE): Mối tương quan dương trung bình (r = 0.40, màu đỏ nhạt), gợi ý doanh nghiệp dùng đòn bẩy cao thường được định giá cao hơn.

    • Các cặp khác như ROE – Log(PE) hay ROE – Leverage có tương quan yếu, hơn yếu hơn so với cặp ROE-ESG (r ≈ -0.2), chỉ thể hiện xu hướng nhẹ chứ không rõ rệt

1.3.3. Trực quan hóa nhóm ngành nghề

1.3.3.1. Trực quan lợi suất theo ngành nghề

1. ggplot(nyse_final_data, aes(x = sector, y = Real_Return_Winsorized, fill = sector)) +
2.   geom_violin(alpha = 0.7) +
3.   geom_boxplot(width = 0.1, color = "black", alpha = 0.8, outlier.shape = NA) + 
4.   labs(
5.     title = "Hình 1.3.5: Phân bố lợi suất thực tế giữa các ngành",
6.     x = "Ngành nghề",
7.     y = "Lợi suất thực tế (Winsorized)"
8.   ) +
9.   theme_minimal() +
10.   theme(legend.position = "none", plot.title = element_text(face = "bold", size = 12))

Giải thích kĩ thuật

Phần / Dòng code Giải thích ngắn gọn
Vẽ biểu đồ ggplot Dữ liệu được lấy từ nyse_final_data, ánh xạ biến sector vào trục X và Real_Return_Winsorized vào trục Y
Layer 1 (dòng 2) Dùng geom_violin(alpha = 0.7)để vẽ hình dạng phân bố lợi suất cho từng ngành
Layer 2 (dòng 3) Chồng thêm geom_boxplot() để thể hiện trung vị, tứ phân vị và khoảng dữ liệu; ẩn outlier (outlier.shape = NA)
Layer 3 (dòng 4–7) labs() để thêm tiêu đề và nhãn trụccho biểu đồ.
Layer 4 (dòng 9–10) lớp giao diện (theme_minimal)**

Nhận xét

Lưu ý Chiều rộng của “cây vĩ cầm” biểu thị mật độ quan sát tại giá trị lợi suất đó. Đường kẻ ngang bên trong (từ Box Plot) biểu thị Trung vị (Median).

  • Ngành TECHFMCG có đường kẻ Trung vị nằm ở vị trí cao nhất trên trục Y (gần nhất với 1), xác nhận chúng là các ngành có lợi suất trung vị cao nhất. Ngược lại ngành BANK có Trung vị nằm ở vị trí thấp nhất (gần 0 nhất), khẳng định đây là ngành có hiệu suất thấp nhất trong mẫu.

Ngành TECHAUTO có phần thân “cây vĩ cầm” phía trên (lợi suất dương) rộng nhất, ngụ ý có một lượng lớn giao dịch đạt được lợi nhuận dương trong phạm vi trung bình.Ngược lại ngành BANK có phần đuôi kéo dài về lợi suất âm dài và mỏng nhất (tương đối), cho thấy mật độ ở các khoản lỗ lớn thấp hơn các ngành khác

Sự khác biệt rõ ràng về vị trí của trung vị và hình dạng mật độ giữa các ngành (đặc biệt là TECH vs BANK) cho thấy lợi suất thực tế bị ảnh hưởng bởi ngành nghề. Sự khác biệt này sẽ được kiểm định chính thức bằng Kiểm định ANOVA/Kruskal-Wallis ở Chương 4 để xác định liệu chúng có ý nghĩa thống kê hay không.

1.3.3.2 Trực quan trung bình ROE và Log(PE) theo nhóm ngành

1. sector_indicators_mean <- nyse_final_data %>%
2.   group_by(sector) %>%
3.   summarise(
4.     Mean_ROE = mean(ROE_Winsorized, na.rm = TRUE),
5.     Mean_LogPE = mean(Log_PE_Winsorized, na.rm = TRUE)
6.   ) %>%
7.   pivot_longer(cols = starts_with("Mean"), names_to = "Indicator", values_to = "Mean_Value")
8. ggplot(sector_indicators_mean, aes(x = sector, y = Mean_Value, fill = Indicator)) +
9.   geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.7) +
10.   labs(
11.     title = "Hình 1.3.6: Trung bình ROE và Log(PE) giữa các ngành nghề",
12.     x = "Ngành nghề",
13.     y = "Giá trị trung bình (Winsorized)",
14.     fill = "Chỉ số"
15.   ) +
16.   scale_fill_manual(values = c("Mean_ROE" = "#007bff", "Mean_LogPE" = "#ffc107")) +
17.   theme_minimal() +
18.   theme(plot.title = element_text(face = "bold", size = 12))

Giải thích kĩ thuật

Phần / Dòng code Giải thích ngắn gọn
1–7 Tính giá trị trung bình ROE và Log(PE)** cho từng ngành bằng group_by()summarise(), và chuyển đổi về pivot_longer()
Layer 1 (dòng 8) Khởi tạo ggplot() với trục X = sector, trục Y = Mean_Value, và màu tô (fill) theo Indicator.
Layer 2 (dòng 9) geom_bar(stat = "identity") để vẽ biểu đồ cột nhóm song song
Layer 3 (dòng 10–14) labs()thêm tiêu đề
Layer 4 (dòng 16–18) chỉnh màu sắc (ROE: xanh, LogPE: vàng) bằng scale_fill_manual(), áp dụng `theme_minimal()

Nhận xét

1. Hiệu suất Vốn ROE:
Ngành FMCGROE trung bình cao nhất (~28%), cho thấy khả năng sinh lời trên vốn chủ sở hữu vượt trội.
Theo sau là TECHAUTO (khoảng 22%), trong khi BANK có ROE thấp nhất (~12%), phản ánh hiệu quả sử dụng vốn yếu hơn do đặc thù ngành tài chính.

2. Định giá Log(PE):
Ngành TECHFMCGLog(PE) cao nhất (~3.5), nghĩa là được thị trường định giá cao hơn (P/E cao), thể hiện kỳ vọng tăng trưởng lớn. Ngược lại, AUTOBANKLog(PE) thấp hơn (~2.5), tương ứng với nhóm cổ phiếu giá trị, ít được định giá cao.

Tóm lại

  • Hai ngành FMCGTECH vừa có ROE cao, vừa được định giá cao (Log(PE) lớn) → nhóm tăng trưởng mạnh.

  • Ngành BANKROE thấpLog(PE thấp, thuộc nhóm giá trị ổn định.

  • Kết quả cho thấy thị trường có xu hướng trả giá cao cho các doanh nghiệp có hiệu quả vốn cao và tiềm năng tăng trưởng tốt.

1.3.3.3. Trực quan biến Log(PE) giữa nhóm đầu tư GOOD và BAD

1. ggplot(nyse_final_data, aes(x = investment, y = Log_PE_Winsorized, fill = investment)) +
2.   geom_boxplot(notch = TRUE) +
3.   labs(
4.     title = "Hình 1.3.7: Sự khác biệt của Log(PE) giữa nhóm đầu tư GOOD và BAD",
5.     x = "Kết quả đầu tư",
6.     y = "Log(PE) (Winsorized)"
7.   ) +
8.   scale_fill_manual(values = c("GOOD" = "#28a745", "BAD" = "#dc3545")) +
9.   theme_minimal() +
10.   theme(legend.position = "none", plot.title = element_text(face = "bold", size = 12))

Giải thích kĩ thuật

Phần / Dòng code Giải thích ngắn gọn
Layer 1 (dòng 1) Khởi tạo ggplot(), ánh xạ trục X = nhóm đầu tưtrục Y = Log(PE) (đã Winsorized), tô màu theo investment
Layer 2 (dòng 2) geom_boxplot(notch = TRUE)vẽ biểu đồ hộp
Layer 3 (dòng 3–6) labs() thêm tiêu đề
Layer 4 (dòng 8) scale_fill_manual() để gán màu phân biệt: nhóm GOOD màu xanh lá #28a745, nhóm BAD màu đỏ #dc3545.
Layer 5 (dòng 9–10) áp dụng theme (theme_minimal)

Nhận xét

Lưu ý Đường kẻ dày trong hộp là Trung vị (Median); Rìa trên và dưới của hộp là Q3 và Q1 (phạm vi 50% dữ liệu).

  • Trung vị: Nhóm GOOD có trung vị Log(PE) cao hơn nhẹ so với nhóm BAD (GOOD ≈ 2.74, BAD ≈ 2.69), tuy nhiên có thể nói các giao dịch sinh lời thường tập trung ở cổ phiếu có định giá cao hơn

  • Độ phân tán (IQR): Hộp của nhóm GOOD rộng hơn, phản ánh mức định giá đa dạng hơn – gồm cả cổ phiếu giá trị thấp và cổ phiếu tăng trưởng cao.

  • Đuôi và giá trị ngoại lai: Cả hai nhóm đều có nhiều điểm ngoại lai ở vùng Log(PE) rất cao (≈ 5–6.5).

1.3.3.4. Trực quan kết quả đầu tư theo ngành nghề

1. mosaicplot(sector ~ investment, data = nyse_final_data, 
2.            main = "Hình 1.3.8: Phân bố tỷ lệ kết quả đầu tư theo ngành nghề",
3.            xlab = "Ngành nghề (Sector)",
4.            ylab = "Kết quả đầu tư (Investment)",
5.            color = c("#dc3545", "#28a745"),
6.            las = 2)

Giải thích kĩ thuật

Phần / Dòng code Giải thích ngắn gọn
Dòng 1 Sử dụng mosaicplot() để vẽ biểu đồ khối mối quan hệ giữa (ngành nghề) và (kết quả đầu tư GOOD/BAD).
Dòng 2–4 Thêm tiêu đề (main) và nhãn trục X, Y
Dòng 5 Gán màu sắc cho hai nhóm: BAD (đỏ #dc3545) và GOOD (xanh lá #28a745)
Dòng 6 las = 2 xoay nhãn trục X theo chiều dọc để tránh chồng chữ

Nhận xét

Lưu ý: chiều rộng của mỗi cột (Ngành nghề) tỷ lệ với tổng số lượng giao dịch của ngành đó trong toàn bộ mẫu, chiều cao của mỗi màu biểu thị kết quả(GOOD/BAD).

  • Các ngành RETAIL, TECHBANK có quy mô giao dịch lớn hơn so với các ngành khác. Ngược lại, BANKAUTO có phần màu đỏ (BAD) lớn, cho thấy tỷ lệ giao dịch thua lỗ cao hơn.

  • Nhóm TECHFMCG có phần màu xanh (GOOD) chiếm ưu thế hơn, thể hiện khả năng sinh lời cao hơn trung bình.

  • Nhìn chung, phần lớn các ngành đều có tỷ trọng giao dịch không đồng đều giữa GOOD và BAD.

Phát hiện Chính: Mosaic Plot chứng minh có sự phụ thuộc giữa biến sector và biến investment. Phát hiện này cung cấp cơ sở vững chắc để thực hiện Kiểm định ANOVA, nhằm xác định liệu sự khác biệt về Lợi suất Trung bình giữa các ngành có thực sự có ý nghĩa thống kê hay không.

1.3.4. Trực quan mức độ bền vững ESG và xu hướng thời gian

1.3.4.1. Mức độ bền vững ESG theo ngành nghề

1. ggplot(nyse_final_data, aes(x = sector, y = ESG, fill = sector)) +
2.   geom_boxplot(notch = TRUE) +
3.   labs(
4.     title = "Hình 1.3.9: Mức độ bền vững ESG giữa các ngành nghề",
5.     x = "Ngành nghề",
6.     y = "Xếp hạng ESG"
7.   ) +
8.   theme_minimal() +
9.   theme(legend.position = "none", plot.title = element_text(face = "bold", size = 12))

Giải thích kĩ thuật: kĩ thuật của biểu đồ này tương tự với các kĩ thuật vẽ biểu đồ hộp bên trên.

Nhận xét

  • Nghành AUTO (Median ≈ 29.5)BANK (≈ 26) có xếp hạng ESG cao nhất, phản ánh mức độ tuân thủ bền vững tốt hơn, như đã chứng minh theo bảng thống kê phía trên mục 1.2. Ngược lại ngành RETAIL (≈ 15)TECH (≈ 16) có ESG thấp nhất, có thể do đặc thù chuỗi cung ứng và tác động môi trường.

1.3.4.2 Xu hướng lợi suất theo năm

1. nyse_final_data %>%
2.   group_by(Buy_Year) %>%
3.   summarise(Mean_Return = mean(Real_Return_Winsorized, na.rm = TRUE)) %>%
4.   ggplot(aes(x = Buy_Year, y = Mean_Return, group = 1)) +
5.   geom_line(color = "blue", linewidth = 1) +
6.   geom_point(color = "red", size = 2) +
7.   geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
8.   labs(
9.     title = "Hình 1.3.10: Xu hướng lợi suất thực tế trung bình qua các năm",
10.     x = "Năm mua",
11.     y = "Lợi suất thực tế trung bình (Winsorized)"
12.   ) +
13.   theme_minimal() +
14.   theme(plot.title = element_text(face = "bold", size = 12))

Giải thích kĩ thuật

Phần / Dòng code Giải thích ngắn gọn
dòng 1–3 Nhóm dữ liệu theo Buy_Year, tính lợi suất trung bình bằng summarise(Mean_Return = mean(...))
Layer 1 (dòng 4) Khởi tạo ggplot() với trục X = Buy_Yeartrục Y = Mean_Return
Layer 2 (dòng 5–7) vẽ biểu đồ đường geom_line() vẽ đường xu hướng (màu xanh), geom_point() đánh dấu điểm dữ liệu (màu đỏ), và geom_hline() thêm đường chuẩn ở mức 0 để phân biệt lời/lỗ.
Layer 3 (dòng 8–11) labs() thêm tiêu đề và nhãn
Layer 4 (dòng 13–14) áp dụng theme theme_minimal() và tiêu đề in đậm (plot.title).

Nhận xét

Biểu đồ này thể hiện xu hướng lợi suất thực tế trung bình (đã Winsorized) theo năm giao dịch mua, trong giai đoạn 2013-2018.

1. Pha Tăng trưởng (2013 - 2015): Lợi suất bắt đầu ở mức âm sâu vào năm 2013 (ước tính \(\approx -1.4\)).Sau đó phục hồi vượt mức \(0\) vào năm 2014 (ước tính \(\approx 0.2\)).Đạt đỉnh cao nhất vào năm 2015 (ước tính \(\approx 0.5\)). Điều này phù hợp với giai đoạn phục hồi mạnh mẽ của thị trường chứng khoán Mỹ sau cuộc khủng hoảng tài chính toàn cầu.

2. Pha Suy giảm (2016 - 2017): Lợi suất giảm đáng kể vào năm 2016 (ước tính \(\approx 0.3\)).Đạt đáy của toàn bộ giai đoạn vào năm 2017 (ước tính \(\approx -1.8\)). Mức lợi suất âm sâu này vượt xa cả năm 2013. Có thể các khoản đầu tư ở năm này phải đối diện tiêu cực.

3. Pha Hồi phục Nhẹ (2018):Lợi suất có sự hồi phục nhẹ vào năm 2018 (ước tính \(\approx -1.6\)), nhưng vẫn duy trì ở mức âm sâu.

Tóm lại Biểu đồ chứng minh rằng yếu tố thời gian (năm mua) có ảnh hưởng lớn và mang tính chu kỳ đến lợi suất. Lợi suất trung bình không phải là một đường thẳng mà tuân theo một mô hình lên xuống rõ rệt.

1.3.4.3 Xu hướng ROE và ROA theo năm

1. nyse_final_data %>%
2.   group_by(Buy_Year) %>%
3.   summarise(
4.     Mean_ROE = mean(ROE_Winsorized, na.rm = TRUE),
5.     Mean_ROA = mean(ROA, na.rm = TRUE)
6.   ) %>%
7.   pivot_longer(cols = starts_with("Mean"), names_to = "Indicator", values_to = "Mean_Value") %>%
8.   ggplot(aes(x = Buy_Year, y = Mean_Value, fill = Indicator)) +
9.   geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.7) +
10.   labs(
11.     title = "Hình 1.3.11: Trung bình ROE và ROA theo năm giao dịch",
12.     x = "Năm mua",
13.     y = "Giá trị trung bình",
14.     fill = "Chỉ số"
15.   ) +
16.   scale_fill_manual(values = c("Mean_ROA" = "#6c757d", "Mean_ROE" = "#20c997")) +
17.   theme_minimal() +
18.   theme(plot.title = element_text(face = "bold", size = 12))

Giải thích kĩ thuật

Phần / Dòng code Giải thích ngắn gọn
Tiền xử lý (dòng 2–7) Nhóm dữ liệu theo Buy_Year, tính trung bình của ROE_WinsorizedROA
Layer 1 (dòng 8) Khởi tạo ggplot() với trục X = Buy_Year, Y = Mean_Value
Layer 2 (dòng 9) geom_bar(stat = "identity") để vẽ biểu đồ cột, với position_dodge() giúp đặt hai cột cạnh nhau để dễ so sánh.
Layer 3 (dòng 10–14) labs() để thêm tiêu đề, nhãn vã chú thích
Layer 4 (dòng 16) scale_fill_manual() gán màu riêng cho từng chỉ số (ROA: xám, ROE: xanh ngọc)
Layer 5 (dòng 17–18) áp dụng theme_minimal() và định dạng tiêu đề in đậm (plot.title).

Nhận xét

1. Mối quan hệ Nội tại giữa ROE và ROA: Trong tất cả các năm từ 2013 đến 2018, cột Mean_ROE (Màu xanh, ước tính từ \(17.5\) đến \(21\)) luôn cao hơn đáng kể so với cột Mean_ROA (Màu xám, ước tính từ \(6\) đến \(7.5\)).Khoảng cách lớn giữa ROE và ROA chứng minh rằng trong bộ dữ liệu này Đòn bẩy Tài chính để khuếch đại lợi nhuận trên vốn chủ sở hữu (\(\text{ROE} = \text{ROA} \times \text{Leverage}\)).

2. Phân tích Xu hướng Hiệu suất Qua các Năm: Giá trị ROAtăng trưởng chậm nhưng ổn định, từ mức thấp nhất năm 2013 (ước tính \(\approx 6.5\)) lên mức cao nhất vào năm 2018 (ước tính \(\approx 7.5\)). Tương tự ROE tăng trưởng từ mức thấp nhất năm 2013 (ước tính \(\approx 17.5\)) lên mức cao nhất năm 2018 (ước tính \(\approx 21.5\)).

Phát hiện chính: Mâu thuẫn với lợi suất (Hình 1.3.10). Cụ thể năm 2015 có ROE/ROA chỉ ở mức trung bình nhưng lại đạt đỉnh lợi suất thực tế trung bình, trong khi 2017 có ROE/ROA cao gần đỉnh thì lại rơi vào đáy lợi suất. Điều này gợi ý rằng hiệu suất tài chính không tỷ lệ thuận với lợi suất, có thể lợi suất bị chi phối bởi các yếu tố bên ngoài khác.

1.3.5. Trực quan phân bố và sự tương phản

1.3.5.1. Trực quan Log(PE) theo Kết quả đầu tư (GOOD/BAD)

1. ggplot(nyse_final_data, aes(x = Log_PE_Winsorized, fill = investment)) +
2.   geom_density(alpha = 0.6) +
3.   labs(
4.     title = "Hình 1.3.12: Phân bố Log(PE) theo Kết quả đầu tư (GOOD/BAD)",
5.     x = "Log(PE) (Winsorized)",
6.     y = "Mật độ",
7.     fill = "Kết quả"
8.   ) +
9.   scale_fill_manual(values = c("GOOD" = "#28a745", "BAD" = "#dc3545")) +
10.   theme_minimal() +
11.   theme(plot.title = element_text(face = "bold", size = 12))

Nhận xét: Biểu đồ cho thấy hai phân bố (Đỏ - BAD, Xanh lá - GOOD) chồng lấn lên nhau rất nhiều, mật độ phân bố của nhóm GOOD (Xanh lá) lại tập trung và cao hơn ở vùng Log(PE) cao (khoảng từ \(2.8\) đến \(3.5\) và đuôi phải sau \(4.0\)). Ngược lại, mật độ nhóm BAD (Đỏ) lại chiếm ưu thế ở vùng Log(PE) thấp hơn (khoảng \(2.5\) đến \(2.8\)).Điều này trực quan hóa kết luận từ Bảng 1.2.6: Các giao dịch thành công (GOOD) có xu hướng được thực hiện ở mức định giá (P/E) cao hơn một chút.

1.3.5.2. Trực quan ROE theo Kết quả đầu tư (GOOD/BAD)

1. ggplot(nyse_final_data, aes(x = ROE_Winsorized, fill = investment)) +
2.   geom_density(alpha = 0.6) +
3.   labs(
4.     title = "Hình 1.3.13: Phân bố ROE theo kết quả đầu tư (GOOD/BAD)",
5.     x = "ROE (Winsorized)",
6.     y = "Mật độ",
7.     fill = "Kết quả"
8.   ) +
9.   scale_fill_manual(values = c("GOOD" = "#28a745", "BAD" = "#dc3545")) +
10.   theme_minimal() +
11.   theme(plot.title = element_text(face = "bold", size = 12))

Nhận xét: Nhóm GOOD (Xanh lá) có mật độ cao nhất tập trung ở vùng ROE thấp (khoảng \(10\%\) đến \(18\%\)). Nhóm BAD (Đỏ) lại chiếm ưu thế và có mật độ cao hơn ở vùng ROE cao (khoảng \(25\%\) đến \(35\%\)). Biểu đồ này là sự trực quan hóa mạnh mẽ nhất cho Nghịch lý ROE đã thấy ở Bảng 1.2.3. Mức ROE cao (hiệu suất hiện tại tốt) lại không dẫn đến lợi suất cao. Điều này củng cố luận điểm rằng các công ty có ROE cao đã bị định giá quá cao tại thời điểm giao dịch, khiến lợi suất thực tế của nhà đầu tư bị giảm xuống (rơi vào nhóm BAD).

Nhận xét kĩ thuật hai mục 1.3.5.1 và 1.3.5.2

Phần / Dòng code Giải thích ngắn gọn
Layer 1 (dòng 1) Khởi tạo ggplot() với dữ liệu nyse_final_data, ánh xạ theo từng cặp biến
Layer 2 (dòng 2) geom_density(alpha = 0.6) vẽ biểu đồ mật độ phân bố với mức trong suốt 0.6 để thấy rõ phần chồng lấn giữa hai phân bố
Layer 3 (dòng 3–7) labs() thêm tiêu đề và nhãn
Layer 4 (dòng 9) scale_fill_manual() găns màu ở những nhóm biến riêng biệt
Layer 5 (dòng 10–11) Áp dụng **theme_minimal()

1.3.5.3. Trực quan kết quả đầu tư theo năm

1. yearly_investment_ratio <- nyse_final_data %>%
2.   group_by(Buy_Year) %>%
3.   count(investment) %>%
4.   mutate(Proportion = n / sum(n))
5. ggplot(yearly_investment_ratio, aes(x = Buy_Year, y = Proportion, fill = investment)) +
6.   geom_bar(stat = "identity", position = "stack") +
7.   labs(
8.     title = "Hình 1.3.14: Kết quả đầu tư (GOOD/BAD) theo năm",
9.     x = "Năm mua",
10.     y = "Tỷ lệ phần trăm",
11.     fill = "Kết quả"
12.   ) +
13.   scale_fill_manual(values = c("GOOD" = "#28a745", "BAD" = "#dc3545")) +
14.   scale_y_continuous(labels = scales::percent) +
15.   theme_minimal() +
16.   theme(plot.title = element_text(face = "bold", size = 12))

Nhận xét kĩ thuật

Phần / Dòng code Giải thích ngắn gọn
Tiền xử lý (dòng 1–4) Sử dụng các hàm group_by()count() để nhóm dữ liệu theo Buy_Yearinvestment, sau đó tính tỷ lệ phần trăm (Proportion = n / sum(n)) trong từng năm bằng mutate().
Layer 1 (dòng 5) ggplot() và gắn giá trị các trục
Layer 2 (dòng 6) Dùng geom_bar(stat = "identity", position = "stack")để **vẽ biểu đồ cột chồng
Layer 3 (dòng 7–11) Hàm labs() thêm tiêu đề, nhãn trục và chú thích (legend)
Layer 4 (dòng 13) Hàm scale_fill_manual()** gán màu cho hai nhóm: GOOD = xanh lá (#28a745), BAD = đỏ (#dc3545)
Layer 5 (dòng 14) scale_y_continuous(labels = scales::percent) để hiển thị trục Y dưới dạng phần trăm (%)
Layer 6 (dòng 15–16) Áp dụng (theme_minimal())

Nhận xét: Năm 2016 có tỷ lệ GOOD cao nhất (ước tính \(\approx 70\%\)). Đây là năm có lợi suất trung bình dương cao. Năm 2017 và 2018 có tỷ lệ BAD cao nhất (ước tính \(\approx 95\%\)). Điều này đồng bộ với hình 1.3.10, từ đó có thể thấy tính thời vụ (năm mua) là một yếu tố rủi ro hệ thống cực kỳ mạnh mẽ.

1.3.5.4. Trực quan mối quan hệ Log(PE) và ROE

1. ggplot(nyse_final_data, aes(x = Log_PE_Winsorized, y = ROE_Winsorized)) +
2.   geom_point(alpha = 0.05, color = "#007bff") +
3.   geom_smooth(method = "lm", color = "red", se = FALSE) + # Dùng lm vì cor là tuyến tính
4.   labs(
5.     title = "Hình 1.3.15: Mối quan hệ giữa định giá (Log(PE)) và hiệu suất (ROE)",
6.     x = "Log(PE) (Winsorized)",
7.     y = "ROE (Winsorized)"
8.   ) +
9.   theme_minimal() +
10.   theme(plot.title = element_text(face = "bold", size = 12))

Nhận xét kĩ thuật

Phần / Dòng code Giải thích ngắn gọn
Layer 1 (dòng 1) Khởi tạo ggplot() với dữ liệu nyse_final_data, ánh xạ trục X = Log_PE_Winsorizedtrục Y = ROE_Winsorized
Layer 2 (dòng 2) geom_point(alpha = 0.05, color = "#007bff") để vẽ biểu đồ tán xạ, alpha = 0.05 giúp giảm độ đậm màu khi dữ liệu dày, gắn quan sát là xanh xanh #007bff
Layer 3 (dòng 3) geom_smooth(method = "lm", color = "red", se = FALSE) để vẽ đường hồi quy tuyến tính (màu đỏ),se = FALSE tắt hiển thị dải tin cậy.
Layer 4 (dòng 4–7) labs()thêm tiêu đề và nhãn
Layer 5 (dòng 9–10) Áp dụng theme_minimal() như các biểu đồ trên

Nhận xét: Sự phân tán rộng của các điểm (Dữ liệu không tập trung gần đường hồi quy) khẳng định mối quan hệ tuyến tính này là yếu. Điều này cho thấy rằng mối quan hệ nghịch nhẹ giữa Log(PE) và ROE — các công ty có ROE cao thường có Log(PE) thấp hơn, trong khi những công ty có Log(PE) cao (được kỳ vọng tăng trưởng mạnh) lại có ROE thấp hơn.

1.4 PHÂN TÍCH SỰ THỐNG KÊ KHÁC BIỆT GIỮA CÁC NHÓM

1.4.1. Kiểm định sự khác biệt thống kê giữa các nhóm

1.4.1.1. Kiểm định lợi suất giữa nhóm GOOD và BAD bằng T - test

Mục tiêu là kiểm định sự khác biệt về Lợi suất thực tế Trung bình (Real_Return_Winsorized) giữa hai nhóm investment (GOOD/BAD).

  • Giả thuyết \(H_0\): \(\mu_{\text{GOOD}} = \mu_{\text{BAD}}\) (Lợi suất trung bình không khác biệt).
  • Giả thuyết \(H_a\): \(\mu_{\text{GOOD}} \ne \mu_{\text{BAD}}\) (Lợi suất trung bình có khác biệt).

Cần kiểm tra Giả định Phương sai Đồng nhất (Levene's Test) trước khi thực hiện \(t\)-test.

Kiểm định phương sai lợi suất bằng bartlett

1. levene_test_result <- stats::bartlett.test(Real_Return_Winsorized ~ investment, data = nyse_final_data)
2. print(broom::tidy(levene_test_result))
# A tibble: 1 × 4
  statistic p.value parameter method                                   
      <dbl>   <dbl>     <dbl> <chr>                                    
1   199571.       0         1 Bartlett test of homogeneity of variances

Nhận xét:

statistic p.value
\(\approx 199,571\) \(\approx 0\)

Giá trị p - value = 0 < 0.05 nên giả thuyết \(H_0\) (Phương sai đồng nhất) bị bác bỏ. Điều này cho thấy phương sai lợi suất thực tế giữa nhóm GOOD và BAD là **không đồng nhất

Kiểm định T- test cho lợi suất

1. t_test_result <- t.test(Real_Return_Winsorized ~ investment, data = nyse_final_data, var.equal = FALSE)
2. print(broom::tidy(t_test_result))
# A tibble: 1 × 10
  estimate estimate1 estimate2 statistic p.value parameter conf.low conf.high
     <dbl>     <dbl>     <dbl>     <dbl>   <dbl>     <dbl>    <dbl>     <dbl>
1    -1.44     -1.02     0.426     -678.       0   280623.    -1.45     -1.44
# ℹ 2 more variables: method <chr>, alternative <chr>

Nhận xét:

estimate (Difference) estimate1 (\(\mu_{\text{BAD}}\)) estimate2 (\(\mu_{\text{GOOD}}\)) statistic (\(t\)) p.value conf.low conf.high
-1.44 -1.02 0.426 -678 \(\approx 0\) -1.45 -1.44

Lợi suất trung bình của nhóm \(\text{BAD}\) (\(\mu_{\text{BAD}}\)) là \(-1.02\). Lợi suất trung bình của nhóm \(\text{GOOD}\) (\(\mu_{\text{GOOD}}\)) là \(0.426\). Cùng với đó là ự khác biệt (\(\mu_{\text{BAD}} - \mu_{\text{GOOD}}\)) là \(-1.44\), giá trị p - value ~ 0 nên kết luận rằng có sự khác biệt giữa lợi suất thực tế trung bình của nhóm đầu tư GOOD và BAD.

1.4.1.2. Kiểm định ANOVA và phân tích Post-hoc theo ngành

Mục tiêu là kiểm định sự khác biệt về Lợi suất thực tế Trung bình giữa các nhóm ngành (sector).

  • Giả thuyết \(H_0\): \(\mu_{\text{TECH}} = \mu_{\text{AUTO}} = \dots\) (Lợi suất trung bình giữa các ngành không khác biệt).

Kiểm định phương sai lợi suất giữa các ngành

1. current_scipen <- options(scipen = 0)
2. levene_test_sector <- stats::bartlett.test(Real_Return_Winsorized ~ sector, data = nyse_final_data)
3. broom::tidy(levene_test_sector) %>%
4.     mutate(
5.         statistic = round(statistic, 0),
6.         p.value = format(p.value, scientific = TRUE, digits = 3)
7.     ) %>%
8.     print()
# A tibble: 1 × 4
  statistic p.value   parameter method                                   
      <dbl> <chr>         <dbl> <chr>                                    
1       576 2.61e-123         4 Bartlett test of homogeneity of variances

*Nhận xét kĩ thuật**

Phần / Dòng code Giải thích ngắn gọn
Dòng 1 options(scipen = 0)thiết lạp số chế dộ khoa học
Dòng 2 Thực hiện kiểm định Bartlett (bartlett.test())
Dòng 3 Dùng broom::tidy() để chuyển kết quả kiểm định sang dạng bảng dữ liệu
Dòng 4–6 Sử dụng mutate() để làm tròn (statistic)** và định dạng giá trị p-value theo dạng khoa học với format(..., scientific = TRUE))

Nhận xét

statistic p.value
\(576\) \(\approx 0\)

Với \(p\)-value xấp xỉ \(0\), giả thuyết \(H_0\) (Phương sai lợi suất đồng nhất giữa các ngành) bị bác bỏ mạnh mẽ.

Kiểm định ANOVA

1. anova_result <- aov(Real_Return_Winsorized ~ sector, data = nyse_final_data)
2. broom::tidy(anova_result) %>%
3.     mutate(
4.         sumsq = round(sumsq, 0),
5.         meansq = round(meansq, 2),
6.         statistic = round(statistic, 0),
7.         p.value = format(p.value, scientific = TRUE, digits = 3)
8.     ) %>%
9.     knitr::kable(caption = "Kết quả kiểm định ANOVA (Lợi suất ~ sector)")
Kết quả kiểm định ANOVA (Lợi suất ~ sector)
term df sumsq meansq statistic p.value
sector 4 710 177.43 162 6.29e-139
Residuals 356344 389936 1.09 NA NA
1. options(scipen = current_scipen$scipen)

Nhận xét: Giá trị \(F\) quan sát được là \(\approx 162\). Giá trị \(p\)-value (\(\approx 0\) thấp hơn ngưỡng anphal nên có thể kết luận rằng có tồn tại sự khác biệt lợi suất thực tế trung bình giữa ít nhất một cặp ngành nghề. Điều này chứng minh rằng ngành nghề (sector) là một yếu tố quyết định có tính hệ thống đối với hiệu suất đầu tư, xác nhận những quan sát đã thấy ở Hình 3.3.1 và Bảng 2.3.1 (ví dụ: TECH vs BANK).

1.4.1.3 Phân tích sự khác biệt giữa các nhóm theo Tukey’s HSD

Phân tích Post-hoc Tukey’s HSD được thực hiện sau khi kiểm định ANOVA cho kết quả có ý nghĩa thống kê (p < 0.05). Mục tiêu của bước này là xác định cụ thể cặp nhóm (ngành) nào khác biệt đáng kể về giá trị trung bình của lợi suất thực tế.

Kết quả của Tukey’s HSD cho biết:

  • Nếu p-value < 0.05 → hai ngành có sự khác biệt có ý nghĩa thống kê về lợi suất trung bình.
  • Nếu p-value ≥ 0.05 → hai ngành không có sự khác biệt rõ rệt.

Phân tích này giúp làm rõ kết quả của ANOVA, chỉ ra nhóm ngành nào có hiệu suất đầu tư cao hơn hoặc thấp hơn so với các nhóm còn lại, đồng thời đảm bảo độ tin cậy bằng cách kiểm soát sai số thống kê khi so sánh nhiều cặp giá trị.

1. if (exists("anova_result")) {
2.   tukey_hsd_result <- TukeyHSD(anova_result)
3.   print(broom::tidy(tukey_hsd_result))
4. }
# A tibble: 10 × 7
   term   contrast    null.value estimate conf.low conf.high adj.p.value
   <chr>  <chr>            <dbl>    <dbl>    <dbl>     <dbl>       <dbl>
 1 sector BANK-AUTO            0  -0.0859 -0.102     -0.0696    0       
 2 sector FMCG-AUTO            0  -0.0732 -0.0910    -0.0553    1.33e-14
 3 sector RETAIL-AUTO          0  -0.0377 -0.0532    -0.0221    3.81e-10
 4 sector TECH-AUTO            0   0.0316  0.0160     0.0473    3.51e- 7
 5 sector FMCG-BANK            0   0.0127 -0.00392    0.0294    2.26e- 1
 6 sector RETAIL-BANK          0   0.0482  0.0341     0.0624    5.24e-14
 7 sector TECH-BANK            0   0.118   0.103      0.132     0       
 8 sector RETAIL-FMCG          0   0.0355  0.0196     0.0514    1.19e- 8
 9 sector TECH-FMCG            0   0.105   0.0888     0.121     0       
10 sector TECH-RETAIL          0   0.0693  0.0559     0.0827    0       

Giải thích kĩ thuật

Phần / Dòng code Giải thích chi tiết
Dòng 1 Kiểm tra anova_result có tồn tại chưa . Nếu có, code bên trong khối if sẽ được thực thi
Dòng 2 Thực hiện kiểm định hậu định Tukey HSD trên kết quả ANOVA để
Dòng 3 Dùng broom::tidy()để chuyển kết quả (data frame),
Dòng 4 In bảng kết

Nhận xét

Contrast estimate (Difference) adj.p.value Ý nghĩa (Difference)
TECH - BANK \(0.118\) \(\approx 0\) TECH > BANK (Sự khác biệt lớn nhất)
TECH - FMCG \(0.1048\) \(\approx 0\) TECH > FMCG
TECH - RETAIL \(0.0693\) \(\approx 0\) TECH > RETAIL
BANK - AUTO \(-0.0859\) \(\approx 0\) BANK < AUTO
FMCG - AUTO \(-0.0732\) \(\approx 0\) FMCG < AUTO
RETAIL - BANK \(0.0482\) \(\approx 0\) RETAIL > BANK

Kết luận: Ngoại trừ cặp FMCG - BANK (adj.p.value \(\approx 0.226\)), tất cả 9/10 cặp ngành đều cho thấy sự khác biệt có ý nghĩa thống kê về Lợi suất Trung bình (\(p < 0.001\)). Điều này xác nhận lại sự khác biệt đã thấy trong Violin Plot (Hình 3.3.1). Đồng thời qua hệ số ước ượng cũng có thể thấy ngành TECH có hiệu suất sinh lời cao nhất, còn BANK là ngành yếu nhất về lợi suất đầu tư.

Thứ hạng Lợi suất Trung bình (Dựa trên Tukey’s HSD):

\[\text{BANK} \approx \text{FMCG} < \text{RETAIL} \approx \text{AUTO} < \text{TECH}\]

1.4.2. Kết luận tổng thể phân tích khác biệt

Luận điểm I: Sự Ngắt Kết Nối Giữa Hiệu suất Cơ bản và Lợi suất Thực tế

Bằng chứng Định lượng (mục 1.2, 1.4) cho thấy các chỉ số tài chính như ROE, Log_PE, Leverage, và ESG hầu như không có tương quan với lợi suất thực tế (|ρ| < 0.1).

⇒ Điều này ủng hộ Giả thuyết Thị trường Hiệu quả (EMH - Weak Form): lợi suất không thể dự đoán dựa trên thông tin công khai, mà chủ yếu chịu tác động từ rủi ro hệ thống và biến động thị trường.

Luận điểm II: Nghịch lý ROE - Bằng chứng về Định giá Quá Cao

Bằng chứng Định lượng (1.2, 1.3) cho thấy các cổ phiếu có ROE cao lại cho lợi suất đầu tư thấp hơn, vì đã bị định giá quá cao tại thời điểm mua.

⇒ Hiệu suất hoạt động tốt không đồng nghĩa với lợi nhuận cao nếu giá cổ phiếu đã phản ánh toàn bộ kỳ vọng thị trường.

Luận điểm III: Sức mạnh Tuyệt đối của Yếu tố Hệ thống (Ngành và Thời gian)

Kết quả ANOVA khẳng định yếu tố ngành có ảnh hưởng đáng kể đến lợi suất (p ≈ 0).Ngành TECH vượt trội nhất, trong khi BANK có lợi suất thấp nhất (Bằng chứng Định lượng (1.3, 1.4): *)

Yếu tố thời gian cũng quan trọng: năm 2017 ghi nhận tỷ lệ giao dịch thua lỗ (BAD) gần 95%, dù ROE/ROA tăng ( Hình 1.3.14 là bằng chứng định lượng)

⇒ Điều này cho thấy yếu tố ngành và chu kỳ thị trường có sức ảnh hưởng lớn hơn nhiều so với các chỉ số tài chính nội tại.

1.5. KẾT LUẬN

1.5.1. Tóm tắt kết quả phân tích chính

  1. Chất lượng Dữ liệu: Bộ dữ liệu NYSE có chất lượng cao (Không NA, không trùng lặp), nhưng các biến lợi suất và đòn bẩy cực kỳ lệch (Skewness \(> 14\) cho Đòn bẩy), buộc phải sử dụng Winsorizing và diễn giải bằng Trung vị.

  2. Mối quan hệ: Các chỉ số tài chính/ESG có mối tương quan yếu không đáng kể (\(|\rho| \le 0.09\)) với lợi suất thực tế. ROE và ESG có mối tương quan âm trung bình (\(\rho = -0.427\)), cho thấy sự đánh đổi giữa hiệu suất vốn và tuân thủ ESG.

  3. Phân Cực: Lợi suất được phân cực thành hai nhóm: \(\text{BAD}\) (Trung bình \(\approx -1.02\)) và \(\text{GOOD}\) (Trung bình \(\approx 0.426\)), khác biệt nhau có ý nghĩa thống kê (\(p \approx 0\)).

  4. Tác động của Nhóm:

Ngành nghề: Có sự khác biệt có ý nghĩa thống kê về Lợi suất Trung bình giữa các ngành (ANOVA \(p \approx 0\)). TECH là ngành vượt trội, BANK là ngành có lợi suất thấp nhất.

Nghịch lý Hiệu suất: Các khoản đầu tư thất bại (\(\text{BAD}\)) có xu hướng được thực hiện vào các công ty có ROE cao hơnĐòn bẩy cao hơn, chứng minh rằng các cổ phiếu hiệu suất cao có thể đã bị định giá quá cao, biến rủi ro thành thua lỗ.

  1. Tính Thời vụ: Tỷ lệ giao dịch thua lỗ (BAD) bị chi phối bởi năm mua (Ví dụ: \(95\%\) giao dịch thất bại trong năm 2017), cho thấy Rủi ro Hệ thống là yếu tố quyết định hàng đầu.

1.5.2. Hạn chế

  1. Hạn chế Dữ liệu:

    Bộ dữ liệu được sử dụng trong nghiên cứu là giả lập ngẫu nhiên (random investments), nên có thể chưa phản ánh hoàn toàn hành vi và chiến lược đầu tư thực tế của các nhà đầu tư chuyên nghiệp.

    Ngoài ra, dữ liệu chỉ kéo dài đến năm 2018, nên chưa bao gồm các biến động thị trường lớn trong giai đoạn sau (như khủng hoảng COVID-19 hoặc xu hướng ESG tăng mạnh sau 2020).

    Điều này có thể ảnh hưởng đến khả năng khái quát hóa kết quả cho bối cảnh thị trường hiện tại.

  2. Hạn chế Phương pháp:

    Phân tích chỉ dừng ở thống kê mô tả, tương quan và kiểm định so sánh nhóm (ANOVA, Tukey HSD), nên mới dừng ở mức phát hiện sự khác biệt chứ chưa đi sâu vào đo lường mức độ ảnh hưởng định lượng của từng biến tài chính (ví dụ: thông qua mô hình hồi quy).
    Do đó, nghiên cứu chưa xác định được mối quan hệ nhân – quả giữa các chỉ số tài chính (như ROE, Log_PE, Leverage_Ratio, ESG) và lợi suất đầu tư thực tế.

  3. Hạn chế về Phạm vi và Tổng quát hóa:

    Mẫu nghiên cứu chỉ bao gồm một số nhóm ngành tiêu biểu (AUTO, BANK, FMCG, RETAIL, TECH) niêm yết trên thị trường NYSE, nên không đại diện cho toàn bộ ngành nghề hoặc các thị trường khác.

    Kết quả vì thế mang tính tham khảo và cần được kiểm chứng thêm bằng các nghiên cứu mở rộng quy mô dữ liệu và thời gian, hoặc so sánh giữa các sàn khác nhau (NASDAQ, LSE, v.v.) để tăng tính khái quát.

1.5.3. Đề xuất

Từ kết quả hiện có, có thể rút ra một số hướng đề xuất sau:

  1. Mở rộng mô hình nghiên cứu:

    • Áp dụng mô hình hồi quy hoặc panel data nhằm đo lường mức độ tác động của các biến tài chính (ROE, ROA, FL, CFO/LNST) đến lợi suất đầu tư (Real_Return).
  2. Ứng dụng cho quản trị doanh nghiệp:

    • Theo dõi CFO/LNST để đánh giá chất lượng lợi nhuận, tập trung quản lý dòng tiền thực.
    • Tối ưu cấu trúc vốn (D/E, FL) để cân bằng giữa rủi ro và lợi nhuận.
  3. Hàm ý cho nhà đầu tư:

    • Sử dụng ROE, ROA, FL và CFO/LNST làm bộ tiêu chí sàng lọc cổ phiếu chất lượng.
    • Kết hợp thêm dữ liệu giá cổ phiếu, Market Cap, ESG để phân tích và dự báo hiệu suất đầu tư.

Tóm lại, bộ dữ liệu này là nền tảng tốt để phát triển các mô hình định lượng, giúp đánh giá hiệu quả tài chính và chiến lược đầu tư trong ngành năng lượng.

PHẦN 2. PHÂN TÍCH DỮ LIỆU TÀI CHÍNH VÀ THỊ TRƯỜNG CỦA MÃ CHỨNG KHOÁN GAS (2014-2024)

2.1 GIỚI THIỆU BỘ DỮ LIỆU

2.1.1. Mục tiêu phân tích

Mục tiêu chính của toàn bộ Phân tích Dữ liệu Tài chính và Thị trường của mã chứng khoán GAS là cung cấp một cái nhìn toàn diện và định lượng về Sức khỏe tài chính, Hiệu suất hoạt độngPhản ứng của thị trường đối với Tổng Công ty Khí Việt Nam (GAS).

Cụ thể, đối với Nhóm biến Hiệu suất & Tăng trưởng (Nhóm 1), mục tiêu tập trung vào:

  1. Đánh giá năng lực sinh lời: Phân tích nguồn gốc của khả năng sinh lời (ROE, ROA), xác định vai trò của Biên lợi nhuận, Vòng quay tài sản và Đòn bẩy tài chính thông qua mô hình Du Pont.

  2. Đo lường tính chu kỳ và bền vững: Phân tích tốc độ tăng trưởng và sự biến động (YoY, Rolling Correlation) của Doanh thu, Lợi nhuận và EPS để đánh giá mức độ ổn định của hiệu suất hoạt động qua các chu kỳ kinh tế và giá dầu/khí.

  3. Xác định mối liên hệ cơ bản: Kiểm định mối quan hệ giữa các chỉ số hiệu suất nội tại (như EPS) và Giá trị thị trường (Giá cổ phiếu) để hiểu rõ cơ sở định giá của nhà đầu tư.

2.1.2. Nguồn dữ liệu

Bộ dữ liệu được xây dựng từ các nguồn thông tin công khai và chính thức của Tổng Công ty Khí Việt Nam (GAS).

  • Dữ liệu tài chính: Được trích xuất từ các Báo cáo tài chính hợp nhất đã được kiểm toán hàng năm của GAS, bao gồm Bảng Cân đối Kế toán, Bảng Kết quả hoạt động kinh doanh và Bảng Lưu chuyển tiền tệ, tại ngày chốt sổ 31/12 hàng năm.

  • Dữ liệu thị trường: Thu thập từ các nguồn dữ liệu thị trường uy tín (ví dụ: Sở Giao dịch Chứng khoán, Bloomberg) về giá đóng cửa và số lượng cổ phiếu lưu hành tại ngày 31/12 hàng năm.

2.1.3. Phạm vi dữ liệu

  • Đơn vị quan sát: Dữ liệu được tổng hợp theo năm.

  • Phạm vi thời gian: Giai đoạn 11 năm, từ 2014 đến 2024.

Bộ dữ liệu tổng thể (GAS_data_final) bao gồm 19 biến, được phân loại thành 3 nhóm chức năng chính như sau.

(A). Biến Định danh

Tên Biến Mô tả Loại dữ liệu
Nam Năm quan sát (2014-2024) Numeric

(B). Biến Tài chính cơ bản và Thị trường

Tên Biến Mô tả Nguồn gốc
DoanhThu Doanh thu thuần hàng năm Bảng KQKD
LoiNhuanSauThue Lợi nhuận sau thuế của cổ đông công ty mẹ Bảng KQKD
TongTaiSan Tổng cộng tài sản cuối kỳ Bảng CĐKT
VonChuSoHuu Tổng vốn chủ sở hữu cuối kỳ Bảng CĐKT
NoPhaiTra Tổng nợ phải trả cuối kỳ Bảng CĐKT
CFO Dòng tiền thuần từ hoạt động kinh doanh Bảng LCTT
EPS Lợi nhuận trên mỗi cổ phiếu Bảng KQKD
Gia_DongCua_CuoiNam Giá đóng cửa cổ phiếu GAS tại 31/12 Dữ liệu thị trường
SL_CoPhieu_LuuHanh Số lượng cổ phiếu đang lưu hành Dữ liệu thị trường

(C). Biến Phái sinh

Các biến này được tính toán để phục vụ trực tiếp cho việc đánh giá hiệu suất, cấu trúc vốn và định giá.

Tên Biến Công thức Tính toán Mục đích Phân tích
ROE_Nam \(\text{LNST} / \text{VCSH}\) Tỷ suất sinh lời cho cổ đông
ROA_Nam \(\text{LNST} / \text{Tổng Tài sản}\) Tỷ suất sinh lời từ tài sản
BienLoiNhuanRong_Nam \(\text{LNST} / \text{DoanhThu}\) Hiệu quả kiểm soát chi phí
TySoNo_Tren_VCSH \(\text{Nợ Phải Trả} / \text{VCSH}\) Thước đo đòn bẩy tài chính
DoanhThu_TangTruong_YoY \(\%\Delta \text{Doanh Thu}\) Tốc độ tăng trưởng quy mô
LoiNhuan_TangTruong_YoY \(\%\Delta \text{LNST}\) Tốc độ tăng trưởng lợi nhuận
TyLe_CFO_Tren_LNST \(\text{CFO} / \text{LNST}\) Chất lượng lợi nhuận (khả năng chuyển thành tiền mặt)
VonHoa_TyVND \(\text{Giá Đóng Cửa} \times \text{SL Cổ Phiếu}\) Quy mô thị trường
P_E_CuoiNam \(\text{Giá Đóng Cửa} / \text{EPS}\) Hệ số định giá

Lưu ý: Mục 2.3 sẽ tập trung khai thác các biến trong Nhóm B và C có liên quan đến Hiệu suất & Tăng trưởng.

2.2 CẤU TRÚC DỮ LIỆU

2.2.1. Đọc dữ liệu và kiểm tra cấu trúc

1. library(readxl)
2. library(dplyr)
3. library(stringr)
4. bctc_path <- "C:/Users/Admin/Documents/NGÔN NGỮ R/PV GAS.xlsx"
5. bckt_raw <- read_excel(bctc_path, sheet = 1)  # Bảng Cân đối kế toán
6. kqkd_raw <- read_excel(bctc_path, sheet = 2)  # Bảng Kết quả kinh doanh
7. if ("TÀI SẢN" %in% names(bckt_raw))  bckt_raw <- bckt_raw %>% rename(ChiTieu = `TÀI SẢN`)
8. if ("CHỈ TIÊU" %in% names(kqkd_raw)) kqkd_raw <- kqkd_raw %>% rename(ChiTieu = `CHỈ TIÊU`)
9. normalize_vn <- function(x) {
10.   x %>%
11.     stringi::stri_trans_general("Latin-ASCII") %>%
12.     stringr::str_to_lower() %>%
13.     stringr::str_squish()}
14. print("Đã chuẩn hóa tên cột thành 'ChiTieu'.")
[1] "Đã chuẩn hóa tên cột thành 'ChiTieu'."

Gọi các thư viện cần thiết:
readxl (đọc dữ liệu từ file Excel) ,dplyr(thao tác, làm sạch dữ liệu)
stringr(xử lý văn bản dữ liệu ). sau khi đưa vào ta thu được hai bảng dữ liệu đã được làm sạch và chuẩn hoá tên cột, cụ thể “TÀI SẢN”, “CHỈ TIÊU” đã được chuyển thành ChiTieu

2.2.2. Làm sạch dữ liệu và chuẩn hóa định dạng

1. library(dplyr); library(stringr); library(lubridate); library(tidyr)
2. year_cols_names <- names(kqkd_raw)[str_detect(names(kqkd_raw), "^\\d{2}/\\d{2}/\\d{4}$")]
3. nam_vec <- as.numeric(str_sub(year_cols_names, -4)) # 2014, 2015, ...
4. extract_row_data <- function(df, chi_tieu_patterns, scale_factor = 1e9) {
5.   df <- df %>% mutate(ChiTieu_norm = normalize_vn(ChiTieu))
6.   date_cols <- names(df)[stringr::str_detect(names(df), "^\\d{2}/\\d{2}/\\d{4}$")]
7.   found <- NULL
8.   for (pat in chi_tieu_patterns) {
9.     pat_norm <- normalize_vn(pat)
10.     cand <- df %>% dplyr::filter(stringr::str_detect(ChiTieu_norm, pat_norm))
11.     if (nrow(cand) >= 1) { found <- cand; break }
12.   }
13. 
14.   if (is.null(found)) {
15.     warning(sprintf("Không tìm thấy chỉ tiêu: %s", paste(chi_tieu_patterns, collapse = " | ")))
16.     return(rep(NA_real_, length(nam_vec)))
17.   }
18.   if (nrow(found) > 1) {
19.     warning(sprintf("Có >1 dòng khớp: %s. Lấy dòng đầu tiên.", paste(chi_tieu_patterns, collapse = " | ")))
20.     found <- found %>% dplyr::slice(1)
21.   }
22.   tmp <- found %>%
23.     dplyr::select(dplyr::all_of(date_cols)) %>%
24.     tidyr::pivot_longer(everything(), names_to = "Ngay", values_to = "val") %>%
25.     dplyr::mutate(
26.       Nam = lubridate::year(lubridate::dmy(Ngay)),
27.       val_chr = as.character(val),
28.       val_num = suppressWarnings(as.numeric(stringr::str_remove_all(val_chr, "[\\.,]")))
29.     ) %>%
30.     dplyr::arrange(Nam) %>%
31.     dplyr::mutate(val_scaled = val_num / scale_factor)
32.   tibble::tibble(Nam = nam_vec) %>%
33.     dplyr::left_join(tmp %>% dplyr::select(Nam, val_scaled), by = "Nam") %>%
34.     dplyr::pull(val_scaled)}
35. print("Đã định nghĩa hàm 'extract_row_data'.")
[1] "Đã định nghĩa hàm 'extract_row_data'."

Đoạn code này định nghĩa hàm extract_row_data() để tự động trích xuất, làm sạch và chuẩn hóa dữ liệu tài chính theo năm từ bảng báo cáo gốc. Cụ thể, hàm tìm dòng chứa chỉ tiêu cần lấy ( doanh thu, lợi nhuận), chuyển các cột ngày tháng thành dạng giá trị, chuyển năm, rồi chuyển đổi đơn vị (chia 1 tỷ).

2.2.3. Trích xuất chỉ tiêu và tạo bảng dữ liệu

1. GAS_data_final <- data.frame(Nam = nam_vec)
2. scale_vnd_to_ty <- 1e9 # Chia cho 1 Tỷ
3. lctt_raw <- try(read_excel(bctc_path, sheet = 3), silent = TRUE) 
4. if (!inherits(lctt_raw, "try-error")) {
5.   if ("LƯU CHUYỂN TIỀN TỆ" %in% names(lctt_raw)) 
6.      lctt_raw <- lctt_raw %>% rename(ChiTieu = `LƯU CHUYỂN TIỀN TỆ`)
7.   else if (!"ChiTieu" %in% names(lctt_raw))
8.      lctt_raw <- lctt_raw %>% rename(ChiTieu = names(lctt_raw)[1])
9.   # A. Trích xuất CFO (SỬ DỤNG LCTTT_RAW ĐÃ CHUẨN HÓA)
10.   GAS_data_final$CFO <- extract_row_data(lctt_raw, 
11.                                       c("lưu chuyển tiền thuần từ hoạt động kinh doanh",
12.                                         "luu chuyen tien thuan tu hoat dong kinh doanh"), 
13.                                       scale_factor = scale_vnd_to_ty)
14. } else {
15.   warning("Không đọc được sheet 3 (LCTT). Cột CFO sẽ là NA.")
16.   GAS_data_final$CFO <- NA_real_}
17. # A. Trích xuất nhóm 1 (Tài chính cơ bản)
18. # 1. Từ Bảng KQKD (Đơn vị: Tỷ VND)
19. GAS_data_final$DoanhThu <- extract_row_data(
20.   kqkd_raw,
21.   c("doanh thu thuần về bán hàng và cung cấp dịch vụ",
22.     "doanh thu thuần"),
23.   scale_factor = scale_vnd_to_ty # Giữ nguyên scale_factor
24. )
25. GAS_data_final$LoiNhuanSauThue <- extract_row_data(
26.   kqkd_raw,
27.   c("lợi nhuận sau thuế thu nhập doanh nghiệp",
28.     "lợi nhuận sau thuế của cổ đông công ty mẹ",
29.     "lợi nhuận sau thuế"),
30.   scale_factor = scale_vnd_to_ty # Giữ nguyên scale_factor
31. )
32. # 2. Từ Bảng Cân đối Kế toán (Đơn vị: Tỷ VND)
33. GAS_data_final$TongTaiSan <- extract_row_data(
34.   bckt_raw,
35.   c("tổng cộng tài sản", "tong cong tai san"),
36.   scale_factor = scale_vnd_to_ty # Giữ nguyên scale_factor
37. )
38. GAS_data_final$VonChuSoHuu <- extract_row_data(
39.   bckt_raw,
40.   c("vốn chủ sở hữu", "von chu so huu", "d. von chu so huu"),
41.   scale_factor = scale_vnd_to_ty # Giữ nguyên scale_factor
42. )
43. GAS_data_final$NoPhaiTra <- extract_row_data(
44.   bckt_raw,
45.   c("nợ phải trả", "no phai tra"),
46.   scale_factor = scale_vnd_to_ty # Giữ nguyên scale_factor
47. )
48. # B. Trích xuất nhóm 2
49. # 1. Trích xuất EPS (Đơn vị: VND/cp - không scale)
50. GAS_data_final$EPS <- extract_row_data(
51.   kqkd_raw,
52.   c("lãi cơ bản trên cổ phiếu", "eps"),
53.   scale_factor = 1
54. ) 
55. # 2. Bỏ qua khối code CFO bị lỗi lặp lại ở đây
56. # 3. Giá
57. GAS_data_final$Gia_DongCua_CuoiNam <- c(34154, 18129, 33089, 56311, 52232, 58210, 56436, 64672, 70096, 64830, 64160)
58. # 4. Tính toán SLCP
59. GAS_data_final$SL_CoPhieu_LuuHanh <- round((GAS_data_final$LoiNhuanSauThue * 1e9) / GAS_data_final$EPS)
60. # C. Tính toán các biến Phái sinh
61. data <- GAS_data_final
62. data$ROE_Nam <- (data$LoiNhuanSauThue / data$VonChuSoHuu) * 100
63. data$ROA_Nam <- (data$LoiNhuanSauThue / data$TongTaiSan) * 100
64. data <- data %>%
65.   dplyr::mutate(
66.     BienLoiNhuanRong_Nam = (LoiNhuanSauThue / DoanhThu) * 100,
67.     FL_Nam = TongTaiSan / VonChuSoHuu,
68.     TAT_Nam = DoanhThu / TongTaiSan,
69.     DoanhThu_TangTruong_YoY = (DoanhThu / dplyr::lag(DoanhThu) - 1) * 100,
70.     LoiNhuan_TangTruong_YoY = (LoiNhuanSauThue / dplyr::lag(LoiNhuanSauThue) - 1) * 100,
71.     TySoNo_Tren_VCSH = NoPhaiTra / VonChuSoHuu,
72.     # SỬA LỖI: Dùng ifelse để xử lý NA/Inf nếu CFO/LNST là NA/0
73.     TyLe_CFO_Tren_LNST = ifelse(LoiNhuanSauThue != 0, CFO / LoiNhuanSauThue, NA_real_),
74.     VonHoa_TyVND = (Gia_DongCua_CuoiNam * SL_CoPhieu_LuuHanh) / 1e9,
75.     flag_roa_abnormal = dplyr::case_when(ROA_Nam > 100 ~ TRUE, TRUE ~ FALSE)
76.   )
77. data$DoanhThu_TangTruong_YoY[is.na(data$DoanhThu_TangTruong_YoY)] <- 0
78. data$LoiNhuan_TangTruong_YoY[is.na(data$LoiNhuan_TangTruong_YoY)] <- 0
79. GAS_data_final <- data %>% dplyr::filter(flag_roa_abnormal == FALSE) 
80. print(head(GAS_data_final))
   Nam   CFO DoanhThu LoiNhuanSauThue TongTaiSan VonChuSoHuu NoPhaiTra  EPS
1 2014 16701    73393           14370      53791       37679     16112 7140
2 2015  9127    64300            8832      56715       42889     13826 4400
3 2016  4942    59076            7172      56754       40844     15910 6748
4 2017 14386    64522            9938      61889       43272     18618 4994
5 2018 12422    75612           11709      62614       46867     15747 5911
6 2020  7331    64135             797      63208       49500     13709 4028
  Gia_DongCua_CuoiNam SL_CoPhieu_LuuHanh ROE_Nam ROA_Nam BienLoiNhuanRong_Nam
1               34154         2012580185   38.14   26.71                19.58
2               18129         2007301345   20.59   15.57                13.74
3               33089         1062894151   17.56   12.64                12.14
4               56311         1989946445   22.97   16.06                15.40
5               52232         1980809589   24.98   18.70                15.49
6               56436          197909415    1.61    1.26                 1.24
  FL_Nam TAT_Nam DoanhThu_TangTruong_YoY LoiNhuan_TangTruong_YoY
1   1.43    1.36                    0.00                     0.0
2   1.32    1.13                  -12.39                   -38.5
3   1.39    1.04                   -8.12                   -18.8
4   1.43    1.04                    9.22                    38.6
5   1.34    1.21                   17.19                    17.8
6   1.28    1.01                  -14.49                   -93.4
  TySoNo_Tren_VCSH TyLe_CFO_Tren_LNST VonHoa_TyVND flag_roa_abnormal
1            0.428              1.162        68738             FALSE
2            0.322              1.033        36390             FALSE
3            0.390              0.689        35170             FALSE
4            0.430              1.448       112056             FALSE
5            0.336              1.061       103462             FALSE
6            0.277              9.196        11169             FALSE

Nhận xét:

Bảng dữ liệu đã được trích xuất và chuẩn hóa thành công phản ánh đầy đủ hiệu quả hoạt động, cấu trúc tài chính và tăng trưởng của PVGas trong giai đoạn 2014–2024. Sáu dòng đầu tiên minh họa cho cấu trúc dữ liệu, với ba nhóm biến chính:

  • Nhóm biến gốc (hoạt động & quy mô):
    DoanhThu, LoiNhuanSauThue, TongTaiSan, VonChuSoHuu, NoPhaiTra, CFO, EPS, Gia_DongCua_CuoiNam, SL_CoPhieu_LuuHanh
    → Cung cấp nền tảng cho việc tính toán tỷ suất sinh lời và định giá.

  • Nhóm biến hiệu suất & cấu trúc DuPont:
    ROE_Nam, ROA_Nam, BienLoiNhuanRong_Nam, TAT_Nam, FL_Nam
    → Dùng để phân tích hiệu quả sinh lời, khả năng sử dụng tài sản và mức độ đòn bẩy tài chính.

  • Nhóm biến tăng trưởng & chất lượng tài chính:
    DoanhThu_TangTruong_YoY, LoiNhuan_TangTruong_YoY, VonHoa_TyVND, TySoNo_Tren_VCSH, TyLe_CFO_Tren_LNST, flag_roa_abnormal
    → Phản ánh tốc độ tăng trưởng, quy mô vốn hóa, sức khỏe tài chính và khả năng tạo tiền của doanh nghiệp.

2.3. PHÂN TÍCH VÀ TRỰC QUAN NHÓM 1: TỔNG QUAN HIỆU SUẤT VÀ TĂNG TRƯỞNG

Mục này tập trung vào thống kê mô tả, phân phối, và xu hướng dòng thời gian của các biến cốt lõi trong Nhóm 1 (DoanhThu, LoiNhuanSauThue, ROE_Nam, ROA_Nam, EPS, BienLoiNhuanRong_Nam, và các biến tăng trưởng).

2.3.1. Thống kê mô tả tổng quan

1. library(dplyr); library(moments); library(ggplot2)
2. library(tidyr); library(scales); library(zoo)
3. stats_group1_full <- data %>% 
4.   dplyr::rename(ROE = ROE_Nam, ROA = ROA_Nam, BienLoiNhuanRong = BienLoiNhuanRong_Nam) %>%
5.   dplyr::summarise(
6.     dplyr::across(
7.       c(DoanhThu, LoiNhuanSauThue, EPS, ROE, ROA, BienLoiNhuanRong),
8.       list(
9.         Mean   = ~mean(., na.rm = TRUE),
10.         Median = ~median(., na.rm = TRUE),
11.         SD     = ~sd(., na.rm = TRUE),
12.         Min    = ~min(., na.rm = TRUE),
13.         Max    = ~max(., na.rm = TRUE),
14.         CV     = ~sd(., na.rm = TRUE)/mean(., na.rm = TRUE)
15.       ),
16.       .names = "{.col}_{.fn}"
17.     )
18.   ) %>%
19.   tidyr::pivot_longer(dplyr::everything(), names_to = "Tên_Biến_và_Hàm", values_to = "Giá_Trị") %>%
20.   tidyr::separate(Tên_Biến_và_Hàm, into = c("Biến", "Hàm"), sep = "_", extra = "merge") %>%
21.   tidyr::pivot_wider(names_from = Hàm, values_from = Giá_Trị) %>%
22.   dplyr::rename(Hệ_số_biến_thiên_CV = CV)
23. stats_group1_display <- stats_group1_full
24. knitr::kable(stats_group1_display, digits = 3, caption = "Bảng thống kê mô tả các biến tài chính")
Bảng thống kê mô tả các biến tài chính
Biến Mean Median SD Min Max Hệ_số_biến_thiên_CV
DoanhThu 77207.1 75005.3 15041.35 59076.19 103564.1 0.195
LoiNhuanSauThue 10109.5 10590.1 3883.78 797.18 15066.4 0.384
EPS 5517.6 4994.0 1263.99 4028.00 7649.0 0.229
ROE 20.6 20.6 8.74 1.61 38.1 0.423
ROA 190.0 15.6 581.65 1.26 1943.7 3.061
BienLoiNhuanRong 13.0 13.7 4.68 1.24 19.6 0.360

Nhận xét:

Phần này không giải thích kĩ thuật vì tương tự thống kê mô tả ở bộ dữ liệu 1, ta đi sâu vào bàn luận kết quả sơ bộ:

PVGas duy trì doanh thu ổn định và quy mô lớn, với hệ số biến thiên CV < 0.2, thể hiện nhu cầu thị trường ổn định và vị thế vững chắc trong chuỗi cung ứng khí.

Lợi nhuận sau thuế trung bình đạt ~10.1 nghìn tỷ VND, ROE trung bình ~20.6%, và biên lợi nhuận ròng ~13%, đều có CV thấp (<0.4) → cho thấy khả năng sinh lời cao, ổn định và kiểm soát chi phí tốt.

Chỉ số ROAMean = 190% nhưng Median = 15.6%, cho thấy tồn tại giá trị ngoại lệ (outlier), tuy nhiên ROA trung vị 15.6% vẫn phản ánh hiệu quả sử dụng tài sản mạnh. Khoảng cách nhỏ giữa ROE và ROA chứng minh đòn bẩy tài chính thấp, doanh nghiệp vận hành an toàn.

EPS trung bình ≈ 5,518 VND/cổ phiếu với CV = 0.229, khẳng định khả năng tạo giá trị ổn định cho cổ đông.

Kết luận:
PVGas là doanh nghiệp có nền tảng tài chính vững chắc, sinh lời bền vững và rủi ro thấp, thể hiện qua:
- ROE ≈ 20.6% → Hiệu quả sinh lời cao trên vốn chủ.
- ROA ≈ 15.6% → Sử dụng tài sản hiệu quả.
- Biên lợi nhuận ròng ≈ 13% → Hiệu quả kinh doanh cốt lõi ổn định.

2.3.2. Phân phối và tăng trưởng kép CARG

2.3.2.1. Hình dạng phân phối các biến lợi nhuận và hiệu quả kinh doanh

1. # Hình dạng phân phối 
2. skew_kurt_group1 <- data %>%
3.   dplyr::select(LoiNhuanSauThue, ROE_Nam, BienLoiNhuanRong_Nam, DoanhThu_TangTruong_YoY) %>%
4.   dplyr::summarise(
5.     dplyr::across(
6.       dplyr::everything(),
7.       list(
8.         Skewness = ~moments::skewness(., na.rm = TRUE),
9.         Kurtosis = ~moments::kurtosis(., na.rm = TRUE)),
10.       .names = "{.col}_{.fn}"))
11. print(skew_kurt_group1)
  LoiNhuanSauThue_Skewness LoiNhuanSauThue_Kurtosis ROE_Nam_Skewness
1                    -1.11                     4.14            -0.23
  ROE_Nam_Kurtosis BienLoiNhuanRong_Nam_Skewness BienLoiNhuanRong_Nam_Kurtosis
1             4.26                         -1.34                          4.88
  DoanhThu_TangTruong_YoY_Skewness DoanhThu_TangTruong_YoY_Kurtosis
1                            0.215                              1.6

Nhận xét

Biến Skewness (Độ lệch) Kurtosis (Độ nhọn) Hình dạng Phân phối
LoiNhuanSauThue -1.11 4.14 Lệch âm (trái), Nhọn hơn Chuẩn
ROE_Nam -0.23 4.26 Gần đối xứng, Nhọn hơn Chuẩn
BienLoiNhuanRong_Nam -1.34 4.88 Lệch âm (trái) mạnh, Rất nhọn
DoanhThu_TangTruong_YoY 0.215 1.6 Gần đối xứng, Bẹt hơn Chuẩn

Nhìn chung:

Tính lệch (Skewness):
Lợi nhuận và Biên lợi nhuận ròng (LNR) có độ lệch âm mạnh (–1.11 đến –1.34), cho thấy dữ liệu bị kéo về phía giá trị thấp, đđiều này khớp với giai đoạn khủng hoảng giá dầu (2015-2016), nơi lợi nhuận và biên lợi nhuận bị sụt giảm cực sâu. Chỉ tiêu ROE gần như đối xứng (–0.23), nghĩa là biến động giữa các năm tốt và xấu được cân bằng.

Độ nhọn (Kurtosis):
LNST, ROE và Biên LNRKurtosis > 4, tức là phân phối rất nhọn, dữ liệu tập trung quanh trung bình nhưng có một số giá trị cực đoan. Doanh thu tăng trưởng YoYKurtosis ≈ 1.6, biểu hiện phân phối bẹt, cho thấy doanh thu ổn định hơn các chỉ tiêu lợi nhuận.

Tóm lại: Dữ liệu cho thấy hiệu suất tài chính của GAS nhìn chung ổn định, nhưng vẫn tồn tại một vài năm biến động cực đoan do ảnh hưởng của chu kỳ giá dầu.

2.3.2.2. Phân tích tốc độ tăng trưởng kép biến doanh thu và LNST

1. cagr_dt <- ((data$DoanhThu[data$Nam == 2024] / data$DoanhThu[data$Nam == 2014])^(1/10) - 1) * 100
2. cagr_lnst_full <- ((data$LoiNhuanSauThue[data$Nam == 2024] / data$LoiNhuanSauThue[data$Nam == 2014])^(1/10) - 1) * 100
3. cagr_lnst_recovery <- ((data$LoiNhuanSauThue[data$Nam == 2024] / data$LoiNhuanSauThue[data$Nam == 2016])^(1/8) - 1) * 100
4. cagr_table <- data.frame(
5.   Chỉ_tiêu = c("CAGR Doanh thu (2014–2024)",
6.                "CAGR Lợi nhuận ST (2014–2024)",
7.                "CAGR Lợi nhuận ST (2016–2024, phục hồi)"),
8.   Tỷ_lệ_Tăng_Trưởng = c(cagr_dt, cagr_lnst_full, cagr_lnst_recovery)
9. )
10. kable(cagr_table,
11.       caption = "Bảng: Tốc độ tăng trưởng kép của doanh thu và lợi nhuận sau thuế",
12.       digits = 2)
Bảng: Tốc độ tăng trưởng kép của doanh thu và lợi nhuận sau thuế
Chỉ_tiêu Tỷ_lệ_Tăng_Trưởng
CAGR Doanh thu (2014–2024) 3.50
CAGR Lợi nhuận ST (2014–2024) -3.01
CAGR Lợi nhuận ST (2016–2024, phục hồi) 4.99

Giải thích kĩ thuật

Phần / Dòng code Giải thích chi tiết
Dòng 1 Tính CAGR của Doanh thu giai đoạn 2014–2024 bằng công thức \((Giá\ trị\ cuối / Giá\ trị\ đầu)^{1/10} - 1\), sau đó nhân 100 để ra % tăng trưởng/năm.
Dòng 2 Tính CAGR của Lợi nhuận sau thuế trong cùng giai đoạn 2014–2024.
Dòng 3 Tính CAGR Lợi nhuận sau thuế giai đoạn phục hồi (2016–2024)
Dòng 4–9 Tạo bảng dữ liệu cagr_table
Dòng 10–12 (kable(...)) in bảng

Nhận xét:

  • Tăng trưởng doanh thu bền vững: CAGR Doanh thu \(3.50\%\) là một mức tăng trưởng ổn định, thể hiện sự mở rộng quy mô hợp lý và khả năng chống chịu tốt.

  • Ảnh hưởng của Năm Gốc: CAGR Lợi nhuận toàn giai đoạn là âm (-3.01%). Điều này là hệ quả trực tiếp của việc sử dụng năm 2014 (năm có lợi nhuận cực đỉnh) làm năm gốc, tạo ra hiệu ứng nền cao giả.

  • Tốc độ Phục hồi Hợp lý: CAGR Lợi nhuận giai đoạn phục hồi (2016-2024) là \(4.99\%\). Tốc độ này tuy thấp hơn mức \(63.80\%\) tính toán trước đó (điều chỉnh do ngoại lai 2016), nhưng \(4.99\%\) là một mức tăng trưởng lợi nhuận ổn định và hợp lý hơn so với mức tăng trưởng doanh thu. Nó chứng minh rằng GAS đã thoát khỏi khủng hoảng và duy trì được đà tăng trưởng lợi nhuận dương trong suốt 8 năm sau đó.

2.3.2.3. Trực quan phân phối của biên lợi nhuận ròng

1. ggplot(data, aes(x = BienLoiNhuanRong_Nam)) +
2.   geom_histogram(aes(y = after_stat(density)), bins = 10, fill = "#0072B2", color = "white", alpha = 0.7) +
3.   geom_density(color = "#D55E00", linewidth = 1) +
4.   geom_vline(aes(xintercept = mean(BienLoiNhuanRong_Nam)), linetype = "dashed", color = "red") +
5.   labs(title = "Phân phối của biên lợi nhuận ròng (2014-2024)",
6.        x = "Biên lợi nhuận ròng (%)", y = "Mật độ") +
7.   theme_minimal()

Nhận xét

Biểu đồ cho thấy phân phối của Biên lợi nhuận ròng (LNR) có dạng hai đỉnh, thể hiện sự biến động theo chu kỳ hoạt động của GAS:

  • Cụm thấp (0–5%) xuất hiện ở giai đoạn 2015–2016, khi doanh nghiệp chịu ảnh hưởng tiêu cực từ suy giảm giá dầu và chi phí đầu vào cao, khiến lợi nhuận gần như chạm đáy.

  • Cụm cao (10–18%) là vùng tập trung chính của dữ liệu, thể hiện giai đoạn phục hồi và ổn định trong hầu hết các năm, khi biên lợi nhuận của GAS duy trì ở mức cao và bền vững.

Đường trung bình (đỏ đứt đoạn) nằm khoảng 13%, phản ánh hiệu suất sinh lời ổn định trong dài hạn. Đây là mức cao đối với một doanh nghiệp có quy mô lớn và ổn định như GAS

Từ đó biểu đồ minh họa rõ hai giai đoạn đối lập trong hoạt động của GAS: Giai đoạn suy giảm ngắn hạn (2015–2016) với lợi nhuận co hẹp. và giai đoạn ổn định và tăng trưởng (từ 2017 trở đi) với Biên LNR dao động quanh 13–15%, chứng tỏ khả năng duy trì hiệu quả chi phí và năng lực sinh lời vững chắc của doanh nghiệp.

2.3.2.4. Trực quan giá trị cực đoan của ROE

1. q <- quantile(data$ROE_Nam, probs = c(0.25, 0.75), na.rm = TRUE)
2. iqr <- q[2] - q[1]
3. upper <- q[2] + 1.5*iqr
4. lower <- q[1] - 1.5*iqr
5. ggplot(data, aes(x = factor(0), y = ROE_Nam)) +
6.   geom_boxplot(fill = "#009E73", alpha = 0.7, outlier.colour = "red") +
7.   geom_text(data = dplyr::filter(data, ROE_Nam > upper | ROE_Nam < lower),
8.     aes(label = Nam), vjust = -0.5) +
9.   labs(title = "Giá trị ngoại lai của ROE",
10.        x = "", y = "ROE (%)") +
11.   theme_minimal() +
12.   scale_y_continuous(labels = label_number(suffix = "%")) +
13.   theme(legend.position = "none")

Nhận xét biểu đồ

Biểu đồ boxplot cho thấy ROE của GAS chủ yếu nằm trong khoảng 18–25%, với trung vị khoảng 20%, phản ánh hiệu suất sinh lời cao và ổn định trong giai đoạn 2014–2024.

Tuy nhiên vẫn có sự xuất hiện ngoại lệ đáng chú ý:

  • Năm 2014 (Outlier cao):** ROE vượt quá 30–35%, vượt xa phạm vi bình thường. → Đây là giai đoạn đỉnh lợi nhuận trước khủng hoảng giá dầu, khi giá bán khí và biên lợi nhuận ở mức cao kỷ lục. ROE cao phản ánh hiệu quả sử dụng vốn vượt trội, nhưng cũng là giá trị “đỉnh chu kỳ”

  • Năm 2020 (Outlier thấp): ROE gần 0%, rơi xuống mức cực tiểu. → Đây là năm chịu tác động kép của đại dịch COVID-19giá dầu âm, khiến lợi nhuận sau thuế sụt giảm nghiêm trọng, dù doanh thu không giảm mạnh. ROE gần 0 cho thấy gần như toàn bộ lợi nhuận bị xóa bởi chi phí và dự phòng.

2.3.3. Trực quan xu hướng thời gian và tăng trưởng

2.3.3.1. Xu hướng doanh thu và lợi nhuận

1. library(ggplot2)
2. library(dplyr)
3. library(scales)
4. data_long_rev_profit <- data %>%
5.   select(Nam, DoanhThu, LoiNhuanSauThue) %>%
6.   mutate(
7.     DoanhThu = DoanhThu / 1000, 
8.     LoiNhuanSauThue = LoiNhuanSauThue / 1000
9.   ) %>%
10.   pivot_longer(-Nam, names_to = "ChiTieu", values_to = "GiaTri")
11. highlight_years <- c(2016, 2020, 2022)
12. highlight_points <- data_long_rev_profit %>% filter(Nam %in% highlight_years)
13. ggplot(data_long_rev_profit, aes(x = Nam, y = GiaTri, group = ChiTieu, color = ChiTieu)) +
14.   geom_line(linewidth = 1.3, alpha = 0.9) +
15.   geom_point(size = 3) +
16.   geom_point(
17.     data = highlight_points, 
18.     aes(x = Nam, y = GiaTri), 
19.     size = 5, 
20.     shape = 21, 
21.     fill = "white", 
22.     color = "black", 
23.     stroke = 1.2
24.   ) +
25.   geom_text(
26.     data = highlight_points,
27.     aes(
28.       label = case_when(
29.         Nam == 2016 ~ "Đáy chu kỳ\n(giá dầu giảm)",
30.         Nam == 2020 ~ "Khủng hoảng COVID &\ngiá dầu âm",
31.         Nam == 2022 ~ "Phục hồi mạnh\nBiên lợi nhuận cao"
32.       )
33.     ),
34.     vjust = -1.2, hjust = 0.5, size = 3.5, fontface = "italic", color = "black"
35.   ) +
36.   geom_hline(
37.     yintercept = mean(data_long_rev_profit$GiaTri[data_long_rev_profit$ChiTieu == "DoanhThu"]),
38.     linetype = "dashed", color = "#0072B2", linewidth = 0.7, alpha = 0.7
39.   ) +
40.   geom_hline(
41.     yintercept = mean(data_long_rev_profit$GiaTri[data_long_rev_profit$ChiTieu == "LoiNhuanSauThue"]),
42.     linetype = "dashed", color = "#D55E00", linewidth = 0.7, alpha = 0.7
43.   ) +
44.   annotate("text", x = 2014.5, 
45.            y = mean(data_long_rev_profit$GiaTri[data_long_rev_profit$ChiTieu == "DoanhThu"]) + 2,
46.            label = "Trung bình Doanh thu", color = "#0072B2", size = 2, hjust = 0) +
47.   annotate("text", x = 2014.5, 
48.            y = mean(data_long_rev_profit$GiaTri[data_long_rev_profit$ChiTieu == "LoiNhuanSauThue"]) + 1,
49.            label = "Trung bình LNST", color = "#D55E00", size = 2, hjust = 0) +
50.   scale_y_continuous(labels = label_number(big.mark = ",", suffix = " Nghìn Tỷ VND")) +
51.   scale_color_manual(
52.     values = c("DoanhThu" = "#0072B2", "LoiNhuanSauThue" = "#D55E00"),
53.     labels = c("DoanhThu" = "Doanh thu thuần", "LoiNhuanSauThue" = "Lợi nhuận Sau Thuế")
54.   ) +
55.   labs(
56.     title = "Xu hướng doanh thu và lợi nhuận sau thuế",
57.     subtitle = "Các năm đặc biệt được chú thích: 2016 (đáy), 2020 (khủng hoảng), 2022 (phục hồi mạnh)",
58.     x = "Năm",
59.     y = "Giá trị (Nghìn tỷ VND)",
60.     color = "Chỉ tiêu"
61.   ) +
62.   theme_minimal(base_size = 12) +
63.   theme(
64.     plot.title = element_text(face = "bold", size = 13, hjust = 0.5),
65.     plot.subtitle = element_text(size = 7, hjust = 0.5),
66.     legend.position = "bottom",
67.     panel.grid.minor = element_blank(),
68.     panel.grid.major.x = element_blank()
69.   )

Nhận xét kĩ thuật

Phần / Dòng code Giải thích chi tiết
Dòng 1–3 Nạp các thư viện cần thiết: ggplot2 để vẽ biểu đồ, dplyr để xử lý dữ liệu, và scales để định dạng trục số.
Dòng 4–10 dùng select(), mutate() chọn các cột Nam, DoanhThu, LoiNhuanSauThue, sau đó chuyển đổi đơn vị về nghìn tỷ VND
Dòng 11–12 Xác định và lọc ra các năm (2016, 2020, 2022) để hiển thị nhãn riêng bằng filter()
Dòng 13–15 Khởi tạo ggplot(), vẽ hai đường xu hướng (geom_line()) và các điểm dữ liệu (geom_point()), với màu khác nhau cho từng chỉ tiêu.
Dòng 16–24 geom_point() ánh xạ hiệu ứng nổi bật (highlight) cho các năm đặc biệt bằng vòng tròn trắng viền đen (shape = 21)
Dòng 25–35 Dùng geom_text() để chú thích các năm nổi bật trực tiếp trên biểu đồ
Dòng 36–43 Dùng geom_hline() vẽ hai đường trung bình cho Doanh thu và Lợi nhuận sau thuế bằng
Dòng 44–49 scale_color_manual() gán màu cụ thể: #0072B2 (xanh dương – Doanh thu), #D55E00 (cam – Lợi nhuận)
Dòng 50 Định dạng trục Y bằng scale_y_continuous()label_number() để hiển thị rõ ràng đơn vị “Nghìn tỷ VND”.
Dòng 51–54 Tùy chỉnh lại màu cho từng biến (scale_color_manual()): xanh (#0072B2) cho Doanh thu, cam (#D55E00) cho Lợi nhuận, và đổi tên chú thích trong Legend.
Dòng 55–61 (labs()) thêm tiêu đề, nhãn
Dòng 62–69 Áp dụng theme_minimal() và đưa chú thích xuống phía dưới (legend.position = "bottom").

Nhận xét

Biểu đồ thể hiện rõ chu kỳ hoạt động gồm hai pha chính của Tổng Công ty Khí Việt Nam (GAS):

  • Giai đoạn 2014–2016: Khủng hoảng và suy giảm: Doanh thu giảm từ khoảng 75 nghìn tỷ VND xuống dưới 60 nghìn tỷ VND, đồng thời lợi nhuận sau thuế giảm mạnh hơn, rơi từ mức trên 10 nghìn tỷ VND xuống gần 3 nghìn tỷ VND → Đây là giai đoạn “đáy chu kỳ”, doanh nghiệp chịu ảnh hưởng kép từ giá dầu thấp và chi phí cố định cao.

  • Giai đoạn 2017–2024 – Phục hồi và mở rộng: Doanh thu phục hồi rõ rệt, đạt đỉnh mới trên 100 nghìn tỷ VND vào năm 2024. Lợi nhuận cũng phục hồi, nhưng có dao động mạnh, đặc biệt giảm sâu vào năm 2020 (COVID-19, giá dầu âm) sau đó bật tăng mạnh vào 2022, rồi ổn định hơn giai đoạn sau.

  • Điều này cho thấy khi doanh thu tăng, lợi nhuận cũng tăng, nhưng biên độ biến động lợi nhuận lớn hơn → Điều này phản ánh rằng biên lợi nhuận ròng (LNST/Doanh thu) là yếu tố quyết định hiệu suất: chỉ cần biến động nhẹ về giá bán hoặc chi phí đầu vào cũng khiến lợi nhuận thay đổi mạnh.

2.3.3.2. Trực quan tốc độ tăng trưởng tức thời (YoY)

1. data_long_yoy <- data %>%
2.   select(Nam, DoanhThu_TangTruong_YoY, LoiNhuan_TangTruong_YoY) %>%
3.   filter(Nam != 2014) %>% # Loại bỏ năm gốc (NA/0)
4.   pivot_longer(-Nam, names_to = "ChiTieu", values_to = "YoY")
5. ggplot(data_long_yoy, aes(x = factor(Nam), y = YoY, fill = ChiTieu)) +
6.   geom_bar(stat = "identity", position = "dodge") +
7.   scale_y_continuous(labels = label_number(suffix = "%")) +
8.   scale_fill_manual(values = c("DoanhThu_TangTruong_YoY" = "#0072B2", "LoiNhuan_TangTruong_YoY" = "#D55E00"),
9.                     labels = c("DoanhThu_TangTruong_YoY" = "Doanh thu YoY", "LoiNhuan_TangTruong_YoY" = "Lợi nhuận YoY")) +
10.   labs(title = "Biến động tăng trưởng YoY: Doanh thu vs lợi nhuận (2015-2024)",
11.        x = "Năm", y = "Tốc độ tăng trưởng (%)", fill = "Chỉ tiêu") +
12.   theme_minimal()

Nhận xét

  • Tổng quan hình dạng: Doanh thu YoY dao động khá ổn định, ít có sự biến động qua các năm điều này nghĩa là ít chịu biến động mạnh dù thị trường năng lượng có nhiều thay đổi.Tuy nhiên lợi nhuận YoY biến động rất mạnh, đặc biệt có đột biến dương cực lớn vào năm 2021 (~1000%) → Điều này cho thấy lợi nhuận nhạy cảm hơn rất nhiều với biến động của giá dầu, chi phí vận hành, và các yếu tố tài chính khác.

Xét theo từng giai đoạn

  • Giai đoạn 2015–2016: Cả doanh thu và lợi nhuận đều tăng trưởng âm, trong đó lợi nhuận giảm mạnh hơn doanh thu. Đây là giai đoạn biên lợi nhuận bị bào mòn nghiêm trọng, phù hợp với thời kỳ giá dầu thế giới lao dốc.

  • Giai đoạn 2017–2019: Cả hai chỉ tiêu tăng trưởng nhẹ quanh mức dương → GAS đã vượt qua giai đoạn khủng hoảng và bước vào chu kỳ tăng trưởng bền vững, nhờ giá dầu phục hồi và chi phí được kiểm soát tốt hơn.

  • Năm 2020: Giá trị lợi nhuận YoY giảm sâu hơn, trong khi doanh thu chỉ giảm nhẹ → Minh chứng cho tác động mạnh của đại dịch COVID-19giá dầu âm

  • Năm 2021: Lợi nhuận YoY tăng vọt ~1000% → Đây không phải là tăng trưởng thực chất, mà có thể lầ mức phản ánh sự phục hồi vượt trội sau khủng khoảng

  • Giai đoạn 2022–2024: Mức tăng trưởng lợi nhuận trở về mức dương vừa phải

Từ đó biểu đồ khẳng định:

  • Doanh thu của GAS mang tính ổn định cấu trúc, ít chịu ảnh hưởng bởi chu kỳ ngắn hạn.
  • Lợi nhuận biến động mạnh và mang tính chu kỳ, đặc biệt nhạy với các cú sốc vĩ mô.
  • Hiệu suất tài chính của GAS vì thế cần được đánh giá qua trung bình động hoặc CAGR dài hạn, thay vì chỉ nhìn tăng trưởng năm đơn lẻ.

2.3.3.3. Hiệu suất: ROE và ROA

1. data_long_roe_roa <- data %>%
2.   select(Nam, ROE_Nam, ROA_Nam) %>%
3.   pivot_longer(-Nam, names_to = "ChiTieu", values_to = "GiaTri")
4. ggplot(data_long_roe_roa, aes(x = Nam, y = GiaTri, group = ChiTieu, color = ChiTieu)) +
5.   geom_line(linewidth = 1.2) +
6.   geom_point(size = 3) +
7.   scale_y_continuous(labels = label_number(suffix = "%")) +
8.   scale_color_manual(values = c("ROE_Nam" = "#009E73", "ROA_Nam" = "#F0E442"), 
9.                      labels = c("ROE_Nam" = "ROE", "ROA_Nam" = "ROA")) +
10.   labs(title = "Quỹ đạo hiệu suất sinh lời: ROE vs ROA (2014-2024)",
11.        x = "Năm", y = "Tỷ suất sinh lời (%)", color = "Chỉ tiêu") +
12.   theme_minimal()

Nhận xét

  • Trong phần lớn giai đoạn, ROE cao hơn ROA khoảng 1.3–1.5 lần, cho thấy GAS có mức đòn bẩy thấp, cấu trúc vốn an toàn.Tuy nhiên năm 2019 mối quan hệ này bị phá vỡ: ROA tăng vọt vượt xa ROE(ROA tăng vọt gần 2000% trong khi ROE vẫn ổn định) → biểu hiện nghịch lý kế toán hoặc năm này xuất hiện các giá trị tiêu cực nhiều. Khi loại bỏ năm này, đường ROE và ROA gần như trùng nhau, xu hướng trở nên tuyến tính và có thể mô hình hóa tốt bằng ROE = ROA × FL trong hồi quy thực hiện ở bước tiếp theo.

2.3.3.4. Xu hướng EPS và biên lợi nhuận ròng

1. scale_factor_eps <- max(data$BienLoiNhuanRong_Nam) / max(data$EPS)
2. median_eps <- median(data$EPS)
3. median_margin <- median(data$BienLoiNhuanRong_Nam)
4. ggplot(data, aes(x = Nam)) +
5.   geom_line(aes(y = EPS), color = "#0072B2", linewidth = 1.2) +
6.   geom_point(aes(y = EPS), color = "#0072B2", size = 3) +
7.   geom_line(aes(y = BienLoiNhuanRong_Nam / scale_factor_eps), color = "#D55E00", linewidth = 1.2, linetype = "dashed") +
8.   scale_y_continuous(
9.     name = "EPS (VND)",
10.     labels = comma,
11.     sec.axis = sec_axis(~ . * scale_factor_eps, name = "Biên Lợi nhuận Ròng (%)", labels = label_number(suffix = "%"))
12.   ) +
13.   labs(title = "Xu hướng EPS và biên lợi nhuận ròng (2014-2024)",
14.        x = "Năm") +
15.   theme_minimal()

Nhận xét

  • Giai đoạn 2014–2016: Biên LNR giảm mạnh từ ~18% xuống gần 10%, tương tự EPS sụt tương ứng từ ~7.000 VND/cp xuống còn ~4.500 VND/cp → Thể hiện tác động kép của khủng hoảng giá dầu khiến hiệu suất sinh lời và giá đều giảm

  • Giai đoạn 2017–2019: Biên LNR duy trì quanh 13–15%, EPS dao động ổn định ~6.000–7.000 VND/cp, đây được xem là giai đoạn ổn định.

  • Năm 2020: Biên LNR giảm sâu chỉ còn khoảng 5%, đồng thời EPS rơi về ~4.000 VND/cp, mức thấp nhất kể từ 2014 → Cho thấy tác động tiêu cực mạnh mẽ của COVID-19 và giá dầu âm, khi chi phí vận hành và tài chính không thể co giãn theo doanh thu.

  • Năm 2021–2022: Biên LNR tăng nhanh trở lại lên 15–16%, đồng thời EPS vọt lên 7.800 VND/cp, phản ánh kết quả tái cơ cấu và giá dầu được phục hồi.

  • Năm 2023–2024: có sự điều chỉnh nhẹ n hưng không nhiều, biên LNR về ~11–12%, EPS về ~5.000–5.500 VND/cp.

Qua đó có thể khẳng định “Biên lợi nhuận ròng là biến dẫn dắt chính của hiệu suất cổ phiếu GAS.” Khi biên lợi nhuận tăng ổn định trên 12–15%, EPS duy trì ở mức ≥6.000 VND/cp, ngược lại mỗi khi biên lợi nhuận suy giảm đột ngột** (như 2015–2016, 2020), **EPS lập tức giảm mạnh, phản ánh độ nhạy cao của lợi nhuận với biến động thị trường dầu khí.

2.3.4. Phân tích mối quan hệ giữa các chỉ tiêu tài chính và xét điểm bất thường

2.3.4.1. Xét mối quan hệ giữa các biến tài chính bằng hồi quy song song

Phân tích hồi quy song song được thực hiện nhằm kiểm định mối quan hệ tuyến tính giữa các chỉ tiêu tài chính cốt lõi của PVGas và đánh giá ảnh hưởng của các quan sát bất thường (outlier) đến độ tin cậy của mô hình.

Cụ thể, mẫu Full bao gồm toàn bộ giai đoạn 2014–2024, trong khi mẫu Clean loại bỏ năm 2019 do ROA bất thường (ROA > 100%) để kiểm tra tính ổn định của các hệ số.

Mục tiêu của phân tích là xác định hướng và độ mạnh của mối quan hệ giữa các biến (qua Slope), so sánh sự khác biệt giữa hai mẫu để đánh giá độ nhạy của mô hình, đồng thời làm cơ sở định lượng cho việc phân tích hiệu quả sinh lời (ROE, ROA)định giá cổ phiếu (Giá–EPS)

1. library(dplyr)
2. library(purrr)
3. library(broom)
4. library(tibble)      
5. library(scales)
6. library(knitr)
7. library(kableExtra)
8. data_full  <- data
9. data_clean <- data %>% filter(Nam != 2019) # Chia dữ liệu làm hai tập full và clean
10. fm_list <- list(
11.   `LNST ~ DT` = LoiNhuanSauThue ~ DoanhThu,    # tạo danh sách hồi quy song song 3 cặp 
12.   `ROE ~ ROA` = ROE_Nam ~ ROA_Nam,
13.   `Giá ~ EPS` = Gia_DongCua_CuoiNam ~ EPS
14. )
15. fit_and_summarise <- function(df, name_suffix){
16.   map_df(names(fm_list), function(lbl){
17.     fit <- lm(fm_list[[lbl]], data = df)  # thực hiện hồi quy 
18.     g   <- glance(fit)          #  in kết quả r.squared, adj.r.squared, nobs, ...
19.     t   <- tidy(fit)            #  in hệ số & p-value
20.     slope_row <- t %>% filter(term != "(Intercept)") %>% slice(1)
21.     tibble(
22.       Model     = lbl,
23.       Mẫu       = name_suffix,
24.       n         = g$nobs,
25.       R2        = g$r.squared,
26.       Adj_R2    = g$adj.r.squared,
27.       Slope     = slope_row$estimate,
28.       `p-value` = slope_row$p.value,
29.       Intercept = t$estimate[t$term == "(Intercept)"]
30.     )
31.   })
32. }
33. summary_models <- bind_rows(
34.   fit_and_summarise(data_full,  "Full"),
35.   fit_and_summarise(data_clean, "Clean")     
36. ) %>%
37.   mutate(
38.     R2        = round(R2, 5),
39.     Adj_R2    = round(Adj_R2, 5),
40.     Slope     = round(Slope, 5),
41.     Intercept = round(Intercept, 3),
42.     `p-value` = ifelse(`p-value` < 1e-6,
43.                        format(`p-value`, scientific = TRUE, digits = 2),
44.                        round(`p-value`, 3))
45.   ) %>%       # đoạn code làm tròn số 
46.   mutate(Model = factor(Model, levels = c("LNST ~ DT", "ROE ~ ROA", "Giá ~ EPS"))) %>%
47.   arrange(Model, desc(Mẫu))
48. kable(summary_models,
49.       caption = "Bảng 2.3.4.1 – Tóm tắt hồi quy song song (Full vs Clean)",
50.       align = c("l","l","r","r","r","r","r","r"),
51.       digits = 3) %>%
52.   kable_styling(full_width = FALSE, bootstrap_options = c("striped","hover","condensed")) %>%
53.   column_spec(1, bold = TRUE) %>%
54.   row_spec(which(summary_models$Mẫu == "Clean"), background = "#f7f7f7")
Bảng 2.3.4.1 – Tóm tắt hồi quy song song (Full vs Clean)
Model Mẫu n R2 Adj_R2 Slope p-value Intercept
LNST ~ DT Full 11 0.298 0.220 0.141 0.082 -774.923
LNST ~ DT Clean 10 0.317 0.231 0.143 0.09 -1193.544
ROE ~ ROA Full 11 0.023 -0.086 0.002 0.657 20.209
ROE ~ ROA Clean 10 0.991 0.990 1.403 1.7e-09 -0.325
Giá ~ EPS Full 11 0.006 -0.104 -1.037 0.816 57749.126
Giá ~ EPS Clean 10 0.010 -0.113 -1.338 0.778 58711.741

Nhận xét đánh giá từng cặp biến:

1. ROE ~ ROA (Clean)

  • R² ≈ 0.991, Adj-R² ≈ 0.990, Slope ≈ 1.403, và p-value ≈ 1.7e-09 → mối quan hệ rất chặt chẽ và có ý nghĩa thống kê cao.Với mức R² gần như tuyệt đối, có thể kết luận rằng ROA là biến giải thích gần như hoàn toàn cho ROE trong giai đoạn phân tích.

  • Hệ số góc ≈ 1.4 cho thấy ROE ≈ 1.4 × ROA, nghĩa là đòn bẩy tài chính (FL) của PVGas chỉ ở mức 1.3–1.4, phản ánh cấu trúc vốn an toàn, ít phụ thuộc nợ vay

  • Mối quan hệ này thể hiện hiệu suất sinh lời của PVGas chủ yếu đến từ hoạt động kinh doanh cốt lõi (ROA) chứ không đến từ khuếch đại vốn bằng nợ.

2. LNST ~ Doanh thu (Clean)

  • R² ≈ 0.317 cho thấy rằng doanh thu chỉ giải thích khoảng 30% biến động lợi nhuận, phần còn lại đến từ hiệu suất hoạt động (ROA), biến động giá khí, tỷ giá, và chi phí tài chính. Đồng thời Adj-R² ≈ 0.231, Slope ≈ 0.143, và p-value ≈ 0.09 → mô hình có ý nghĩa trung bình, mối quan hệ tuyến tính vừa phải giữa doanh thu và lợi nhuận sau thuế.

  • Mỗi 1 tỷ đồng doanh thu tăng thêm chỉ giúp lợi nhuận tăng khoảng 0.14 tỷ đồng, cho thấy lợi nhuận bị ảnh hưởng mạnh bởi biên lợi nhuận ròng và chi phí biến đổi.

    → Nhìn chung, LNST chịu ảnh hưởng đáng kể từ cấu trúc chi phí và biến động biên lợi nhuận hơn là quy mô doanh thu thuần.

3. Giá ~ EPS (Clean)

  • R² ≈ 0.010, Adj-R² ≈ -0.113, Slope ≈ -1.338, p-value ≈ 0.778 → mô hình không có ý nghĩa thống kê, mối quan hệ giữa giá cổ phiếu và EPS gần như không tồn tại trong ngắn hạn.Điều này ngụ ý rằng sự biến động giá cổ phiếu GAS không phản ánh biến động cùng chiều với EPS mà có thể chịu ảnh hưởng bởi kỳ vọng thị trường, cổ tức, giá dầu thế giới, hoặc chính sách Nhà nước.

2.3.4.2. Tương quan:ROE ~ ROA

1. library(ggplot2)
2. library(dplyr)
3. library(scales)
4. pt_2019 <- data %>% filter(Nam == 2019)
5. r2_full  <- summary(lm(ROE_Nam ~ ROA_Nam, data = data))$r.squared
6. r2_clean <- summary(lm(ROE_Nam ~ ROA_Nam, data = filter(data, Nam != 2019)))$r.squared
7. ggplot(data, aes(x = ROA_Nam, y = ROE_Nam)) +
8.   annotate("rect", xmin = 0, xmax = 40, ymin = 0, ymax = 40,
9.            fill = "grey95", alpha = 0.6) +
10.   geom_point(aes(color = "Full sample"), size = 3, alpha = 0.9) +
11.   geom_point(data = pt_2019, color = "red", size = 4, shape = 8) +
12.   geom_text(data = pt_2019,
13.             aes(label = "2019"),
14.             vjust = -1, color = "red", fontface = "bold", size = 3.5) +
15.   geom_smooth(method = "lm", se = TRUE, color = "#1f77b4",
16.               fill = alpha("#1f77b4", 0.15)) +
17.   geom_smooth(data = filter(data, Nam != 2019),
18.               aes(x = ROA_Nam, y = ROE_Nam),
19.               method = "lm", se = TRUE,
20.               color = "#d62728", linetype = "dashed",
21.               fill = alpha("#d62728", 0.12)) +
22.   geom_abline(slope = 1, intercept = 0,
23.               linetype = "dotdash", color = "grey40") +
24.   annotate("text", x = 6, y = 37,
25.            label = sprintf("R² Full = %.3f", r2_full),
26.            color = "#1f77b4", hjust = 0, size = 3.3) +
27.   annotate("text", x = 6, y = 33,
28.            label = sprintf("R² Clean = %.3f", r2_clean),
29.            color = "#d62728", hjust = 0, size = 3.3) +
30.   coord_cartesian(xlim = c(0, 40), ylim = c(0, 40)) +
31.   scale_x_continuous(labels = label_number(suffix = "%")) +
32.   scale_y_continuous(labels = label_number(suffix = "%")) +
33.   labs(title = "Biểu đồ: Tương quan: ROE ~ ROA (Full vs Clean)",
34.        subtitle = "Đường nét liền: Full | Đường gạch: Clean (loại 2019) | Đường chấm: ROE = ROA",
35.        x = "ROA (%)", y = "ROE (%)", color = "Mẫu dữ liệu") +
36.   scale_color_manual(values = c("Full sample" = "#1f77b4")) +
37.   theme_minimal(base_size = 12) +
38.   theme(
39.     legend.position = "bottom",
40.     panel.grid.minor = element_blank(),
41.     panel.grid.major.x = element_blank()
42.   )

Nhận xét kĩ thuật:

Dòng Giải thích kĩ thuật
Dòng 1–3 Nạp các thư viện chính: ggplot2 (vẽ biểu đồ), dplyr (lọc dữ liệu), scales (định dạng phần trăm).
Dòng 4 Dùng filter() để tách riêng dữ liệu năm 2019
Dòng 5–6 Sử dụng lm() để hồi quy tuyến tính ROE ~ ROA cho hai mẫu (FullClean), sau đó trích xuất bằng $r.squared.
Dòng 7–14 Vẽ điểm dữ liệu tán xạ bằng geom_point(), tô nền xám bằng annotate("rect")
Dòng 15–21 Vẽ hai đường hồi quy tuyến tính cụ thể liền xanh (#1f77b4): Mẫu Fullđứt đỏ (#d62728): Mẫu Clean (loại 2019).
Dòng 22 tham chiếu ROE = ROAbằng geom_abline()
Dòng 24–29 Dùng annotate("text") để hiển thị trực tiếp R² FullR² Clean trên biểu đồ
(30–32) Giới hạn trục X, Y trong khoảng 0–40%, đồng thời định dạng nhãn phần trăm bằng label_number(suffix="%").
Dòng 33–35 Gán tiêu đề, phụ đề, nhãn trục và chú thích
Dòng 36–42 Tùy chỉnh giao diện bằng scale_color_manual()theme_minimal(), ẩn bớt lưới phụ

Nhận xét

Biểu đồ thể hiện mối quan hệ giữa ROEROA, hai chỉ tiêu cốt lõi phản ánh hiệu quả sinh lời và mức đòn bẩy tài chính của GAS.

  • Ở mô hình Full (màu xanh), hệ số tương quan rất thấp (R² ≈ 0.02), do bị làm nhiễu bởi năm 2019, năm ROA tăng đột biến (~2000%) như nhận định bước trên. Khi loại bỏ năm này mô hình Clean (màu đỏ gạch), mối quan hệ trở nên gần tuyến tính (R² ≈ 0.99), với độ dốc ≈ 1.4, thể hiện đòn bẩy tài chính chỉ khoảng 1.4 lần.

  • Đường chấm ROE = ROA cho thấy toàn bộ các điểm dữ liệu nằm phía trên, khẳng định ROE luôn cao hơn ROA, tức doanh nghiệp PV GAS có sử dụng đòn bẩy nhưng ở mức thấp và kiểm soát tốt, mối quan hệ ROE–ROA thể hiện hiệu quả vận hành ổn định.

2.3.4.3. Tương quan: Giá ~ EPS

Xây dựng mô hình tuyến tính giữa giá và EPS

1. library(dplyr)
2. library(ggplot2)
3. library(broom)
4. library(scales)
5. if ("conflicted" %in% rownames(installed.packages())) {
6.   conflicted::conflict_prefer("select",   "dplyr", quiet = TRUE)
7.   conflicted::conflict_prefer("filter",   "dplyr", quiet = TRUE)
8.   conflicted::conflict_prefer("rename",   "dplyr", quiet = TRUE)
9.   conflicted::conflict_prefer("summarise","dplyr", quiet = TRUE)
10. }
11. d_price <- data %>%
12.   dplyr::select(Nam, Gia_DongCua_CuoiNam, EPS) %>%
13.   dplyr::filter(!is.na(EPS), !is.na(Gia_DongCua_CuoiNam))
14. d_clean <- d_price %>% dplyr::filter(Nam != 2019)  # loại outlier nếu muốn
15. m_full  <- lm(Gia_DongCua_CuoiNam ~ EPS, data = d_price)
16. m_clean <- lm(Gia_DongCua_CuoiNam ~ EPS, data = d_clean)
17. r2_full  <- summary(m_full)$r.squared
18. r2_clean <- summary(m_clean)$r.squared
19. summary_models_price_eps <- dplyr::bind_rows(
20.   broom::tidy(m_full)  %>% mutate(Model = "Giá ~ EPS", Mẫu = "Full"),
21.   broom::tidy(m_clean) %>% mutate(Model = "Giá ~ EPS", Mẫu = "Clean")
22. ) %>%
23.   dplyr::filter(term != "(Intercept)") %>%
24.   dplyr::select(Model, Mẫu,
25.                 Slope = estimate,
26.                 `Std.Err` = std.error,
27.                 `t` = statistic,
28.                 `p-value` = p.value) %>%
29.   dplyr::mutate(across(c(Slope, `Std.Err`, `t`), ~round(., 4)),
30.                 `p-value` = signif(`p-value`, 3))
31. print(summary_models_price_eps)
# A tibble: 2 × 6
  Model     Mẫu   Slope Std.Err      t `p-value`
  <chr>     <chr> <dbl>   <dbl>  <dbl>     <dbl>
1 Giá ~ EPS Full  -1.04    4.32 -0.24      0.816
2 Giá ~ EPS Clean -1.34    4.60 -0.291     0.778

Nhận xét kĩ thuật

Dòng Giải thích kĩ thuật
1–4 Gọi các thư việndplyr,ggplot2, broom(tóm tắt mô hình hồi quy), scales(định dạng số liệu).
5–10 dùng conflict_prefer() để thực hiện select, filter, rename, summarise
11–13 Tạo tập dữ liệu mới d_price gồm ba biến chính: Nam, Gia_DongCua_CuoiNamEPS. Sau đó (NA) bằng filter(!is.na())
14 Tạo tập dữ liệu d_clean bằng cách loại bỏ năm 2019
15–16 Xây dựng hai mô hình hồi quy tuyến tính bằng lm()mẫu full và clean
17–18 Tính summary(model)$r.squared
19–21 Dùng broom::tidy()để trích xuất kết quả hồi quy (slope, std.error, p-value), gắn nhãn ModelMẫu (Full/Clean) bằng mutate(), thực hiện kết hợp bảng bằng bind_rows().
22–28 Lọc bỏ hệ số chặn (Intercept)
29–30 Làm tròn các giá trị số bằng mutate(across()) và chuẩn hóa định dạng p-value với signif()
31 In ra bảng kết quả

Nhận xét

Mẫu Hệ số dốc (β) p-value Diễn giải
Full (11 năm) -1.04 0.006 0.816 Không có ý nghĩa thống kê. Mối quan hệ gần như ngẫu nhiên.
Clean (10 năm) -1.34 0.010 0.778 Kết quả tương tự; loại bỏ 2019 không cải thiện đáng kể.

Cả hai mô hình đều có R² rất thấp (<1%)p-value > 0.7, chứng minh rằng biến động giá cổ phiếu GAS không phụ thuộc tuyến tính vào EPS kế toán

Biểu đồ tương quan giá và EPS

1. ggplot(d_price, aes(x = EPS, y = Gia_DongCua_CuoiNam)) +
2.   annotate("rect", xmin = 3000, xmax = 8000, ymin = 20000, ymax = 75000,
3.            fill = "grey95", alpha = 0.7) +
4.   geom_point(aes(color = "Full"), size = 3, alpha = 0.9) +
5.   geom_smooth(method = "lm", se = TRUE, color = "#1f77b4",
6.               fill = alpha("#1f77b4", 0.15)) +
7.   geom_smooth(data = d_clean, aes(x = EPS, y = Gia_DongCua_CuoiNam, color = "Clean"),
8.               method = "lm", se = TRUE, linetype = "dashed",
9.               fill = alpha("#d62728", 0.12)) +
10.   annotate("text", x = min(d_price$EPS, na.rm=TRUE), y = max(d_price$Gia_DongCua_CuoiNam, na.rm=TRUE),
11.            hjust = 0, vjust = 1.2, size = 3.5, color = "#1f77b4",
12.            label = sprintf("R² Full = %.3f", r2_full)) +
13.   annotate("text", x = min(d_price$EPS, na.rm=TRUE), y = max(d_price$Gia_DongCua_CuoiNam, na.rm=TRUE) - 3000,
14.            hjust = 0, vjust = 1.2, size = 3.5, color = "#d62728",
15.            label = sprintf("R² Clean = %.3f", r2_clean)) +
16.   scale_x_continuous(labels = comma) +
17.   scale_y_continuous(labels = comma) +
18.   scale_color_manual(values = c("Full" = "#1f77b4", "Clean" = "#d62728"),
19.                      name = "Mẫu dữ liệu") +
20.   labs(title = "Biểu đồ: Tương quan: Giá cổ phiếu ~ EPS (Full vs Clean)",
21.        subtitle = "Đường liền: Full | Đường gạch: Clean (loại 2019)",
22.        x = "EPS (VND/cp)", y = "Giá đóng cửa cuối năm (VND)") +
23.   theme_minimal(base_size = 12) +
24.   theme(legend.position = "bottom",
25.         panel.grid.minor = element_blank(),
26.         panel.grid.major.x = element_blank())

Nhận xét

Biểu đồ cho thấy mối tương quan giữa EPS và giá cổ phiếu của GAS gần như không có, với hệ số xác định rất thấp (R² Full = 0.006, R² Clean = 0.010).
Cả hai đường hồi quy (Full – xanh, Clean – đỏ gạch) đều gần như nằm ngang,
cho thấy EPS tăng không kéo theo giá cổ phiếu tăng. Việc loại bỏ năm 2019 (outlier) không cải thiện đáng kể mô hình, chứng minh rằng giá cổ phiếu GAS không bị chi phối bởi lợi nhuận kế toán, mà có thể chịu ảnh hưởng mạnh từ yếu tố vĩ mô và kỳ vọng thị trường.

2.3.4.4. Tương quan hiệu quả hoạt động thực tế: LNST ~ Doanh thu

1. library(dplyr)
2. library(ggplot2)
3. library(broom)
4. library(scales)
5. d_oper <- data %>%
6.   dplyr::select(Nam, DoanhThu, LoiNhuanSauThue) %>%
7.   dplyr::filter(!is.na(DoanhThu), !is.na(LoiNhuanSauThue))
8. d_oper_clean <- d_oper %>% dplyr::filter(Nam != 2019)
9. m_full  <- lm(LoiNhuanSauThue ~ DoanhThu, data = d_oper)
10. m_clean <- lm(LoiNhuanSauThue ~ DoanhThu, data = d_oper_clean)
11. r2_full  <- summary(m_full)$r.squared
12. r2_clean <- summary(m_clean)$r.squared
13. # Biểu đồ 2.3.4.d: Tương quan LNST ~ Doanh thu
14. ggplot(d_oper, aes(x = DoanhThu, y = LoiNhuanSauThue)) +
15.   annotate("rect", xmin = 50000, xmax = 100000, ymin = 5000, ymax = 15000,
16.            fill = "grey95", alpha = 0.6) +
17.   geom_point(aes(color = "Full"), size = 3, alpha = 0.9) +
18.   geom_smooth(method = "lm", se = TRUE, color = "#0072B2", fill = alpha("#0072B2", 0.15)) +
19.   geom_smooth(data = d_oper_clean,
20.               aes(x = DoanhThu, y = LoiNhuanSauThue, color = "Clean"),
21.               method = "lm", se = TRUE, linetype = "dashed",
22.               fill = alpha("#D55E00", 0.12)) +
23.   annotate("text", x = 55000, y = 14500, label = sprintf("R² Full = %.3f", r2_full),
24.            hjust = 0, size = 3.5, color = "#0072B2") +
25.   annotate("text", x = 55000, y = 13500, label = sprintf("R² Clean = %.3f", r2_clean),
26.            hjust = 0, size = 3.5, color = "#D55E00") +
27.   scale_x_continuous(labels = label_number(big.mark = ",", suffix = " tỷ VND")) +
28.   scale_y_continuous(labels = label_number(big.mark = ",", suffix = " tỷ VND")) +
29.   scale_color_manual(values = c("Full" = "#0072B2", "Clean" = "#D55E00"),
30.                      name = "Mẫu dữ liệu") +
31.   labs(title = "Biểu đồ: Tương quan: Lợi nhuận sau thuế ~ Doanh thu (Full vs Clean)",
32.        subtitle = "Đường liền: Full | Đường gạch: Clean (loại 2019)",
33.        x = "Doanh thu thuần (tỷ VND)",
34.        y = "Lợi nhuận sau thuế (tỷ VND)") +
35.   theme_minimal(base_size = 12) +
36.   theme(legend.position = "bottom",
37.         panel.grid.minor = element_blank(),
38.         panel.grid.major.x = element_blank())

Nhận xét kĩ thuật

Nhận xét

  • Quan sát cho thấy cả hai mô hình Full và Clen đều có độ dốc dương, nghĩa là khi doanh thu tăng thì lợi nhuận cũng tăng , tuy nhiên mức tương quan chỉ trung bình yếu, với R² Full = 0.298 và R² Clean = 0.317. Điều này chỉ ra rằng doanh thu chỉ giải thích được khoảng 30% biến động lợi nhuận, phần còn lại đến từ các yếu tố khác như giá dầu, chi phí vận hành, và chênh lệch tỷ giá. Mặc dù có xu hướng cùng chiều, LNST của GAS không tỷ lệ tuyến tính hoàn toàn với doanh thu, phản ánh đặc trưng của ngành khí - biên lợi nhuận phụ thuộc mạnh vào điều kiện thị trường hơn là quy mô doanh thu.

  • Kết quả củng cố nhận định rằng tăng trưởng quy mô (doanh thu) là động lực chính, còn biên lợi nhuận và đòn bẩy sẽ được giải thích sâu hơn trong phần 2.4 Phân tích DuPont.

2.3.5. Tóm tắt các phát hiện chính về Hiệu suất và Tăng trưởng của GAS (2014–2024)

Tổng hợp các phát hiện định lượng và trực quan hóa từ toàn bộ nhóm biến Hiệu suất & Tăng trưởng, bao gồm Doanh thu, Lợi nhuận, ROE, ROA, Biên lợi nhuận ròng, EPS và Tốc độ tăng trưởng YoY, nhằm khái quát hóa đặc trưng vận hành và năng lực sinh lời của Tổng công ty Khí Việt Nam (GAS) trong giai đoạn 2014–2024.

1. Nền tảng quy mô ổn định và sức chống chịu chu kỳ mạnh

  • Doanh thu thuần bình quân ≈ 77 nghìn tỷ VND, với hệ số biến thiên (CV) = 0.195, thể hiện độ ổn định cao bất chấp các biến động chu kỳ giá dầu.
  • CAGR Doanh thu = 3.5%/năm cho cả giai đoạn 2014–2024, phản ánh tốc độ mở rộng hợp lý và nhất quán.
  • Trong khi đó, CAGR Lợi nhuận giai đoạn 2016–2024 = 4.99%, cho thấy doanh nghiệp đã phục hồi bền vững sau khủng hoảng 2015–2016 và duy trì đà tăng trưởng tích cực.

Kết luận: Quy mô hoạt động của GAS có tính ổn định cấu trúc, đóng vai trò “vành đai hấp thụ rủi ro” trong chu kỳ giá năng lượng.

2. Biên lợi nhuận ròng cao và duy trì ổn định

  • Biên lợi nhuận ròng trung bình ≈ 13.0%, dao động chủ yếu trong khoảng 10–18%.

  • Phân phối có Skewness âm (-1.34)Kurtosis cao (4.88), nghĩa là:

    • Phần lớn năm GAS có biên lợi nhuận tốt,
    • Nhưng tồn tại một số năm đáy cực thấp (2015–2016) khi giá dầu giảm mạnh.

Kết luận: GAS duy trì khả năng kiểm soát chi phí và biên lợi nhuận hiệu quả; chỉ biến động mạnh trong các cú sốc dầu khí toàn cầu.

3. ROE duy trì mức cao, ROA ổn định – đòn bẩy tài chính an toàn

  • ROE trung bình = 20.6%, ROA trung vị ≈ 15.6%, chênh lệch nhỏ phản ánh đòn bẩy tài chính thấp (FL ≈ 1.3).
  • Ngoại trừ năm 2019 (ROA ≈ 2000%) – sai lệch kế toán hoặc mẫu số bất thường – hai chỉ tiêu này di chuyển gần như song song và đồng pha.

4. Mối quan hệ giữa Doanh thu và Lợi nhuận: tăng trưởng thực chất

  • Hồi quy ( = -775 + 0.14 ) ⇒ Khi doanh thu tăng 1.000 tỷ, lợi nhuận tăng ≈ 140 tỷ VND (tương ứng hiệu suất 14%).
  • ( R^2 ≈ 0.30–0.32 ), chứng tỏ mối quan hệ tuyến tính vừa phải nhưng ổn định, phản ánh rằng phần lớn biến động lợi nhuận đến từ biến thiên biên lợi nhuận, không phải doanh thu.

Kết luận: Tăng trưởng doanh thu của GAS thực sự chuyển hóa thành lợi nhuận, nhưng biên lợi nhuận là nhân tố quyết định hiệu suất ròng.

5. Mối liên hệ Giá cổ phiếu – EPS yếu: thị trường phản ứng chậm

  • Độ dốc âm và R² rất thấp cho thấy thị trường không phản ánh trực tiếp lợi nhuận kế toán vào giá cổ phiếu, mà chịu chi phối mạnh bởi giá dầu, biến động vĩ mô, và tâm lý đầu tư.

6. Tổng hợp

Tóm tắt phân tích

Giai đoạn Đặc trưng chính Tác động tài chính
2014–2016 Suy giảm mạnh do khủng hoảng dầu khí Biên LNR < 5%, ROE giảm, EPS thấp
2017–2019 Phục hồi và ổn định Biên LNR ~13–15%, ROE ~20%
2020 Cú sốc COVID và giá dầu âm Lợi nhuận gần 0, ROE thấp nhất
2021–2024 Phục hồi mạnh và tái ổn định ROE, EPS và Biên LNR tăng trở lại

Bảng tóm tắt ngắn gọn:

Chỉ tiêu Trung bình Độ biến động Xu hướng chính
Doanh thu ~77 nghìn tỷ VND Thấp Ổn định, tăng chậm
LNST ~10 nghìn tỷ VND Trung bình Nhạy với chu kỳ giá dầu
Biên LNR ~13% Thấp Duy trì bền vững
ROE ~20.6% Thấp Ổn định, đòn bẩy thấp
ROA ~15.6% (median) Cao (do 2019) Hiệu quả tài sản cao
EPS ~5,500 VND/cp Thấp Gắn chặt Biên LNR
R²(ROE~ROA) 0.991 (clean) Quan hệ tuyến tính mạnh
R²(LNST~DT) 0.30 Quan hệ dương, ổn định
R²(Giá~EPS) 0.01 Thị trường phản ứng yếu

2.4. PHÂN TÍCH HIỆU SUẤT TÀI CHÍNH VÀ CẤU TRÚC SINH LỜI

2.4.1. Phân tích cấu trúc sinh lời ROE bằng Dupont

Mục tiêu của phần này là tách tỷ suất sinh lời trên vốn chủ sở hữu (ROE) thành ba yếu tố chính để xác định nguồn gốc tạo ra lợi nhuận của doanh nghiệp PV GAS:

\[ ROE = \text{NPM} \times \text{TAT} \times \text{FL} \]

Trong đó:

  • NPM: Biên lợi nhuận ròng (Net Profit Margin) dùng để đo hiệu quả kiểm soát chi phí và khả năng chuyển hóa doanh thu thành lợi nhuận ròng.

  • TAT: Hiệu suất sử dụng tài sản (Total Asset Turnover) sẽ phản ánh tốc độ quay vòng tài sản

  • FL: Đòn bẩy tài chính (Financial Leverage) cho biết mức khuếch đại lợi nhuận từ vốn chủ sở hữu.

2.4.1.1. Cấu trúc ROE theo thời gian

Tóm tắt trung bình DuPont trung bình (2014–2024

1. library(dplyr)
2. library(tidyr)
3. library(ggplot2)
4. library(scales)
5. dupont_df <- data %>%
6.   mutate(
7.     BienLoiNhuanRong = BienLoiNhuanRong_Nam / 100,   
8.     TAT = TAT_Nam,                                   
9.     FL  = FL_Nam,                                    
10.     ROE_DuPont = BienLoiNhuanRong * TAT * FL * 100   
11.   ) %>%
12.   select(Nam, BienLoiNhuanRong, TAT, FL, ROE_DuPont, ROE_Nam)
13. dupont_summary <- dupont_df %>%
14.   summarise(
15.     Mean_NPM = mean(BienLoiNhuanRong, na.rm = TRUE) * 100,
16.     Mean_TAT = mean(TAT, na.rm = TRUE),
17.     Mean_FL  = mean(FL, na.rm = TRUE),
18.     Mean_ROE_ThucTe = mean(ROE_Nam, na.rm = TRUE),
19.     Mean_ROE_DuPont = mean(ROE_DuPont, na.rm = TRUE)
20.   )
21. print(dupont_summary)
  Mean_NPM Mean_TAT Mean_FL Mean_ROE_ThucTe Mean_ROE_DuPont
1       13       12    1.25            20.6            20.6

Nhận xét

Chỉ tiêu Giá trị trung bình Ý nghĩa
Biên lợi nhuận ròng (NPM) 13% Doanh nghiệp duy trì biên lợi nhuận ổn định và cao trong ngành năng lượng.
Hiệu suất sử dụng tài sản (TAT) 12% Mỗi đồng tài sản tạo ra 0.12 đồng doanh thu, phản ánh hiệu quả tài sản ở mức khá.
Đòn bẩy tài chính (FL) 1.25 lần Mức đòn bẩy thấp, cấu trúc vốn an toàn, rủi ro tài chính nhỏ.
ROE thực tế (Mean) 20.6% Mức sinh lời cao, ổn định qua nhiều năm.
ROE tính theo DuPont 20.6% Khớp hoàn toàn với ROE thực tế → mô hình phản ánh đúng cấu trúc sinh lời.

Biểu đồ 2.4.1.1: Cấu trúc ROE theo thời gian

1. dupont_long <- dupont_df %>%
2.   select(Nam, BienLoiNhuanRong, TAT, FL) %>%
3.   pivot_longer(cols = c(BienLoiNhuanRong, TAT, FL),
4.                names_to = "ThànhPhan", values_to = "GiáTrị")
5. ggplot(dupont_long, aes(x = Nam, y = GiáTrị, fill = ThànhPhan)) +
6.   geom_area(alpha = 0.8, color = "white", size = 0.4) +
7.   scale_fill_manual(
8.     values = c("BienLoiNhuanRong" = "#0072B2",
9.                "TAT" = "#E69F00",
10.                "FL"  = "#56B4E9"),
11.     labels = c("BienLoiNhuanRong" = "Biên lợi nhuận ròng (NPM)",
12.                "TAT" = "Hiệu suất tài sản (TAT)",
13.                "FL"  = "Đòn bẩy tài chính (FL)")
14.   ) +
15.   labs(
16.     title = "Cấu trúc ROE theo thời gian (2014–2024)",
17.     subtitle = "ROE = Biên lợi nhuận ròng × Hiệu suất sử dụng tài sản × Đòn bẩy tài chính",
18.     x = "Năm",
19.     y = "Giá trị (hệ số)",
20.     fill = "Thành phần"
21.   ) +
22.   theme_minimal(base_size = 10) +
23.   theme(legend.position = "bottom",
24.         plot.title = element_text(face = "bold", hjust = 0.5),
25.         plot.subtitle = element_text(size = 9, hjust = 0.5))

Nhận xét

  • Hình tam giác vàng lớn tại năm 2019 thể hiện hiệu suất sử dụng tài sản (TAT) đột biến — do mẫu số “Tổng tài sản” giảm mạnh hoặc giá trị kế toán bất thường, dẫn đến ROA và ROE cực cao (outlier). Đây là hiện tượng sai lệch kế toán (hoặc hiệu ứng cơ sở nhỏ) chứ không phải hiệu suất thực tế.
  • Ngoài năm 2019, ba thành phần NPM – TAT – FL đều ổn định quanh trục giá trị thấp và song hành theo thời gian, phản ánh mô hình vận hành bền vững, ít phụ thuộc đòn bẩy.

→ Có thể khẳng định: TAT và NPM là hai yếu tố chi phối ROE, trong khi FL giữ vai trò khuếch đại nhẹ

2.4.1.2.So sánh ROE thực tế và ROE theo mô hình DuPont

1. ggplot(dupont_df, aes(x = Nam)) +
2.   geom_line(aes(y = ROE_Nam, color = "ROE thực tế"), linewidth = 1.2) +
3.   geom_point(aes(y = ROE_Nam, color = "ROE thực tế"), size = 3) +
4.   geom_line(aes(y = ROE_DuPont, color = "ROE tính theo DuPont"), linewidth = 1.2, linetype = "dashed") +
5.   geom_point(aes(y = ROE_DuPont, color = "ROE tính theo DuPont"), size = 2) +
6.   scale_color_manual(values = c("ROE thực tế" = "#D55E00", "ROE tính theo DuPont" = "#0072B2")) +
7.   scale_y_continuous(labels = label_number(suffix = "%")) +
8.   labs(
9.     title = "So sánh ROE thực tế và ROE theo mô hình DuPont",
10.     x = "Năm",
11.     y = "Tỷ suất sinh lời (%)",
12.     color = "Loại ROE"
13.   ) +
14.   theme_minimal(base_size = 12) +
15.   theme(legend.position = "bottom",
16.         plot.title = element_text(face = "bold", hjust = 0.5),
17.         panel.grid.minor = element_blank())

Nhận xét

  • Hai đường ROE thực tế (cam)ROE theo DuPont (xanh) trùng khớp hoàn toàn, R² ≈ 1.
  • Sai lệch chỉ xuất hiện nhẹ quanh các giai đoạn 2020–2021 (COVID và hồi phục), chứng tỏ mô hình DuPont giải thích gần như toàn bộ biến động sinh lời của GAS.
  • Điều này cho thấy ROE của GAS được chi phối gần như hoàn toàn bởi ba yếu tố nội tại, ít chịu tác động của yếu tố ngoài bảng (ví dụ: lợi nhuận tài chính hay chênh lệch tỷ giá).

Tổng hợp cấu trúc sinh lời của doanh nghiệp PV GAS

Thành phần Vai trò trong ROE Đặc điểm tại GAS
NPM Quyết định chất lượng lợi nhuận Ổn định quanh 13%, cao so với trung bình ngành.
TAT Phản ánh hiệu quả khai thác tài sản Duy trì 0.12–0.15, cải thiện giai đoạn sau 2021.
FL Khuếch đại lợi nhuận vốn chủ Thấp (1.2–1.3) → GAS gần như không vay nợ nhiều.

2.4.1.3. Trực quan độ nhạy của ROE theo DuPont

Cơ sở lý thuyết

Theo mô hình DuPont:

\[ ROE = NPM \times TAT \times FL \]

Ta có vi phân tương đối (độ nhạy tuyến tính):

\[ \frac{\Delta ROE}{ROE} = \frac{\Delta NPM}{NPM} + \frac{\Delta TAT}{TAT} + \frac{\Delta FL}{FL} \]

Suy ra, hệ số co giãn của ROE theo từng biến được tính bằng:

\[ E_{ROE,x} = \frac{\partial (ROE) / ROE}{\partial x / x} = \frac{x}{ROE} \times \frac{\partial (ROE)}{\partial x} \]

Do \(\frac{\partial ROE}{\partial NPM} = TAT \times FL\), ta có:

Thành phần Hệ số co giãn
\(E_{ROE,NPM} = \frac{NPM \times TAT \times FL}{ROE}\) ≈ 1
\(E_{ROE,TAT} = \frac{NPM \times TAT \times FL}{ROE}\) ≈ 1
\(E_{ROE,FL} = \frac{NPM \times TAT \times FL}{ROE}\) ≈ 1

Trong mô hình tuyến tính hoàn hảo, tất cả các hệ số co giãn đều bằng 1.
Tuy nhiên, trong dữ liệu thực tế, do phi tuyến và các hiệu ứng kế toán, ta đo mức thay đổi ROE (%) khi từng biến tăng 1%, giữ các biến khác cố định.

Mục tiêu

Phân tích độ nhạy nhằm xác định ROE của GAS nhạy cảm nhất với yếu tố nào trong ba thành phần của mô hình DuPont:

  • Biên lợi nhuận ròng (NPM)
  • Hiệu suất sử dụng tài sản (TAT)
  • Đòn bẩy tài chính (FL)

Từ đó, xác định nguồn gốc động lực sinh lời chủ yếumức độ bền vững của ROE.

1. library(dplyr)
2. library(ggplot2)
3. library(scales)
4. dupont_sens <- dupont_df %>%
5.   mutate(
6.     dNPM = (BienLoiNhuanRong * 1.01) * TAT * FL * 100,
7.     dTAT = BienLoiNhuanRong * (TAT * 1.01) * FL * 100,
8.     dFL  = BienLoiNhuanRong * TAT * (FL * 1.01) * 100,
9.     Sens_NPM = (dNPM - ROE_DuPont) / ROE_DuPont * 100,
10.     Sens_TAT = (dTAT - ROE_DuPont) / ROE_DuPont * 100,
11.     Sens_FL  = (dFL  - ROE_DuPont) / ROE_DuPont * 100
12.   ) %>%
13.   select(Nam, Sens_NPM, Sens_TAT, Sens_FL) %>%
14.   pivot_longer(cols = starts_with("Sens_"),
15.                names_to = "ThànhPhan", values_to = "ĐộNhạy") %>%
16.   mutate(ThànhPhan = recode(ThànhPhan,
17.                             "Sens_NPM" = "Biên lợi nhuận ròng (NPM)",
18.                             "Sens_TAT" = "Hiệu suất tài sản (TAT)",
19.                             "Sens_FL"  = "Đòn bẩy tài chính (FL)"))
20. ggplot(dupont_sens, aes(x = Nam, y = ĐộNhạy, color = ThànhPhan, group = ThànhPhan)) +
21.   geom_line(linewidth = 1.2) +
22.   geom_point(size = 2) +
23.   geom_hline(yintercept = 1, color = "grey40", linetype = "dotted") +
24.   scale_color_manual(values = c("#0072B2", "#E69F00", "#56B4E9")) +
25.   scale_y_continuous(labels = label_percent(scale = 1)) +
26.   labs(
27.     title = "Độ nhạy của ROE theo mô hình DuPont",
28.     subtitle = "Biểu diễn mức thay đổi (%) của ROE khi từng thành phần tăng 1%",
29.     x = "Năm", y = "Độ nhạy (%)",
30.     color = "Thành phần ảnh hưởng"
31.   ) +
32.   theme_minimal(base_size = 12) +
33.   theme(legend.position = "bottom",
34.         plot.title = element_text(face = "bold", hjust = 0.5))

Nhận xét kĩ thuật

  • Dòng 4–12: dùng mutate() tạo hàm tính các giá trị ROE giả định (dNPM, dTAT, dFL) khi từng yếu tố tăng 1%, rồi tính độ nhạy (%) bằng công thức
    (dX - ROE_DuPont) / ROE_DuPont * 100.

  • Dòng 13–19: chọn các cột cần thiết bằng select(), chuyển dữ liệu sang dạng dài pivot_longer() , và đổi tên biến recode().

  • Dòng 20–25 (ggplot(), geom_line(), geom_point(), geom_hline()): vẽ biểu đồ đường biểu diễn độ nhạy của từng yếu tố qua các năm, thêm đường tham chiếu 1% để dễ so sánh.

  • Dòng 24 (scale_color_manual()) & 25 (scale_y_continuous()): thiết lập màu sắc cho từng yếu tố và định dạng trục Y hiển thị phần trăm (label_percent).

  • Dòng 26–34 (labs(), theme_minimal(), theme()): đặt tiêu đề, nhãn và tùy chỉnh bố cục hiển thị của biểu đồ.

Kết quả mô phỏng độ nhạy

Thành phần Độ nhạy trung bình (E) Diễn giải
NPM (Biên lợi nhuận ròng) ≈ 1.00 Tăng 1% NPM → ROE tăng 1%
TAT (Hiệu suất tài sản) ≈ 1.00 Tăng 1% TAT → ROE tăng 1%
FL (Đòn bẩy tài chính) ≈ 1.00 Tăng 1% FL → ROE tăng 1%

Kết quả cho thấy ba đường (NPM, TAT, FL) trùng nhau ở mức 1%, chứng tỏ ROE của GAS biến động tuyến tính hoàn hảo theo từng yếu tố trong mô hình DuPont. Mặc dù độ nhạy tương đối bằng nhau (1:1), tác động thực tế khác nhau do giá trị nền của từng yếu tố khác nhau:

  • NPM (~13%) có ảnh hưởng lớn nhất đến ROE, phản ánh hiệu quả kiểm soát chi phí và biến động giá dầu/khí.

  • TAT (~0.12) có tác động nhỏ hơn do vòng quay tài sản chậm

  • FL (~1.25) ổn định, cho thấy GAS ít sử dụng nợ vay và duy trì cấu trúc vốn an toàn.

2.4.1.4. Mô phỏng tác động đồng thời của NPM và TAT lên ROE

1. Mục tiêu

Phân tích và trực quan hóa tác động kết hợp giữa Biên lợi nhuận ròng (NPM)Hiệu suất sử dụng tài sản (TAT) đến tỷ suất sinh lời trên vốn chủ (ROE) theo mô hình DuPont. Từ đó xác định vùng sinh lời tối ưu, và đánh giá mức độ phụ thuộc lẫn nhau giữa hai yếu tố vận hành cốt lõi.

2. Cơ sở lý thuyết

Theo mô hình DuPont rút gọn (vì FL gần như ổn định):

\[ ROE = NPM \times TAT \times FL \]

Với giá trị trung bình \(FL = 1.25\) (giai đoạn 2014–2024), công thức trở thành:

\[ ROE = 1.25 \times NPM \times TAT \]

Từ đó, mô phỏng ROE theo các mức kết hợp khác nhau của NPMTAT nhằm đánh giá:

  • Mức độ gia tăng ROE khi biên lợi nhuận (NPM) cải thiện;
  • Khả năng bứt phá hiệu quả sinh lời khi hiệu suất tài sản (TAT) tăng cao.
1. library(ggplot2)
2. library(dplyr)
3. library(scales)
4. npm_seq <- seq(0.05, 0.25, by = 0.005)   # 5% → 25%
5. tat_seq <- seq(0.05, 0.25, by = 0.005)   # 0.05 → 0.25
6. fl_fixed <- 1.25
7. heat_df <- expand.grid(NPM = npm_seq, TAT = tat_seq) %>%
8.   mutate(ROE = NPM * TAT * fl_fixed)
9. ggplot(heat_df, aes(x = NPM, y = TAT, fill = ROE)) +
10.   geom_tile() +
11.   geom_contour(aes(z = ROE), color = "white", linewidth = 0.3) +
12.   scale_fill_gradient(low = "#f7fbff", high = "#08306b", labels = label_percent(accuracy = 1)) +
13.   labs(
14.     title = "Mô phỏng tác động đồng thời của NPM và TAT lên ROE",
15.     subtitle = "Mô hình DuPont (FL cố định = 1.25) | ROE = NPM × TAT × FL",
16.     x = "Biên lợi nhuận ròng (NPM)",
17.     y = "Hiệu suất sử dụng tài sản (TAT)",
18.     fill = "ROE (%)"
19.   ) +
20.   theme_minimal(base_size = 9) +
21.   theme(
22.     legend.position = "right",
23.     plot.title = element_text(face = "bold", hjust = 0.5),
24.     plot.subtitle = element_text(size = 7)
25.   )

Nhận xét kĩ thuật

  • Dòng 1-3: tải các gói dữ liệu cần thiết cho biểu đồ ( đã phân tích trên)

  • Dòng 4–6: dùng seq() & gán biến tạo dãy giá trị cho NPM và TAT trong khoảng 0.05–0.25 (tức 5–25%), và cố định FL = 1.25.

  • Dòng 7–8: tạo kết hợp giữa NPM và TAT bằng expand.grid(), rồidùng mutate()tính ROE = NPM × TAT × FL cho từng điểm.

  • Dòng 9–11: dùng geom_tile() tạo bản đồ nhiệt (heatmap) thể hiện cường độ ROE theo màu sắc, geom_contour() thêm các đường đồng mức ROE

  • Dòng 12 (): chỉnh thang màu từ nhạt (ROE thấp) đến đậm (ROE cao) bằng scale_fill_gradient()

  • Dòng 13–19: dùng labs() đặt tiêu đề, phụ đề, nhãn trục và ghi chú thang màu, nêu công thức chú thích.

  • Dòng 20–25: dùng theme_minimal()làm gọn giao diện, căn giữa tiêu đề và bố trí chú thích ở bên phải.

Nhận xét

Thành phần Ảnh hưởng đến ROE Giải thích chi tiết
NPM – Biên lợi nhuận ròng Tác động mạnh nhất Khi NPM tăng, mỗi đồng doanh thu tạo ra nhiều lợi nhuận hơn → ROE tăng nhanh.
TAT – Hiệu suất sử dụng tài sản Tác động khuếch đại Khi TAT cao, tài sản quay vòng nhanh hơn → cùng biên lợi nhuận, ROE vẫn cao hơn.
FL – Đòn bẩy tài chính Ổn định, đóng vai trò cố định FL cố định 1.25 giúp ROE phản ánh đúng hiệu quả nội tại thay vì bị khuếch đại bởi nợ vay.

Tóm lại: Mô hình mô phỏng xác nhận ROE của GAS phụ thuộc đồng thời và tuyến tính vào NPM và TAT.Vùng hiệu quả cao (ROE > 6%) đạt được khi NPM > 20% và TAT > 0.20,thể hiện khả năng sinh lời bền vững của GAS từ hiệu quả vận hành chứ không từ rủi ro tài chính.

2.4.2. Độ nhạy lợi nhuận ROA/ROE theo NPM & TAT

Kiểm định và đánh giá mối quan hệ tuyến tính giữa Biên lợi nhuận ròng (NPM)Tỷ suất sinh lời trên tài sản (ROA). Mục tiêu là xác định xem ROA có phản ánh trực tiếp khả năng sinh lợi ròng, hay chịu ảnh hưởng mạnh của yếu tố khác như cơ cấu tài sản hoặc chi phí vốn.

2.4.2.1. Chuẩn hóa dữ liệu đầu vào

1. library(dplyr)
2. library(ggplot2)
3. library(broom)
4. library(scales)
5. dupont_df <- data %>%
6.   transmute(
7.     Nam,
8.     NPM = BienLoiNhuanRong_Nam / 100,
9.     TAT = TAT_Nam,
10.     FL  = FL_Nam,
11.     ROA = ROA_Nam / 100,
12.     ROE_ThucTe = ROE_Nam / 100
13.   ) %>%
14.   mutate(
15.     ROE_DuPont = NPM * TAT * FL
16.   )

2.4.2.2. Phân tích (NPM) và (ROA) giữa mẫu gốc và mẫu điều chỉnh bằng hồi quy

1. d_profit <- dupont_df %>% dplyr::select(Nam, NPM, ROA)
2. d_profit_clean <- d_profit %>% filter(Nam != 2019)
3. lm_full  <- lm(NPM ~ ROA, data = d_profit)
4. lm_clean <- lm(NPM ~ ROA, data = d_profit_clean)
5. res_full  <- summary(lm_full)
6. res_clean <- summary(lm_clean)
7. result_table_242 <- tibble::tibble(
8.   Mẫu      = c("Full", "Clean"),
9.   n        = c(nrow(d_profit), nrow(d_profit_clean)),
10.   R2       = c(res_full$r.squared,  res_clean$r.squared),
11.   Adj_R2   = c(res_full$adj.r.squared, res_clean$adj.r.squared),
12.   Slope    = c(coef(lm_full)[2], coef(lm_clean)[2]),
13.   `p-value(Slope)` = c(res_full$coefficients[2,4], res_clean$coefficients[2,4]),
14.   Intercept= c(coef(lm_full)[1], coef(lm_clean)[1])
15. )
16. print(result_table_242)
# A tibble: 2 × 7
  Mẫu       n     R2  Adj_R2   Slope `p-value(Slope)` Intercept
  <chr> <int>  <dbl>   <dbl>   <dbl>            <dbl>     <dbl>
1 Full     11 0.0525 -0.0528 0.00184       0.498         0.127 
2 Clean    10 0.930   0.921  0.718         0.00000670    0.0218

Nhận xét kĩ thuật

  • Dòng 1–2 : dùng select() chọn NPMROA từ bộ dupont_dftạo ở bước chuẩn hóa dữ liệu, dùng filter() 2019 khỏi mẫu “Clean”

  • Dòng 3–4 (lm()): xây dựng hai mô hình hồi quy tuyến tính NPM ~ ROA cho mẫu Full và Clean

  • Dòng 5–6: dùng summary() để tổng hợp , Adj R², hệ số góc (Slope)p-value.

  • Dòng 7–15: tính các giá trị và tổng hợp kết quả của hai mô hình vào bảng result_table_242

  • Dòng 16 (print()): in bảng kết quả so sánh giữa hai mô hình.

Kết quả mô hình:

Mẫu n Adj-R² Slope p-value(Slope) Intercept
Full 11 0.0525 -0.0528 0.00184 0.4979 0.1267
Clean 10 0.9302 0.9214 0.7176 0.000067 0.0218

Nhận xét chi tiết

  • Mẫu Full:
    • R² chỉ đạt 0.05, hệ số hồi quy (Slope) rất nhỏ ≈ 0.0018p-value = 0.4979mối quan hệ không có ý nghĩa thống kê.
    • Nghĩa là trong mẫu đầy đủ, ROA không giải thích được biến động của NPM, chủ yếu do năm 2019 là một outlier khiến mối quan hệ bị nhiễu.
    • Hệ số âm của Adj-R² cho thấy mô hình không phù hợp, độ sai lệch lớn.
  • Mẫu Clean (loại năm 2019):
    • R² tăng vọt lên 0.93, Adj-R² đạt 0.92, p-value cực nhỏ (6.7e-05)mối quan hệ rất mạnh và có ý nghĩa thống kê cao.
    • Hệ số góc Slope ≈ 0.72 cho thấy mỗi 1% ROA tăng thêm sẽ làm Biên lợi nhuận ròng (NPM) tăng khoảng 0.72%.
    • Điều này phản ánh mối quan hệ tuyến tính chặt chẽ giữa hiệu quả sử dụng tài sản và biên lợi nhuận, tức là khi PVGas sử dụng tài sản hiệu quả hơn, khả năng sinh lời ròng cũng tăng tương ứng.

Bảng tổng kết

Nhận xét Diễn giải
Mối quan hệ Tuyến tính, chặt chẽ và có ý nghĩa thống kê cao trong mẫu Clean
Hệ số dốc (Slope) 0.72 → ROA tăng 1% → NPM tăng 0.72%
Ý nghĩa NPM phản ánh gần như trực tiếp hiệu quả hoạt động (ROA) của doanh nghiệp
Kết luận Sau khi loại bỏ năm 2019, mô hình trở nên ổn định và phù hợp, khẳng định ROA là yếu tố quyết định biên lợi nhuận ròng của PVGas

2.4.2.3. Trực quan NPM ~ ROA

1. ggplot() +
2.   geom_point(data = d_profit,
3.              aes(x = ROA, y = NPM),
4.              size = 3, alpha = 0.85, color = "#264C99") +
5.   geom_smooth(data = d_profit,
6.               aes(x = ROA, y = NPM),
7.               method = "lm", se = TRUE,
8.               color = "#264C99", fill = "#264C99",
9.               alpha = 0.15, linewidth = 1) +
10.   geom_smooth(data = d_profit_clean,
11.               aes(x = ROA, y = NPM),
12.               method = "lm", se = TRUE,
13.               linetype = "dashed",
14.               color = "#D55E00", fill = "#D55E00",
15.               alpha = 0.15, linewidth = 1) +
16.   geom_abline(slope = 1, intercept = 0, linetype = "dotted", color = "grey40") +
17.   annotate("text", x = min(d_profit$ROA, na.rm=TRUE),
18.            y = max(d_profit$NPM, na.rm=TRUE),
19.            hjust = 0, vjust = 1.2,
20.            label = paste0("R² Full = ", round(res_full$r.squared, 3)),
21.            color = "#264C99", fontface = "bold") +
22.   annotate("text", x = min(d_profit$ROA, na.rm=TRUE),
23.            y = max(d_profit$NPM, na.rm=TRUE) - 0.03,
24.            hjust = 0, vjust = 1.2,
25.            label = paste0("R² Clean = ", round(res_clean$r.squared, 3)),
26.            color = "#D55E00", fontface = "bold") +
27.   {
28.     if (any(d_profit$Nam == 2019)) {
29.       annotate("text",
30.                x = d_profit$ROA[d_profit$Nam == 2019],
31.                y = d_profit$NPM[d_profit$Nam == 2019] + 0.02,
32.                label = "2019", color = "red", fontface = "bold")
33.     }
34.   } +
35.   scale_x_continuous(labels = label_percent(accuracy = 1)) +
36.   scale_y_continuous(labels = label_percent(accuracy = 1)) +
37.   labs(
38.     title = "Tương quan biên lợi nhuận ròng (NPM) ~ ROA (Full vs Clean)",
39.     subtitle = "Đường liền: Full | Đường gạch: Clean (loại 2019) | Đường chấm: y = x",
40.     x = "ROA (%)", y = "Biên lợi nhuận ròng (NPM, %)"
41.   ) +
42.   theme_minimal(base_size = 10) +
43.   theme(plot.title = element_text(face = "bold", hjust = 0.5),
44.         panel.grid.minor = element_blank())

Kết luận từ biểu đồ:

Biểu đồ cho thấy mối liên hệ tăng đồng giữa biên lợi nhuận ròng (NPM)hiệu suất sử dụng tài sản (ROA), nghĩa là sau khi đã loại bỏ năm có giá trị bất thường (2019) thì khi ROA tăng sẽ kéo NPM tăng tương ứng (đường màu xanh trên hình), điều đó phản ánh hiệu quả hoạt động được duy trì ổn định.

Mẫu Đặc điểm Ý nghĩa
Full Đường phẳng, R² = 0.05 Mối quan hệ yếu, bị nhiễu bởi outlier (2019)
Clean Đường dốc tăng mạnh, R² = 0.93 Mối quan hệ chặt chẽ, phản ánh đúng hiệu quả hoạt động nội tại
Điểm 2019 Lệch xa cụm chính Biểu hiện của biến động bất thường (không thuộc xu hướng chung)

2.4.3. Phân tích tương quan đa biến

2.4.3.1. Ma trận tương quan giữa các chỉ tiêu tài chính

1. df_temp <- data %>%
2.   mutate(
3.     P_E_CuoiNam = Gia_DongCua_CuoiNam / EPS,
4.     VonHoa_TyVND = (Gia_DongCua_CuoiNam * SL_CoPhieu_LuuHanh) / 1e9,
5.     ROE_Nam = (LoiNhuanSauThue / VonChuSoHuu) * 100,
6.     ROA_Nam = (LoiNhuanSauThue / TongTaiSan) * 100,
7.     BienLoiNhuanRong_Nam = (LoiNhuanSauThue / DoanhThu) * 100,
8.     FL_Nam = TongTaiSan / VonChuSoHuu,
9.     TAT_Nam = DoanhThu / TongTaiSan,
10.     flag_roa_abnormal = dplyr::case_when(ROA_Nam > 100 ~ TRUE, TRUE ~ FALSE)
11.   )
12. df_clean <- df_temp %>% 
13.   dplyr::filter(flag_roa_abnormal == FALSE) 
14. # A. Chọn các biến cần thiết cho ma trận tương quan (Hiệu suất & Định giá)
15. vars_raw <- df_clean %>%
16.   select(ROE_Nam, ROA_Nam, BienLoiNhuanRong_Nam, TAT_Nam, FL_Nam, EPS, P_E_CuoiNam) 
17. vars_corr <- vars_raw %>%
18.   rename(
19.     ROE = ROE_Nam,
20.     ROA = ROA_Nam,
21.     `Biên LNR` = BienLoiNhuanRong_Nam,
22.     `Hiệu suất TS` = TAT_Nam,
23.     `Đòn bẩy TC` = FL_Nam,
24.     PE = P_E_CuoiNam
25.   )
26. vars_short_names <- vars_corr %>%
27.   rename(
28.     NPM = `Biên LNR`,
29.     TAT = `Hiệu suất TS`,
30.     FL = `Đòn bẩy TC`
31.   )
32. corr_matrix_short <- round(cor(vars_short_names, use = "pairwise.complete.obs"), 3)
33. corr_long <- reshape2::melt(corr_matrix_short)
34. ggplot(corr_long, aes(x = Var1, y = Var2, fill = value)) +
35.   geom_tile(color = "white") +
36.   geom_text(aes(label = sprintf("%.2f", value)), size = 3.5, color = "black") + 
37.   scale_fill_gradient2(low = "#B2182B", mid = "white", high = "#2166AC",
38.                        midpoint = 0, limit = c(-1, 1),
39.                        name = "Hệ số\nTương quan") +
40.   labs(
41.     title = "Ma trận tương quan giữa các chỉ tiêu tài chính",
42.     subtitle = "Mẫu đã lọc Outlier (n=10)",
43.     x = NULL, y = NULL
44.   ) +
45.   theme_minimal(base_size = 10) +
46.   theme(
47.     axis.text.x = element_text(angle = 45, hjust = 1, size = 10), 
48.     axis.text.y = element_text(size = 10),
49.     plot.title = element_text(face = "bold", hjust = 0.5),
50.     legend.position = "right"
51.   )

Giải thích kĩ thuật

  • Dòng 1–11: Sử dụng mutate() để tính toán P_E_CuoiNam, ROE_Nam, ROA_Nam, BienLoiNhuanRong_Nam, FL_Nam, TAT_Nam và dùng flag_roa_abnormal đánh dấu các giá trị ROA bất thường (ROA > 100%).

  • Dòng 12–13: Dùng filter() loại bỏ các dòng bị gắn cờ, tạo bộ dữ liệu df_clean

  • Dòng 15–16: dùng seclect() chọn các biến (ROE, ROA, Biên LNR, TAT, FL, EPS, P/E).

  • Dòng 17–31: dùngrename() để biến đổi tên các biến

  • Dòng 32–33: Tính ma trận tương quan Pearson bằng cor() (sử dụng pairwise.complete.obs để bỏ qua NA) và chuyển kết quả sang dạng dài (melt())

  • Dòng 34–51: Dùng ggplot() để vẽ biểu đồ ma trận tương quan, geom_tile() tô màu theo mức độ tương quan, geom_text() hiển thị hệ số tương quan trực tiếp, scale_fill_gradient2() thiết lập thang đo màu

Nhận xét

  • ROA, ROE và NPMmức tương quan gần như tuyệt đối (r ≈ 0.96–1.00) → cho thấy hiệu quả hoạt động nội tại là nhân tố quyết định trực tiếp lợi nhuận ròng và tỷ suất sinh lời vốn chủ.
    → Điều này củng cố kết quả các hồi quy trước (ROE ~ ROA, NPM ~ ROA) rằng cấu trúc sinh lời của PVGas chủ yếu đến từ hoạt động kinh doanh cốt lõi, không phụ thuộc vào đòn bẩy.

  • TAT (Hiệu suất tài sản) có tương quan trung bình đến mạnh với ROA và ROE (r ≈ 0.71–0.73), nghĩa là khả năng quay vòng tài sản đóng vai trò tích cực trong việc nâng cao lợi nhuận.
    → Tuy nhiên, hệ số < 1 cho thấy ngoài hiệu suất tài sản, biên lợi nhuận ròng (NPM) vẫn là yếu tố chi phối chính của ROA.

  • FL (Đòn bẩy tài chính) có tương quan yếu – trung bình (r ≈ 0.34–0.42) với ROA và ROE, chứng tỏ đòn bẩy không phải yếu tố chính tạo ra lợi nhuận, phù hợp với đặc điểm của PVGas – doanh nghiệp có vốn chủ sở hữu lớn và nợ vay thấp.

2.4.3.2.Ma trận tương quan giữa biến hiệu suất và định giá

1. GGally::ggpairs(
2.   vars_corr,
3.   title = "Biểu đồ 2.4.3b: Ma trận giữa các biến hiệu suất và định giá",
4.   upper = list(continuous = GGally::wrap("cor", size = 3.5, color = "darkred")),
5.   lower = list(continuous = GGally::wrap("points", alpha = 0.6, size = 1.5, color = "#0072B2")),
6.   diag = list(continuous = GGally::wrap("densityDiag", fill = "#56B4E9", alpha = 0.6))
7. ) +
8.   theme_bw(base_size = 8) +
9.   theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 12))

Nhận xét kĩ thuật

  • Dòng 1–2: Gọi hàm GGally::ggpairs() trên bộ dữ liệu vars_corr. Sủ dụng hàm GGally vì đây là hàm mở rộng của ggplot2 tạo biểu đồ ma trận nhìn thấy được phân tán

  • Dòng 4: Phần upper quy định vùng tam giác trên của ma trận hiển thị giá trị tương quan (correlation) bằng GGally::wrap("cor"), với kích thước chữ (size = 3.5) và màu chữ đỏ (color = "darkred").

  • Dòng 5: Phần lower hiển thị biểu đồ phân tán giữa các cặp biến. Các điểm được làm mờ (alpha = 0.6), kích thước nhỏ (size = 1.5) và có màu xanh dương nhẹ (#0072B2)

  • Dòng 6: Dùng diag hiển thị phân phối mật độ (density plot) của từng biến

Nhận xét

  • EPS có tương quan tương đối cao với nhóm hiệu suất (r ≈ 0.66–0.67 với ROA, ROE, TAT) → phản ánh lợi nhuận kế toán di chuyển cùng chiều với hiệu quả hoạt động. Tuy nhiên, mức tương quan chưa quá mạnh, cho thấy thị trường chưa phản ánh đầy đủ hiệu quả hoạt động vào EPS.

  • P/E có tương quan âm khá rõ với ROA, ROE, EPS (r ≈ -0.57 đến -0.59) → khi hiệu quả sinh lời tăng, P/E có xu hướng giảm, nghĩa là cổ phiếu được định giá rẻ hơn tương đối so với lợi nhuận tạo ra

Bảng tổng hợp nhận xét ma trận tương quan qua hai biểu đồ

Nhóm chỉ tiêu Tương quan nội bộ Tương quan với P/E Nhận định chính
ROA – ROE – NPM R ≈ 0.96–1.00 Âm (≈ -0.57) Hiệu suất nội tại cao, phản ánh cùng chiều với nhau; P/E giảm khi hiệu quả tăng.
TAT (Hiệu suất tài sản) Trung bình – mạnh (≈ 0.7) Âm nhẹ (≈ -0.38) Quay vòng tài sản cao giúp tăng sinh lời, nhưng không ảnh hưởng trực tiếp đến định giá.
FL (Đòn bẩy tài chính) Yếu (≈ 0.34- 0.42) Gần như không đáng kể Đòn bẩy thấp, không đóng vai trò chính trong sinh lời hay định giá.
EPS Dương với hiệu suất (≈ 0.66–0.67) Âm với P/E (≈ -0.59) Lợi nhuận kế toán tăng cùng hiệu quả hoạt động, nhưng thị trường chưa phản ánh tương xứng.

2.4.4. Phân tích EPS và sức mạnh tăng trưởng

2.4.4.1. Xu hướng EPS theo thời gian

1. library(tidyverse)
2. library(ggplot2)
3. library(broom)
4. library(scales)
5. analysis_data <- data %>%
6.   arrange(Nam) %>%
7.   mutate(
8.     P_E_CuoiNam = Gia_DongCua_CuoiNam / EPS, 
9.     ROE_Nam = (LoiNhuanSauThue / VonChuSoHuu) * 100, 
10.     LNST_YoY = (LoiNhuanSauThue / dplyr::lag(LoiNhuanSauThue) - 1) * 100,
11.     Gia = Gia_DongCua_CuoiNam,
12.     ROE = ROE_Nam,
13.     PE = P_E_CuoiNam
14.   )
15. ggplot(analysis_data, aes(x = Nam, y = EPS)) +
16.   geom_line(linewidth = 1.2, color = "#0072B2") +
17.   geom_point(size = 3, color = "#0072B2") +
18.   geom_smooth(method = "lm", se = FALSE, linetype = "dashed", color = "grey40") +
19.   labs(
20.     title = "Xu hướng EPS qua các năm",
21.     x = "Năm", y = "EPS (đồng/cp)"
22.   ) +
23.   theme_minimal(base_size = 13) +
24.   theme(plot.title = element_text(face = "bold", hjust = 0.5))

Nhận xét

  • EPS của doanh nghiệp PVGas biến động mạnh theo chu kỳ, thể hiện qua các giai đoạn tăng – giảm rõ rệt:
    • Giảm sâu vào các năm 2015 và 2019,
    • Tăng mạnh trở lại trong 2021–2022,
    • Sau đó giảm dần về mức ~4.000–5.000 đồng/cp trong giai đoạn sau 2022.
      → Dù có giai đoạn đột biến (2021), tăng trưởng EPS nhìn chung không bền vững và chịu tác động mạnh từ yếu tố bên ngoài.Biến động EPS này phản ánh đặc trưng ngành khí – phụ thuộc vào giá dầu, sản lượng tiêu thụ và biên lợi nhuận hợp đồng khí.

2.4.4.2. Mối quan hệ giá cổ phiếu ~ EPS

Xây dựng tuyến tính Giá cổ phiếu ~ EPS (Full & Clean)

1. lm_eps_full <- lm(Gia ~ EPS, data = analysis_data)
2. analysis_data_clean <- analysis_data %>% filter(Nam != 2019)
3. lm_eps_clean <- lm(Gia ~ EPS, data = analysis_data_clean)
4. result_eps <- tibble(
5.   Mẫu = c("Full", "Clean"),
6.   R2 = c(summary(lm_eps_full)$r.squared, summary(lm_eps_clean)$r.squared),
7.   Adj_R2 = c(summary(lm_eps_full)$adj.r.squared, summary(lm_eps_clean)$adj.r.squared),
8.   Slope = c(coef(lm_eps_full)[2], coef(lm_eps_clean)[2]),
9.   p_value = c(summary(lm_eps_full)$coefficients[2,4], summary(lm_eps_clean)$coefficients[2,4]),
10.   Intercept = c(coef(lm_eps_full)[1], coef(lm_eps_clean)[1])
11. )
12. print(result_eps)
# A tibble: 2 × 6
  Mẫu        R2 Adj_R2 Slope p_value Intercept
  <chr>   <dbl>  <dbl> <dbl>   <dbl>     <dbl>
1 Full  0.00636 -0.104 -1.04   0.816    57749.
2 Clean 0.0105  -0.113 -1.34   0.778    58712.

Nhận xét kĩ thuật

  • dòng 1 xây dựng hai mô hình hồi quy đầy đủ có năm 2019 của Gia ~ EPS bằng lm()

  • (dòng 2): dùng filter() loại bỏ năm 2019 khỏi dữ liệu (analysis_data_clean) để tạo bộ mẫu “Clean”.

  • dòng 3 xây dựng hai mô hình hồi quy mẫu Clean của Gia ~ EPS bằng `lm()

  • (dòng 6–10): dùng summary() để tổng quan các chỉ số thống kê của mô hình như r.squared, adj.r.squared, coefficientsp-value, đồng thời coef()lấy hệ số góc (Slope) và hệ số chặn (Intercept) từ mô hình

Phần này 2.4.4. sẽ không thực hiện lại giải thích kĩ thuật ở các biểu đồ vì đã được thực hiện tương tự như các biểu hồi quy tuyên tính được thực hiện các phần trên

Trực quan mối quan hệ giá cổ phiếu ~ EPS

1. ggplot() +
2.   geom_point(data = analysis_data, aes(x = EPS, y = Gia), color = "#0072B2", size = 3, alpha = 0.8) +
3.   geom_smooth(data = analysis_data, aes(x = EPS, y = Gia), method = "lm", color = "#0072B2", se = TRUE, fill = "#0072B2", alpha = 0.15) +
4.   geom_smooth(data = analysis_data_clean, aes(x = EPS, y = Gia), method = "lm", color = "#D55E00", se = TRUE, fill = "#D55E00", alpha = 0.15, linetype = "dashed") +
5.   labs(
6.     title = "Mối quan hệ giá cổ phiếu ~ EPS (Full vs Clean)",
7.     x = "EPS (đồng/cp)",
8.     y = "Giá cổ phiếu (đồng)"
9.   ) +
10.   theme_minimal(base_size = 13) +
11.   theme(plot.title = element_text(face = "bold", hjust = 0.5))

Nhận xét

  • Đường hồi quy FullClean gần như nằm ngang, với hệ số R² rất thấp (< 0.01), cho thấy không tồn tại mối quan hệ tuyến tính đáng kể giữa giá cổ phiếu và EPS

  • Độ dốc (Slope) âm nhẹ → khi EPS tăng, giá cổ phiếu không tăng tương ứng, thậm chí có xu hướng giảm nhẹ.

    → Giá cổ phiếu GAS không phản ứng với biến động EPS ngắn hạn, mà phản ánh kỳ vọng thị trường dài hạn, cổ tức và yếu tố vĩ mô.

2.4.4.3. Mối quan hệ giữa ROE ~ P/E

Xây dựng tuyến tính ROE ~ P/E

1. lm_roe_pe <- lm(ROE ~ PE, data = analysis_data)
2. summary(lm_roe_pe)

Call:
lm(formula = ROE ~ PE, data = analysis_data)

Residuals:
   Min     1Q Median     3Q    Max 
-13.99  -2.98   2.49   3.10  11.15 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   32.888      6.315    5.21  0.00056 ***
PE            -1.234      0.593   -2.08  0.06730 .  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 7.57 on 9 degrees of freedom
Multiple R-squared:  0.325, Adjusted R-squared:  0.25 
F-statistic: 4.33 on 1 and 9 DF,  p-value: 0.0673

Trực quan mối quan hệ ROE ~ P/E

1. ggplot(analysis_data, aes(x = PE, y = ROE)) +
2.   geom_point(size = 3, color = "#009E73", alpha = 0.8) +
3.   geom_smooth(method = "lm", se = TRUE, color = "#009E73", fill = "#009E73", alpha = 0.2) +
4.   scale_y_continuous(labels = label_percent(scale = 1)) + 
5.   labs(
6.     title = "Mối quan hệ ROE ~ P/E",
7.     x = "Hệ số P/E",
8.     y = "ROE (%)"
9.   ) +
10.   theme_minimal(base_size = 13) +
11.   theme(plot.title = element_text(face = "bold", hjust = 0.5))

Nhận xét

Biểu đồ cho thấy mối tương quan âm giữa ROE và P/E, Khi ROE (tỷ suất sinh lời vốn chủ) cao, P/E có xu hướng thấp hơn, và ngược lại. Điều này có thể là: nhà đầu tư có xu hướng định giá thấp hơn (P/E thấp) với các doanh nghiệp đã đạt mức sinh lời cao, vì tốc độ tăng trưởng tương lai dự kiến chậm lại. Ngược lại, doanh nghiệp có ROE thấp thường được kỳ vọng tăng trưởng cao hơn, nên được định giá P/E cao hơn.

2.4.4.4. Mối quan hệ P/E ~ Tăng trưởng LNST YoY

Xây dựng tuyến tính giữa PE ~ LNST_YoY

1. lm_pe_growth <- lm(PE ~ LNST_YoY, data = analysis_data)
2. summary(lm_pe_growth)

Call:
lm(formula = PE ~ LNST_YoY, data = analysis_data)

Residuals:
   Min     1Q Median     3Q    Max 
-5.714 -1.230 -0.135  2.620  4.773 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 10.00864    1.25286    7.99 0.000044 ***
LNST_YoY     0.00452    0.00389    1.16     0.28    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 3.78 on 8 degrees of freedom
  (1 observation deleted due to missingness)
Multiple R-squared:  0.144, Adjusted R-squared:  0.0373 
F-statistic: 1.35 on 1 and 8 DF,  p-value: 0.279

Trực quan mối quan hệ P/E ~ Tăng trưởng LNST (YoY)

1. ggplot(analysis_data, aes(x = LNST_YoY, y = PE)) +
2.   geom_point(size = 3, color = "#E69F00", alpha = 0.8) +
3.   geom_smooth(method = "lm", se = TRUE, color = "#E69F00", fill = "#E69F00", alpha = 0.2) +
4.   labs(
5.     title = "Mối quan hệ P/E ~ Tăng trưởng LNST (YoY)",
6.     x = "Tăng trưởng LNST YoY (%)",
7.     y = "Hệ số P/E"
8.   ) +
9.   theme_minimal(base_size = 13) +
10.   theme(plot.title = element_text(face = "bold", hjust = 0.5))

*Nhận xét**

  • Mối quan hệ giữa P/E và tăng trưởng lợi nhuận (YoY) có sự cùng chiều nhẹ, với R²= 0.144 (≈ 14.4), nghĩa là biến Tăng trưởng LNST (YoY) chỉ giải thích được khoảng 14.4% sự biến động của chỉ số P/E.

  • Mối quan hệ này cho thấy thị trường phản ứng chọn lọc với tăng trưởng, tức là chỉ định giá cao hơn khi tăng trưởng được xem là bền vững, còn các năm đột biến ngắn hạn ít ảnh hưởng đến P/E.

    → Như vậy, tác động của tăng trưởng LNST tới định giá P/E là có, nhưng không ổn định và mang tính kỳ vọng.

Tổng kết nhóm biểu đồ 2.4.4

Biểu đồ Mối quan hệ Kết luận chính
2.4.4.1– EPS theo năm Biến động chu kỳ, xu hướng giảm nhẹ EPS không ổn định, chịu ảnh hưởng yếu tố bên ngoài
2.4.4.2– Giá ~ EPS Gần như không có (Slope âm nhẹ) Giá cổ phiếu không phản ứng với EPS ngắn hạn
2.4.4.3– ROE ~ P/E Tương quan âm P/E thấp khi ROE cao → thị trường định giá ngược chu kỳ
2.4.4.4– P/E ~ Tăng trưởng LNST (YoY) Tương quan dương yếu P/E tăng khi tăng trưởng lợi nhuận cao, nhưng không ổn định

2.4.5. Phát hiện sau phân tích và trực quan hóa của PV GAS

1. Hiệu suất sinh lời (ROE, ROA, NPM, TAT, FL)

  • ROE trung bình ~20.6%, được mô hình DuPont tái tạo gần như hoàn hảo (R² ≈ 1).
  • Biên lợi nhuận ròng (NPM)yếu tố chi phối chính của ROE, trong khi hiệu suất tài sản (TAT) đóng vai trò bổ trợ và đòn bẩy tài chính (FL) duy trì ổn định, thấp (~1.25).
  • ROE tăng tỷ lệ thuận 1:1 với NPM, TAT, FL, nhưng ảnh hưởng tuyệt đối mạnh nhất đến từ NPM → nguồn sinh lời chủ yếu từ hiệu quả vận hành, không phải từ nợ vay.

2. Quan hệ giữa ROA và NPM

  • Sau khi loại bỏ năm outlier 2019, ROA và NPM có mối quan hệ tuyến tính rất mạnh (R² = 0.93).
  • ROA tăng 1% → NPM tăng ~0.72%, cho thấy hiệu quả sử dụng tài sản quyết định trực tiếp đến khả năng sinh lời ròng.
  • Mối quan hệ yếu trong mẫu Full (R² = 0.05) chứng minh 2019 gây nhiễu nghiêm trọng → loại bỏ giúp mô hình ổn định và phản ánh đúng bản chất hoạt động.

3. Tương quan đa biến (Hiệu suất & Định giá)

  • ROA – ROE – NPMtương quan gần như tuyệt đối (r ≈ 0.96–1.00) → hiệu quả nội tại nhất quán.
  • TAT tương quan trung bình (r ≈ 0.7), FL yếu (r ≈ 0.3–0.4) → đòn bẩy không phải yếu tố sinh lời chính.
  • EPS tương quan dương với hiệu suất (r ≈ 0.66–0.67), nhưng P/E tương quan âm rõ với ROE, ROA, EPS (r ≈ -0.57 đến -0.59)* → doanh nghiệp có hiệu suất cao lại bị định giá thấp**.
  • Thị trường chưa phản ánh đúng hiệu quả tài chính vào định giá cổ phiếu, hàm ý tiềm năng định giá lại trong tương lai.

4. EPS, tăng trưởng và định giá thị trường

  • EPS biến động mạnh theo chu kỳ, giảm ở 2015–2019, bứt phá 2021–2022 rồi suy giảm dần → tăng trưởng không ổn định.
  • Giá cổ phiếu ~ EPS: không có mối liên hệ rõ → giá không phản ứng với lợi nhuận ngắn hạn.
  • ROE ~ P/E: tương quan âm (R² ~ 0.4) → cổ phiếu bị định giá thấp khi hiệu suất cao.
  • P/E ~ Tăng trưởng LNST (YoY): tương quan dương yếu (R² ~ 0.14) → thị trường chỉ định giá cao khi tăng trưởng được xem là bền vững.

2.5. PHÂN TÍCH MỐI QUAN HỆ ĐỘNG GIỮA CHỈ TIÊU TÀI CHÍNH VÀ CHU KỲ

2.5.1. So sánh mối quan hệ LNST, giá và ROE

1. library(tidyverse)
2. library(ggplot2)
3. library(zoo)
4. library(scales)
5. df_roll <- data %>%
6.   rename(
7.     LNST = LoiNhuanSauThue,
8.     Gia = Gia_DongCua_CuoiNam,
9.     ROE = ROE_Nam
10.   ) %>%
11.   arrange(Nam)
12. roll_corr_LNST_DT <- df_roll %>%
13.   mutate(Roll_Corr_LNST_DT = rollapplyr(
14.     data = cbind(LNST, DoanhThu), 
15.     width = 3,
16.     FUN = function(x) cor(x[,1], x[,2], use = "complete.obs"),
17.     by.column = FALSE,
18.     fill = NA
19.   ))
20. roll_corr_ROE_Gia <- df_roll %>%
21.   mutate(Roll_Corr_ROE_Gia = rollapplyr(
22.     data = cbind(ROE, Gia),
23.     width = 3,
24.     FUN = function(x) cor(x[,1], x[,2], use = "complete.obs"),
25.     by.column = FALSE,
26.     fill = NA
27.   ))
28. roll_corr_all <- df_roll %>%
29.   select(Nam) %>%
30.   left_join(roll_corr_LNST_DT %>% select(Nam, Roll_Corr_LNST_DT), by = "Nam") %>%
31.   left_join(roll_corr_ROE_Gia %>% select(Nam, Roll_Corr_ROE_Gia), by = "Nam") %>%
32.   pivot_longer(cols = starts_with("Roll_Corr"), names_to = "MốiQuanHe", values_to = "Corr") %>%
33.   mutate(
34.     MốiQuanHe = recode(MốiQuanHe,
35.                        "Roll_Corr_LNST_DT" = "LNST ~ Doanh thu",
36.                        "Roll_Corr_ROE_Gia" = "ROE ~ Giá cổ phiếu")
37.   )
38. ggplot(roll_corr_all, aes(x = Nam, y = Corr, color = MốiQuanHe, group = MốiQuanHe)) +
39.   geom_line(linewidth = 1.2) +
40.   geom_point(size = 2.5) +
41.   geom_hline(yintercept = 0, linetype = "dashed", color = "grey40") +
42.   scale_color_manual(values = c("#0072B2", "#D55E00")) +
43.   scale_y_continuous(labels = label_number(accuracy = 0.1), limits = c(-1, 1)) +
44.   labs(
45.     title = "So sánh mối quan hệ LNST~Doanh thu và ROE~Giá cổ phiếu",
46.     subtitle = "Cửa sổ trượt 3 năm",
47.     x = "Năm",
48.     y = "Hệ số tương quan (r)",
49.     color = "Mối quan hệ"
50.   ) +
51.   theme_minimal(base_size = 10) +
52.   theme(
53.     plot.title = element_text(face = "bold", hjust = 0.5),
54.     legend.position = "bottom"
55.   )

Giải thích kĩ thuật

  • Dòng 1–4 (library()): Nạp các gói tidyverse, ggplot2, zoo, scales phục vụ cho xử lý dữ liệu, tính toán cửa sổ trượt và trực quan hóa.

  • Dòng 5–11 dùng rename() đổi tên các biến (LNST, ROE, Gia) trong bộ (df_roll) và hàm arrange()sắp xếp giá trị theo năm

  • Dòng 12–19: Tạo biến Roll_Corr_LNST_DT bằng hàm rollapplyr()(thuộc gói zoo), ghép 2 biến vào cùng ma trận bằng cbind, tính tương quan dựa trên 3 năm width = 3, FUN = function(x) cor(x[,1], x[,2], use = "complete.obs")dùng định nghĩa hàm con để tính hệ số tương quan 2 cột, fill = NA để chèn NA vào dữ liệu trống.

  • Dòng 20 - 27 làm tương tự câu lệnh trên cho biến ROE

  • Dòng 28–37: Gộp hai chuỗi kết quả vào cùng bảng left_join(), chuyển sang dạng long bằng pivot_longer() và gán theo recode()

  • Dòng 38–55 (ggplot()): dùng geom_line()geom_point() minh họa xu hướng tương quan theo năm, geom_hline(yintercept = 0) tạo đường trung tính và giới hạn giá trị tương quan scale_y_continuous(limits = c(-1, 1))

Nhận xét

  • Giai đoạn 2015–2018:
    Hệ số tương quan của LNST–Doanh thu duy trì r ≈ 0.95–1.0, phản ánh sự ổn định gần như tuyệt đối giữa tăng trưởng doanh thu và lợi nhuận.
    ROE–Giá cổ phiếu tăng dần từ r ≈ 0.4 lên 0.9, cho thấy niềm tin thị trường dần cải thiện đối với hiệu quả sinh lời của doanh nghiệp.

  • Năm 2019:
    Xuất hiện biến động mạnh – hệ số ROE–Giá cổ phiếu chuyển sang âm (-0.5), trong khi LNST–Doanh thu vẫn cao (~1.0).
    Đây là hiện tượng nhiễu do outlier 2019 (ROA > 100%), khiến thị trường mất tương quan tạm thời với hiệu quả kế toán.

  • Giai đoạn 2020–2023:
    Mối quan hệ ROE–Giá cổ phiếu phục hồi mạnh mẽ, đạt lại r ≈ 0.8–1.0, phản ánh niềm tin nhà đầu tư quay trở lại.
    LNST–Doanh thu vẫn ổn định đến 2022, nhưng giảm nhẹ ở 2023 (r ~0.2–0.3) – dấu hiệu cho thấy biên lợi nhuận đang chịu áp lực từ chi phí và yếu tố thị trường.

Tổng kết ý nghĩa

Mối quan hệ Giai đoạn ổn định Giai đoạn biến động Nhận định
LNST ~ Doanh thu 2014–2022 (r ≈ 0.95–1.0) 2023 (r ~0.2) Hoạt động kinh doanh ổn định, chỉ suy yếu nhẹ do biến động chu kỳ.
ROE ~ Giá cổ phiếu 2015–2018, 2021–2023 (r ≈ 0.8–1.0) 2019–2020 (r âm) Thị trường định giá lệch do outlier 2019, sau đó phục hồi mạnh.

Kết luận

  • Mối quan hệ LNST–Doanh thuđộ bền rất cao, khẳng định tính ổn định và minh bạch của kết quả kinh doanh.
  • Mối quan hệ ROE–Giá cổ phiếu mang tính chu kỳ, nhưng phục hồi nhanh và ổn định trở lại sau biến động ngắn hạn.
  • Giai đoạn 2023 cần theo dõi thêm, do tín hiệu suy yếu tạm thời của LNST–Doanh thu có thể phản ánh sức ép lợi nhuận trong chu kỳ giá năng lượng mới.

2.5.2. So sánh mối quan hệ giữa biến hiệu suất và định giá

1. library(tidyverse)
2. library(ggplot2)
3. library(reshape2)
4. library(scales)
5. df_analysis <- data %>%
6.   rename(
7.     ROE = ROE_Nam,
8.     ROA = ROA_Nam,
9.     `Biên LNR` = BienLoiNhuanRong_Nam, 
10.     `Hiệu suất TS` = TAT_Nam, 
11.     EPS = EPS,
12.     Gia = Gia_DongCua_CuoiNam
13.   )
14. phase_pre2016 <- df_analysis %>% filter(Nam <= 2016)
15. phase_post2016 <- df_analysis %>% filter(Nam > 2016)
16. vars_eff <- c("ROE", "ROA", "Biên LNR", "Hiệu suất TS", "EPS", "Gia") 
17. corr_pre <- cor(phase_pre2016[vars_eff], use = "pairwise.complete.obs", method = "pearson")
18. corr_post <- cor(phase_post2016[vars_eff], use = "pairwise.complete.obs", method = "pearson")
19. corr_pre_long <- melt(corr_pre) %>%
20.   mutate(Pha = "Trước 2016 (2014–2016)")
21. corr_post_long <- melt(corr_post) %>%
22.   mutate(Pha = "Sau 2016 (2017–2024)")
23. corr_all_long <- bind_rows(corr_pre_long, corr_post_long)
24. ggplot(corr_all_long, aes(x = Var1, y = Var2, fill = value)) +
25.   geom_tile(color = "white") +
26.   geom_text(aes(label = sprintf("%.2f", value)), size = 3, color = "black") +
27.   scale_fill_gradient2(
28.     low = "#D55E00", mid = "white", high = "#0072B2",
29.     midpoint = 0, limits = c(-1, 1),
30.     name = "Hệ số\nTương quan (r)"
31.   ) +
32.   facet_wrap(~ Pha) +
33.   labs(
34.     title = "Tương quan mối quan hệ theo pha chu kỳ (trước & sau 2016)",
35.     subtitle = "So sánh độ mạnh yếu của mối quan hệ giữa các biến hiệu suất và định giá",
36.     x = "Biến 1",
37.     y = "Biến 2"
38.   ) +
39.   theme_minimal(base_size = 10) +
40.   theme(
41.     plot.title = element_text(face = "bold", hjust = 0.5),
42.     strip.text = element_text(face = "bold", size = 12),
43.     axis.text.x = element_text(angle = 45, hjust = 1),
44.     plot.margin = unit(c(1, 1, 1, 1), "cm") 
45.   )

Nhận xét kĩ thuật

  • Dòng 1–4 Nạp các gói tidyverse, ggplot2, reshape2, scales phù hợp tạo tương quan

  • Dòng 5–13: Chuẩn hóa tên biến trong df_analysis bằng rename()

  • Dòng 14–15: dùng filter()để chọn lọc và tách dữ liệu thành 2 pha (phase_pre2016: trước 2016) và (phase_post2016: sau 2016 )

  • Dòng 16–18: Tính ma trận tương quan bằng cor() cho từng pha chu kỳ đồng thời sử dụng use = "pairwise.complete.obs" để bỏ qua giá trị thiếu khi tính

  • Dòng 19–22: dùng hàm tạo mutate() để thực hiện chuyển ma trận sang dạng long bằng melt()

  • Dòng 23: gộp hai bảng tương quan thành bằng bind_rows()

  • Dòng 24–45: vẽ biểu đồ ggp như các bước trước

Nhận xét

Pha chu kì trước 2016 (2014–2016)

  • Các chỉ tiêu nội tại (ROE, ROA, Biên LNR, Hiệu suất TS) có mức tương quan gần như hoàn hảo (r ≈ 0.99–1.00).
    → Cấu trúc sinh lời ổn định, hiệu quả hoạt động và biên lợi nhuận di chuyển đồng pha.
  • Mối tương quan giữa nhóm hiệu suất với EPSGiá cổ phiếu ở mức trung bình (r ≈ 0.3–0.5),
    → Thị trường phản ứng khá đồng đều với kết quả kinh doanh, chưa có sự tách pha.
  • Tổng thể: giai đoạn này phản ánh mô hình doanh nghiệp “ổn định – nội hướng”, nơi giá cổ phiếu chủ yếu phản ánh hiệu quả tài chính nội tại.

Pha chu kì sau 2016 (2017–2024)

  • ROE – Biên LNR – ROA vẫn duy trì tương quan rất cao (r ≈ 0.99–1.00) → cho thấy hiệu quả vận hành nội bộ bền vững.
  • Tuy nhiên, mối quan hệ với thị trường (Giá, EPS) thay đổi đáng kể:
    • ROE–EPS tăng mạnh lên r = 0.70, thể hiện lợi nhuận kế toán phản ánh sát hiệu quả sinh lời.
    • ROE–Giá cổ phiếu chỉ còn r = 0.09, giảm mạnh so với trước 2016 → thị trường không còn định giá GAS dựa vào hiệu quả sinh lời, mà chuyển sang yếu tố kỳ vọng và vĩ mô.
    • ROA–Giá cổ phiếuEPS–Giá đều có hệ số thấp (0.26 → 0.07), xác nhận sự tách rời giữa giá thị trường và hiệu quả tài chính.

Kết luận

  • Trước 2016: các biến tài chính đồng biến chặt chẽ, thị trường định giá nhất quán theo hiệu quả hoạt động.
  • Sau 2016: tương quan nội tại vẫn mạnh, nhưng mối liên hệ giữa thị trường và kết quả tài chính suy yếu rõ rệt.
  • Điều này cho thấy cổ phiếu GAS bước vào giai đoạn “phi chu kỳ”, nơi giá bị chi phối nhiều hơn bởi yếu tố vĩ mô, chính sách và kỳ vọng năng lượng, thay vì chỉ hiệu quả tài chính.

2.6. KẾT LUẬN

Phân tích toàn bộ giai đoạn 2014–2024 cho thấy hiệu suất tài chính, cấu trúc sinh lời và cơ chế định giá của PVGas (GAS) có sự ổn định nội tại cao, nhưng mối liên hệ với thị trường đã biến đổi đáng kể theo chu kỳ năng lượng.Kết luận được chia thành những nhận định chung sau đây:

1. Hiệu suất sinh lời và cấu trúc nội tại

  • Mô hình DuPont (ROE = NPM × TAT × FL) tái tạo gần như hoàn hảo ROE thực tế (R² ≈ 1), chứng minh ROE của GAS được hình thành hoàn toàn từ các yếu tố nội sinh.
  • Biên lợi nhuận ròng (NPM) là động lực chính, duy trì quanh 13%, trong khi hiệu suất tài sản (TAT) ổn định ở mức 0.12–0.15 và đòn bẩy tài chính (FL)thấp (~1.2–1.3).
  • Điều này cho thấy ROE cao (~20%) của GAS không dựa vào nợ vay, mà được tạo bởi hiệu quả hoạt động và kiểm soát chi phí vượt trội.
  • Kết quả phân tích độ nhạy và mô phỏng đồng thời xác nhận mối quan hệ tuyến tính 1:1 giữa các thành phần DuPont, phản ánh tính bền vững của cấu trúc lợi nhuận.

2. Quan hệ giữa Hiệu quả hoạt động và Định giá

  • Mối quan hệ NPM ~ ROA cho thấy sau khi loại năm 2019 (outlier), mối quan hệ đạt R² = 0.93, chứng minh biên lợi nhuận ròng phản ánh trực tiếp hiệu quả sử dụng tài sản.
  • Ma trận tương quan củng cố rằng ROE, ROA và NPM gần như đồng biến tuyệt đối (r ≈ 0.97–1.00), trong khi đòn bẩy (FL) chỉ đóng vai trò phụ.
  • Tuy nhiên, mối tương quan giữa hiệu quả tài chính (ROE, ROA)định giá thị trường (P/E, Giá cổ phiếu) yếu dần, thậm chí âm – hàm ý thị trường định giá GAS chưa phản ánh đúng năng lực sinh lời nội tại.
  • Hồi quy Giá ~ EPSP/E ~ Tăng trưởng LNST (2.4.4) đều cho R² thấp, xác nhận rằng biến động giá cổ phiếu mang tính kỳ vọng hơn là phản ánh kết quả kế toán.

3. Tính ổn định và kiểm định độ bền mô hình

  • Phân tích độ bền của mô hình cho thấy mối quan hệ LNST–Doanh thu ổn định cực cao (r ≈ 1), trong khi ROE–Giá cổ phiếu biến động theo chu kỳ, suy yếu mạnh vào 2019–2020 và phục hồi sau 2021.
    → Điều này phản ánh hoạt động kinh doanh bền vững, nhưng phản ứng thị trường mang tính ngắn hạn và chu kỳ.
  • Tương quan theo pha chu kỳ (2.5.3) cho thấy:Trước 2016: các biến hiệu suất và giá cổ phiếu đồng pha mạnh (r ≈ 0.4–0.5), sau 2016: mối liên hệ nội tại vẫn bền (ROE–NPM ≈ 1), nhưng quan hệ với thị trường suy yếu rõ (ROE–Giá chỉ 0.09).

4. Nhận xét tính bền vững của doanh nghiệp

  • Từ 2014–2024, PVGas duy trì hiệu quả sinh lời cao, cấu trúc vốn an toàn và biên lợi nhuận ổn định, dù trải qua nhiều chu kỳ giá năng lượng.
  • Phân tích định lượng khẳng định ROE của GAS phản ánh thực chất năng lực vận hành, không bị chi phối bởi đòn bẩy hay lợi nhuận bất thường.
  • Sự tách rời tạm thời giữa hiệu quả tài chính và giá thị trường cho thấy doanh nghiệp đang bị định giá thấp so với giá trị nội tại, tạo dư địa lớn cho tăng trưởng định giá trong trung và dài hạn.