Models
Data models and constants in Python SDK 3.3.2
This page lists the SDK's data models (the page name utilities is a legacy name; the content is Models). All models are imported from ssi_sdk.models:
from ssi_sdk.models import Account, OHLCData, PlaceOrderResponse, TradeMessageEvery model is a dataclass. A field typed X | str | None means the SDK returns the enum member when it recognises the value, the raw string when the value is unknown, and None when the server did not send it. For the enums see Enums.
Authentication
Token
| Field | Type | Description |
|---|---|---|
access_token | str | Access token (hidden from repr; do not print/log) |
token_type | str | Token type (default "Bearer") |
expires_at | int | Expiration time, epoch seconds (0 = unknown / treated as expired) |
refresh_token | str | Refresh token (hidden from repr) |
refresh_token_expires_at | int | Refresh token expiration |
Properties: effective_expires_at (the effective expiry time) and can_refresh (whether a refresh is possible).
OTPResponse
Result of auth.request_otp_typed().
| Field | Type | Description |
|---|---|---|
message | str | Message from the server |
transaction_id | str | None | Only present for Smart OTP; pass it to ensure_authenticated(transaction_id=...). See Smart OTP |
Account
Account
| Field | Type | Description |
|---|---|---|
account_no | str | Account number |
account_type | AccountType | str | None | Account type; the raw string for an unknown type, None when the server did not send it (no longer defaults to Cash) |
Market Data
OHLCData
| Field | Type | Description |
|---|---|---|
symbol | str | Stock symbol |
trading_date | str | Trading date |
open_price | float | int | Open price |
high_price | float | int | High price |
low_price | float | int | Low price |
close_price | float | int | Close price |
volume | int | Volume |
value | float | int | Trade value |
MarketIndexes
| Field | Type | Description |
|---|---|---|
index | str | Index code |
index_name | str | Index name |
board | Board | str | None | Board |
board_raw | str | None | Raw board code as the server sent it |
MarketIndexSummary
MarketIndexSummary has no index or board field; the index code is the argument you pass when calling.
| Field | Type | Description |
|---|---|---|
trading_date | str | Trading date |
index_value | float | Index value |
index_change | float | Change |
index_change_percent | float | Change (%) |
total_trade | int | Total trade volume |
total_trade_value | float | Total trade value |
total_advance_stock | int | Advancing stocks |
total_decline_stock | int | Declining stocks |
total_steady_stock | int | Unchanged stocks |
total_match | int | Total matched volume |
total_match_value | float | Total matched value |
total_deal | int | Total negotiated (put-through) volume |
total_deal_value | float | Total negotiated value |
total_ceiling_stock | int | Stocks at ceiling |
total_floor_stock | int | Stocks at floor |
total_prop_buy | int | Proprietary buy volume |
total_prop_buy_value | float | Proprietary buy value |
total_prop_sell | int | Proprietary sell volume |
total_prop_sell_value | float | Proprietary sell value |
total_buy_foreign / total_buy_foreign_value | optional | Foreign buy volume / value |
total_sell_foreign / total_sell_foreign_value | optional | Foreign sell volume / value |
net_purchases_foreign_volume / net_purchases_foreign_value | optional | Foreign net buy volume / value |
The foreign fields are optional (None when the server did not send them).
SecuritiesInfo
A numeric field the server omits is None (not 0); an empty date is None.
| Field | Type | Description |
|---|---|---|
symbol | str | Stock symbol |
board | Board | str | None | Board |
index | str | None | Index |
symbol_name_vi | str | None | Vietnamese name |
symbol_name_en | str | None | English name |
lot_size | int | None | Lot size |
listed_shares | int | None | Listed shares |
icb_code | str | None | ICB industry code |
icb_name | str | None | ICB industry name |
maturity_date | str | None | Maturity date |
first_trading_date | str | None | First trading date |
last_trading_date | str | None | Last trading date |
cw_underlying_symbol | str | None | CW underlying symbol |
cw_exercise_price | float | None | CW exercise price |
cw_execution_ratio | float | None | CW execution ratio |
i_index | float | None | I-index |
i_nav | float | None | iNAV value |
open_interest | int | None | Open interest (derivatives) |
settlement_price | float | None | Settlement price (derivatives) |
stock_type | str | None | Security type |
MasterData
Ceiling / floor / reference price of a symbol (from get_master_data()).
| Field | Type | Description |
|---|---|---|
board | Board | str | None | Board |
symbol | str | Stock symbol |
trading_date | str | Trading date |
ceiling | float | None | Ceiling price |
floor | float | None | Floor price |
ref_price | float | None | Reference price |
CorporateAction
One corporate action (dividend, bonus shares, rights issue, ...) of a symbol (from get_corporate_actions() and get_corporate_actions_historical()). Every field is a str exactly as the server sends it: dates stay YYYY/MM/DD text and ratio is not parsed, because its meaning depends on the event type. A field the server leaves blank (a newly announced event has no ex-right date or ratio yet) is "".
| Field | Type | Description |
|---|---|---|
symbol | str | Stock symbol |
event_title | str | Event name |
exright_date | str | Ex-right date |
record_date | str | Record date |
issue_date | str | Issue date |
exchange | str | Exchange code, for example "HOSE" |
ratio | str | Event ratio as text, for example "0.9388" |
SecuritiesSummary
| Field | Type | Description |
|---|---|---|
symbol | str | Stock symbol |
trading_date | str | Trading date |
price_change | float | Price change |
price_change_percent | float | Price change (%) |
open_price | float | Open price |
high_price | float | High price |
low_price | float | Low price |
close_price | float | Close price |
average_price | float | Average price |
total_match | int | Total matched volume |
total_match_value | float | Total matched value |
total_buy | int | Total buy volume |
total_trade_buy | float | Total buy value |
total_sell | int | Total sell volume |
total_trade_sell | float | Total sell value |
total_foreign_buy / total_foreign_buy_value | optional | Foreign buy volume / value |
total_foreign_sell / total_foreign_sell_value | optional | Foreign sell volume / value |
remain_foreign_room / total_foreign_room | optional | Remaining foreign room / total foreign room |
total_deal / total_deal_value | optional | Negotiated volume / value |
open_interest / settlement_price | optional | Open interest / settlement price (derivatives) |
ceiling / floor / ref_price | None | Not sent by this endpoint; use get_master_data() |
DownloadData and DownloadDataRequest are deprecated; do not use them.
Portfolio
Balances (EquityAccountBalance, DerivativeAccountBalance) and positions (Position) can be None when the account has no data yet, so check for None before using them.
EquityAccountBalance
| Field | Type | Description |
|---|---|---|
account_no | str | Account number |
account_balance | float | Account balance |
total_debt | float | Total debt |
interest_loan | float | Loan interest |
overdue_fee_loan | float | Overdue loan fee |
withdrawable | float | Withdrawable cash |
on_hold_cash | float | Cash on hold |
sell_unmatched | float | Unmatched sell proceeds |
sell_t0 | float | Sell proceeds T0 |
sell_t1 | float | Sell proceeds T1 |
sell_t2 | float | Sell proceeds T2 |
buy_unmatched | float | Unmatched buy amount |
buy_t0 | float | Buy amount T0 |
buy_t1 | float | Buy amount T1 |
buy_t2 | float | Buy amount T2 |
advance_cash_t0 | float | Cash advance T0 |
advance_cash_t1 | float | Cash advance T1 |
hold_subscription | float | Cash held for subscription |
dividend | float | Dividend |
DerivativeAccountBalance
| Field | Type | Description |
|---|---|---|
account_no | str | Account number |
account_balance | float | Account balance |
fee | float | Fee |
commission | float | Commission |
interest | float | Interest |
ext_interest | float | External interest |
loan | float | Loan |
delivery_amount | float | Delivery amount |
floating_pl | float | Unrealized P/L |
trading_pl | float | Trading P/L |
total_pl | float | Total P/L |
withdrawable | float | Withdrawable cash |
cash_ssi | float | SSI cash |
valid_non_cash_ssi | float | Valid non-cash assets, SSI |
withdrawable_ssi | float | Withdrawable, SSI |
cash_vsdc | float | VSDC cash |
valid_non_cash_vsdc | float | Valid non-cash assets, VSDC |
withdrawable_vsdc | float | Withdrawable, VSDC |
cash_withdrawable_ssi and cash_withdrawable_vsdc are old aliases of withdrawable_ssi / withdrawable_vsdc; they still read but emit a DeprecationWarning.
EquityPosition
| Field | Type | Description |
|---|---|---|
account_no | str | Account number |
symbol | str | Stock symbol |
quantity | int | Total quantity |
sellable_quantity | int | Sellable quantity |
cost_price | float | Cost price |
buying_quantity | int | Quantity being bought |
selling_quantity | int | Quantity being sold |
mortgage_quantity | int | Mortgaged quantity |
block_quantity | int | Blocked quantity |
dividend_quantity | int | Dividend quantity |
bought_quantity | int | Bought quantity |
sold_quantity | int | Sold quantity |
t1_buy_quantity | int | T1 buy quantity |
t2_buy_quantity | int | T2 buy quantity |
t1_sell_quantity | int | T1 sell quantity |
t2_sell_quantity | int | T2 sell quantity |
restricted_quantity | int | Restricted quantity |
DerivativePosition
| Field | Type | Description |
|---|---|---|
account_no | str | Account number |
symbol | str | Contract symbol |
long / short / net | int | Long / short / net position |
bid_avg_price / ask_avg_price | float | Average buy / sell price |
floating_pl / trading_pl | float | P/L |
trade_price | float | Trade price |
AllDerivativePosition
| Field | Type | Description |
|---|---|---|
open_positions | list[DerivativePosition] | Open positions |
closed_positions | list[DerivativePosition] | Closed positions |
account_no | str | Account number |
Order
| Field | Type | Description |
|---|---|---|
account_no | str | Account number |
client_request_id | str | Client request ID |
order_id | str | Order ID |
symbol | str | Stock symbol |
side | OrderSide | str | None | Buy/Sell |
order_type | OrderType | str | None | Order type |
price | int | float | OrderType | str | Order price (can be an order type such as ATO, ATC) |
avg_price | float | Average matched price |
quantity | int | Order quantity |
os_quantity | int | None | Outstanding quantity |
filled_quantity | int | Filled quantity |
cancel_quantity | int | Cancelled quantity |
status | OrderStatus | str | None | Order status |
input_time / modify_time | str | Input / modify time |
message | str | Message |
Trading Responses
PlaceOrderResponse
order_id, client_request_id, status (OrderStatus | str)
ModifyOrderResponse
client_modify_id, order_id, client_request_id, status (OrderStatus | str)
CancelOrderResponse
client_cancel_id, order_id, client_request_id, status (OrderStatus | str)
MaxBuySellResponse
account_no, symbol, max_buy_quantity, max_sell_quantity, margin_ratio (str | None), purchasing_power (int | None)
Conditional Orders (FCO)
FCOPlaceResponse
Result of placing a conditional order — fco_id
FCOCancelResponse
Result of cancelling a conditional order — fco_id
FCOListResponse
Paginated list of conditional orders.
| Field | Type | Description |
|---|---|---|
page_index | int | Current page |
page_size | int | Page size |
items_count | int | Total records |
pages_count | int | Total pages |
fco_list | list[FCOInfo] | FCO order list |
FCOInfo
Details of one conditional order.
| Field | Type | Description |
|---|---|---|
fco_id | str | FCO order ID |
client_id | str | Username / Client ID |
account_no | str | Account number |
quantity | int | Order quantity |
price | str | Order price |
price_slip | float | None | Price slippage |
order_type | OrderType | str | None | Order type placed when triggered |
symbol | str | Stock symbol |
type | FCOType | str | None | Conditional order type |
from_date | str | Effective from |
to_date | str | Effective to |
matched_quantity | int | Matched quantity |
is_place_order | bool | Whether the order has been placed on the book |
status | FCOStatus | str | None | FCO order status |
detail | str | Status detail |
params | FCOParams | None | Trigger parameters of the FCO order |
FCOParams
Trigger parameters of a conditional order.
| Field | Type | Description |
|---|---|---|
stop_price | float | None | Stop / trigger price |
side | OrderSide | None | Order side (Buy/Sell) |
active_price | float | None | Activation price (Trailing Stop) |
trailing_amount | float | None | Trailing amount |
tp_active_price | float | None | Take Profit activation price |
sl_active_price | float | None | Stop Loss activation price |
tp_price | str | None | Take Profit price |
sl_price | str | None | Stop Loss price |
tp_slip | float | None | Take Profit slippage |
sl_slip | float | None | Stop Loss slippage |
operator | FCOOperator | str | None | Trigger comparison operator |
The request parameter classes used when placing orders (GTDParams, StopParams, TrailingStopParams, OCOParams, BullBearParams) also have an optional code field (OTP code, default None).
FCOStatusHistoryItem
One row of the status-change history of a conditional order (from get_fco_status_history).
| Field | Type | Description |
|---|---|---|
state | str | State (see FCOStatus in Enums) |
time | str | When the state changed |
code | str | None | Status code, if any |
detail | str | Detail |
FCOOrderBookResponse
FCO matching log (paginated).
| Field | Type | Description |
|---|---|---|
page_index | int | Current page |
page_size | int | Page size |
items_count | int | Total records |
pages_count | int | Total pages |
order_book | list[FCOOrder] | FCO order log |
FCOOrder
Trade / execution log of an FCO order.
| Field | Type | Description |
|---|---|---|
fco_id | str | Parent FCO order ID |
account_no | str | Account number |
quantity | int | Quantity |
price | str | Order price |
symbol | str | Stock symbol |
type | FCOType | str | None | Conditional order type |
side | OrderSide | str | None | Order side |
order_type | OrderType | str | None | Child order type |
is_main_order | bool | Is the main order |
is_attached_order | bool | Is an attached order |
created_time / updated_time | str | Created / updated time |
unique_id | str | Unique ID |
order_id | str | Exchange order ID |
matched_quantity | int | Matched quantity |
os_quantity | int | Outstanding quantity |
avg_price | float | Average matched price |
status | OrderStatus | str | None | Child order status |
detail | str | Detail |
Batch Order
Models for batch orders (place / cancel several orders in one request). Usage, examples and limits: Services, section 5.4.
The two TypedDicts below describe each element you pass to place_batch_orders / cancel_batch_orders:
| Type | Required fields | Optional fields |
|---|---|---|
BatchPlaceOrderItem | account_no, symbol, side, quantity, price, order_type | client_request_id |
BatchCancelOrderItem | account_no | order_id, client_request_id |
BatchOrderRequest
| Field | Type | Description |
|---|---|---|
batch_request_id | str | ID of the whole batch (reusing an id is an HTTP 409) |
batch_request_time | int | Time the batch is sent, epoch milliseconds |
orders | list[dict] | The orders |
It has to_dict() (camelCase payload) and to_str() (the JSON string that is signed and sent).
BatchOrderResult
Outcome of one order in the batch.
| Field | Type | Description |
|---|---|---|
client_request_id | str | Client request ID of the order |
order_id | str | Order ID |
status | OrderStatus | str | Status |
success | bool | Whether this order succeeded (default False) |
error_code | str | Server error code when the order was rejected |
error_message | str | Server error text when the order was rejected |
client_cancel_id | str | ID of the cancel request (generated by the SDK, only for batch cancel) |
BatchOrderResponse
| Field | Type | Description |
|---|---|---|
batch_request_id | str | ID of the whole batch |
results | list[BatchOrderResult] | One result per order |
Note: the SDK's per-batch maximum is MAX_BATCH_ORDERS = 20 (override with Config.max_batch_orders), while the API reference says 50; the limit the server actually applies has not been confirmed. See Configuration and Services, section 5.4.
Streaming Messages
These messages arrive through the callbacks of stream.streaming, see Services, section 6.
TradeMessage
type, trading_time, symbol, price, quantity, side, total_volume, plus the optional open, high, low, avg (None when the server did not send them).
IntervalMessage
| Field | Type | Description |
|---|---|---|
type | DataType | Data type |
interval_time | str | Interval time |
trading_time | str | Trading time |
symbol | str | Stock symbol |
open | float | int | Open |
high | float | int | High |
low | float | int | Low |
close | float | int | Close |
volume | int | Volume |
IndexTickMessage
Real-time index tick (see Services, section 6.7).
| Field | Server key | Description |
|---|---|---|
type | Data type | |
symbol | s | Index code |
board | b | Board |
status | ss | Status |
trading_time | t | Time |
value | v | Index value |
change | c | Change |
change_percent | cr | Change (%) |
advances | adv | Advancing stocks |
declines | dec | Declining stocks |
no_change | nc | Unchanged stocks |
ceilings | ce | Stocks at ceiling |
floors | fl | Stocks at floor |
total_match_value | tmv | Total matched value |
total_match_quantity | tmq | Total matched quantity |
total_put_value | tvp | Total negotiated value |
total_put_quantity | tqp | Total negotiated quantity |
total_quantity | tq | Total quantity |
total_value | tv | Total value |
raw | The whole data object the server sent |
Not confirmed: the attribute names are inferred from the server's abbreviations and have not been checked against a real frame. When you need to be sure, read msg.raw.
IndexSummaryMessage
| Field | Type | Description |
|---|---|---|
index | str | Index code taken from the topic, upper-case (for example "VN30") |
data | dict | The server's payload, untouched |
The fields inside data are not publicly documented, so the SDK does not guess them; read them with msg.get("key1", "key2", default=None) (returns the value of the first key present).
MarketFlagMessage
| Field | Type | Description |
|---|---|---|
board | str | Board code as the server sends it: HOSE, HNX, UPCOM or DER (derivatives; not the enum Board's DERIVATIVES) |
trading_time | str | Time |
flag | str | Session flag (for example "ATO", "LO", "ATC"), kept as the raw string |
MarketDataMessage
symbol, board, trading_time, ceiling, floor, ref_price
QuoteMessage
type, trading_time, symbol, bid_prices, bid_volumes, ask_prices, ask_volumes
ForeignRoomMessage
type, trading_time, symbol, total_room, current_room, buy_quantity, buy_value, sell_quantity, sell_value
PutMessage
type, trading_time, symbol, price, quantity, total_quantity, total_value
OddLotMessage
type, trading_time, symbol, price, quantity, bid_prices, bid_volumes, ask_prices, ask_volumes
MarketStatusMessage
market, status, trading_date
OrderStatusMessage
type, account_no, client_request_id, order_id, symbol, side, order_type, price, quantity, os_quantity, filled_quantity, cancel_quantity, status, input_time, modified_time, message, plus avg_price, reject_reason, system_request_id, error_code, error_message, notify_id, connection_id.
modify_time is a deprecated alias of modified_time. os_quantity is None when the order comes from the REST order book. An order the server rejects reports status RJ with error_code.
OrderMatchMessage
type, notify_id, connection_id, client_request_id, order_id, symbol, side, account_no, match_price, match_qty, match_time
PortfolioMessage
type, account_no, symbol, long_qty, short_qty, net, bid_avg_price, ask_avg_price, trade_price, market_price, floating_pl, trading_pl, position_type
total_asset, cash_balance and stock_value are deprecated and always None.
FCOOrderUpdateMessage
FCO conditional-order status update (streaming, received via on_trading when event_type == "fcoEvent").
| Field | Type | Description |
|---|---|---|
fco_id | str | FCO order ID |
process_status | FCOStatus | None | FCO processing status (INIT, WAIT, WC, TER, ...) |
matched_quantity | int | Matched quantity |
is_place_order | bool | Whether the order has been placed on the book |
symbol | str | Stock symbol |
quantity | int | Order quantity |
price | str | Order price |
account_no | str | Account number |
updated_time | str | Update time (YYYY/MM/DD HH:MM:SS) |
status | str | Status code |
message | str | Detail message / trigger or disconnect reason |
username | str | Username that placed the order |
event_type | str | Event type ("fcoEvent") |
type | FCOType | None | Conditional order type (GTD, STOP, ...) |
HeartbeatMessage
method, channel, status, message
ConnectionEvent
Connection-state event of the stream, received via on_connection. It is a frozen dataclass and is not exported at top level: from ssi_sdk.transport.reconnect import ConnectionEvent.
| Field | Type | Description |
|---|---|---|
state | str | connected, reconnected, disconnected or failed |
reconnect_count | int | Number of reconnects so far (default 0) |
error | Exception | None | The error that caused the event (default None) |
Details: Services, section 6.9.
Trading WebSocket
Import from ssi_sdk (these were in ssi_sdk.experimental in 3.3.1 and earlier; that module was removed in 3.3.2). Full usage: Services, section 7; how to create the service: Client Classes.
TradingWSResponse
Result of a command sent over the Trading WebSocket.
| Field | Type | Description |
|---|---|---|
id | str | Request ID |
method | str | Method that was called |
status | int | Status code (default 200) |
result | Any | Returned data |
rate_limit | dict | Rate-limit information the server sends back |
received_time | int | None | Time the response was received |
TradingWSError
Extends WebSocketError; raised when the server rejects a command or refuses the connection. Constructor TradingWSError(status, code, message); attributes .status, .error_code and .server_message. See Exceptions.
Wrapper Types
AccountBalance
| Field | Type | Description |
|---|---|---|
equity | EquityAccountBalance | None | Equity balance |
derivative | DerivativeAccountBalance | None | Derivative balance |
Position
| Field | Type | Description |
|---|---|---|
equity | list[EquityPosition] | None | Equity positions |
derivative | AllDerivativePosition | None | Derivative positions |
PPMMR
| Field | Type | Description |
|---|---|---|
equity | EquityPPMMR | None | Equity PPMMR |
derivative | DerivativePPMMR | None | Derivative PPMMR |
OrderBook
| Field | Type | Description |
|---|---|---|
orders | list[Order] | Order list |
total_orders | int | Total orders |
Constants
The SDK's limit constants (module ssi_sdk.constant). The values are SDK defaults only; the ones that relate to the server may differ in practice.
| Constant | Value | Meaning |
|---|---|---|
MAX_CLIENT_REQUEST_ID_LENGTH | 20 | Maximum length of client_request_id |
MAX_BATCH_ORDERS | 20 | Maximum orders per batch (SDK default; override with Config.max_batch_orders) |
DEFAULT_SIZE / DEFAULT_PAGE | 1000 / 1 | Default page size / page number for pagination |
CORPORATE_ACTIONS_MAX_DAYS | 5 | Longest date range of one corporate actions request (days) |
CORPORATE_ACTIONS_LANGUAGES | ("vn", "en") | Allowed language values for corporate actions |
TOPIC_MARKET_FLAG | "market.flag" | Session flag topic |
TOKEN_EXPIRY_SKEW_MS | 30000 | A token counts as expired 30 seconds early |
WS_RECONNECT_MAX_DELAY_MS | 60000 | Maximum stream reconnect delay |
WS_RATE_LIMIT_BACKOFF_MS | 30000 | Wait time when rate limited on the WebSocket |
WS_TOKEN_REFRESH_LEAD_MS | 60000 | How long before expiry the token is refreshed |
WS_SERVER_MAX_CONNECTIONS | 10 | Maximum WebSocket connections on the server side |
WS_MAX_FRAME_BYTES | 4000 | Maximum frame size the SDK sends (server limit is 4096) |
Time constants carry the _ms suffix (milliseconds). For the matching configuration options see Configuration.