Phương pháp chuẩn hoá dữ liệu
Mục lục
Trang này mô tả thư viện làm gì với phản hồi của nguồn trước khi trả cho bạn một DataFrame.
Nguồn trả dữ liệu theo định dạng riêng, dựng cho trang web của chính họ: tên trường viết tắt, đơn vị mỗi nơi một kiểu, mốc thời gian dạng số, một bảng chia thành nhiều trang. Nếu thư viện chỉ chuyển tiếp phản hồi đó, bạn sẽ nhận một khối JSON thô. Thư viện đọc phản hồi rồi tái tạo nó thành một bảng có cột, kiểu và đơn vị cố định để lập trình. Việc này không chỉ là đổi tên cột: có bước phải suy ra ý nghĩa của trường, đối chiếu giữa các dòng, và có bước tự tính thêm.
Vì có suy diễn và đối chiếu, bảng thư viện trả về không phải lúc nào cũng khớp hoàn toàn với dữ liệu gốc. Khi phát hiện sai lệch, vnstock xác thực rồi sửa trong bản cập nhật thư viện gần nhất. Với số liệu dùng cho quyết định quan trọng, hãy đối chiếu với tài liệu do doanh nghiệp hoặc sở giao dịch công bố.
Tóm tắt các bước
| Bước | Thư viện làm gì | Chỗ có thể sai lệch |
|---|---|---|
| 1. Gửi truy vấn | Truy vấn đi từ máy bạn tới nguồn, sau khi kiểm cấp quyền | Nguồn đổi định dạng hoặc gián đoạn |
| 2. Đọc phản hồi | Giải mã phản hồi, đọc nối các trang | Chạm trần số truy vấn một lần gọi thì dừng sớm và ghi rõ trong df.attrs |
| 3. Đặt tên | Đổi tên trường của nguồn sang tên cột hoặc mã chỉ tiêu chung | Một trường được hiểu sai nghĩa |
| 4. Đơn vị và kiểu | Quy về nghìn đồng, đồng, tỷ lệ; ép kiểu số, ngày, chuỗi | Quy đổi đơn vị |
| 5. Thời gian | Gắn múi giờ, đổi mốc dạng số sang ngày giờ | Mốc của nến khung lớn |
| 6. Tính thêm | Gộp nến khung lớn, cộng các thành phần, đọc số từ câu chữ | Phép tính hoặc cách đọc |
| 7. Kiểm bảng | Đối chiếu với bộ cột, kiểu và giá trị cố định của từng hàm | — |
| 8. Cắt theo cấp | Cắt số dòng, số kỳ theo cấp tài khoản | — |
| 9. Ghi nguồn gốc | Ghi nguồn, thời điểm, cách xử lý vào df.attrs | — |
Bước 1 tới 7 chạy trong lõi xử lý, giống nhau cho mọi lối gọi. Lớp Python chỉ đổi bảng sang
pandas.DataFrame.
Bốn kiểu xử lý: algorithm_role
Mỗi kết quả ghi trong df.attrs["algorithm_role"] thư viện đã làm gì để có nó. Giá trị chọn theo
việc lời gọi thực sự làm, không theo tên hàm.
algorithm_role | Khi nào | Nghĩa |
|---|---|---|
retrieve_normalize | Có gửi truy vấn, không có cột tự tính | Đọc phản hồi của nguồn rồi tái tạo thành bảng chuẩn |
retrieve_derive | Có gửi truy vấn và có cột tự tính | Như trên, cộng thêm các cột nguồn không trả sẵn |
bundled_reference | Không gửi truy vấn nào | Bảng lấy từ dữ liệu có sẵn trong thư viện (danh mục chỉ số, lịch nghỉ giao dịch), hoặc tính từ dữ liệu đó và đồng hồ máy bạn |
normalize_supplied | Bạn tự đưa dữ liệu vào qua Connector | Đọc dữ liệu bạn lấy bằng tài khoản của mình, tái tạo thành bảng chuẩn; thư viện không gửi truy vấn |
Khi thư viện tự tính một cột, tên cột đó nằm trong df.attrs["derived_fields"]. Phần mô tả đầy đủ
nằm trong df.attrs["algorithm_participation"].
from vnstock import Market, provenance
df = Market().equity("VIC").ohlcv(start="2026-01-01", end="2026-03-01", interval="1W")
print(df.attrs["algorithm_role"]) # retrieve_derive
print(df.attrs["derived_fields"]) # ['time', 'open', 'high', 'low', 'close', 'volume', 'value']
print(provenance.summary(df)) # mô tả đủ các trường, tiếng ViệtCùng lệnh đó ở khung 1D cho retrieve_normalize và không có derived_fields: nến ngày lấy thẳng
từ nguồn.
Giá và nến
Đơn vị. Giá cổ phiếu, chứng chỉ quỹ, chứng quyền tính bằng nghìn đồng (63.0 là 63.000 đồng).
Chỉ số và hợp đồng tương lai tính bằng điểm. Khối lượng tính bằng cổ phiếu hoặc hợp đồng.
Thời gian. Thị trường Việt Nam theo giờ Asia/Ho_Chi_Minh. Nến ngày mang mốc 07:00 giờ Việt
Nam, tức 00:00 UTC của ngày giao dịch, như nguồn gửi. Tài sản quốc tế (ngoại hối, hàng hoá, chỉ số
thế giới, tiền mã hoá) theo UTC.
Gộp nến. Khi nguồn không phục vụ một khung, thư viện dựng nến khung đó từ nến khung nhỏ hơn:
| Cột | Cách lấy |
|---|---|
open | Giá mở của nến nhỏ đầu tiên |
close | Giá đóng của nến nhỏ cuối cùng |
high, low | Cao nhất, thấp nhất trong các nến nhỏ |
volume, value | Tổng các nến nhỏ |
time | Nến phút: đầu khoảng (nến 5 phút 09:15–09:19 mang mốc 09:15). Nến tuần, tháng trong nước: phiên cuối của tuần hoặc tháng. Nến tuần, tháng quốc tế: đầu tuần (Chủ nhật) hoặc ngày đầu tháng, giờ UTC |
| Nguồn | Khung tự gộp | Gộp từ |
|---|---|---|
vci | 5m, 15m, 30m | 1m |
vci | 1W, 1M | 1D |
kbs | 5m, 15m, 30m | 1m |
dukascopy | 1H, 4H | 1m |
dukascopy | 1W, 1M | 1D |
length và limit đếm nến sau khi gộp. Nếu số nến nhỏ cần đọc vượt trần truy vấn một lần gọi, kết
quả dừng ở phần mới nhất và df.attrs có request_cap_rows; thư viện cũng in một cảnh báo.
Khớp lệnh
Chiều lệnh. Cột match_type ghi Buy, Sell theo nhãn nguồn gửi. Nguồn kbs ghi chữ thường
buy, sell để giống bản 4.x. Lệnh khớp trong phiên định kỳ không có bên chủ động; nếu nguồn không
ghi chiều, thư viện gắn ATO hoặc ATC theo lịch phiên của sở (cổ phiếu: 09:00–09:15 và
14:30–14:45; hợp đồng tương lai: 08:45–09:00 và 14:30–14:45). Đây là bước suy diễn theo giờ khớp.
Mã lệnh. Nguồn nào không gửi mã lệnh thì cột id ghép từ ngày giao dịch và khối lượng luỹ kế của
phiên (ví dụ 20261019_7276900). Khối lượng luỹ kế chỉ tăng nên mỗi lệnh có một mã riêng.
Danh sách chưa đủ phiên. Nguồn thường trả N lệnh mới nhất. Khi danh sách không phủ từ đầu phiên,
df.attrs có session_missing và session_covered, kèm một cảnh báo nêu limit nên thử.
Báo cáo tài chính
Mỗi nguồn đặt tên dòng báo cáo theo cách riêng. Thư viện quy tất cả về một bộ mã chỉ tiêu chung,
nên cùng một dòng có cùng mã dù lấy từ vci, kbs hay mas.
| Tiền tố mã | Báo cáo |
|---|---|
IS_ | Kết quả kinh doanh |
BS_ | Cân đối kế toán |
CF_ | Lưu chuyển tiền tệ |
RT_ | Chỉ số tài chính |
Mẫu báo cáo theo loại hình. Doanh nghiệp thường, ngân hàng, công ty chứng khoán và công ty bảo
hiểm dùng bốn mẫu khác nhau. Mặc định thư viện tự nhận loại hình, từ danh mục chỉ tiêu nguồn công bố
cho mã đó hoặc từ tên các dòng. Bạn chỉ định được bằng com_type= (regular, bank,
securities, insurance).
Từ dòng của nguồn tới mã chung. Một bảng ánh xạ cho biết mỗi tên dòng của nguồn thuộc mã nào. Các quy tắc sau áp dụng khi dựng bảng:
| Quy tắc | Ví dụ |
|---|---|
| Mỗi tên dòng của nguồn thuộc đúng một mã | net_cash_flows_during_the_period → CF_NET_CASH_FLOWS_DURING_THE_PERIOD |
| Một mã nhận được nhiều tên dòng, vì mỗi mẫu báo cáo đặt tên khác nhau. Cùng một kỳ mà có hai giá trị khác nhau thì cộng lại; hai giá trị bằng nhau thì lấy một | "Lợi nhuận trước thuế" của mẫu doanh nghiệp và của mẫu ngân hàng |
| Trên báo cáo lưu chuyển tiền tệ, một tên dòng lặp lại trong cùng bảng thì lấy dòng đầu tiên có số | Phần tiền của khách hàng ở công ty chứng khoán; khối dòng tổng thứ hai ở công ty bảo hiểm |
| Chi phí, khấu hao luỹ kế và các khoản dự phòng luôn mang dấu âm | Giá vốn hàng bán, chi phí lãi vay |
| Lợi ích cổ đông không kiểm soát trên kết quả kinh doanh mang dấu dương | — |
| Một vài tỷ lệ của ngân hàng nguồn gửi dạng phần trăm được nhân 0,01 thành tỷ lệ | Biên lãi thuần 3.2 → 0.032 |
| Công ty bảo hiểm: "phải trả dài hạn khác" đọc là dự phòng nghiệp vụ bảo hiểm | — |
| Ngân hàng: kỳ có khoản đầu tư liên doanh bằng đúng khoản đầu tư liên kết thì bỏ kỳ đó ở dòng liên doanh, vì đó là một khoản ghi hai lần | — |
Số liệu ghi bằng đồng (unit = "VNĐ"). Báo cáo tài chính vẫn ghi algorithm_role là
retrieve_normalize: các con số là của nguồn, thư viện sắp lại theo mã chung và áp các quy tắc
trên. Dòng nào chịu quy tắc cộng, đổi dấu hay nhân hệ số là do bảng ánh xạ quyết định.
Đối chiếu với báo cáo đã công bố. Bảng ánh xạ được kiểm bằng cách đặt số thư viện trả về cạnh báo
cáo tài chính doanh nghiệp công bố, tải qua Fundamental().equity(symbol).filing(). Ví dụ: báo cáo
lưu chuyển tiền tệ quý 1/2026 của FPT (doanh nghiệp), VCB (ngân hàng), HCM (chứng khoán) và BVH (bảo
hiểm) khớp tới 1.000 đồng ở cả ba nguồn vci, kbs, mas. Số do nguồn trình bày có thể đã gộp
hoặc làm tròn khác bản công bố; thư viện giữ số của nguồn, không tự sửa.
from vnstock import Fundamental
cf = Fundamental().equity("FPT").cash_flow(period="quarter")
q1 = cf[cf["period"] == "2026-Q1"].set_index("id")["value"]
print(q1["CF_CASH_AND_CASH_EQUIVALENTS_AT_END_OF_PERIOD"])
files = Fundamental().equity("FPT").filing() # danh sách tài liệu đã công bố để đối chiếuSự kiện đọc từ tin công bố
Company(source="cafef", symbol=...).events() (trong vnstock.api) lấy tin công bố thông tin của
doanh nghiệp từ CafeF. Nguồn chỉ có tiêu đề tin, nên các cột hành động doanh nghiệp được đọc ra từ
câu chữ của tiêu đề:
- loại sự kiện (
event_code,issue_type); - ngày đăng ký cuối cùng, ngày giao dịch không hưởng quyền, với năm suy từ ngày đăng tin;
- tỷ lệ thực hiện và giá phát hành.
Cổ tức tiền mặt ghi theo phần trăm được quy ra đồng trên mệnh giá 10.000 đồng. Một tiêu đề nêu hai
hành động thì thành hai dòng. Các cột này nằm trong derived_fields.
Dữ liệu có sẵn và dữ liệu bạn tự đưa vào
Danh mục chỉ số, lịch nghỉ giao dịch và trạng thái phiên (Reference().market.status()) dùng bảng
đóng gói trong thư viện, không gửi truy vấn. Bảng này chỉ cập nhật tới bản thư viện bạn đang cài,
nên có thể thiếu thay đổi xảy ra sau đó.
Connector đọc dữ liệu bạn tự lấy từ nguồn bằng tài khoản của mình. Thư viện chỉ tái tạo dữ liệu đó
thành bảng chuẩn; nếu có cột tự tính, ví dụ khối lượng ròng bằng mua trừ bán, cột đó cũng nằm trong
derived_fields.
Giới hạn
- Suy diễn có thể sai. Ý nghĩa một trường, loại hình doanh nghiệp, nhãn phiên định kỳ, sự kiện đọc từ tiêu đề đều là bước suy luận.
- Nguồn đổi định dạng. Khi nguồn đổi tên trường hoặc cấu trúc, bảng có thể thiếu dòng hoặc báo lỗi cho tới bản cập nhật kế tiếp.
- Số của nguồn. Thư viện không sửa số nguồn gửi. Số đó có thể gộp, làm tròn hoặc cập nhật muộn so với bản công bố.
- Dữ liệu đóng gói chỉ mới tới bản thư viện đang cài.
Báo sai lệch
Khi thấy số không khớp tài liệu công bố, báo tại GitHub Issues kèm:
- Lệnh đã gọi, gồm
source=và kỳ. - Kết quả
provenance.summary(df). - Dòng và con số đúng, kèm tài liệu công bố (tên tài liệu, trang).
vnstock xác thực sai lệch rồi sửa trong bản cập nhật thư viện gần nhất.
Xem thêm: Kiến trúc thư viện cho df.attrs và trích
dẫn nguồn gốc, Nguồn dữ liệu cho nguồn mặc định của từng hàm.