Vnstock Logo

Quy ước dữ liệu và lỗi

Thử nghiệm

Mục lục

Bản thử nghiệm, chưa phát hành chính thức

Trang này viết cho vnstock_quant v1.0.0rc1, bản thử nghiệm. Tên hàm, tham số và cột dữ liệu có thể còn đổi trước ngày phát hành; khi cài, ghi rõ số phiên bản như ở trang Cài đặt. Bản đang phát hành chính thức là v0.5.0, xem tài liệu bản đó.

Trang này gom những điều đúng với mọi nhóm hàm của vnstock_quant: dữ liệu đầu vào trông như thế nào, lỗi được báo ra sao và các quy ước tính toán mà kết quả tuân theo. Từng trang nhóm hàm chỉ nói phần riêng của nhóm đó.


Dữ liệu đầu vào

Thư viện nhận dữ liệu dạng pandas và trả kết quả căn theo chỉ mục bạn đưa vào. Lớp Python chỉ đổi cột sang mảng số rồi dựng lại bảng có nhãn; mọi phép tính và kiểm tra đầu vào nằm trong lõi Rust, nên thiếu cột hay lệch độ dài được báo bằng InputDataError kèm tên cột thiếu.

Nhóm hàmDạng dữ liệuGhi chú
ta, backtest, micro.cvd, micro.realizedBảng nến: cột open, high, low, close, volume viết thường, chỉ mục thời gian DatetimeIndex hoặc cột timeta chỉ cần các cột mà chỉ báo dùng; backtest nhận thêm price_unit để nhận ra bảng tính bằng nghìn đồng hay đồng
risk, portfoliopandas.Series hoặc DataFrame lợi suất giản đơn từng kỳ, chỉ mục DatetimeIndexTính từ giá đóng cửa đã điều chỉnh bằng risk.returns(prices); hai chuỗi được căn theo ngày giao dịch chung
faBáo cáo tài chính dạng long: cột period, id, value (hồ sơ v5) hoặc report_period, item_id, item_value (hồ sơ v6), mã chỉ tiêu của vnstock, gói trong fa.DatasetChỉ số dùng mẫu số bình quân cần ít nhất hai kỳ. Giá cho định giá: time, close (đồng; bảng hồ sơ v6 theo nghìn đồng được tự đổi), total_shares
pricesBảng giá gốc theo phiên (giá tham chiếu, trần, sàn nếu có, OHLC, khối lượng) và bảng sự kiện của events() (cột event_type, ex_right_date, ratio của thế hệ 6, hoặc bảng thế hệ 5 đã lưu)Bảng có giá lẻ bước giá 10 đồng bị từ chối vì đã được điều chỉnh; xem Giá điều chỉnh
micro.bars, micro.classifyBảng khớp lệnh: time, price, volume, cột bên chủ động nếu nguồn có (match_type ở hồ sơ v5; side và session ở hồ sơ v6)Lệnh trong phiên ATO, ATC không có bên chủ động; không có bên chủ động thì suy bằng tick rule

Hai hồ sơ cột của vnstock 6

vnstock 6 trả bảng theo hồ sơ v5 (tên cột và đơn vị như thế hệ 5, mặc định) hoặc v6 (tên cột mới, giá theo nghìn đồng ở nhiều bảng). Các hàm tải của vnstock_quant luôn đọc hồ sơ v5. Bảng bạn tự tải và đưa vào thì ở hồ sơ nào cũng được: thư viện đọc attrs["profile"] của bảng để đổi đơn vị khi cần.

Kết quả là DataFrame hoặc Series cùng chỉ mục với đầu vào. Siêu dữ liệu đi kèm nằm trong attrs (ví dụ bảng hệ số của prices.adjust ở attrs["factors"]). Thư viện không tự đổi đơn vị giá trừ khi hàm có tham số unit hoặc price_unit; hãy dùng một đơn vị nhất quán trong cả phiên làm việc.


Hệ thống phân cấp ngoại lệ

Các lỗi của thư viện kế thừa từ VnstockQuantError. Mã lỗi giúp bạn phân biệt sai tham số, dữ liệu đầu vào, quyền sử dụng và những trường hợp khác:

Text
VnstockQuantError (Lớp cơ sở)
├── InvalidParameterError      # Tham số sai tên, sai kiểu hoặc ngoài khoảng (mã: QUANT_INVALID_PARAMETER)
├── UnknownIndicatorError      # Không có chỉ báo, tính năng hay hàm mang tên đó (mã: QUANT_UNKNOWN_INDICATOR,
│                              #   QUANT_UNKNOWN_FEATURE, QUANT_UNKNOWN_FUNCTION)
├── UnknownRatioError          # Mã chỉ số tài chính không tồn tại (mã: QUANT_UNKNOWN_RATIO)
├── InputDataError             # Dữ liệu đầu vào thiếu cột hoặc các cột lệch độ dài (mã: QUANT_INPUT_DATA)
│   └── CausalityViolationError  # Tín hiệu hoặc chỉ báo trong backtest đọc dữ liệu tương lai (mã: QUANT_CAUSALITY_VIOLATION)
├── DependencyError            # Thiếu vnstock, hoặc vnstock đang cài không thuộc thế hệ 6 (mã: QUANT_DEPENDENCY_MISSING)
├── EntitlementError           # Cấp quyền hiện tại không mở tính năng này
│   ├── TierRequiredError      # Cần gói quyền sử dụng cao hơn (mã: QUANT_TIER_REQUIRED, QUANT_SCOPE_LIMIT)
│   └── QuotaExceededError     # Hết lượt dùng thử trong ngày, hoặc một lần chạy thử quá lớn cho cấp (mã: QUANT_TRIAL_EXHAUSTED, QUANT_QUOTA_LIMIT)
├── AuthError                  # Lỗi API key, thiết bị hoặc kết nối máy chủ cấp quyền
├── UnsupportedError           # Bản phát hành đã bị tắt, cần nâng cấp (mã: VNSTOCK_RELEASE_DISABLED)
│   └── ReleaseExpiredError    # Bản phát hành đã hết hạn hiệu lực (mã: VNSTOCK_RELEASE_EXPIRED)
└── InternalError              # Lỗi ngoài dự kiến bên trong thư viện

Lỗi do vnstock 6 ném khi tải dữ liệu (chưa chọn nguồn, nguồn không đọc được loại dữ liệu, thiếu khoá, nguồn từ chối) được giữ nguyên, không bọc lại; mã của chúng bắt đầu bằng VNSTOCK_:

MãNghĩaViệc nên làm
VNSTOCK_INPUT_SOURCEChưa chọn nguồnNêu source= hoặc vnstock.sources.use(...)
VNSTOCK_ROUTE_UNSUPPORTEDNguồn đã chọn không đọc được loại dữ liệu nàyXem vnstock.sources.readers(route)
VNSTOCK_CREDENTIAL_MISSINGChưa có khoá của nguồnvnstock keys set <nguồn>
VNSTOCK_SOURCE_AUTH, VNSTOCK_SOURCE_LOGIN, VNSTOCK_SOURCE_OTPNguồn từ chối khoá, hoặc cần mở phiênKiểm khoá bằng vnstock keys check <nguồn>; nguồn có OTP thì vnstock auth <nguồn>
VNSTOCK_SOURCE_RATE_LIMITEDNguồn từ chối vì gọi quá nhanhChờ vài phút, tải ít mã hơn mỗi lần

Trong fa.Dataset.load(), sáu mã đầu khi tải giá hoặc thuyết minh không làm dừng cả lần tải: thư viện báo một cảnh báo, chỉ số liên quan trả MISSING_MARKET hoặc MISSING_INPUT. Lỗi mạng và lỗi tần suất vẫn được ném ra.

Mọi lỗi đều có các thuộc tính code (mã lỗi), kind (nhóm lỗi), message (nội dung tiếng Việt), retryable (có nên thử lại không) và action (việc nên làm tiếp, có thể là None). str(e) có dạng [code] message (action).

Ví dụ bắt lỗi theo nghiệp vụ

Python
import vnstock_quant as vq

try:
    # Ví dụ gọi hàm tính toán cần quyền hạn
    result = vq.portfolio.twr(values, flows)
except vq.TierRequiredError as e:
    print(f"Lỗi quyền hạn: {e.message}")
    print(f"Việc nên làm: {e.action}")
except vq.QuotaExceededError as e:
    print(f"Đã hết lượt dùng thử hôm nay [{e.code}]. Lượt sẽ được làm mới lúc 00:00 giờ Việt Nam.")
except vq.AuthError as e:
    print(f"Không kiểm tra được quyền sử dụng: {e}")
except vq.InvalidParameterError as e:
    print(f"Tham số không hợp lệ: {e}")
except vq.VnstockQuantError as e:
    print(f"Lỗi chung của vnstock_quant: {e}")

Tắt cảnh báo hệ thống

Các lưu ý không làm dừng chương trình được phát qua lớp cảnh báo VnstockQuantWarning. Ở bản 1.0, một số tính năng chưa đủ chắc chắn được tắt hoặc chạy kèm cảnh báo nêu rõ điều kiện, thay vì trả một con số trông như thật:

Cảnh báoKhi nàoĐiều kiện để có số
Bảng thử nghiệm của vnstock 6Lần đầu tải BCTC, giá theo phiên, lịch sự kiện trong một tiến trìnhĐối chiếu với báo cáo gốc hoặc thông báo của sở trước khi dùng cho quyết định
Định giá tắt vì thiếu số cổ phiếufa không có cột total_sharesTruyền total_shares qua Dataset.from_frames, hoặc estimate_shares=True
Định giá tắt vì giá đã điều chỉnhGiá đóng cửa lẻ bước giá 10 đồngĐưa bảng giá đóng cửa gốc qua Dataset.from_frames
Số cổ phiếu là ước tínhestimate_shares=TrueChỉ để tham khảo; lệch nhiều sau đợt phát hành
Không phân biệt được phiên ATO, ATCBảng khớp lệnh không có cột sessionBỏ các lệnh khớp lúc 09:15 và 14:45 trước khi tính nếu cần
Biểu phí chưa xác minhbacktest dùng biểu phí có verified=FalseTruyền fee theo biểu phí thật của bạn
Chi phí phái sinh chưa mô phỏngbacktest với hồ sơ vn_futuresLãi lỗ thường cao hơn thực tế; tự trừ thuế, phí vị thế, phí ký quỹ

Bạn có thể tắt cảnh báo nếu muốn, nhưng nên đọc chúng ít nhất một lần:

Python
import warnings
from vnstock_quant import VnstockQuantWarning

# Bỏ qua các cảnh báo không trọng yếu của vnstock_quant
warnings.filterwarnings("ignore", category=VnstockQuantWarning)

Các quy ước phương pháp luận chung

Trước khi so sánh kết quả giữa các hàm, hãy chú ý các quy ước sau:

Quy ướcChi tiết áp dụng
Tỷ lệ và phân sốMọi tỷ lệ phần trăm được biểu diễn dưới dạng phân số thập phân (ví dụ 0.18 đại diện cho 18%). Kết quả tính toán trả về cũng tuân thủ định dạng phân số.
Giá và chuỗi lợi suấtChuỗi lợi suất giản đơn được tính toán dựa trên giá đóng cửa đã điều chỉnh (adjusted close). Việc dùng giá chưa điều chỉnh sẽ tạo ra các phiên thua lỗ giả tạo vào ngày giao dịch không hưởng quyền.
Số phiên giao dịch một nămMặc định sử dụng 252 phiên/năm theo chuẩn quốc tế đối với dữ liệu ngày (52 tuần, 12 tháng). Dữ liệu thực tế tại sàn HOSE giai đoạn 2017–2025 ghi nhận trung bình 249,8 phiên/năm. Bạn có thể truyền periods=250 vào các hàm rủi ro nếu muốn quy đổi chuẩn xác theo năm dựa trên lịch giao dịch Việt Nam.
Lãi suất phi rủi ro (rf)Là lãi suất năm, mặc định là 0. Bạn có thể chỉ định lãi suất trái phiếu Chính phủ kỳ hạn 1 năm hoặc lãi suất tiết kiệm 12 tháng của nhóm ngân hàng Big 4.
Chỉ mục thời gian (time)Căn cứ vào DatetimeIndex của pandas. Khi tính toán tương quan hoặc đo lường so với thị trường (Benchmark), hai chuỗi dữ liệu được căn chỉnh theo ngày giao dịch chung, không căn chỉnh theo số thứ tự hàng.
Xử lý dữ liệu khuyết thiếuKhông bao giờ âm thầm điền số 0 vào ô trống. Báo cáo tài chính thiếu chỉ tiêu được đánh dấu qua cột reason, kể cả khi báo cáo chỉ có chỉ tiêu cấp 1 (taxonomy rút gọn): chỉ tiêu chi tiết vắng mặt là chưa biết, không phải 0. Các hàm danh mục từ chối tính nếu chuỗi lợi suất chứa NaN.
Độ đo rủi ro sụt giảm (VaR/CVaR)Trả về giá trị dương đại diện cho mức lỗ tiềm tàng tại ngưỡng tin cậy xác định.
Ràng buộc bán khống (Short-selling)Không cho phép vị thế bán khống trong các bài toán tối ưu danh mục, phù hợp với quy định của thị trường chứng khoán cơ sở Việt Nam.

Đọc tiếp