19. Corporate Actions
View dividends, bonus shares and rights issues for today or a date range, filtered by symbol and language
Objective
View corporate action events (dividends, bonus shares, rights issues...) for today or for a past date range, filtered by symbol and language. Matches Sample 19 in the tutorials repo (SDK v3.3.2). The sample is read-only: it places no orders and needs no OTP.
Flow
Auth (token cache) → Market Data API (Corporate Actions) → List of CorporateAction- Call
get_corporate_actions()for today's events - Call
get_corporate_actions_historical(from_date, to_date)for events in a date range (at most 5 days per call) - Filter by symbol (
symbol="SSI") and language (language="en") - A range that is too wide is blocked by the SDK with a
ValidationErrorbefore any server call; split the range into chunks of at most 5 days and call each chunk
Samples in the repo
| Language | File |
|---|---|
| Python | python/sample_19_corporate_actions.py, python/sample_19_corporate_actions_async.py |
| Node.js | node/sample_19_corporate_actions.js |
| .NET | dotnet/Sample19CorporateActions.cs |
| Go | go/sample_19_corporate_actions.go |
This page uses Python for illustration. Repo: ssi-fastconnect-v3-tutorials.
Prerequisites
- Credentials in
config.json, see Tutorial 1. The repo samples load the config throughconfig.py(from config import config), so no credentials appear in the code. - A token with the scope
data:corporateActions:get. auth_helper.py(token cache, Tutorial 1). This sample only calls Market Data, so no OTP is needed.
Sample Code — Sync
The code below is taken verbatim from the repo sample (the Vietnamese comments and output text are kept as in the repo).
"""
Sample 19 — Sự kiện doanh nghiệp (Corporate actions)
=====================================================
Xem cổ tức, cổ phiếu thưởng, quyền mua... của các mã. Chỉ ĐỌC dữ liệu, không đặt lệnh.
Luồng:
1. get_corporate_actions(): sự kiện của HÔM NAY
2. get_corporate_actions_historical(from, to): sự kiện trong một khoảng ngày ở quá khứ
(server cho tối đa 5 ngày mỗi lần gọi)
3. Lọc theo mã (symbol) và ngôn ngữ ("vn" / "en")
4. Khoảng ngày quá rộng bị SDK chặn tại client (ValidationError), không gọi server
Lưu ý:
- SDK tự lấy hết các trang (pageSize 100), bạn không cần tự phân trang.
- Mọi trường là chuỗi đúng như server gửi. Ngày có dạng YYYY/MM/DD, ratio KHÔNG được parse
vì ý nghĩa phụ thuộc loại sự kiện. Trường server để trống (sự kiện mới công bố chưa có
ngày GDKHQ/tỷ lệ) là "".
- Ngày truyền vào phải đúng dạng YYYY/MM/DD (không dùng dấu '-').
- "Hôm nay" lấy theo ngày của máy bạn.
"""
from datetime import datetime, timedelta
from ssi_sdk import Auth, Data, ValidationError
from auth_helper import ensure_auth
from config import config
DATE_FMT = "%Y/%m/%d"
def show(actions, limit=10):
for a in actions[:limit]:
print(
f" {a.symbol:<8} | {a.exchange:<6} | GDKHQ: {a.exright_date or '-':<10} "
f"| Chốt: {a.record_date or '-':<10} | Phát hành: {a.issue_date or '-':<10} "
f"| Tỷ lệ: {a.ratio or '-':<8} | {a.event_title}"
)
if len(actions) > limit:
print(f" ... còn {len(actions) - limit} sự kiện")
with Auth(config) as auth:
ensure_auth(auth)
with Data(auth) as data:
# --- Bước 1: Sự kiện của hôm nay ---
print("--- Sự kiện doanh nghiệp hôm nay ---")
today_actions = data.market_data.get_corporate_actions()
print(f"Tổng số sự kiện: {len(today_actions)}")
show(today_actions)
# --- Bước 2: Sự kiện trong 5 ngày gần nhất (tối đa 5 ngày cho mỗi lần gọi) ---
today = datetime.now()
from_date = (today - timedelta(days=4)).strftime(DATE_FMT)
to_date = today.strftime(DATE_FMT)
print(f"\n--- Sự kiện từ {from_date} đến {to_date} ---")
range_actions = data.market_data.get_corporate_actions_historical(from_date, to_date)
print(f"Tổng số sự kiện: {len(range_actions)}")
show(range_actions)
# --- Bước 3: Lọc theo mã, trả tiêu đề bằng tiếng Anh ---
print("\n--- Sự kiện của mã SSI (tiếng Anh) ---")
ssi_actions = data.market_data.get_corporate_actions_historical(
from_date, to_date, symbol="SSI", language="en"
)
print(f"Tổng số sự kiện: {len(ssi_actions)}")
show(ssi_actions)
# --- Bước 4: Khoảng ngày quá rộng bị chặn tại SDK ---
print("\n--- Khoảng 30 ngày (vượt giới hạn 5 ngày) ---")
too_wide_from = (today - timedelta(days=30)).strftime(DATE_FMT)
try:
data.market_data.get_corporate_actions_historical(too_wide_from, to_date)
except ValidationError as e:
print(f" SDK từ chối trước khi gọi server: {e}")
print(" -> chia khoảng ngày thành các đoạn <= 5 ngày rồi gọi từng đoạn.")
# --- Response Summary ---
print("\n[Response] today_count|range_count|ssi_range_count")
print(f"{len(today_actions)}|{len(range_actions)}|{len(ssi_actions)}")Sample Code — Async
Async uses the same flow; steps 1-3 are independent, so they run in parallel with asyncio.gather.
"""
Sample 19 (Async) — Sự kiện doanh nghiệp (Corporate actions)
=============================================================
Xem cổ tức, cổ phiếu thưởng, quyền mua... của các mã. Chỉ ĐỌC dữ liệu, không đặt lệnh.
Luồng:
1. get_corporate_actions(): sự kiện của HÔM NAY
2. get_corporate_actions_historical(from, to): sự kiện trong một khoảng ngày ở quá khứ
(server cho tối đa 5 ngày mỗi lần gọi)
3. Lọc theo mã (symbol) và ngôn ngữ ("vn" / "en")
4. Khoảng ngày quá rộng bị SDK chặn tại client (ValidationError), không gọi server
Bước 1-3 độc lập nên chạy song song bằng asyncio.gather.
Lưu ý: SDK tự lấy hết các trang. Mọi trường là chuỗi đúng như server gửi (ngày YYYY/MM/DD,
ratio không được parse, trường để trống là ""). Ngày truyền vào phải đúng dạng YYYY/MM/DD.
"""
import asyncio
from datetime import datetime, timedelta
from ssi_sdk import AsyncAuth, AsyncData, ValidationError
from auth_helper import ensure_auth_async
from config import config
DATE_FMT = "%Y/%m/%d"
def show(actions, limit=10):
for a in actions[:limit]:
print(
f" {a.symbol:<8} | {a.exchange:<6} | GDKHQ: {a.exright_date or '-':<10} "
f"| Chốt: {a.record_date or '-':<10} | Phát hành: {a.issue_date or '-':<10} "
f"| Tỷ lệ: {a.ratio or '-':<8} | {a.event_title}"
)
if len(actions) > limit:
print(f" ... còn {len(actions) - limit} sự kiện")
async def main():
async with AsyncAuth(config) as auth:
await ensure_auth_async(auth)
async with AsyncData(auth) as data:
today = datetime.now()
from_date = (today - timedelta(days=4)).strftime(DATE_FMT)
to_date = today.strftime(DATE_FMT)
# --- Bước 1-3: Gọi song song ---
today_actions, range_actions, ssi_actions = await asyncio.gather(
data.market_data.get_corporate_actions(),
data.market_data.get_corporate_actions_historical(from_date, to_date),
data.market_data.get_corporate_actions_historical(
from_date, to_date, symbol="SSI", language="en"
),
)
print("--- Sự kiện doanh nghiệp hôm nay ---")
print(f"Tổng số sự kiện: {len(today_actions)}")
show(today_actions)
print(f"\n--- Sự kiện từ {from_date} đến {to_date} ---")
print(f"Tổng số sự kiện: {len(range_actions)}")
show(range_actions)
print("\n--- Sự kiện của mã SSI (tiếng Anh) ---")
print(f"Tổng số sự kiện: {len(ssi_actions)}")
show(ssi_actions)
# --- Bước 4: Khoảng ngày quá rộng bị chặn tại SDK ---
print("\n--- Khoảng 30 ngày (vượt giới hạn 5 ngày) ---")
too_wide_from = (today - timedelta(days=30)).strftime(DATE_FMT)
try:
await data.market_data.get_corporate_actions_historical(too_wide_from, to_date)
except ValidationError as e:
print(f" SDK từ chối trước khi gọi server: {e}")
print(" -> chia khoảng ngày thành các đoạn <= 5 ngày rồi gọi từng đoạn.")
# --- Response Summary ---
print("\n[Response] today_count|range_count|ssi_range_count")
print(f"{len(today_actions)}|{len(range_actions)}|{len(ssi_actions)}")
asyncio.run(main())CorporateAction fields
| Field | Meaning |
|---|---|
symbol | Ticker symbol |
event_title | Event name |
exright_date | Ex-rights date |
record_date | Record date |
issue_date | Issue / execution date |
exchange | Exchange, e.g. HOSE |
ratio | Event ratio, as a string |
Notes
- At most 5 days per call:
to_datemust not be more than 5 days afterfrom_date. To cover a longer period, split it into chunks of at most 5 days and call each chunk. - Every field is a string: the SDK keeps the values exactly as the server sends them. Dates look like
YYYY/MM/DD;ratiois not parsed because its meaning depends on the event type. - A field can be an empty string
"": a newly announced event may not have an ex-rights date or ratio yet (exright_date,ratio). The sample printsa.ratio or '-'. Do not assume every field has a value. - Checked before the server is called: the SDK validates the date format (
YYYY/MM/DD, no-),from_datenot afterto_date, the 5-day maximum span,symbolandlanguage. Any failure raisesValidationErrorand no request is sent. language:"vn"(default) or"en"; it sets the language ofevent_title.- Symbol filter:
symbolis one symbol (letters and digits only, up to 20 characters). Leave it out to get all symbols. - "Today" is your machine's date:
get_corporate_actions()takes the current date from the machine running the code. - The SDK fetches every page for you: no manual paging.
- Verification status: per the SDK 3.3.2 changelog, these two methods were written from the API documentation and unit-tested, but not yet run against the live server. If results differ from the API documentation, report it to SSI.
- Endpoint, parameters and scope: data-corporateActions. Handling
ValidationError, rate limits and server errors: Error Handling & Rate Limits.