Giá điều chỉnh
Mục lục
Tính năng trên trang này đang trong giai đoạn phát triển thử nghiệm và chưa ổn định. Bạn dùng được để tìm hiểu và chạy thử, nhưng tên hàm hay công cụ, tham số và cấu trúc kết quả có thể còn đổi giữa các bản phát hành, cách tính và cách xử lý cũng có thể còn được hiệu chỉnh.
Hãy đối chiếu kết quả với một cách tính độc lập trước khi đưa vào quy trình nghiên cứu, và ghim phiên bản thư viện trong dự án để mã đang chạy không tự đổi theo bản mới.
vnstock_quant.prices chuyển bảng giá chưa điều chỉnh (dạng trade_history() của vnstock) sang giá đã điều chỉnh theo sự kiện quyền. Hàm dùng danh sách sự kiện (events()) và kiểm từng sự kiện với giá tham chiếu, giá trần, giá sàn do sàn đặt, nên bạn biết sự kiện nào khớp với sàn và sự kiện nào cần xem lại. Cần cấp quyền sử dụng từ Bronze, cùng nhóm quyền risk (Quyền dùng và hạn mức).
| Hàm | Trả về |
|---|---|
prices.adjust(prices, events, ...) | Bảng giá đầu vào với các cột giá đã nhân hệ số; bảng hệ số trong attrs["factors"] |
prices.factors(prices, events, ...) | Bảng hệ số: mỗi phiên giao dịch không hưởng quyền một dòng, kèm nhân chứng của sàn và trạng thái |
prices.from_vnstock(symbol, start, end, ...) | open, high, low, close, volume đã điều chỉnh, đơn vị đồng, tải qua vnstock |
Chuỗi lợi suất cho risk, portfolio và backtest nên tính từ giá đã điều chỉnh: giá chưa điều chỉnh tạo ra phiên thua lỗ giả vào ngày giao dịch không hưởng quyền.
Dữ liệu mẫu
Ví dụ dùng bốn phiên có dạng của trade_history(), chạy được không cần mạng. Phiên 12/06/2024 là ngày giao dịch không hưởng quyền của FPT: cổ tức tiền 1.000 đồng và cổ phiếu thưởng 15%.
import pandas as pd
from vnstock_quant import prices
tz = "Asia/Ho_Chi_Minh"
sessions = pd.DataFrame({
"trading_date": pd.to_datetime(["2024-06-10", "2024-06-11", "2024-06-12", "2024-06-13"]).tz_localize(tz),
"reference_price": [144_000.0, 145_000.0, 126_517.0, 132_000.0],
"ceiling_price": [154_000.0, 155_100.0, 135_300.0, 141_200.0],
"floor_price": [134_000.0, 134_900.0, 117_700.0, 122_800.0],
"open": [144_500.0, 145_500.0, 128_000.0, 132_500.0],
"high": [146_000.0, 147_000.0, 133_000.0, 134_000.0],
"low": [143_500.0, 145_000.0, 127_500.0, 131_500.0],
"close": [145_000.0, 146_500.0, 132_000.0, 133_000.0],
"matched_volume": [3.1e6, 2.8e6, 6.4e6, 4.0e6],
})
events = pd.DataFrame({
"event_code": ["DIV", "ISS", "ISS"],
"issue_type": [None, "bonus_share", "esop"],
"event_title_vi": ["Cổ tức tiền 1.000đ", "Cổ phiếu thưởng 15%", "ESOP 0,5%"],
"exright_date": pd.to_datetime(["2024-06-12", "2024-06-12", "2024-06-13"]).tz_localize(tz),
"exercise_ratio": [0.1, 0.15, 0.005],
"value_per_share": [1000.0, None, None],
})Với dữ liệu thật:
from vnstock import Market, Reference
sessions = Market().equity("FPT").trade_history(start="2024-01-01", end="2024-12-31")
events = Reference().company("FPT").events()trade_history() trả tối đa 1.000 phiên mỗi lần gọi. Cần chuỗi dài thì dùng prices.from_vnstock, hàm này tự tải theo từng cửa sổ ba năm.
Điều chỉnh giá
adjusted = prices.adjust(sessions, events)
adjusted[["trading_date", "close", "reference_price"]]Giá các phiên trước 12/06/2024 được nhân với (146.500 − 1.000) / (1,15 × 146.500) ≈ 0,8636. Phiên cuối giữ nguyên. ESOP không làm đổi giá tham chiếu nên không được điều chỉnh. Khối lượng và các cột *_adjusted của bảng đầu vào giữ nguyên.
Bảng hệ số và nhân chứng của sàn
table = prices.factors(sessions, events)
table[["date", "kinds", "cash", "stock", "exchange_factor", "witness", "factor", "status"]]factor: hệ số nhân cho mọi giá trướcdate.exchange_factor: hệ số suy từ giá tham chiếu của sàn (126.517 / 146.500).witness = "reference": giá tham chiếu và trung điểm trần, sàn cùng xác nhận sự kiện.status = "confirmed": sự kiện khớp với sàn.
Trạng thái khác cho biết mức tin cậy thấp hơn: implied khi chỉ suy được từ giá sàn đặt, inferred khi danh sách sự kiện không có nhưng giá tham chiếu và biên độ cùng đổi, unresolved khi sự kiện và giá sàn không khớp nhau. Trạng thái cần bạn chú ý đều kèm cảnh báo VnstockQuantWarning.
Tuỳ chọn
split = prices.factors(sessions, events, mode="split") # chỉ sự kiện cổ phiếu
exchange = prices.factors(sessions, events, basis="exchange") # theo giá tham chiếu đã làm tròn của sàn
split["factor"].iloc[0], exchange["factor"].iloc[0]| Tham số | Giá trị | Dùng khi |
|---|---|---|
mode | full (mặc định) | Lợi suất, rủi ro, backtest: cổ tức tiền được tính như đã tái đầu tư |
split | Chỉ báo kỹ thuật, so đồ thị giá không tính cổ tức tiền | |
basis | event (mặc định) | Giá lý thuyết từ sự kiện, không phụ thuộc cách làm tròn của sàn |
exchange | Đúng giá tham chiếu sàn đã đặt (đã làm tròn bước giá) | |
infer | True (mặc định) | Điều chỉnh cả lần giá tham chiếu và biên độ cùng đổi mà danh sách sự kiện không có |
unit | auto, dong, thousand | Đơn vị của bảng giá; auto nhận ra bảng nghìn đồng của ohlcv() |
Quyền mua không có giá phát hành trong events(). Thư viện suy giá từ giá tham chiếu. Nếu biết giá chính xác, điền vào cột value_per_share của dòng quyền mua:
rights = pd.DataFrame({
"event_code": ["ISS"], "issue_type": ["rights_issue"], "event_title_vi": ["Quyền mua 20%"],
"exright_date": pd.to_datetime(["2024-06-12"]).tz_localize(tz),
"exercise_ratio": [0.2], "value_per_share": [10_000.0],
})
prices.factors(sessions[["trading_date", "close"]], rights)[["rights_price", "rights_price_source", "factor"]]Tải trực tiếp qua vnstock
bars = prices.from_vnstock("FPT", start="2019-01-01")
bars.tail()
pd.DataFrame(bars.attrs["factors"]) # bảng hệ sốBảng trả về có dạng như Market().equity(s).ohlcv() (open, high, low, close, volume, chỉ mục time) nhưng đơn vị là đồng. Dùng thẳng được cho vnstock_quant.ta, risk.returns và portfolio.
Đọc tiếp
- Quy ước dữ liệu và lỗi — Vì sao chuỗi lợi suất cần giá đã điều chỉnh.
- Rủi ro và hiệu suất — Tính lợi suất và các thước đo từ giá đã điều chỉnh.
- Luật thị trường, phí và sự kiện trong backtest — Cách mô-đun backtest xử lý cổ tức và quyền mua khi mô phỏng.
