> ## Documentation Index
> Fetch the complete documentation index at: https://hoalulab.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Sub/Unsub Trading Data

> Theo dõi và hủy theo dõi dữ liệu giao dịch qua WebSocket FastConnect — bao gồm lệnh thường, khớp lệnh, danh mục và lệnh điều kiện (FCO).

## Tổng quan

Kênh **TRADING** cho phép client nhận các sự kiện giao dịch theo thời gian thực: trạng thái lệnh, khớp lệnh, thay đổi danh mục và sự kiện lệnh điều kiện (FCO).

Client cần subscribe theo tài khoản (`accountNo`) để nhận event. Mỗi topic tương ứng với một nhóm sự kiện cụ thể.

## Topic pattern

```text theme={null}
order.[accountNo/*]
portfolio.[accountNo-accountNo/*]
```

| Topic | Mô tả | Ví dụ |
| - | - | - |
| `order.<accountNo>` | Sự kiện lệnh (đặt/sửa/hủy/khớp) và lệnh điều kiện (FCO) của một tài khoản cụ thể | `order.1231991` |
| `order.<accountNo1>-<accountNo2>` | Sự kiện lệnh của nhiều tài khoản cụ thể | `order.1231996-1231998` |
| `order.*` | Sự kiện lệnh và lệnh điều kiện (FCO) của tất cả tài khoản trong phạm vi quyền | `order.*` |
| `portfolio.<accountNo>` | Cập nhật danh mục (tài sản, vị thế) của một tài khoản cụ thể | `portfolio.1231991` |
| `portfolio.<accountNo1>-<accountNo2>` | Cập nhật danh mục của nhiều tài khoản cụ thể | `portfolio.1231996-1231998` |
| `portfolio.*` | Cập nhật danh mục của tất cả tài khoản trong phạm vi quyền | `portfolio.*` |

<Note>
  Sự kiện lệnh điều kiện (FCO) được trả về trên cùng kênh `order` — không cần subscribe topic riêng.
</Note>

<Warning>
  Subscribe topic `portfolio` hiện **chỉ hỗ trợ tài khoản đuôi 8 (tài khoản phái sinh)**. Tài khoản cơ sở (đuôi 1) hoặc ký quỹ (đuôi 6) chưa được hỗ trợ.
</Warning>

## Subscribe

Gửi message với `method: "SUBSCRIBE"` và `channel: "TRADING"`:

```json theme={null}
{
  "method": "SUBSCRIBE",
  "channel": "TRADING",
  "topics": ["order.1231991", "order.1231996-1231998", "order.*", "portfolio.0901351"]
}
```

### Quy tắc subscribe

* Có thể subscribe nhiều topic trong cùng một message.
* Subscribe `order.*` sẽ nhận event lệnh của **tất cả** tài khoản (bao gồm cả lệnh điều kiện FCO).
* Subscribe `portfolio.*` sẽ nhận event danh mục của **tất cả** tài khoản.
* Subscribe cùng topic nhiều lần không gây lỗi — server bỏ qua topic đã subscribe.
* Sau khi reconnect, client **phải subscribe lại** toàn bộ topic cần theo dõi.

## Unsubscribe

Gửi message với `method: "UNSUBSCRIBE"` và `channel: "TRADING"`:

```json theme={null}
{
  "method": "UNSUBSCRIBE",
  "channel": "TRADING",
  "topics": ["order.0901351", "portfolio.0901351"]
}
```

### Quy tắc unsubscribe

* Chỉ unsubscribe các topic đã subscribe trước đó.
* Unsubscribe topic chưa subscribe không gây lỗi — server bỏ qua.
* Unsubscribe **không** ảnh hưởng đến các topic khác đang subscribe.
* Để kiểm tra danh sách topic đang subscribe, dùng `LIST_SUBSCRIPTION`.

## Kiểm tra subscription hiện tại

```json theme={null}
{
  "method": "LIST_SUBSCRIPTION"
}
```

Response trả về scope theo nhóm:

```json theme={null}
{
  "trading": "order.0901351;portfolio.0901351",
  "data": ""
}
```

***

## Các loại event

Sau khi subscribe thành công, client sẽ nhận các event sau theo thời gian thực.

### Binding event trong SDK

```js theme={null}
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));
});
```

<Note>
  Sự kiện lệnh điều kiện (FCO) được trả về qua cùng binding `onClientPortfolioEvent`.
</Note>

***

### Order Event

Sự kiện trạng thái lệnh — phát sinh khi lệnh được đặt, sửa, hủy hoặc thay đổi trạng thái.

```json theme={null}
{
  "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": ""
}
```

<ResponseField name="eventType" type="string">
  Loại event: `"orderEvent"`
</ResponseField>

<ResponseField name="notifyId" type="Long">
  Số serial của event message
</ResponseField>

<ResponseField name="connectionId" type="string">
  Định danh phiên kết nối stream của client
</ResponseField>

<ResponseField name="clientRequestId" type="string">
  Định danh lệnh trong ngày, tự động sinh nếu không truyền. Dùng để đối chiếu tương ứng với lệnh từ đầu client
</ResponseField>

<ResponseField name="orderId" type="string">
  Số định danh lệnh được ghi nhận tại hệ thống giao dịch
</ResponseField>

<ResponseField name="symbol" type="string">
  Mã chứng khoán
</ResponseField>

<ResponseField name="side" type="string">
  Chiều mua/bán của lệnh (`B` → BUY / `S` → SELL)
</ResponseField>

<ResponseField name="orderType" type="string">
  Loại lệnh (`LO`, `ATO`, `ATC`,...)
</ResponseField>

<ResponseField name="accountNo" type="string">
  Số tài khoản đặt lệnh
</ResponseField>

<ResponseField name="price" type="string">
  Giá
</ResponseField>

<ResponseField name="quantity" type="number">
  Khối lượng
</ResponseField>

<ResponseField name="cancelQty" type="number">
  Khối lượng đã hủy
</ResponseField>

<ResponseField name="osQty" type="number">
  Khối lượng chưa khớp
</ResponseField>

<ResponseField name="filledQty" type="number">
  Khối lượng khớp
</ResponseField>

<ResponseField name="inputTime" type="string">
  Thời gian tiếp nhận đặt lệnh (format theo quy chuẩn chung)
</ResponseField>

<ResponseField name="modifiedTime" type="string">
  Thời gian sửa, cập nhật trạng thái lệnh (format theo quy chuẩn chung)
</ResponseField>

<ResponseField name="orderStatus" type="string">
  Trạng thái lệnh, tham chiếu theo bảng trạng thái lệnh
</ResponseField>

<ResponseField name="rejectReason" type="string">
  Lý do từ chối
</ResponseField>

<ResponseField name="errorCode" type="string">
  Mã lỗi lệnh
</ResponseField>

<ResponseField name="errorMessage" type="string">
  Thông tin lệnh lỗi
</ResponseField>

***

### Order Match Event

Sự kiện khớp lệnh — phát sinh khi lệnh được khớp (một phần hoặc toàn bộ).

```json theme={null}
{
  "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"
}
```

<ResponseField name="eventType" type="string">
  Loại event: `"orderMatchEvent"`
</ResponseField>

<ResponseField name="notifyId" type="Long">
  Số serial của event message
</ResponseField>

<ResponseField name="connectionId" type="string">
  Định danh phiên kết nối stream của client
</ResponseField>

<ResponseField name="clientRequestId" type="string">
  Định danh lệnh trong ngày, tự động sinh nếu không truyền. Dùng để đối chiếu tương ứng với lệnh từ đầu client
</ResponseField>

<ResponseField name="orderId" type="string">
  Số định danh lệnh được ghi nhận tại hệ thống giao dịch
</ResponseField>

<ResponseField name="symbol" type="string">
  Mã chứng khoán
</ResponseField>

<ResponseField name="side" type="string">
  Chiều mua/bán của lệnh (`B` → BUY / `S` → SELL)
</ResponseField>

<ResponseField name="accountNo" type="string">
  Số tài khoản đặt lệnh
</ResponseField>

<ResponseField name="matchPrice" type="string">
  Giá khớp
</ResponseField>

<ResponseField name="matchQty" type="number">
  Khối lượng khớp
</ResponseField>

<ResponseField name="matchTime" type="string">
  Thời gian khớp (format theo quy chuẩn chung)
</ResponseField>

***

### Client Portfolio Event

Sự kiện cập nhật danh mục — phát sinh khi số dư hoặc tài sản thay đổi.

```json theme={null}
{
  "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"
}
```

<ResponseField name="eventType" type="string">
  Loại event: `"clientPortfolioEvent"`
</ResponseField>

<ResponseField name="notifyId" type="Long">
  Số serial của event message
</ResponseField>

<ResponseField name="connectionId" type="string">
  Định danh phiên kết nối stream của client
</ResponseField>

<ResponseField name="symbol" type="string">
  Mã chứng khoán
</ResponseField>

<ResponseField name="accountNo" type="string">
  Số tài khoản
</ResponseField>

<ResponseField name="longQty" type="number">
  Vị thế long
</ResponseField>

<ResponseField name="shortQty" type="number">
  Vị thế short
</ResponseField>

<ResponseField name="net" type="number">
  Vị thế net (tính bằng long - short)
</ResponseField>

<ResponseField name="bidAvgPrice" type="string">
  Giá mua trung bình
</ResponseField>

<ResponseField name="askAvgPrice" type="string">
  Giá bán trung bình
</ResponseField>

<ResponseField name="tradePrice" type="string">
  Giá khớp
</ResponseField>

<ResponseField name="marketPrice" type="string">
  Giá thị trường
</ResponseField>

<ResponseField name="floatingPL" type="string">
  Lãi/lỗ tạm tính
</ResponseField>

<ResponseField name="tradingPL" type="string">
  Lãi/lỗ đã chốt
</ResponseField>

***

### FCO Event (Lệnh điều kiện)

Sự kiện lệnh điều kiện (FCO — FastConnect Conditional Order) — phát sinh khi lệnh điều kiện thay đổi trạng thái (khởi tạo, kích hoạt, khớp, hủy...).

<Note>
  FCO Event được trả về trên cùng kênh streaming `order` — client nhận qua binding `onClientPortfolioEvent`.
</Note>

```js theme={null}
client.bind(client.events.onClientPortfolioEvent, function (e, data) {
  // Xử lý FCO event
  console.log(e + ": ");
  console.log(JSON.stringify(data));
});
```

**Ví dụ FCO Event Response:**

```json theme={null}
{
  "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"
  }
}
```

<ResponseField name="type" type="string">
  Loại event: `"fcoEvent"`
</ResponseField>

<ResponseField name="data" type="object">
  Thông tin chi tiết của event
</ResponseField>

<ResponseField name="data.fcoId" type="string">
  ID lệnh điều kiện (UUID)
</ResponseField>

<ResponseField name="data.notifyID" type="number">
  ID thông báo
</ResponseField>

<ResponseField name="data.processStatus" type="string">
  Trạng thái xử lý lệnh điều kiện. Tham khảo [Phụ lục FCO](/docs/api-reference/appendix/fco-reference)
</ResponseField>

<ResponseField name="data.matchedQuantity" type="number">
  Khối lượng đã khớp
</ResponseField>

<ResponseField name="data.isPlaceOrder" type="boolean">
  `true`: Có lệnh thực phát sinh (xuất hiện lệnh ở Orderbook). `false`: Chưa có lệnh thực phát sinh
</ResponseField>

<ResponseField name="data.instrumentID" type="string">
  Mã chứng khoán. Đối với phái sinh, truyền theo mã tổng quát hoặc chi tiết: `1M`, `2M`, `1Q`, `2Q`, `VN30FYYMM`
</ResponseField>

<ResponseField name="data.quantity" type="number">
  Khối lượng muốn đặt lệnh
</ResponseField>

<ResponseField name="data.price" type="string">
  Giá đặt (đơn vị đồng). Giá số (vd: `"23500"`) hoặc `"MP"`, `"MOK"`, `"MTL"`
</ResponseField>

<ResponseField name="data.account" type="string">
  Tiểu khoản đặt lệnh (ví dụ tài khoản đuôi 8, đuôi 6)
</ResponseField>

<ResponseField name="data.updatedTime" type="string">
  Thời gian cập nhật (Unix timestamp milliseconds), vd: `"1751966448000"`
</ResponseField>

<ResponseField name="data.status" type="string">
  Mã trạng thái. Tham chiếu [bảng mã lỗi](/docs/api-reference/appendix/error-codes)
</ResponseField>

<ResponseField name="data.message" type="string">
  Thông báo kết quả hoặc lỗi
</ResponseField>

<ResponseField name="data.username" type="string">
  ID người dùng tại SSI
</ResponseField>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.