私有WebSocket#
私有WebSocket订阅准则#
所有私有频道均通过 WebSocket subscribe 订阅。除非另有说明,id 可由客户端自定义;vaultAddress 用于订阅子账户,pointBoard 默认为 false,marketTypes 默认为全部市场。
{
"id": "req001",
"op": "subscribe",
"args": [
{
"channel": "<channel>",
"vaultAddress": "xxxxx",
"pointBoard": "false",
"marketTypes": "[\"spot\", \"perp\"]"
}
]
}
Backend 预建连(connect_backends)#
ExchangeOS 私有频道支持在订阅前预先建立 Backend 连接,以降低首次订阅及首次数据推送的延迟。ExchangeOS 私有频道的 Backend 为 okx-defi-tradezone-indexerpubsub-awstky-pro。connect_backends 只负责连接预热,不会建立频道订阅,也不会取代 subscribe。
登录成功后、发送 subscribe 前,可先发送:
{
"id": "req-connect-1",
"op": "connect_backends",
"args": [
{
"backend": "okx-defi-tradezone-indexerpubsub-awstky-pro"
}
]
}
connect_backends 成功时不会返回同步的请求级成功响应。收到以下异步事件后,才表示 Backend 连接已建立:
{
"event": "backend",
"code": 0,
"msg": "Success",
"backend": "okx-defi-tradezone-indexerpubsub-awstky-pro",
"extraInfo": "",
"connId": "50b71049"
}
推荐时序:建立 WebSocket → 完成私有频道登录 → 发送 connect_backends → 等待 event=backend 且 code=0 → 发送 subscribe → 收到 event=subscribe → 接收频道数据。
connect_backends 是可选的连接预热机制。若客户端未发送,首次 subscribe 仍会触发惰性建连,既有订阅流程可以继续使用;其响应顺序为 event=backend、code=0 → event=subscribe → 频道数据。
后端连接状态事件(event: backend)#
event=backend 是服务端主动下发的后端连接状态事件。它不是某一次请求的响应,也不是频道数据。
该事件用于通知客户端:推送服务与某个 Backend 的连接发生中断,或连接及订阅已经恢复。推送侧负责自动重连并恢复订阅,客户端不需要重新发送 connect_backends 或 subscribe。
触发时机#
| 状态 | 触发场景 | code | msg |
|---|---|---|---|
| 后端连接首次建立成功 | 由 connect_backends,或 send/subscribe 触发惰性建连,且后端连接建立成功。 | 0 | Success |
| 后端连接异常断开 | 推送服务收到 gRPC onError。此时 WebSocket 仍然存活,推送侧开始自动重新连接并恢复订阅。 | 50011 | Backend stream disconnected |
| 后端连接被服务端主动关闭 | 推送服务收到 gRPC onCompleted。此时 WebSocket 仍然存活,推送侧开始自动重新连接并恢复订阅。 | 50012 | Backend stream completed by server |
| 后端连接及订阅恢复完成 | 推送侧完成重新连接,并完成该 Backend 下活跃订阅的自动恢复。 | 0 | Success |
帧格式#
{
"event": "backend",
"code": 0,
"msg": "Success",
"backend": "core-trading-v2",
"extraInfo": "",
"connId": "abcd1234"
}
| 字段 | 说明 |
|---|---|
event | 固定为 backend。 |
code | 0:连接成功;50011:异常断开;50012:服务端关闭。 |
msg | 状态描述。 |
backend | 状态发生变化的 Backend 标识。 |
extraInfo | 预留字段,当前固定为空字符串。 |
connId | 当前 WebSocket 连接 ID。 |
客户端处理原则#
event=backend不表示 WebSocket 已断开。WebSocket 仍然存活,只是推送服务与某个 Backend 之间的连接发生变化。- 收到
code=50011或code=50012后,客户端不需要重新发送connect_backends或subscribe,也不需要主动关闭或重建 WebSocket。推送侧会自动完成 Backend 重连及订阅恢复。 - 没有数据补偿需求的客户端,可以只识别、记录或忽略
event=backend,不需要增加其他处理。 - 推送侧的自动恢复只能确保恢复完成后的消息继续推送,无法补回 Backend 断线期间已错过的业务消息。
- 对订单、成交、仓位及资产等有数据完整性要求的客户端,可以记录
code=50011/50012与后续code=0的时间,并在收到恢复事件后,通过对应的 REST API 查询最新状态、执行数据核对或进行业务补偿。 - 如果 WebSocket 本身断开,仍按照既有的 WebSocket 重连、登录及重新订阅流程处理。WebSocket 断线与
event=backend代表的 Backend 下游连接中断,是两种不同的情况。
定时账户与持仓快照 exchangeos-balance-and-position#
每 5 秒推送一次完整的账户与持仓快照。
定时快照中的 Position 不返回 tradeId。订阅请求的 id 可由用户自定义。
订阅请求#
{
"id": "req001",
"op": "subscribe",
"args": [
{
"channel": "exchangeos-balance-and-position",
"vaultAddress": "xxxxx",
"pointBoard": "false",
"marketTypes": "[\"spot\", \"perp\"]"
}
]
}
订阅参数#
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | String | 是 | 用户自定义请求 ID。 |
| op | String | 是 | 固定为 subscribe。 |
| args | Array | 是 | 订阅参数列表。 |
| > channel | String | 是 | 固定为 exchangeos-balance-and-position。 |
| > vaultAddress | String | 否 | 子账户地址。 |
| > pointBoard | String | 否 | true 表示积分盘,false 表示实盘。默认值为 false。 |
| > marketTypes | String | 否 | 需要返回的市场类型,例如 ["spot", "perp"]。默认返回全部市场类型。 |
账户总权益计算#
- Total Equity (XP) = Collateral Equity (XP) (Cross + Isolated) + Crypto Balance (TEST_BTC/TEST_ETH) × Dollar USD Value + Yes/No Token × Prediction Market 当前价格。
- Prediction Market 当前价格取值顺序:结算价、YES Best Bid、No 的
1 - Best Ask。 - Total Equity (USDS) = Collateral Equity (USDS) (Cross + Isolated) + Crypto Balance (BTC/ETH) × Dollar USD Value + SWAP Total USD Value。
分页规则#
type、curPage、lastPage、totalCount和activeCount均位于data内。data为 Object,不使用data: [{ "orders": [] }]结构。- 同一轮快照的所有分页具有相同的
block_height、block_timestamp、totalCount和activeCount。 - 每页的
pTime为该页实际生成时间,因此不同页的pTime可不同。 - 客户端应在收到
lastPage=true后,再将该轮快照原子应用。 - 事件发生后,如果已没有未完成订单,仍会推送
orders=[]、totalCount="0"和activeCount="0"。
顶层消息字段#
| 字段 | 类型 | 说明 |
|---|---|---|
| arg | Object | 订阅参数。 |
| > channel | String | 频道名称。 |
| > marketTypes | String | 已订阅的市场类型。 |
| > pointBoard | String | 是否为积分盘。 |
| backend | String | 后端标识。 |
| block_height | String | 快照对应的链上区块高度。 |
| block_timestamp | String | 快照对应的链上区块时间,Unix 毫秒时间戳。 |
| data | Object | 账户及持仓快照数据。 |
| pTime | String | 当前分页的实际生成时间,Unix 毫秒时间戳。 |
| user | String | 用户账户地址。 |
data 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
| curPage | String | 当前页码。 |
| lastPage | Boolean | 是否为当前轮快照的最后一页。 |
| type | String | 固定为 snapshot。 |
| totalEq | String | 账户总权益,包含所有业务线;perp 包含全仓与逐仓,不包含 Swap。 |
| notionalUsd | String | 账户维度的总持仓名义价值,适用于实盘或积分盘。 |
| positionMode | String | 持仓模式:oneWay 或 hedge。 |
| assetsCnt | String | 资产数量。 |
| positionsCnt | String | 持仓数量。 |
| details | Array | 资产明细。 |
| positions | Array | 持仓明细。 |
Asset 结构#
cashBal 和 eq 同时为 0 的币种不返回,USDS 除外。
| 字段 | 类型 | 说明 |
|---|---|---|
| tokenId | String | Token ID。 |
| collateralEnabled | Boolean | 是否为保证金币种。 |
| cashBal | String | 余额数量,包含 perp 和 spot 冻结金额。 |
| availBal | String | 可用余额。仅保证金币种有值。 |
| frozenMgn | String | 冻结数量。保证金币种包含 spot、perp 和 prediction Market 的冻结金额;非保证金币种仅包含 spot 和 prediction Market 冻结金额。 |
| frozenMgnRatio | String | 冻结保证金率。 |
| perpFrozen | String | perp 冻结保证金,包括 perp 仓位和挂单占用保证金。 |
| spotFrozen | String | spot 冻结金额,包括 spot 挂单占用金额。 |
| predFrozen | String | Prediction Market 冻结保证金。 |
| lastPx | String | 最新成交价。 |
| tokenPx | String | spot USD 价格。优先使用 tokenPx 计算 spot USD 价值;没有 tokenPx 时使用 lastPx;均不存在时显示 --。 |
| marketType | String | 市场类型。 |
| accAvgPx | String | 平均成本价。 |
| spotUpl | String | spot 盈亏。 |
| entryCost | String | 持有总成本。 |
| spotUplRatio | String | spot 盈亏百分比。 |
| availEq | String | 可用保证金。 |
| upl | String | 全仓未实现盈亏。 |
| eq | String | 全仓与逐仓总价值。 |
| eqUsd | String | eq 的 USD 价值,即 eq × tokenPx。 |
| isoUpl | String | 逐仓未实现盈亏。 |
| isoEq | String | 逐仓总价值。 |
| totalLever | String | 仓位杠杆,coinEquity=0 时返回 None。 |
| mmr | String | 维持保证金,为各持仓 MM 和清算手续费之和,不包含逐仓。 |
| mgnRatio | String | 维持保证金率:(coinMM + coinPerpLiqTradingFee) / coinEquity。coinEquity=0 时返回 None。 |
Position 结构#
| 字段 | 类型 | 说明 |
|---|---|---|
| assetId | String | 资产 ID。 |
| positionSide | String | 持仓方向:net、long 或 short。net 表示买卖模式;long 和 short 表示开平模式。 |
| marginMode | String | 保证金模式:cross 或 isolated。 |
| pos | String | 持仓数量。 |
| leverage | String | 杠杆倍数,仅支持整数。Equity=0 时返回 None。 |
| avgPx | String | 持仓均价。 |
| fundingFee | String | 开仓以来累计资金费。 |
| imr | String | 初始保证金。全仓为 notional_value / leverage;无法取得标记价格时返回 None。 |
| mmr | String | 维持保证金。 |
| mgnRatio | String | 维持保证金率。全仓取币种维持保证金率,与仓位无关;逐仓按仓位计算。 |
| markPx | String | 标记价格。 |
| lastPx | String | 最新成交价格。 |
| idxPx | String | 标的对应的最新指数价格;无指数价格时返回 ""。 |
| positionValue | String | 持仓 USD 价值。 |
| quoteUsdPx | String | 计价币的 USD 价格。 |
| liqPx | String | 预估强平价。 |
| upl | String | 按 Mark Price 计算的未实现盈亏。 |
| uplRatio | String | 按 Mark Price 计算的未实现盈亏百分比。 |
| uplLastPx | String | 按 Last Price 计算的未实现盈亏。 |
| uplRatioLastPx | String | 按 Last Price 计算的未实现盈亏百分比。 |
| margin | String | 逐仓保证金余额。全仓返回 None;逐仓为 collateral_balance。 |
| pnl | String | 平仓盈亏。 |
| realizedPnl | String | 已实现盈亏。 |
| fee | String | 该仓位的累计交易手续费。 |
| closeOrderAlgo | Array | 仓位的止盈止损订单。 |
| tpLimitOrders | Array | 仓位的 TP Limit 订单。 |
| assetStatus | String | 合约状态。 |
assetStatus 枚举#
| 值 | 说明 |
|---|---|
| normal | 正常交易。 |
| scheduled | 正常交易,但仅允许 reduceOnly=true 的订单。 |
| converging | 交割准备中,默认持续 30 分钟;标记价格开始收敛;仅允许只减仓订单。 |
| regressing | 交割撤销中,恢复正常交易;标记价格回归正常公式。 |
响应示例#
{
"arg": {
"channel": "exchangeos-balance-and-position",
"marketTypes": "[\"all\"]",
"pointBoard": "false"
},
"backend": "okx-defi-tradezone-indexerpubsub-awstky-pro",
"block_height": "42775890",
"block_timestamp": "1788157193630",
"data": {
"assetsCnt": "2",
"curPage": "0",
"details": [
{
"accAvgPx": "",
"availBal": "200.015022",
"availEq": "3351.725522",
"cashBal": "200.015022",
"collateralEnabled": true,
"entryCost": "",
"eq": "3739.515022",
"eqUsd": "3739.515022",
"frozenMgn": "387.789500",
"frozenMgnRatio": "0.1037",
"isoEq": "0.000000",
"isoUpl": "0.000000",
"marketType": "spot",
"mgnRatio": "0.005703",
"mmr": "19.389475",
"perpFrozen": "387.789500",
"predFrozen": "0.000000",
"spotFrozen": "0.000000",
"spotUpl": "",
"spotUplRatio": "",
"tokenId": "0",
"tokenPx": "1",
"totalLever": "1.037004",
"upl": "3539.500000"
}
],
"lastPage": true,
"notionalUsd": "3877.895",
"positionMode": "hedge",
"positions": [
{
"assetId": "602",
"assetStatus": "normal",
"avgPx": "3000.000",
"closeOrderAlgo": [
{
"assetId": "602",
"assetStatus": "normal",
"cTime": "1788156156130",
"isActive": true,
"isMarket": true,
"leverage": "10",
"marginMode": "cross",
"oid": "117984458",
"positionSide": "long",
"reduceOnly": true,
"side": "sell",
"size": "0.100",
"tpLimit": false,
"tpsl": "tp",
"triggerCond": "gte",
"triggerPriceType": "mark",
"triggerPx": "80000.000"
}
],
"fee": "-3.750000",
"fundingFee": "23562.904548",
"idxPx": "38390.000",
"imr": "383.950000",
"lastPx": "38395.000",
"leverage": "10",
"liqPx": "625.632",
"marginMode": "cross",
"markPx": "38395.000",
"mgnRatio": "0.005703",
"mmr": "19.197500",
"pnl": "0.000000",
"pos": "0.100",
"positionSide": "long",
"positionValue": "3839.5",
"quoteUsdPx": "1",
"realizedPnl": "23559.154548",
"tpLimitOrders": [],
"upl": "3539.500000",
"uplLastPx": "3539.500000",
"uplRatio": "9.218648",
"uplRatioLastPx": "9.218648"
}
],
"positionsCnt": "2",
"totalEq": "3756.498022",
"type": "snapshot"
},
"pTime": "1788157193711",
"user": "0x2e988a386a799f506693793c6a5af6b54dfaabfb"
}
账户与持仓事件更新 exchangeos-balance-and-position-updates#
面向 Open API 开发者的私有账户与持仓更新频道。
订阅成功后,当余额、Position 或账户数据发生变化时,频道按事件推送增量数据。
当 Position 完全平仓时,增量推送仍会返回该 Position,并将 pos 设为 "0"。
订阅请求的 id 可由用户自定义。
订阅母账户#
{
"id": "req001",
"op": "subscribe",
"args": [
{
"channel": "exchangeos-balance-and-position-updates",
"vaultAddress": "xxxxx",
"pointBoard": "false",
"marketTypes": "[\"spot\", \"perp\"]"
}
]
}
订阅子账户#
{
"id": "req001",
"op": "subscribe",
"args": [
{
"channel": "exchangeos-balance-and-position-updates",
"marketTypes": "[\"spot\", \"perp\"]",
"vaultAddress": "xxxxx"
}
]
}
订阅参数#
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | String | 是 | 用户自定义请求 ID。 |
| op | String | 是 | 固定为 subscribe。 |
| args | Array | 是 | 订阅参数列表。 |
| > channel | String | 是 | 固定为 exchangeos-balance-and-position-updates。 |
| > vaultAddress | String | 否 | 子账户地址;订阅母账户时省略。 |
| > pointBoard | String | 否 | true 表示积分盘,false 表示实盘。默认值为 false。 |
| > marketTypes | String | 否 | 市场类型,例如 ["spot", "perp"]。默认返回全部市场类型。 |
推送最外层字段#
| 字段 | 类型 | 说明 |
|---|---|---|
| arg | Object | 订阅信息。 |
| > channel | String | 固定为 exchangeos-balance-and-position-updates。 |
| > vaultAddress | String | 子账户地址;订阅母账户时省略。 |
| block_height | String | 本次数据对应的链上区块高度。 |
| block_timestamp | String | 本次数据对应的链上区块时间,Unix 毫秒时间戳。语义等同 uTime,作为本次 data.details[] 与 data.positions[] 的数据版本。 |
| pTime | String | WebSocket 消息实际生成或推送时间,Unix 毫秒时间戳;不参与数据去重。 |
| user | String | 本次推送对应的母账户或子账户地址。 |
| data | Object | 首次为完整账户快照;后续为本次事件涉及的账户、Token 与 Position 更新。type 位于 data 内。 |
data 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
| type | String | 数据模式:snapshot 或 update。 |
| eventType | String | 本次数据变化的业务事件类型。 |
| totalEq | String | 事件处理完成后的实盘资产总权益 USD 价值;不包含积分盘资产。 |
| notionalUsd | String | 事件处理完成后所有 perp 持仓 USD 名义价值的绝对值总和;包含全仓和逐仓。Hedge 的 long 和 short 不轧差,不包含未成交挂单。 |
| positionMode | String | 账户持仓模式:oneWay 或 hedge。 |
| details | Array | 本次事件涉及的 Token 最新状态。 |
| positions | Array | 本次事件涉及的 perp Position 最新状态。 |
| trades | Array | 本次事件涉及的成交标识列表。首次快照或没有一般撮合成交时返回 []。 |
type 与 eventType 的语义不同:
data.type表示数据模式:snapshot或update。data.eventType表示造成本次增量数据的业务事件。- 当
type="snapshot"时,eventType返回""。不得通过eventType判断数据是全量还是增量。
details[] 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
| tokenId | String | Token ID;USDS 为 "0"。 |
| marketType | String | 市场类型。 |
| collateralEnabled | Boolean | 是否可作为保证金。USDS 与积分盘独立积分 Token 可为 true,一般 spot Token 为 false。 |
| eq | String | Token 总权益,以 Token 原生单位表示;保证金 Token 为全仓与逐仓权益合计。 |
| eqUsd | String | Token 总权益估值;实盘 Token 折算为 USD,积分盘 Token 按 1 Point = 1 USD 的展示口径折算。 |
| isoEq | String | 逐仓权益,以保证金 Token 原生单位表示;非保证金 Token 返回 ""。 |
| cashBal | String | Token 余额,以 Token 原生单位表示,包含冻结部分。 |
| availBal | String | Token 可用余额,以 Token 原生单位表示。 |
| availEq | String | 可用全仓保证金;非保证金 Token 返回 ""。 |
| frozenMgn | String | Token 总占用数量,等于 spotFrozen + perpFrozen + predFrozen。 |
| spotFrozen | String | spot 挂单占用,以 Token 原生单位表示。 |
| perpFrozen | String | Perp 全仓仓位与挂单占用;包含逐仓挂单占用,不包含逐仓仓位保证金。非保证金 Token 返回 ""。 |
| predFrozen | String | Prediction Market 占用,以 Token 原生单位表示。 |
| mmr | String | 全仓维持保证金;不包含逐仓。非保证金 Token 返回 ""。 |
| mgnRatio | String | 全仓维持保证金率;非保证金 Token 返回 ""。 |
| frozenMgnRatio | String | 全仓资金占用率;非保证金 Token 返回 ""。 |
| accAvgPx | String | spot 累计成本均价;Phase 1 实时频道固定返回 ""。 |
| spotUpl | String | spot 未实现盈亏;Phase 1 实时频道固定返回 ""。 |
| spotUplRatio | String | spot 未实现盈亏率;Phase 1 实时频道固定返回 ""。 |
| entryCost | String | spot 总成本;Phase 1 实时频道固定返回 ""。 |
| upl | String | perp 全仓未实现盈亏;非保证金 Token 返回 ""。 |
| isoUpl | String | perp 逐仓未实现盈亏;非保证金 Token 返回 ""。 |
| lastPx | String | Token 最新 spot 成交价;无成交价时返回 ""。 |
| tokenPx | String | Token 的 USD 估值价格;无估值价格时返回 ""。 |
| totalLever | String | 保证金 Token 维度的全仓总杠杆;非保证金 Token、不适用或无法计算时返回 ""。 |
positions[] 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
| assetId | String | perp 产品 ID。 |
| assetStatus | String | 合约状态:normal、scheduled、converging 或 regressing。 |
| positionSide | String | 仓位方向:net、long 或 short。 |
| marginMode | String | 保证金模式:cross 或 isolated。 |
| leverage | String | 仓位杠杆倍数。 |
| pos | String | 仓位数量,以 base 单位表示;完全平仓的增量事件返回 "0"。 |
| avgPx | String | 持仓均价。 |
| markPx | String | 标记价格。 |
| positionValue | String | 仓位名义价值,以 USD 计价。 |
| upl | String | 未实现盈亏。 |
| uplRatio | String | 未实现盈亏率。 |
| liqPx | String | 预估强平价格;无法计算时返回 ""。 |
| imr | String | 全仓初始保证金;逐仓返回 ""。 |
| margin | String | 逐仓保证金余额;全仓返回 ""。 |
| mmr | String | 维持保证金。 |
| mgnRatio | String | 维持保证金率。 |
| realizedPnl | String | 已实现盈亏。 |
| fee | String | 累计交易手续费。 |
| fundingFee | String | 开仓以来累计资金费。 |
| lastPx | String | 最新成交价,仅用于展示,不作为风控或去重依据。 |
| idxPx | String | 标的对应的最新指数价格;无指数价格时返回 ""。 |
| quoteUsdPx | String | 计价 Token 的 USD 价格。 |
| pnl | String | 平仓盈亏。 |
| uplLastPx | String | 按最新成交价计算的未实现盈亏。 |
| uplRatioLastPx | String | 按最新成交价计算的未实现盈亏率。 |
| closeOrderAlgo | Array | 与该 Position 关联的 Position TPSL 订单;无关联订单时返回 []。 |
closeOrderAlgo[] 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
| oid | String | Position TPSL 的链上订单 ID。 |
| assetId | String | 关联 Position 的 perp 产品 ID。 |
| assetStatus | String | 产品状态:normal、scheduled、converging 或 regressing。 |
| side | String | 平仓订单方向:buy 或 sell。 |
| positionSide | String | 关联仓位方向:net、long 或 short。 |
| marginMode | String | 关联仓位保证金模式:cross 或 isolated。 |
| price | String | 触发后的委托价格;Trigger Market 返回 "0"。 |
| size | String | 触发后的平仓数量,以 base 单位表示;Entire Position TPSL 可返回 "0",由链上触发时按实际仓位数量执行。 |
| reduceOnly | Boolean | 是否为只减仓订单;Position TPSL 固定为 true。 |
| triggerPx | String | 触发价格。 |
| triggerPriceType | String | 触发价格类型:mark 或 index。 |
| triggerCond | String | Gte 或 Lte,表示触发参考价格与 triggerPx 的比较条件。 |
| isMarket | Boolean | 触发后是否以市价执行。 |
| tpsl | String | Position TPSL 类型:tp 或 sl。 |
| parentOrderId | String | Position TPSL 无母订单,固定返回 ""。 |
| isActive | Boolean | Position TPSL 是否已启用。 |
| tpLimit | Boolean | 是否为 TP Limit。 |
trades[] 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
| assetId | String | 成交所属产品 ID;可以为 perp 或 spot。 |
| tradeId | String | 全局一般撮合成交 ID,用于成交去重和关联账户状态更新。非一般撮合事件不生成特殊值。 |
eventType 枚举#
| 值 | 说明 |
|---|---|
| filled | 一般成交。 |
| liquidation | 强平。 |
| adl | 自动减仓。 |
| settlement | 结算。 |
| ctfOperation | CTF 操作。 |
| fundingFee | 资金费。 |
| setLeverage | 设置杠杆。 |
| transferred | 资金划转。 |
| deposit | 充值。 |
| withdraw | 提现。 |
| adjustMargin | 调整保证金。 |
| clawBack | 追回。 |
| vaultOperation | Vault 操作。 |
| tokenBurn | Token 销毁。 |
| purchaseFee | 购买费用。 |
| orderUpdated | 订单更新。 |
一般成交事件示例#
同一链上时间点发生两笔 perp 成交及一笔 spot 成交:
{
"arg": {
"channel": "exchangeos-balance-and-position-updates",
"marketTypes": "[\"all\"]",
"pointBoard": "false"
},
"backend": "okx-defi-tradezone-indexerpubsub-awstky-pro",
"block_height": "42779616",
"block_timestamp": "1788157566230",
"pTime": "1788157566312",
"user": "0x2e988a386a799f506693793c6a5af6b54dfaabfb",
"data": {
"type": "update",
"eventType": "filled",
"totalEq": "44476.681072",
"notionalUsd": "5071.600000",
"positionMode": "hedge",
"details": [
{
"tokenId": "0",
"collateralEnabled": true,
"eq": "3739.131072",
"eqUsd": "3739.131072",
"isoEq": "0.000000",
"cashBal": "807.531072",
"availBal": "807.531072",
"availEq": "3331.971072",
"frozenMgn": "407.160000",
"spotFrozen": "0.000000",
"perpFrozen": "407.160000",
"predFrozen": "0.000000",
"mmr": "25.358000",
"mgnRatio": "0.006782",
"frozenMgnRatio": "0.108892",
"accAvgPx": "",
"spotUpl": "",
"spotUplRatio": "",
"entryCost": "",
"upl": "2931.600000",
"isoUpl": "0.000000",
"lastPx": "",
"tokenPx": "1",
"totalLever": "1.356358"
}
],
"positions": [
{
"assetId": "602",
"assetStatus": "normal",
"positionSide": "long",
"marginMode": "cross",
"leverage": "10",
"pos": "0.080",
"avgPx": "3000.000",
"markPx": "38395.000",
"positionValue": "3071.600000",
"upl": "2831.600000",
"uplRatio": "9.218648",
"liqPx": "625.632",
"imr": "307.160000",
"margin": "",
"mmr": "15.358000",
"mgnRatio": "0.006782",
"realizedPnl": "24266.670598",
"fee": "-4.133950",
"fundingFee": "23562.904548",
"lastPx": "38395.000",
"idxPx": "38390.000",
"quoteUsdPx": "1",
"pnl": "707.900000",
"uplLastPx": "2831.600000",
"uplRatioLastPx": "9.218648",
"closeOrderAlgo": [],
"tpLimitOrders": []
}
],
"trades": [
{
"assetId": "602",
"tradeId": "839"
},
{
"assetId": "702",
"tradeId": "840"
},
{
"assetId": "301",
"tradeId": "841"
}
]
}
}
部分强平事件示例#
强平、ADL、资金费和结算等非一般撮合事件不会产生新的普通成交 tradeId,因此 trades=[]。事件原因由 eventType 判断。
{
"arg": {
"channel": "exchangeos-balance-and-position-updates"
},
"block_height": "12092501",
"block_timestamp": "1785218460000",
"pTime": "1785218460040",
"user": "0x2e988a386a799f506693793c6a5af6b54dfaabfb",
"data": {
"type": "update",
"eventType": "liquidation",
"totalEq": "124950.960900",
"notionalUsd": "2100.000000",
"positionMode": "oneWay",
"details": [
{
"tokenId": "0",
"collateralEnabled": true,
"eq": "124950.960900",
"eqUsd": "124950.960900",
"isoEq": "0.000000",
"cashBal": "125100.960900",
"availBal": "124688.460900",
"availEq": "124688.460900",
"frozenMgn": "262.500000",
"spotFrozen": "0.000000",
"perpFrozen": "262.500000",
"predFrozen": "0.000000",
"mmr": "10.500000",
"mgnRatio": "0.000084",
"frozenMgnRatio": "0.002101",
"accAvgPx": "",
"spotUpl": "",
"spotUplRatio": "",
"entryCost": "",
"upl": "-150.000000",
"isoUpl": "0.000000",
"lastPx": "1.000000",
"tokenPx": "1.000000",
"totalLever": "0.016807"
}
],
"positions": [
{
"assetId": "602",
"assetStatus": "normal",
"positionSide": "net",
"marginMode": "cross",
"leverage": "8",
"pos": "0.750",
"avgPx": "3000.000",
"markPx": "2800.000",
"positionValue": "2100.000000",
"upl": "-150.000000",
"uplRatio": "-0.266667",
"liqPx": "2650.000",
"imr": "262.500000",
"margin": "",
"mmr": "10.500000",
"mgnRatio": "0.000084",
"realizedPnl": "-150.000000",
"fee": "-1.050000",
"fundingFee": "0.000000",
"lastPx": "2801.000",
"idxPx": "2799.500",
"quoteUsdPx": "1.000000",
"pnl": "-150.000000",
"uplLastPx": "-149.250000",
"uplRatioLastPx": "-0.265333",
"closeOrderAlgo": []
}
],
"trades": []
}
}
去重规则#
| 数据类型 | 识别键 |
|---|---|
| Token | tokenId |
| Position | assetId + marginMode + positionSide |
| Trade | tradeId |
事件触发的未完成订单全量快照 exchangeos-orders#
订阅成功后,立即推送母账户或指定子账户当前全部未完成订单的完整快照。
该频道不定时推送。后续发生 Order Event 或 Fill Event 时,系统会重新查询并推送事件发生后的完整未完成订单快照,而非仅推送发生变化的订单。
首次订阅或后续订单、成交事件发生后,如账户没有未完成订单,仍会推送:
orders=[]totalCount="0"activeCount="0"curPage="0"lastPage=true
订阅请求#
{
"id": "req001",
"op": "subscribe",
"args": [
{
"channel": "exchangeos-orders",
"vaultAddress": "xxxxx",
"pointBoard": "false",
"marketTypes": "[\"spot\", \"perp\"]"
}
]
}
订阅参数#
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | String | 否 | 用户自定义请求 ID。 |
op | String | 是 | 固定为 subscribe。 |
args | Array | 是 | 订阅参数列表。 |
> channel | String | 是 | 固定为 exchangeos-orders。 |
> vaultAddress | String | 否 | 子账户地址。不传表示订阅母账户。 |
> pointBoard | String | 否 | true 表示积分盘,false 表示实盘。默认值为 false。 |
> marketTypes | String | 否 | 市场范围,支持 spot、prediction 和 perp。不传表示全部市场。 |
推送最外层字段#
| 字段 | 类型 | 说明 |
|---|---|---|
arg | Object | 订阅条件回显。 |
backend | String | 生成本次推送的后端服务名称。 |
block_height | String | 本轮快照对应的链上区块高度。 |
block_timestamp | String | 本轮快照对应的链上区块时间,Unix 毫秒时间戳。 |
pTime | String | 当前页面推送消息的生成时间,Unix 毫秒时间戳。 |
user | String | 数据所属的母账户或子账户地址。 |
data | Object | 本轮未完成订单快照、分页和计数数据。 |
data 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
type | String | 固定为 snapshot,表示本次为事件触发后的完整未完成订单快照。 |
curPage | String | 本轮快照当前页码,从 "0" 开始。 |
lastPage | Boolean | 是否为本轮快照的最后一页。 |
totalCount | String | 本轮未完成订单总数,包含尚未启用的 Order-Attached TPSL。所有分页的值相同。 |
activeCount | String | 本轮已启用订单总数,不包含尚未启用的 Order-Attached TPSL。所有分页的值相同。 |
orders | Array | 当前页面的未完成订单。元素可以是 Order 或 StopOrder;没有订单时返回 []。 |
分页规则#
type、curPage、lastPage、totalCount和activeCount均位于data内。data为 Object,不使用data: [{ "orders": [] }]。- 同一轮快照的所有分页具有相同的
block_height、block_timestamp、totalCount和activeCount。 - 每页的
pTime为该页的实际生成时间,因此不同页面的pTime可以不同。 - 客户端应收齐全部页面,并在收到
lastPage=true后原子应用整轮快照。 - 若事件发生后已没有未完成订单,仍会推送
orders=[]、totalCount="0"和activeCount="0"。
orders[] 元素类型#
orders[] 平铺返回两种数据结构:
Order:已进入订单簿的普通限价单,或已转换为普通挂单的 TP Limit。StopOrder:独立 Trigger、Order-Attached TPSL 或 Position-Attached TPSL。
Order-Attached TPSL 不会嵌套在母订单的 attachAlgoOrds[] 中,而是作为独立的 StopOrder 元素出现在同一个 orders[] 中,并通过 parentOrderId 关联母订单。
Order 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
oid | String | 链上订单 ID。 |
clientOrderId | String | 用户自定义订单 ID。 |
assetId | String | 产品 ID。 |
assetStatus | String | 产品状态:normal、scheduled、converging 或 regressing。 |
side | String | 订单方向:buy 或 sell。 |
positionSide | String | Position 方向:net、long 或 short;非 perp 返回 ""。 |
marginMode | String | 保证金模式:cross 或 isolated;非 perp 返回 ""。 |
leverage | String | 杠杆倍数,仅支持整数;Equity 为 0 或非 perp 时返回 ""。 |
orderType | String | 订单类型,固定为 limit。 |
tif | String | 订单有效期类型:gtc、ioc、fok、alo 或 gtd。 |
price | String | 委托价格。 |
size | String | 委托数量,以 base 单位表示。 |
accFillSz | String | 累计成交数量,以 base 单位表示。 |
state | String | 订单状态,例如 open 或 partially_filled。 |
reduceOnly | Boolean | 是否为只减仓订单。 |
cTime | String | 订单创建时间,Unix 毫秒时间戳。 |
expiresAfter | String | 订单有效截止时间;不适用时返回 ""。 |
isMarket | Boolean | 是否为市价执行订单。 |
outcomeReverse | Boolean | 是否反转 Outcome。 |
tpLimit | Boolean | 是否为 TP Limit 订单。 |
Order 不提供 avgPx、parentOrderId、triggerPx、triggerPriceType、triggerCond、tpsl 或 attachAlgoOrds。
累计成交均价应通过 REST GET /trade/fills 或私有频道 exchangeos-user-fills 计算。
StopOrder 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
oid | String | Trigger 或 TPSL 订单 ID。 |
assetId | String | 产品 ID。 |
assetStatus | String | 产品状态:normal、scheduled、converging 或 regressing。 |
side | String | 订单方向:buy 或 sell。 |
positionSide | String | Position 方向:net、long 或 short;非 perp 返回 ""。 |
marginMode | String | 保证金模式:cross 或 isolated;非 perp 返回 ""。 |
leverage | String | 杠杆倍数,仅支持整数;Equity 为 0 或非 perp 时返回 ""。 |
size | String | Trigger 或 TPSL 订单数量。 |
price | String | Trigger Limit 的委托价格;Trigger Market 返回 ""。 |
isMarket | Boolean | 触发后是否以市价执行。true 为 Trigger Market,false 为 Trigger Limit。 |
reduceOnly | Boolean | 是否为只减仓订单。 |
cTime | String | Trigger 或 TPSL 创建时间,Unix 毫秒时间戳。 |
triggerPx | String | 触发价格。 |
triggerPriceType | String | 触发价格来源:mark 或 index。 |
triggerCond | String | 触发条件:Gte 或 Lte。 |
tpsl | String | 订单用途:tp、sl、up 或 down。 |
parentOrderId | String | Order-Attached TPSL 的母订单 ID;独立 Trigger 或 Position-Attached TPSL 返回 ""。 |
isActive | Boolean | 是否已启用。Order-Attached TPSL 在母订单终态前为 false。 |
tpLimit | Boolean | 是否为 TP Limit。 |
StopOrder 不提供 clientOrderId、state、accFillSz 或 outcomeReverse。
完整推送示例#
以下示例包含一笔普通 perp 限价母订单,以及尚未启用的 Order-Attached TP 和 SL。三笔数据平铺在 data.orders[] 中;totalCount="3",只有母订单已启用,因此 activeCount="1"。
{
"arg": {
"channel": "exchangeos-orders",
"marketTypes": "[\"all\"]",
"pointBoard": "false"
},
"backend": "okx-defi-tradezone-indexerpubsub-awstky-pro",
"block_height": "42790146",
"block_timestamp": "1788158619230",
"data": {
"activeCount": "1",
"curPage": "0",
"lastPage": true,
"orders": [
{
"accFillSz": "0.000",
"assetId": "602",
"assetStatus": "normal",
"cTime": "1788158619200",
"clientOrderId": "0x030000277b000001a06a12f500000001",
"expiresAfter": "",
"isMarket": false,
"leverage": "10",
"marginMode": "cross",
"oid": "117984456",
"orderType": "limit",
"outcomeReverse": false,
"positionSide": "long",
"price": "38000.000",
"reduceOnly": false,
"side": "buy",
"size": "0.100",
"state": "open",
"tif": "gtc",
"tpLimit": false
},
{
"assetId": "602",
"assetStatus": "normal",
"cTime": "1788158619200",
"isActive": false,
"isMarket": true,
"leverage": "10",
"marginMode": "cross",
"oid": "117984458",
"parentOrderId": "117984456",
"positionSide": "long",
"price": "",
"reduceOnly": true,
"side": "sell",
"size": "0.100",
"tpLimit": false,
"tpsl": "tp",
"triggerCond": "Gte",
"triggerPriceType": "mark",
"triggerPx": "40000.000"
},
{
"assetId": "602",
"assetStatus": "normal",
"cTime": "1788158619200",
"isActive": false,
"isMarket": true,
"leverage": "10",
"marginMode": "cross",
"oid": "117984459",
"parentOrderId": "117984456",
"positionSide": "long",
"price": "",
"reduceOnly": true,
"side": "sell",
"size": "0.100",
"tpLimit": false,
"tpsl": "sl",
"triggerCond": "Lte",
"triggerPriceType": "mark",
"triggerPx": "35000.000"
}
],
"totalCount": "3",
"type": "snapshot"
},
"pTime": "1788158619303",
"user": "0x2e988a386a799f506693793c6a5af6b54dfaabfb"
}
空订单快照示例#
Order Event 或 Fill Event 发生后,如账户已没有未完成订单:
{
"arg": {
"channel": "exchangeos-orders",
"marketTypes": "[\"all\"]",
"pointBoard": "false"
},
"backend": "okx-defi-tradezone-indexerpubsub-awstky-pro",
"block_height": "42790150",
"block_timestamp": "1788158620000",
"data": {
"activeCount": "0",
"curPage": "0",
"lastPage": true,
"orders": [],
"totalCount": "0",
"type": "snapshot"
},
"pTime": "1788158620080",
"user": "0x2e988a386a799f506693793c6a5af6b54dfaabfb"
}
设置更新 exchangeos-setting-updates#
用于推送账户设置更新的事件触发频道。
订阅成功后,频道不会推送当前设置快照。仅当 positionMode、roleId、leverage 或 marginMode 实际发生变化时,才推送更新消息。
若设置没有变化,频道不会推送空消息。
该频道没有首次推送。订阅请求的 id 可由用户自定义。
订阅子账户时,通过 vaultAddress 指定子账户地址。
订阅请求#
{
"id": "req001",
"op": "subscribe",
"args": [
{
"channel": "exchangeos-setting-updates",
"vaultAddress": "xxxxx",
"pointBoard": "false",
"marketTypes": "[\"spot\", \"perp\"]"
}
]
}
订阅参数#
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | String | 否 | 用户自定义请求 ID。 |
op | String | 是 | 固定为 subscribe。 |
args | Array | 是 | 订阅参数列表。 |
> channel | String | 是 | 固定为 exchangeos-setting-updates。 |
> vaultAddress | String | 否 | 子账户地址。不传表示订阅母账户。 |
> pointBoard | String | 否 | true 表示积分盘,false 表示实盘。默认值为 false。 |
> marketTypes | String | 否 | 市场类型,例如 ["spot", "perp"]。不传表示全部市场类型。 |
推送最外层字段#
| 字段 | 类型 | 说明 |
|---|---|---|
arg | Object | 订阅信息。 |
> channel | String | 固定为 exchangeos-setting-updates。 |
> vaultAddress | String | 子账户地址;订阅母账户时省略。 |
backend | String | 生成本次推送的后端服务名称。 |
block_height | String | 本次设置变更对应的链上区块高度。 |
block_timestamp | String | 本次设置变更对应的链上区块时间,Unix 毫秒时间戳。 |
pTime | String | WebSocket 消息实际生成或推送时间,Unix 毫秒时间戳。 |
user | String | 本次更新所属的母账户或子账户地址。 |
data | Object | 本次实际发生变化的账户级或产品级设置。 |
data 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
accSetting | Object | 账户级设置更新。账户级设置没有变化时,不推送该字段。 |
assetSetting | Array | 产品级设置更新。没有产品级设置更新时返回 []。 |
accSetting 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
roleId | String | 保证金角色 ID。用于为特殊用户应用定制保证金规则。 |
positionMode | String | 仓位模式。oneWay 表示买卖模式;hedge 表示开平模式。 |
assetSetting[] 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
assetId | String | 合约 ID。 |
positionSide | String | 仓位方向。oneWay 模式使用 net;hedge 模式使用 long 或 short。 |
leverage | String | 杠杆倍数,仅支持整数。 |
marginMode | String | 保证金模式:cross 表示全仓,isolated 表示逐仓。 |
示例:修改 roleId 或 positionMode#
{
"arg": {
"channel": "exchangeos-setting-updates"
},
"backend": "okx-defi-tradezone-indexer-pubsub",
"block_height": "11904367",
"block_timestamp": "1785897600000",
"data": {
"accSetting": {
"roleId": "3",
"positionMode": "oneWay"
},
"assetSetting": []
},
"pTime": "1788158619303",
"user": "0x2e988a386a799f506693793c6a5af6b54dfaabfb"
}
示例:修改 leverage 或 marginMode#
{
"arg": {
"channel": "exchangeos-setting-updates"
},
"block_height": "95616486",
"block_timestamp": "1785897600000",
"pTime": "1788158619303",
"user": "0x2e988a386a799f506693793c6a5af6b54dfaabfb",
"data": {
"assetSetting": [
{
"assetId": "202",
"positionSide": "long",
"leverage": "10",
"marginMode": "isolated"
},
{
"assetId": "202",
"positionSide": "short",
"leverage": "20",
"marginMode": "isolated"
}
]
},
"backend": "okx-defi-tradezone-indexer-pubsub"
}
用户订单状态频道 exchangeos-user-order-status#
按事件推送订单提交结果及后续状态变化;不推送历史订单。拒绝订单即使未生成 oid 也会推送,此时 oid 返回空字符串。
data 直接返回 OrderDetail[],不使用 orderStatuses[] 或 order 中间对象。批量请求中的每个订单项分别返回一项,顺序与原请求订单顺序一致。
{
"id": "req001",
"op": "subscribe",
"args": [
{
"channel": "exchangeos-user-order-status",
"vaultAddress": "0x...",
"pointBoard": "false",
"marketTypes": "[\"spot\", \"perp\"]"
}
]
}
订阅参数#
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
channel | String | 是 | 固定为 exchangeos-user-order-status。 |
vaultAddress | String | 否 | 子账户地址;不传表示订阅母账户。 |
pointBoard | String | 否 | "true" 表示积分盘,"false" 表示实盘;默认 "false"。 |
marketTypes | String | 否 | 市场类型 JSON Array 字符串,可包含 spot、prediction、perp;不传表示全部市场。 |
data[]:OrderDetail 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
oid | String | 订单 ID;拒绝订单未生成订单时为 ""。 |
clientOrderId | String | 客户端订单 ID。 |
assetId | String | 产品 ID。 |
marketType | String | 市场类型,例如 spot、prediction 或 perp。 |
state | String | 订单状态,见下表。 |
cancelReason | String | 取消或拒绝原因,见下表;无原因时为空字符串。 |
cTime | String | 订单创建时间,Unix epoch 毫秒。 |
marginMode | String | cross 或 isolated。 |
positionSide | String | net、long 或 short。 |
side | String | buy 或 sell。 |
price | String | 委托价格。 |
size | String | 委托数量。 |
sizeType | String | 数量单位,例如 base 或 quote。 |
accFillSz | String | 累计成交数量。 |
reduceOnly | Boolean | 是否仅减仓。 |
outcomeReverse | Boolean | 是否为结果反转订单。 |
parentOrderId | String | 母订单 ID;无关联时为空字符串。 |
tif | String | 有效期策略,例如 gtc 或 ioc。 |
triggerInfo | Object | 条件单或 TPSL 触发信息;普通订单可不返回。 |
children | Array | 触发后生成的关联子订单;无子订单时可不返回。 |
side 与 positionSide#
| 业务方向 | side | positionSide |
|---|---|---|
| 买入/买卖模式 | buy | net |
| 卖出/买卖模式 | sell | net |
| Open Long | buy | long |
| Close Long | sell | long |
| Open Short | sell | short |
| Close Short | buy | short |
state 枚举#
| 值 | 含义 | 说明 |
|---|---|---|
open | 订单已打开 | 订单已进入订单簿或成功创建。 |
canceled | 订单已取消 | 具体取消原因由 cancelReason 判断。 |
rejected | 订单被拒绝 | 下单或触发执行失败;可能尚未生成 oid。 |
filled | 订单已成交 | 订单已全部成交并进入终态。 |
modified | 订单原地修改 | 保持相同 oid,通常用于同价缩量。 |
triggered | 触发单已触发 | 触发条件满足;生成的订单 ID 通过 children 返回。 |
active | 条件单已启用 | Order-Attached TPSL 子单因父订单成交而进入启用状态。 |
cancelReason 枚举#
cancelReason | 含义 |
|---|---|
iocNoFill | IOC 订单没有可成交流动性。 |
fokNotFilled | FOK 订单无法全部成交。 |
aloRejected | ALO / Post-only 订单因会立即成交而被拒绝。 |
userCancel | 用户主动取消。 |
selfTradeCancel | 自成交保护导致取消。 |
expired | GTD 订单到期取消。 |
makerInsufficientBalance | Maker 余额不足导致取消。 |
clearOrderBook | 清理订单簿导致取消。 |
userModify | 用户修改订单导致取消或重新挂单。 |
reduceOnlyTrim | Reduce-only 限制导致订单数量裁减。 |
marginInsufficient | 保证金不足,订单被拒绝或剩余部分被取消。 |
assetHalted | 资产停止交易或下线导致取消。 |
relatedPositionClosed | 关联仓位已关闭或方向翻转。 |
parentOrderCanceled | 父订单未成交终止,关联子单被取消。 |
marginTierExceeded | 超过仓位档位上限。 |
triggerShrunkToZero | 触发单经限额裁减后,可执行数量为零。 |
triggerPriceOutOfBand | 触发后的限价超出价格保护区间。 |
tpLimitActivationInvariantViolated | TP Limit 启用时,仓位模式等执行条件已发生变化。 |
sizeDecimalsAdjust | 数量精度调整导致数量被截断。 |
priceDecimalsAdjust | 价格精度调整导致订单撤销。 |
priceDecimalsAdjustModify | 价格精度调整后,订单继续存在并被原地修改。 |
推送示例#
{
"arg": {
"channel": "exchangeos-user-order-status",
"marketTypes": "[\"perp\"]",
"pointBoard": "true"
},
"backend": "okx-defi-tradezone-indexer-pubsub-pre",
"block_height": "148342375",
"block_timestamp": "1791195529876",
"data": {
"orderStatuses": [
{
"order": {
"accFillSz": "0.000",
"assetId": "302",
"cTime": "1791195529876",
"clientOrderId": "0x03328ef1b810936f92a04d7cb4ad775b",
"marginMode": "cross",
"marketType": "perp",
"oid": "107928539",
"outcomeReverse": false,
"positionSide": "net",
"price": "119.800",
"reduceOnly": false,
"side": "buy",
"size": "0.080",
"sizeType": "base",
"tif": "gtc"
},
"state": "open"
},
{
"order": {
"accFillSz": "0.080",
"assetId": "302",
"cTime": "1791195529876",
"clientOrderId": "0x03328ef1b810936f92a04d7cb4ad775b",
"marginMode": "cross",
"marketType": "perp",
"oid": "107928539",
"outcomeReverse": false,
"positionSide": "net",
"price": "119.800",
"reduceOnly": false,
"side": "buy",
"size": "0.080",
"sizeType": "base",
"tif": "gtc"
},
"state": "filled"
},
{
"order": {
"accFillSz": "0.000",
"assetId": "302",
"cTime": "1791195529876",
"clientOrderId": "0x0397153bdc7272bb7bc8bf49769e1ae4",
"marginMode": "cross",
"marketType": "perp",
"oid": "107928540",
"outcomeReverse": false,
"parentOrderId": "107928539",
"positionSide": "net",
"price": "0.000",
"reduceOnly": true,
"side": "sell",
"size": "0.000",
"sizeType": "base",
"tif": "ioc",
"triggerInfo": {
"isMarket": true,
"parentOrderId": "107928539",
"triggerPriceType": "mark",
"triggerPx": "130.000",
"triggerType": "tp"
}
},
"state": "open"
},
{
"order": {
"accFillSz": "0.000",
"assetId": "302",
"cTime": "1791195529876",
"clientOrderId": "0x0371963d1dcc395160419fc0d51b0d0c",
"marginMode": "cross",
"marketType": "perp",
"oid": "107928541",
"outcomeReverse": false,
"parentOrderId": "107928539",
"positionSide": "net",
"price": "0.000",
"reduceOnly": true,
"side": "sell",
"size": "0.000",
"sizeType": "base",
"tif": "ioc",
"triggerInfo": {
"isMarket": true,
"parentOrderId": "107928539",
"triggerPriceType": "mark",
"triggerPx": "80.000",
"triggerType": "sl"
}
},
"state": "open"
},
{
"order": {
"accFillSz": "0.000",
"assetId": "302",
"cTime": "1791195529876",
"clientOrderId": "0x0397153bdc7272bb7bc8bf49769e1ae4",
"marginMode": "cross",
"marketType": "perp",
"oid": "107928540",
"outcomeReverse": false,
"parentOrderId": "107928539",
"positionSide": "net",
"price": "0.000",
"reduceOnly": true,
"side": "sell",
"size": "0.080",
"sizeType": "base",
"tif": "ioc",
"triggerInfo": {
"isMarket": true,
"parentOrderId": "107928539",
"triggerPriceType": "mark",
"triggerPx": "130.000",
"triggerType": "tp"
}
},
"state": "active"
},
{
"order": {
"accFillSz": "0.000",
"assetId": "302",
"cTime": "1791195529876",
"clientOrderId": "0x0371963d1dcc395160419fc0d51b0d0c",
"marginMode": "cross",
"marketType": "perp",
"oid": "107928541",
"outcomeReverse": false,
"parentOrderId": "107928539",
"positionSide": "net",
"price": "0.000",
"reduceOnly": true,
"side": "sell",
"size": "0.080",
"sizeType": "base",
"tif": "ioc",
"triggerInfo": {
"isMarket": true,
"parentOrderId": "107928539",
"triggerPriceType": "mark",
"triggerPx": "80.000",
"triggerType": "sl"
}
},
"state": "active"
}
]
},
"pTime": "1791195529910",
"user": "0x11bb62db5379b5c79ff996e69b88b8175c49f4fe"
}
用户成交频道 exchangeos-user-fills#
订阅成功后,新成交按事件推送;不首推历史成交。
- 不分页;每批成交数量由
data.fills[]长度确定。 - 历史成交及断线期间数据由 REST
GET /trade/fills获取。 - 建议先建立 WS 订阅并暂存事件,再查询 REST 历史成交,最后通过
tradeId合并去重。 - 普通撮合成交以非空
tradeId唯一识别和去重。 - 强平、ADL、结算等系统成交可能返回
tradeId: "";不得将所有空tradeId视为同一笔成交。 - 外层
block_timestamp表示本批次链上数据时间。同一批次可包含多笔成交;不得因相同block_timestamp相互覆盖。
{
"id": "req001",
"op": "subscribe",
"args": [
{
"channel": "exchangeos-user-fills",
"vaultAddress": "0x...",
"pointBoard": "false",
"marketTypes": "[\"spot\", \"perp\"]"
}
]
}
推送外层字段#
| 字段 | 类型 | 说明 |
|---|---|---|
arg | Object | 订阅条件回显。 |
backend | String | 产生本次推送的后端服务名称。 |
block_height | String | 本次批次对应的链上区块高度。 |
block_timestamp | String | 本次批次链上数据时间,Unix epoch 毫秒。 |
pTime | String | WebSocket 消息生成时间,Unix epoch 毫秒;不参与成交去重。 |
user | String | 数据所属母账户或子账户地址。 |
data | Object | 本次成交推送内容。 |
data.fills | Array of Object | Fill 数组;同一批次可包含多笔成交。 |
data.fills[] 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
tradeId | String | 普通撮合成交 ID;普通成交中唯一。强平、ADL、结算等未产生普通成交 ID 的事件返回 ""。 |
oid | String | 产生本次成交的链上订单 ID;不适用时返回 ""。 |
clientOrderId | String | 用户自定义订单 ID;未设置或不适用时返回 ""。 |
assetId | String | 产品 ID。 |
marketType | Object | 市场及交易属性。perp 包含 marginMode、positionSide;spot、Prediction 返回对应市场对象。 |
side | String | 订单方向:buy 或 sell。 |
execType | String | 流动性角色:maker 或 taker。 |
price | String | 本次成交价格。 |
size | String | 本次成交数量。 |
sizeType | String | 数量单位:base 或 quote。 |
remainingSize | String | 本次成交后的订单剩余数量。 |
fee | String | 本次收取的手续费,不带正负号;未收取时返回 "0"。 |
feeTokenId | String | 手续费币种 Token ID;不适用时返回 ""。 |
rebate | String | 本次返佣金额,不带正负号;未产生返佣时返回 "0"。 |
rebateToken | String | 返佣币种 Token ID;未产生返佣时返回 ""。 |
oppositeOrderId | String | 对手方订单 oid。 |
oppositeUser | String | 对手方地址。 |
pnl | String | 本次成交产生的已实现盈亏;spot 或不适用时返回 ""。 |
fillDir | String | 成交细分方向,见下表。 |
startPosition | String | 撮合前的 Position 数量或 spot 资产余额。 |
twapId | String | 所属 TWAP 母单 ID;非 TWAP 成交返回 ""。 |
FillDir 枚举#
| 值 | 含义 |
|---|---|
Buy | 买方成交;适用于普通订单簿撮合或 Prediction Market 转让结算。 |
Sell | 卖方成交;适用于普通订单簿撮合或 Prediction Market 转让结算。 |
BuySplit | 双方均为买方触发的隐式拆分,仅 Prediction Market。 |
SellMerge | 双方均为卖方触发的隐式合并,仅 Prediction Market。 |
BackstopLiquidation | 保险基金接管亏损仓位的清算成交。 |
BackstopLiquidator | 保险基金作为流动性提供方的清算成交视角。 |
Adl | 自动减仓成交。 |
AdlOpponent | 被 ADL 选中且仓位被强制减少的对手方成交。 |
AdlPreviousPrice | ADL 以前序价格计算的成交。 |
AdlOpponentPreviousPrice | ADL 对手方以前序价格计算的成交。 |
NetLiquidation | 净清算成交。 |
NetAdl | 净自动减仓成交。 |
Settlement | 结算成交。 |
Open | 永续开仓或同向加仓。 |
Close | 永续反向减仓,包括恰好平至零。 |
ReverseOpen | 单笔成交先平掉原仓位,再反向开出新仓位。 |
DecimalAdjustSettle | 数量精度调整的用户尾数结算;当前版本不会发送。 |
DecimalAdjustTakeover | 精度调整中由 Liquidator 承接净尾仓;当前版本不会发送。 |
推送示例#
{
"arg": {
"channel": "exchangeos-user-fills",
"marketTypes": "[\"spot\", \"perp\"]",
"pointBoard": "false"
},
"backend": "okx-defi-tradezone-indexerpubsub-awstky-pro",
"block_height": "12092417",
"block_timestamp": "1785218400074",
"pTime": "1785218400150",
"user": "0x2e988a386a799f506693793c6a5af6b54dfaabfb",
"data": {
"fills": [
{
"tradeId": "780",
"oid": "90005",
"clientOrderId": "",
"assetId": "602",
"marketType": {
"perp": {
"marginMode": "isolated",
"positionSide": "long"
}
},
"side": "sell",
"execType": "taker",
"price": "2895",
"size": "1.5",
"sizeType": "base",
"remainingSize": "0",
"fee": "1.085625",
"feeTokenId": "0",
"rebate": "0",
"rebateToken": "",
"oppositeOrderId": "",
"oppositeUser": "",
"pnl": "-157.5",
"fillDir": "Sell",
"startPosition": "1.5",
"twapId": ""
}
]
}
}
用户资金费频道 exchangeos-user-fundings#
该频道为纯增量资金费事件频道。订阅成功后不补发历史资金费、不推送空快照;仅在账户实际支付或收到资金费时推送。推送频率取决于产品 settlementInterval,并非固定每小时一次。
历史资金费及断线期间数据通过以下 REST 接口查询:
GET /account/bills?billType=funding_fee{
"id": "123",
"op": "subscribe",
"args": [
{
"channel": "exchangeos-user-fundings",
"vaultAddress": "0x...",
"pointBoard": "false",
"marketTypes": "[\"spot\", \"perp\"]"
}
]
}
fundings[] 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
assetId | String | 合约 ID。 |
fundingFee | String | 负数表示支付资金费;正数表示收到资金费。 |
pos | String | 仓位数量。 |
fundingRate | String | 资金费率。 |
marginMode | String | cross 或 isolated。 |
positionSide | String | net、short 或 long。 |
推送示例#
{
"arg": {
"channel": "exchangeos-user-fundings"
},
"backend": "okx-defi-tradezone-indexer-pubsub",
"block_height": "13451456",
"block_timestamp": "1785218400074",
"pTime": "1788158619303",
"user": "0x2e988a386a799f506693793c6a5af6b54dfaabfb",
"data": {
"fundings": [
{
"assetId": "602",
"fundingFee": "-45",
"fundingRate": "-0.015",
"marginMode": "cross",
"positionSide": "short",
"pos": "-1.5"
}
]
}
}
用户账本更新频道 exchangeos-user-ledger-updates#
推送资金费以外的账本变化,包括充值、提现、账户间划转、子账户划转、清算、Vault 操作、Prediction Market 操作、逐仓保证金划转及保证金模式切换等。
资金费事件不由本频道推送,请使用 exchangeos-user-fundings。
{
"id": "req001",
"op": "subscribe",
"args": [
{
"channel": "exchangeos-user-ledger-updates",
"vaultAddress": "0x...",
"pointBoard": "false",
"marketTypes": "[\"spot\", \"perp\"]"
}
]
}
推送规则#
- 事件触发推送,不首推历史数据。
- 单条 WebSocket 推送最外层为 JSON Object,不使用
[{...}]数组包装。 - 业务 payload 固定为
data: { "ledgerUpdates": [...] }。 - 每项
ledgerUpdates[]固定包含time、hash和delta。 delta包含受影响账户users[],以及且仅有一个具体事件 variant。- 应通过 variant key 判断事件类型,不能依赖字段数量或字段顺序。
block_timestamp是批次区块时间;ledgerUpdates[].time是单笔账本事件时间;pTime是推送生成时间。三者不可混用。
ledgerUpdates[] 字段#
| 字段 | 类型 | 说明 |
|---|---|---|
time | String | 单笔账本事件发生时间,Unix epoch 毫秒。 |
hash | String | 对应交易或事件 Hash;用于追踪及辅助去重。 |
delta | Object | 账本变更内容。 |
delta.users | Array of String | 本次账本事件涉及的账户地址。 |
delta.<variant> | Object | 具体账本事件数据;每个 delta 只返回一个 variant。 |
delta variant#
| Variant | 说明 |
|---|---|
liquidationPenalityCompensationEvent | 清算罚金与补偿事件。Penality 为既有 wire key 拼写,客户端应按原字串解析。 |
transfer | 账户或市场账本间划转。 |
subAccountTransfer | 母账户与子账户之间的划转。 |
deposit | 从 X Layer 充值。 |
withdraw | 提现至 X Layer。 |
vaultCreate | 建立 Vault。 |
vaultDeposit | 存入 Vault。 |
vaultWithdraw | 从 Vault 提取。 |
vaultDistribution | Vault 收益分配。 |
vaultLeaderCommission | Vault Leader 佣金。 |
predictionSplit | Prediction Market 拆分。 |
predictionMerge | Prediction Market 合并。 |
predictionRedeem | Prediction Market 结算赎回。 |
predictionConvert | Prediction Market negRisk 转换。 |
depositAndRedeem | 已结算 Prediction Market Token 充值并自动赎回。 |
tokenBurn | Token 全量销毁造成的用户余额变更。 |
actionPurchaseFee | 购买 Action Allowance 产生的费用。 |
isolatedMarginTransfer | 全仓账户与逐仓仓位之间的保证金划转。 |
updateMarginMode | Cross / Isolated 保证金模式切换及相关抵押品移动。 |
已定义 variant 字段#
transfer#
| 字段 | 类型 | 说明 |
|---|---|---|
user | String | 发起账户。 |
destination | String | 接收账户。 |
sourceDex / destinationDex | String | 转出与转入业务线,例如 perp、spot。 |
tokenId | String | 币种 ID。 |
amount | String | 划转数量。 |
fee | String | 划转手续费。 |
updateMarginMode#
| 字段 | 类型 | 说明 |
|---|---|---|
user | String | 账户地址。 |
assetId | String | 产品 ID。 |
marginMode | String | 更新后的保证金模式。 |
moves | Array | 保证金移动明细。 |
moves[].side | String | 仓位方向。 |
moves[].amount | String | 移动金额。 |
liquidationPenalityCompensationEvent#
| 字段 | 类型 | 说明 |
|---|---|---|
marginMode | String | 保证金模式。 |
fullTakeOver | Boolean | 是否全量接管。 |
liquidatorItems | Object | 以清算方地址为键的清算项。 |
chargeList | Array | 清算罚金和补偿明细。 |
chargeList[].assetId | String | 产品 ID。 |
chargeList[].positionSide | String | 仓位方向。 |
chargeList[].penality | String | 清算罚金;字段拼写为既有 wire key。 |
chargeList[].fee | String | 手续费。 |
chargeList[].wearingCompensation | String | 补偿金额。 |
chargeList[].isLongPosition | Boolean | 是否为多头仓位。 |
chargeList[].takeoverSize | String | 接管数量。 |
chargeList[].takeoverPrice | String | 接管价格。 |
推送示例#
{
"arg": {
"channel": "exchangeos-user-ledger-updates"
},
"backend": "okx-defi-tradezone-indexer-pubsub",
"block_height": "13451456",
"block_timestamp": "1785218400074",
"pTime": "1785218400150",
"user": "0x2e988a386a799f506693793c6a5af6b54dfaabfb",
"data": {
"ledgerUpdates": [
{
"time": "1785218400068",
"hash": "0x8c76a11353098545b176cc04214c06fa3758b4574ce4f7aa3762d4565afae821",
"delta": {
"users": [
"0x2e988a386a799f506693793c6a5af6b54dfaabfb",
"0x93f51fc5190b1e7bb82238bcc2f93430b43a9243"
],
"transfer": {
"user": "0x2e988a386a799f506693793c6a5af6b54dfaabfb",
"destination": "0x93f51fc5190b1e7bb82238bcc2f93430b43a9243",
"sourceDex": "perp",
"destinationDex": "spot",
"tokenId": "0",
"amount": "500",
"fee": "0.1"
}
}
}
]
}
}
- 私有WebSocket订阅准则Backend 预建连(connect_backends)后端连接状态事件(event: backend)触发时机帧格式客户端处理原则定时账户与持仓快照 exchangeos-balance-and-position订阅请求订阅参数账户总权益计算分页规则顶层消息字段data 字段Asset 结构Position 结构assetStatus 枚举响应示例账户与持仓事件更新 exchangeos-balance-and-position-updates订阅母账户订阅子账户订阅参数推送最外层字段data 字段details[] 字段positions[] 字段closeOrderAlgo[] 字段trades[] 字段eventType 枚举一般成交事件示例部分强平事件示例去重规则事件触发的未完成订单全量快照 exchangeos-orders订阅请求订阅参数推送最外层字段data 字段分页规则orders[] 元素类型Order 字段StopOrder 字段完整推送示例空订单快照示例设置更新 exchangeos-setting-updates订阅请求订阅参数推送最外层字段data 字段accSetting 字段assetSetting[] 字段示例:修改 roleId 或 positionMode示例:修改 leverage 或 marginMode用户订单状态频道 exchangeos-user-order-status订阅参数data[]:OrderDetail 字段side 与 positionSidestate 枚举cancelReason 枚举推送示例用户成交频道 exchangeos-user-fills推送外层字段data.fills[] 字段FillDir 枚举推送示例用户资金费频道 exchangeos-user-fundingsfundings[] 字段推送示例用户账本更新频道 exchangeos-user-ledger-updates推送规则ledgerUpdates[] 字段delta variant已定义 variant 字段transferupdateMarginModeliquidationPenalityCompensationEvent推送示例
