1. Mục tiêu của bài học
Bài 2 đã xây dựng một master dataset ở tần suất ngày, trong đó WTI, DXY, USD/VND, VN-Index và Dow Jones được ghép theo ngày giao dịch. Bài 3 tiếp tục từ bộ dữ liệu này và chuyển dữ liệu từ tần suất ngày sang tần suất tháng bằng lệnh collapse của Stata.
Mục tiêu không chỉ là giảm số quan sát. Quan trọng hơn, người nghiên cứu phải xác định đúng cách đại diện cho từng biến tài chính trong một tháng. Giá mở cửa, giá đóng cửa, mức cao nhất, mức thấp nhất và khối lượng giao dịch không thể được tổng hợp theo cùng một quy tắc.
- Tạo biến thời gian tháng từ biến ngày.
- Hiểu vì sao nên xây dựng dữ liệu tháng từ dữ liệu ngày khi làm việc với nhiều thị trường.
- Sử dụng collapse với các thống kê firstnm, lastnm, max, min, sum và count.
- Kiểm tra ngày giao dịch đầu tháng và cuối tháng thực tế của từng thị trường.
- Tính lại tỷ lệ thay đổi hoặc lợi suất tháng từ giá đóng cửa tháng.
- Tạo bộ dữ liệu stock_monthly.dta cho các bài phân tích chuỗi thời gian tiếp theo.
2. Tại sao không nhất thiết tải trực tiếp dữ liệu theo tháng?
Nhiều nguồn dữ liệu cho phép tải trực tiếp dữ liệu ở tần suất tháng (ví dụ: Investing.com). Cách này có thể sử dụng được, nhưng khi nghiên cứu đồng thời nhiều thị trường, nó có một số hạn chế cần lưu ý.
Thứ nhất, các thị trường không có cùng lịch giao dịch. Ngày giao dịch cuối cùng của một tháng tại Việt Nam có thể khác ngày giao dịch cuối cùng của thị trường Hoa Kỳ hoặc của thị trường ngoại hối. Nếu dữ liệu tháng được ghi bằng ngày giao dịch thực tế rồi ghép trực tiếp theo biến date, hai quan sát thuộc cùng một tháng vẫn có thể không khớp ngày.
Thứ hai, nếu quy trình tải hoặc xử lý dữ liệu quy ước một ngày cố định, chẳng hạn ngày cuối tháng theo lịch, ngày đó có thể rơi vào cuối tuần hoặc ngày nghỉ. Tùy cách nhà cung cấp ghi nhận dữ liệu, điều này có thể tạo missing hoặc làm ngày đại diện của tháng không đồng nhất giữa các chuỗi. Vì vậy, vấn đề không phải là dữ liệu tháng tải trực tiếp luôn sai, mà là người nghiên cứu có ít quyền kiểm soát hơn đối với cách hình thành quan sát tháng.
Khi bắt đầu từ dữ liệu ngày, chúng ta có thể chủ động xác định tháng bằng mdate, sau đó để mỗi thị trường tự lấy quan sát hợp lệ đầu tiên và cuối cùng trong tháng. Nhờ đó, các thị trường được quy về cùng một tháng ngay cả khi ngày giao dịch thực tế khác nhau.
3. Mở master dataset của Bài 2
use “$data\stock_daily.dta”, clear
sort date
format date %td
isid date
Bộ dữ liệu đầu vào vẫn là master dataset ở tần suất ngày. isid date kiểm tra rằng mỗi ngày chỉ xuất hiện một lần trong bộ dữ liệu sau khi merge ở Bài 2.
4. Chuyển daily date sang monthly date
gen mdate = mofd(date)
format mdate %tm
label variable mdate “Month”
mofd() là viết tắt của month of daily date. Hàm này nhận một Stata daily date và trả về Stata monthly date tương ứng. Ví dụ, mọi ngày trong tháng 5/2026 đều được chuyển thành cùng một giá trị tháng 2026m5.
Đây là bước then chốt trước collapse, bởi vì ta muốn tất cả quan sát ngày trong cùng một tháng thuộc về cùng một nhóm.
5. Ghi nhận ngày giao dịch thực tế của từng thị trường
gen trade_date_vni = ///
date if !missing(close_vni)
gen trade_date_dji = ///
date if !missing(close_dji)
format trade_date_* %td
Master dataset có thể chứa một ngày mà thị trường này giao dịch nhưng thị trường khác không giao dịch. Vì vậy, trước khi collapse, ta tạo biến ngày giao dịch riêng cho từng thị trường. Sau khi chuyển sang monthly, các biến này cho phép xác định ngày giao dịch đầu tiên và cuối cùng thực tế trong mỗi tháng.
6. Nguyên tắc tổng hợp dữ liệu tài chính theo tháng
Không nên dùng một thống kê duy nhất cho tất cả các biến. Quy tắc tổng hợp phụ thuộc vào ý nghĩa kinh tế của biến.

firstnm và lastnm đặc biệt hữu ích vì chúng bỏ qua missing. Điều này rất phù hợp với master dataset nhiều thị trường: nếu một thị trường nghỉ giao dịch vào ngày đầu hoặc ngày cuối theo lịch, Stata vẫn lấy được quan sát hợp lệ đầu tiên hoặc cuối cùng của chính thị trường đó trong tháng.
7. Sử dụng lệnh collapse
Trước khi collapse, dữ liệu được sắp xếp theo tháng và ngày:
sort mdate date
Sau đó có thể tổng hợp nhiều loại biến trong cùng một lệnh:
collapse ///
(firstnm) ///
open_wti open_dxy open_usdvnd open_vni open_dji ///
(lastnm) ///
close_wti close_dxy close_usdvnd close_vni close_dji ///
(max) ///
high_wti high_dxy high_usdvnd high_vni high_dji ///
(min) ///
low_wti low_dxy low_usdvnd low_vni low_dji ///
(sum) ///
volume_wti volume_dxy volume_vni volume_dji, ///
by(mdate)
Sau collapse, mỗi tháng chỉ còn một quan sát. Dữ liệu vì vậy chuyển từ dạng daily sang monthly (xem do-file).

8. Vì sao không lấy trung bình giá đóng cửa?
Nếu mục tiêu là xây dựng chuỗi giá cuối tháng, close tháng phải là giá đóng cửa của phiên giao dịch cuối cùng trong tháng, không phải trung bình của tất cả giá đóng cửa hằng ngày. Trung bình giá ngày trả lời một câu hỏi khác: mức giá trung bình trong tháng.
Tương tự, open tháng thường được hiểu là giá mở cửa của phiên giao dịch đầu tiên trong tháng; high tháng là mức cao nhất và low tháng là mức thấp nhất quan sát được trong tháng. Do đó, lựa chọn thống kê trong collapse phải xuất phát từ định nghĩa kinh tế của biến.
9. Đếm số ngày giao dịch trong mỗi tháng
(count) ///
n_wti = close_wti ///
n_dxy = close_dxy ///
n_usdvnd = close_usdvnd ///
n_vni = close_vni ///
n_dji = close_dji
Các biến n_* cho biết mỗi thị trường có bao nhiêu quan sát ngày trong từng tháng. Chúng giúp phát hiện các tháng có số ngày giao dịch bất thường hoặc dữ liệu bị thiếu nhiều.
Số ngày giao dịch giữa các thị trường không nhất thiết bằng nhau. Đây không phải mặc nhiên là lỗi dữ liệu, vì lịch nghỉ lễ và lịch giao dịch có thể khác nhau.
10. Lưu ngày giao dịch đầu tiên và cuối cùng của tháng
(min) ///
firstdate_vni = trade_date_vni ///
firstdate_dji = trade_date_dji ///
(max) ///
lastdate_vni = trade_date_vni ///
lastdate_dji = trade_date_dji
Vì date là biến số tăng theo thời gian, min của trade_date là ngày giao dịch đầu tiên và max là ngày giao dịch cuối cùng trong tháng. Các biến này rất hữu ích để kiểm chứng rằng dữ liệu tháng thực sự được xây dựng từ những ngày giao dịch hợp lệ, thay vì giả định tất cả thị trường có cùng ngày cuối tháng.
11. Không collapse biến change bằng mean
Trong dữ liệu ngày của Bài 2, change là tỷ lệ thay đổi hằng ngày. Không nên lấy trung bình change để tạo tỷ lệ thay đổi tháng, vì trung bình của các tỷ lệ thay đổi ngày không bằng tỷ lệ thay đổi của cả tháng.
Sau khi đã có close tháng, tỷ lệ thay đổi tháng có thể được tính lại từ hai mức giá đóng cửa liên tiếp:
tsset mdate
gen change_vni = ///
close_vni / L.close_vni – 1
Ví dụ, nếu VN-Index đóng cửa tháng trước ở 1.200 điểm và tháng hiện tại ở 1.260 điểm, tỷ lệ thay đổi tháng là 1.260/1.200 – 1 = 0,05, tức 5%.
Nếu cần log return, có thể tạo ở bài phân tích sau bằng sai phân log của giá đóng cửa tháng.
12. Khai báo chuỗi thời gian ở tần suất tháng
tsset mdate
Ở bộ dữ liệu monthly, mdate là biến thời gian lịch thực sự và là lựa chọn tự nhiên để khai báo chuỗi thời gian. Khi đó, L.close_vni có nghĩa là giá đóng cửa của tháng trước và D.close_vni là chênh lệch so với tháng trước.
Khác với dữ liệu daily của nhiều thị trường, khoảng cách giữa hai giá trị mdate liên tiếp có ý nghĩa rõ ràng là một tháng. Nếu một tháng thật sự không có quan sát, Stata sẽ nhận diện đó là một khoảng trống thời gian thay vì coi hai tháng không liền nhau là hai quan sát liên tiếp.
13. Biến xu thế t = _n nên tạo khi nào?
Nguyên tắc của Bài 2 vẫn được giữ nguyên: không nên tạo t = _n quá sớm rồi sử dụng nó cho mọi mẫu nghiên cứu. Nếu sau đó loại bớt các tháng bằng keep if, t có thể không còn liên tục.
Master monthly dataset nên giữ mdate làm biến thời gian chính. Khi đã xác định mẫu cuối cùng cho một mô hình cụ thể, có thể tạo biến xu thế t:
use “$data\stock_monthly.dta”, clear
keep if sample_month_all == 1
sort mdate
gen t = _n
label variable t “Monthly time trend”
Ở đây t có thể được sử dụng như một biến xu thế tuyến tính hoặc làm chỉ số quan sát nếu mô hình cần. Tuy nhiên, đối với lag và difference theo tháng, mdate vẫn là biến thời gian có ý nghĩa kinh tế rõ hơn.
14. Xây dựng mẫu tháng chung
gen sample_month_all = ///
!missing(close_wti) ///
& !missing(close_dxy) ///
& !missing(close_usdvnd) ///
& !missing(close_vni) ///
& !missing(close_dji)
sample_month_all bằng 1 khi cả năm thị trường đều có giá đóng cửa trong tháng. Tương tự, có thể xây dựng sample_month_vni_global hoặc sample_month_vni_fx tùy câu hỏi nghiên cứu.
Việc tạo mẫu sau collapse có một lợi thế: một thị trường không cần giao dịch đúng cùng ngày với thị trường khác. Chỉ cần cả hai có dữ liệu hợp lệ trong cùng tháng, chúng có thể được đưa vào phân tích monthly.
15. Kiểm tra bộ dữ liệu monthly
sort mdate
isid mdate
misstable summarize ///
close_wti ///
close_dxy ///
close_usdvnd ///
close_vni ///
close_dji
isid mdate xác nhận mỗi tháng chỉ còn một quan sát. misstable summarize giúp kiểm tra các tháng vẫn còn thiếu dữ liệu của từng thị trường.
16. Lưu master dataset ở tần suất tháng
save “$data\stock_monthly.dta”, replace
Tệp stock_monthly.dta trở thành master dataset ở tần suất tháng. Bộ dữ liệu daily ban đầu vẫn được giữ nguyên và có thể sử dụng lại nếu cần xây dựng dữ liệu tuần, quý hoặc một cách tổng hợp tháng khác.
17. Daily và monthly phục vụ những câu hỏi khác nhau
Chuyển từ daily sang monthly làm giảm số quan sát và loại bỏ một phần biến động rất ngắn hạn. Đổi lại, dữ liệu monthly thường thuận tiện hơn khi kết hợp với các biến kinh tế vĩ mô như CPI, lãi suất, cung tiền, chỉ số sản xuất công nghiệp hoặc các biến được công bố theo tháng. Một nghiên cứu có thể nghĩ tới là hiệu quả về mặt thông tin trên thị trường chứng khoán, ví dụ Việt Nam (giả thuyết về thị trường hiệu quả, với mục tiêu là semi-strong form efficiency).
Vì vậy, collapse không chỉ là một thao tác kỹ thuật để giảm kích thước dữ liệu. Nó là một quyết định về tần suất nghiên cứu. Tần suất được lựa chọn phải phù hợp với câu hỏi nghiên cứu, cơ chế kinh tế và tần suất của các biến khác trong mô hình.
Lời kết
Bắt đầu từ dữ liệu daily và chủ động chuyển sang monthly giúp người nghiên cứu kiểm soát rõ cách hình thành từng quan sát tháng. Cách tiếp cận này đặc biệt hữu ích khi nghiên cứu nhiều thị trường có lịch giao dịch khác nhau, bởi vì mỗi thị trường có thể sử dụng ngày giao dịch hợp lệ đầu tiên và cuối cùng của chính nó nhưng vẫn được quy về cùng một mốc tháng.
Khi sử dụng collapse, điều quan trọng nhất là không áp dụng cùng một phép tổng hợp cho mọi biến. Giá mở cửa, giá đóng cửa, mức cao nhất, mức thấp nhất, khối lượng và lợi suất có ý nghĩa khác nhau và cần được xử lý theo đúng bản chất kinh tế của chúng.
