Sub/Unsub Trading Data
Subscribe and unsubscribe to trading data via FastConnect WebSocket — including regular orders, order matches, portfolio updates, and conditional orders (FCO).
Overview
The TRADING channel allows clients to receive real-time trading events: order status, order matches, portfolio changes, and conditional order (FCO) events.
Clients must subscribe by account number (accountNo) to receive events. Each topic corresponds to a specific group of events.
Topic pattern
order.[accountNo/*]
portfolio.[accountNo-accountNo/*]| Topic | Description | Example |
|---|---|---|
order.<accountNo> | Order events (place/modify/cancel/match) and conditional order (FCO) events for a specific account | order.1231991 |
order.<accountNo1>-<accountNo2> | Order events for several specific accounts | order.1231996-1231998 |
order.* | Order and FCO events for all accounts within scope | order.* |
portfolio.<accountNo> | Portfolio updates (assets, positions) for a specific account | portfolio.1231991 |
portfolio.<accountNo1>-<accountNo2> | Portfolio updates for several specific accounts | portfolio.1231996-1231998 |
portfolio.* | Portfolio updates for all accounts within scope | portfolio.* |
Note: Conditional order (FCO) events are delivered on the same
orderchannel — no separate topic subscription is needed.Note: Subscribing to the
portfoliotopic is currently only supported for accounts ending in 8 (derivative accounts). Cash accounts (ending in 1) and margin accounts (ending in 6) are not yet supported.
Subscribe
Send a message with method: "SUBSCRIBE" and channel: "TRADING":
{
"method": "SUBSCRIBE",
"channel": "TRADING",
"topics": [
"order.1231991",
"order.1231996-1231998",
"order.*",
"portfolio.0901351"
]
}Subscribe rules
- Multiple topics can be included in a single message.
- Subscribing to
order.*receives order events from all accounts (including FCO events). - Subscribing to
portfolio.*receives portfolio events from all accounts. - Subscribing to the same topic multiple times does not cause an error — the server ignores already-subscribed topics.
- After reconnecting, the client must re-subscribe to all required topics.
Unsubscribe
Send a message with method: "UNSUBSCRIBE" and channel: "TRADING":
{
"method": "UNSUBSCRIBE",
"channel": "TRADING",
"topics": ["order.0901351", "portfolio.0901351"]
}Unsubscribe rules
- Only unsubscribe from topics that were previously subscribed.
- Unsubscribing from a topic that was not subscribed does not cause an error — the server ignores it.
- Unsubscribing does not affect other currently subscribed topics.
- To check which topics are currently subscribed, use
LIST_SUBSCRIPTION.
Check current subscriptions
{
"method": "LIST_SUBSCRIPTION"
}The response returns scopes by group:
{
"trading": "order.0901351;portfolio.0901351",
"data": ""
}Event types
After a successful subscription, the client will receive the following events in real time.
Binding events in the SDK
client.bind(client.events.onOrderEvent, function (e, data) {
console.log(e + ": ");
console.log(JSON.stringify(data));
});
client.bind(client.events.onOrderMatchEvent, function (e, data) {
console.log(e + ": ");
console.log(JSON.stringify(data));
});
client.bind(client.events.onClientPortfolioEvent, function (e, data) {
console.log(e + ": ");
console.log(JSON.stringify(data));
});Conditional order (FCO) events are delivered via the same
onClientPortfolioEventbinding.
Order Event
Order status event — triggered when an order is placed, modified, canceled, or changes status.
{
"eventType": "orderEvent",
"notifyId": 123456789,
"connectionId": "conn-001",
"clientRequestId": "req-20240226-001",
"orderId": "ORD123456",
"symbol": "VNM",
"side": "B",
"orderType": "LO",
"accountNo": "0901351",
"price": "72000",
"quantity": 1000,
"cancelQty": 0,
"osQty": 1000,
"filledQty": 0,
"inputTime": "2026/03/01 14:20:55",
"modifiedTime": "2026/03/01 14:20:55",
"orderStatus": "PD",
"rejectReason": "",
"errorCode": "",
"errorMessage": ""
}| Field | Type | Description |
|---|---|---|
eventType | string | Event type: "orderEvent" |
notifyId | Long | Serial number of the event message |
connectionId | string | Client stream connection session identifier |
clientRequestId | string | Order identifier for the day, auto-generated if not supplied. Used to match against the client's original order |
orderId | string | Order identifier recorded in the trading system |
symbol | string | Securities symbol |
side | string | Order side (B → BUY / S → SELL) |
orderType | string | Order type (LO, ATO, ATC,...) |
accountNo | string | Trading account number |
price | string | Price |
quantity | number | Quantity |
cancelQty | number | Canceled quantity |
osQty | number | Outstanding (unmatched) quantity |
filledQty | number | Filled/matched quantity |
inputTime | string | Time the order was received (standard format) |
modifiedTime | string | Time the order status was modified/updated (standard format) |
orderStatus | string | Order status, refer to the order status table |
rejectReason | string | Rejection reason |
errorCode | string | Order error code |
errorMessage | string | Order error information |
Order Match Event
Order match event — triggered when an order is matched (partially or fully).
{
"eventType": "orderMatchEvent",
"notifyId": 1061597,
"connectionId": "connection_id_value",
"clientRequestId": "91530521",
"orderId": "26022601219922",
"symbol": "MSR",
"side": "S",
"accountNo": "Q276811",
"matchPrice": "43100.0",
"matchQty": 500,
"matchTime": "2026/03/01 14:20:55"
}| Field | Type | Description |
|---|---|---|
eventType | string | Event type: "orderMatchEvent" |
notifyId | Long | Serial number of the event message |
connectionId | string | Client stream connection session identifier |
clientRequestId | string | Order identifier for the day, auto-generated if not supplied. Used to match against the client's original order |
orderId | string | Order identifier recorded in the trading system |
symbol | string | Securities symbol |
side | string | Order side (B → BUY / S → SELL) |
accountNo | string | Trading account number |
matchPrice | string | Matched price |
matchQty | number | Matched quantity |
matchTime | string | Match time (standard format) |
Client Portfolio Event
Portfolio update event — triggered when account balance or assets change.
{
"eventType": "clientPortfolioEvent",
"notifyId": 1023456,
"connectionId": "CONN-8899-XYZZ",
"symbol": "VND",
"accountNo": "0123456789",
"longQty": 1500,
"shortQty": 500,
"net": 1000,
"bidAvgPrice": "12.35",
"askAvgPrice": "12.40",
"tradePrice": "12.38",
"marketPrice": "12.45",
"floatingPL": "1500.75",
"tradingPL": "2500.50"
}| Field | Type | Description |
|---|---|---|
eventType | string | Event type: "clientPortfolioEvent" |
notifyId | Long | Serial number of the event message |
connectionId | string | Client stream connection session identifier |
symbol | string | Securities symbol |
accountNo | string | Account number |
longQty | number | Long position |
shortQty | number | Short position |
net | number | Net position (long - short) |
bidAvgPrice | string | Average buy price |
askAvgPrice | string | Average sell price |
tradePrice | string | Matched price |
marketPrice | string | Market price |
floatingPL | string | Unrealized profit/loss |
tradingPL | string | Realized profit/loss |
FCO Event (Conditional Order)
Conditional order event (FCO — FastConnect Conditional Order) — triggered when a conditional order changes status (initialized, activated, matched, canceled, etc.).
FCO Events are delivered on the same
orderstreaming channel — the client receives them via theonClientPortfolioEventbinding.
client.bind(client.events.onClientPortfolioEvent, function (e, data) {
// Handle FCO event
console.log(e + ": ");
console.log(JSON.stringify(data));
});Example FCO Event Response:
{
"type": "fcoEvent",
"data": {
"fcoId": "7528ac20-a340-4233-8bb7-a2379fc3c638",
"notifyID": 1249008,
"processStatus": "INIT",
"matchedQuantity": 0,
"isPlaceOrder": false,
"instrumentID": "ssi",
"quantity": 4000,
"price": "MP",
"account": "1231496",
"updatedTime": "1751966448000",
"status": "200",
"message": "Success",
"username": "123149"
}
}| Field | Type | Description | Valid Values / Format |
|---|---|---|---|
type | string | Event type | "fcoEvent" |
data | object | Event detail payload | — |
data.fcoId | string | Conditional order ID | UUID |
data.notifyID | number | Notification ID | — |
data.processStatus | string | Conditional order processing status | See FCO Reference |
data.matchedQuantity | number | Matched quantity | — |
data.isPlaceOrder | boolean | Whether a child order has been placed | true: A real order was placed (appears in Orderbook). false: No real order placed yet |
data.instrumentID | string | Securities symbol. For derivatives, use generic or specific codes: 1M, 2M, 1Q, 2Q, VN30FYYMM | — |
data.quantity | number | Desired order quantity | — |
data.price | string | Order price (in VND) | Numeric (e.g., "23500") or "MP", "MOK", "MTL" |
data.account | string | Sub-account for the order (e.g., account ending in 8 or 6) | — |
data.updatedTime | string | Update time (Unix timestamp in milliseconds) | "1751966448000" |
data.status | string | Status code | See Error Codes |
data.message | string | Result or error message | — |
data.username | string | SSI user ID | — |
See also
- Connect WebSocket — connection setup and authentication
- Heartbeat — ping/pong keep-alive mechanism
- Sub/Unsub Market Data — subscribe to market data
- FCO Reference — conditional order types in detail
- Error Codes — status and error code lookup