OKX API v5 交易技术介绍及指南
随着 OKX 全新统一账户交易系统的推出,我们一直致力于升级 API,添加新功能和增强功能。在本文档中,我们将概述最新 API 版本 v5的主要变化,并向交易者介绍现在可通过 OKX 交易 API 使用的各种配置参数。
API v5 中的变更
跨产品的统一 API
与 API v3 不同,API v5 中的端点(例如下订单和检索位置)在产品之间是统一的。
例如,下订单时,我们只需要调用以下URL并在请求体中指定产品(即仪器类型):
| POST /api/v5/trade/order |
同一 API 中的所有仪器类型都使用相同的请求和响应数据模型,这意味着我们不再需要单独对每个产品 API 进行建模。
更短的命名约定
在 API v5 中,缩写的字段名称使用驼峰式命名法,以节省带宽和内存消耗。
例如:
| 场地 | V5 API | V3 API |
| 货币 | ccy | 货币 |
| 仪器 ID | 机构编号 | 仪器 ID |
| 潜在的 | 尤利 | 潜在的 |
| 未实现盈亏 | 联合利华 | 未实现盈亏 |
标准 WebSocket 压缩
API v3 中接收消息时手动解压缩在 v5 中不再需要,而是用标准 WebSocket 扩展“Per-Message Deflate”代替。
要利用 WebSocket 压缩,请确保在客户端启用扩展,即请求标头中应存在“permessage-deflate”。
公共和私有 WebSocket
WebSocket 通道现在分为具有不同 URL 的公共通道(例如,股票行情、蜡烛)和私人通道(例如,仓位、账户)。
连接公共 WebSocket 时,订阅前无需登录请求,否则服务器将拒绝订阅请求。
通过 WebSocket 下单
除了 REST 之外,现在还可以通过 WebSocket 下单/修改/取消订单。详情请参阅本文档中提到的交易部分。
验证
API v5 中的 REST 身份验证与 API v3 中的相同(即在请求标头中签名)。
WebSocket 身份验证也与 API v3 非常相似(即发送登录请求),但键值对的格式有所变化:
| { “op”:“login”, “args”:[ { “apiKey”:“975d5d66-57ce-40fb-b714-afc0b66518083”, “密码”:“123456”, “时间戳”:“1538054050”, “签名”:“7L + zFQ + CEgGu5rzCj4 + BdV2 / uUHGqddA9pI6ztsLLPs =” } ] } |
管理子账户的API密钥
使用 API v5,可以在使用主帐户(即主帐户)时对子帐户的 API 密钥进行 CRUD(创建、读取、更新、删除)。
| 创造 | POST /api/v5/用户/子账户/apikey |
| 读 | 获取/api/v5/用户/子账户/apikey |
| 更新 | POST /api/v5/users/subaccount/modify-apikey |
| 删除 | POST /api/v5/users/subaccount/delete-apikey |
出于安全原因,强烈建议将 API 密钥绑定到特定的 IP 地址。
配置账户和子账户
创建子账户及其API密钥后,我们可以在交易前通过API配置主账户和子账户。
账户配置
可以通过 REST API 检索每个帐户/子帐户的帐户配置:
| 获取/api/v5/account/config |
它将返回(1)账户模式、(2)仓位模式、(3)自动借入设置和(4)期权希腊字母类型。
账户模式
在OKX的统一账户交易系统中,我们有(i)简单模式,(ii)单币种保证金模式,和(iii)多币种保证金模式。
我们只能通过 Web UI 更改这些模式,因为该过程需要用户操作。
位置
净头寸是随着 OKX 的统一账户交易系统而推出的,是对现有多头/空头头寸的补充。
| 净持仓 | 仓位只能在单边持有。交易所将根据您指定的仓位(正/负)自动开仓/平仓。 |
| 多头/空头仓位 | 可以同时担任双方职务 |
要更改持仓模式,我们可以调用以下 REST API。请注意,必须先平仓所有仓位。
| POST /api/v5/account/设置位置模式 |
自动借用
自动借入是一项仅适用于多币种保证金模式的新功能,并且只能通过网页用户界面进行更改。
期权希腊值类型
我们可以通过 v5 中的 REST API 设置希腊字母类型选项,类似于 v3:
| POST /api/v5/account/set-greeks |
全仓/逐仓模式
在OKX的统一账户交易系统中,我们可以灵活地同时使用交叉(单币种和多币种)保证金和逐仓(即固定)保证金交易同一工具。
因此,我们不再提供用于设置每个标的资产的保证金模式的 API。现在,我们会在下单时指定保证金模式(即交易模式)。
管理杠杆
获得杠杆
我们可以通过以下 REST API 检索杠杆信息:
| 获取/api/v5/account/leverage-info |
目前没有全局的杠杆设置,可以设置不同范围内的杠杆。
对于保证金工具类型:

对于其他仪器类型:

设置杠杆
获取杠杆信息后,我们可以相应地设置杠杆:
| POST /api/v5/account/set-leverage |
通过这两个API,我们可以编写程序来预先设置每个工具的杠杆。
例如,考虑以下场景:
- 账户模式:多币种保证金
- 定位模式:网络
- 我们想要将杠杆设置为 3.0 的工具:
- BTC-USDT、EOS-USDT、LTC-BTC、LTC-USDT
- BTC-USD-210319, BTC-USD-210326, BTC-USD-210625
- BTC-USD-掉期
- 仅对上述工具的跨保证金模式感兴趣
对于现货/保证金工具,由于杠杆是按币种设置的,我们可以提取货币对并按币种设置,即BTC、USDT、EOS、LTC。
设置BTC杠杆为3.0的示例请求体(适用于卖出BTC-USDT,买入LTC-BTC):
| { “lever”:“3.0”, “mgnMode”:“cross”, “ccy”:“BTC” } |
设置USDT、EOS、LTC的请求体类似。
接下来,我们要设置BTC-USD-210319、BTC-USD-210326和BTC-USD-210625的杠杆。由于它们的标的资产相同,即BTC-USD,因此我们只需对其中一个工具设置一次杠杆即可。
| { “lever”:“3.0”, “mgnMode”:“cross”, “instId”:“BTC-USD-210326” } |
最后,我们要设置BTC-USD-掉期合约的杠杆。尽管与上述期货合约的标的(BTC-USD)相同,但期货合约和掉期合约的杠杆是分开的。
为此,我们可以使用以下请求主体调用 API:
| { “lever”:“3.0”, “mgnMode”:“cross”, “instId”:“BTC-USD-SWAP” } |
现在我们应该已经为这 8 种仪器设置好了上述 6 个 API 调用。
通过上述说明,用户应该能够使用新的 API 设置子账户,并配置账户以适合他们的交易偏好。
使用 API v5 进行交易
贸易模式
由于全仓和逐仓模式下单的灵活性,我们需要指定交易模式(tdMode)。
下表显示了需要设置的tdMode值:

假设我们要下以下订单作为示例:
- 账户模式:多币种保证金
- 定位模式:网络
- 交易品种:BTC-USDT-SWAP
- 保证金模式:交叉
- 方向:买入(多头)
- 类型:限制
- 价格:50,912.4 USDT
- 数量:1 续
通过查看上面的交易模式表,tdMode 应该设置为“交叉”。
为了在系统中更好地识别订单,建议在下单时提供客户提供的订单ID (clOrdId)。客户提供的订单ID应区分大小写,以字母开头,最多32个字符。
在此示例中,我们将 clOrdId 指定为 testBTC0123。
订阅订单频道
在我们下订单之前,我们应该用 WebSocket 订阅订单频道,这样我们就可以监控订单状态的变化(例如,实时、已完成)并在必要时采取行动(例如,执行后下达新订单)。
在 API v5 中,订阅订单渠道时有几种订阅粒度。
为了订阅上述BTC-USDT-SWAP订单更新,我们可以在连接并登录私有WebSocket后发送以下任一项:
| 仪器类型 | 工具类型 + 标的(仅限衍生品) |
仪器类型+仪器ID | |
| 要求 | { “op”: “subscribe”, “args”: [ { “channel”: “orders”, “instType”: “SWAP” } ] } |
{ “op”: “subscribe”, “args”: [ { “channel”: “orders”, “instType”: “SWAP”, “uly”: “BTC-USDT” } ] } |
{ “op”: “subscribe”, “args”: [ { “channel”: “orders”, “instType”: “SWAP”, “instId”: “BTC-USDT-SWAP” } ] } |
| 成功的响应 | { “event”: “subscribe”, “arg”: { “channel”: “orders”, “instType”: “SWAP” } } |
{ “event”: “subscribe”, “args”: [ { “channel”: “orders”, “instType”: “SWAP”, “uly”: “BTC-USDT” } ] } |
{ “event”: “subscribe”, “args”: [ { “channel”: “orders”, “instType”: “SWAP”, “instId”: “BTC-USDT-SWAP” } ] } |
我们可以将 ANY 作为 instType 传递,以便一次性订阅所有产品类型。
请注意,订单频道不会发布您订阅前订单的任何初始快照。它仅在订单状态发生变化时(例如,从有效变为已取消)发布。
如果我们想获取订阅前所有的活跃订单详情,可以调用以下API:
| 获取/api/v5/trade/orders-pending |
下订单
订阅订单频道后,我们就可以下达BTC-USDT-SWAP订单了。
在 API v5 中,我们可以使用 REST 或 WebSocket 下订单。
休息
我们可以调用以下 REST API,服务器将使用订单 ID(ordId)确认请求:
| REST API | POST /api/v5/trade/order |
| 请求正文 | { “instId”: “BTC-USDT-SWAP”, “tdMode”: “cross”, “clOrdId”: “testBTC0123”, “side”: “buy”, “ordType”: “limit”, “px”: “50912.4”, “sz”: “1” } |
| 成功的响应 | { “code”: “0”, “msg”: “”, “data”: [ { “clOrdId”: “testBTC0123”, “ordId”: “288981657420439575”, “tag”: “”, “sCode”: “0”, “sMsg”: “” } ] } |
请注意,这仅表示交易所已成功接收请求并分配了订单 ID。订单目前可能尚未生效,我们接下来应该检查订单状态。
WebSocket
或者,我们可以通过 WebSocket 下订单,理论上,这比使用 REST API 更高效,而且开销更少。
由于WebSocket操作是异步的,我们还需要提供消息ID(id)来识别相应的响应。
登录私有WebSocket后,我们可以发送以下WebSocket消息:
| { “id”: “NEWtestBTC0123”, “op”: “order”, “args”: [ { “instId”: “BTC-USDT-SWAP”, “tdMode”: “cross”, “clOrdId”: “testBTC0123”, “side”: “buy”, “ordType”: “limit”, “px”: “50912.4”, “sz”: “1” } ] } |
服务器将使用以下示例响应确认请求,其中包含相同的消息 ID(即 NEWtestBTC0123)以及交易所分配的订单 ID(ordId):
| { “id”: “NEWtestBTC0123”, “op”: “order”, “data”: [ { “clOrdId”: “”, “ordId”: “288981657420439575”, “tag”: “”, “sCode”: “0”, “sMsg”: “” } ], “code”: “0”, “msg”: “” } |
请注意,这仅表示交易所已成功接收请求并分配了订单ID。订单目前可能尚未生效,我们需要检查订单状态。
检查订单状态
下订单后,我们应该期待来自订单渠道的状态为“实时”的 WebSocket 消息。
示例消息(按工具类型+标的订阅订单通道):
| { “arg”: { “channel”: “orders”, “instType”: “SWAP”, “uly”: “BTC-USDT” }, “data”: [ { “accFillSz”: “0”, “amendResult”: “”, “avgPx”: “”, “cTime”: “1615170596148”, “category”: “normal”, “ccy”: “”, “clOrdId”: “testBTC0123”, “code”: “0”, “fee”: “0”, “feeCcy”: “USDT”, “fillPx”: “”, “fillSz”: “0”, “fillTime”: “”, “instId”: “BTC-USDT-SWAP”, “instType”: “SWAP”, “lever”: “3”, “msg”: “”, “ordId”: “288981657420439575”, “ordType”: “limit”, “pnl”: “0”, “posSide”: “net”, “px”: “50912.4”, “rebate”: “0”, “rebateCcy”: “USDT”, “reqId”: “”, “side”: “buy”, “slOrdPx”: “”, “slTriggerPx”: “”, “state”: “live”, “sz”: “1”, “tag”: “”, “tdMode”: “cross”, “tpOrdPx”: “”, “tpTriggerPx”: “”, “tradeId”: “”, “uTime”: “1615170596148” } ] } |
订单完成后,将推送以下示例消息,状态更改为“已完成”,以及其他与完成相关的字段。
此次填充还将设置一个交易 ID(tradeId),可用于与仓位进行核对,这将在下面介绍。
| { “arg”: { “channel”: “orders”, “instType”: “SWAP”, “uly”: “BTC-USDT” }, “data”: [ { “accFillSz”: “1”, “amendResult”: “”, “avgPx”: “50912.4”, “cTime”: “1615170596148”, “category”: “normal”, “ccy”: “”, “clOrdId”: “testBTC0123”, “code”: “0”, “fee”: “-0.1018248”, “feeCcy”: “USDT”, “fillPx”: “50912.4”, “fillSz”: “1”, “fillTime”: “1615170598021”, “instId”: “BTC-USDT-SWAP”, “instType”: “SWAP”, “lever”: “3”, “msg”: “”, “ordId”: “288981657420439575”, “ordType”: “limit”, “pnl”: “0”, “posSide”: “net”, “px”: “50912.4”, “rebate”: “0”, “rebateCcy”: “USDT”, “reqId”: “”, “side”: “buy”, “slOrdPx”: “”, “slTriggerPx”: “”, “state”: “filled”, “sz”: “1”, “tag”: “”, “tdMode”: “cross”, “tpOrdPx”: “”, “tpTriggerPx”: “”, “tradeId”: “60477021”, “uTime”: “1615170598022” } ] } |
修改订单
使用 API v5 时,所有工具类型均支持订单修改,您可以修改订单的价格 (newPx) 和/或金额 (newSz)。此外,您还可以使用失败取消 (cxlOnFail) 参数,在修改失败时取消订单。
休息:
| POST /api/v5/trade/修改订单 |
WebSocket 操作(op)参数:
| “op”:“修改订单” |
与下订单类似,通过 REST 或 WebSocket 发送修改请求后,我们应该得到确认。
请注意,订单一旦全部完成或取消,则无法修改。
取消订单
同样,我们可以使用 REST 或 WebSocket 取消订单。
休息:
| POST /api/v5/trade/取消订单 |
WebSocket 操作(op)参数:
| “op”: “取消订单” |
发送取消请求后,系统会收到确认。只有当我们从 WebSocket 订单通道收到状态为“已取消”的订单更新时,订单才会被取消。
请注意,订单已全部完成或已取消时无法取消。
批量操作
支持批量下单、修改和撤单操作,单次最多支持20个订单。统一API的优势在于支持不同类型的订单。
休息:
| 地方 | POST /api/v5/trade/batch-orders |
| 修正 | POST /api/v5/trade/amend-batch-orders |
| 取消 | POST /api/v5/trade/cancel-batch-orders |
WebSocket 操作(op)参数:
| 地方 | “op”: “批量订单” |
| 修正 | “op”: “批量修改订单” |
| 取消 | “op”: “批量取消订单” |
批量操作并非全有或全无,也就是说,它允许部分订单操作成功。发送请求后收到确认信息时,我们应该检查每个订单的 sCode 和 sMsg 字段。
账户和仓位信息
统一账户
在 OKX 的统一账户交易系统下,所有交易品种共用一个统一账户。因此,使用 API v5 进行交易时,无需单独的现货、保证金、期货、掉期或期权账户。
WebSocket 订阅
建议使用 WebSocket 订阅账户频道,以接收账户更新。账户频道提供可选参数“ccy”,用于指定我们感兴趣的账户的币种进行订阅。
以下是连接并登录私有 WebSocket 后的示例请求和响应:
| 帐户 | 特定货币账户 | |
| 要求 | { “op”:“订阅”, “args”:[ { “channel”:“account” } ] } |
{ “op”: “subscribe”, “args”: [ { “channel”: “account”, “ccy”: “BTC” } ] } |
| 成功的响应 | { “事件”:“订阅”, “参数”:{ “频道”:“帐户” } } |
{ “事件”:“订阅”, “参数”:{ “通道”:“账户”, “ccy”:“BTC” } } |
初始快照
与订单通道不同,账户通道会针对非零余额的币种,即非零权益、可用权益或可用余额,发布一个初始快照。
假设我们的BTC和USDT余额不为零,且账户设置为多币种保证金模式。账户通道中应该会收到以下示例消息:
| 帐户 | 特定货币账户 |
| { “arg”: { “channel”: “账户” }, “data”: [ { “adjEq”: “30979.1086748182657014”, “details”: [ { “availBal”: “”, “availEq”: “18962.59868274799”, “ccy”: “USDT”, “crossLiab”: “0”, “disEq”:“18978.5272656414983116”, “eq”:“18962.59868274799”, “frozenBal”:“0”, “interest”:“0”, “isoEq”:“0”, “isoLiab”:“0”, “liab”:“0”, “mgnRatio”: “”, “ordFrozen”: “0”, “upl”: “0” }, { “availBal”: “”, “availEq”: “0”, “ccy”: “BTC”, “crossLiab”:“0.509575622217854”, “disEq”:“-25408.4180739947324516”, “eq”:“-0.5096053466363398”, “frozenBal”:“0”, “利息”: “0.0000297244184858”, “isoEq”:“0”, “isoLiab”:“0”, “liab”:“0.509575622217854”, “mgnRatio”:“”, “ordFrozen”:“0”, “upl”:“0” } ], “imr”: “8469.4726913315758219”, “isoEq”: “0”, “mgnRatio”: “39.9556239578938079”, “mmr”:“762.252542219842”, “totalEq”:“44480.5383005753085878”, “uTime”:“1615190165641” } ] } |
{ “arg”: { “channel”: “账户”, “ccy”: “BTC” }, “data”: [ { “adjEq”: “30979.1086748182657014”, “details”: [ { “availBal”: “”, “availEq”: “0”, “ccy”: “BTC”, “crossLiab”: “0.509575622217854”, “disEq”:“-25408.4180739947324516”, “eq”:“-0.5096053466363398”, “frozenBal”:“0”, “利息”:“0.0000297244184858”, “isoEq”:“0”, “isoLiab”:“0”, “liab”:“0.509575622217854”, “mgnRatio”:“”, “ordFrozen”:“0”, “upl”:“0” } ], “imr”:“8469.4726913315758219”, “isoEq”:“0”, “mgnRatio”:“39.9556239578938079”, “mmr”:“762.252542219842”, “totalEq”:“44480.5383005753085878”, “uTime”:“1615190165641” } ] } |
后续更新
随后我们将收到以下驱动的帐户更新:
| 事件驱动的更新 | 由下单和取消订单等事件驱动的更新。多个事件(例如,同时执行多个订单)可能会聚合为一个账户更新。
仅发布受影响代币的数据,包括代币余额变为零的情况。 |
| 固定时间更新 | 定期推送更新(截至撰写本文时为 10 秒)。
与初始快照类似,所有余额非零的币种(或使用 ccy 参数指定的币种)都将被推送。 |
休息
或者我们仍然可以调用 REST API 来获取非零余额的硬币余额:
| 获取/api/v5/账户/余额 |
我们可以使用“ccy”传递可选参数,该参数包含单个货币(例如 BTC)或多个货币(不超过 20 个),并以逗号分隔(例如 BTC、USDT、ETH)。例如:
| 获取 /api/v5/account/balance?ccy=BTC,USDT,ETH |
然而,与 WebSocket 中的帐户通道不同,如果使用 REST API 中的“ccy”参数指定了硬币余额,无论余额是否为零,只要我们之前拥有过该硬币,就始终会返回该硬币余额。
最大可交易金额
在多币种保证金模式下启用自动借入后,您可以通过从 OKX 借入来买入/卖出超过该货币可用现金余额的工具。
在这种情况下,检索该工具的最大可用交易量(包括可用权益和可从交易所借出的金额)非常有用。
为此,我们可以定期轮询以下 REST API:
| 获取/api/v5/account/max-avail-size |
以下是多币种保证金模式下,BTC-USDT 全仓模式的请求与响应示例:
| 要求 | 获取 /api/v5/account/max-avail-size?instId=BTC-USDT&tdMode=cross |
| 成功响应 | { “code”: “0”, “data”: [ { “availBuy”: “213800.4239369798722052”, “availSell”: “1.3539405224369181”, “instId”: “BTC-USDT” } ], “msg”: “” } |
对于现货工具,availBuy 以报价货币表示,availSell 以基础货币表示。
上述响应意味着最多有 213,800.42 USDT 可用于买入 BTC-USDT,最多有 1.35394052 BTC 可用于卖出 BTC-USDT。这应该与您在网页界面上交易时看到的金额相同。
职位
在 API v5 中,不同产品的持仓 API 也已统一。建议使用 WebSocket 检索持仓数据。
WebSocket 订阅
与订单通道类似,在 API v5 中订阅仓位通道时有几种订阅粒度。
要订阅上述 BTC-USDT-SWAP 持仓更新,我们可以在连接并登录私有 WebSocket 后发送以下内容之一:
| 仪器类型 | 工具类型 + 标的(仅限衍生品) |
仪器类型+仪器ID | |
| 要求 | { “op”: “subscribe”, “args”: [ { “channel”: “positions”, “instType”: “SWAP” } ] } |
{ “op”: “subscribe”, “args”: [ { “channel”: “positions”, “instType”: “SWAP”, “uly”: “BTC-USDT” } ] } |
{ “op”: “subscribe”, “args”: [ { “channel”: “positions”, “instType”: “SWAP”, “instId”: “BTC-USDT-SWAP” } ] } |
| 成功的响应 | { “事件”:“订阅”, “参数”:{ “通道”:“仓位”, “instType”:“SWAP” } } |
{ “event”: “subscribe”, “args”: [ { “channel”: “positions”, “instType”: “SWAP”, “uly”: “BTC-USDT” } ] } |
{ “event”: “subscribe”, “args”: [ { “channel”: “positions”, “instType”: “SWAP”, “instId”: “BTC-USDT-SWAP” } ] } |
我们可以将 ANY 作为 instType 传递,以便一次性订阅所有产品类型的仓位。
初始快照
仓位通道将发布非零仓位的初始快照,即 pos > 0 或 pos < 0。
延续上文BTC-USDT-SWAP全仓杠杆订单(持仓净额模式)示例,预期消息示例如下(按品种+标的订阅):
| { “arg”: { “channel”: “positions”, “instType”: “SWAP”, “uly”: “BTC-USDT” }, “data”: [ { “adl”: “2”, “availPos”: “”, “avgPx”: “50912.4”, “cTime”: “1615170596148”, “ccy”: “USDT”, “imr”: “165.15734103333082”, “instId”: “BTC-USDT-SWAP”, “instType”: “SWAP”, “interest”: “0”, “last”: “51000”, “lever”: “3”, “liab”: “”, “liabCcy”: “”, “liqPx”: “”, “margin”: “”, “mgnMode”: “cross”, “mgnRatio”: “0”, “mmr”: “1.98188809239997”, “optVal”: “”, “pTime”: “1615196199624”, “pos”:“1”, “posCcy”:“”, “posId”:“287999792370819074”, “posSide”:“net”, “tradeId”:“60477021”, “uTime”:“1615170598022”, “upl”: “0.4520230999924388”, “uplRatio”:“0.0027394232555804” } ] } |
后续更新
与账户渠道类似,随后我们将收到以下驱动的持仓更新:
| 事件驱动的更新 | 由开仓和平仓等事件驱动的更新。多个事件(例如,多个订单同时执行)可能会聚合为一个仓位更新。
仅会发布受影响的仓位数据,包括平仓时的数据(即仓位变为零)。 |
| 固定时间更新 | 每隔一定间隔(截至撰写本文时为 10 秒)推送更新。
所有符合订阅粒度的非零位置都将被推送。 |
位置 ID
您可能会注意到每个位置数据中都包含一个位置 ID (posId) 字段,该字段可在调用 REST API 时用作可选查询参数,如下一节所示。
该字段由mgnMode+posSide+instId+ccy生成,包含在数据中,用于您同一账户下唯一标识该仓位,平仓、重开仓位后该字段不会发生变化。
休息
或者我们仍然可以调用非零位置的 REST API:
| 获取/api/v5/account/positions |
可用的粒度如下:
| 粒度 | 示例请求 |
| 仪器类型 | 获取 /api/v5/account/positions?instType=SWAP |
| 仪器 ID | 获取/api/v5/account/positions?instId=BTC-USDT-SWAP |
| 位置ID(单个) | 获取/api/v5/account/positions?posId=287999792370819074 |
| 位置 ID(多个,最多 20 个) | 获取/api/v5/account/positions?posId=287999792370819074,289098391880081414 |
与 WebSocket 中的仓位通道不同,只要我们之前已经开仓,并且 REST API 中的参数 posId 中指定了仓位,则无论仓位是否关闭,都会返回该仓位。
填补和职位之间的协调
通过在仓位通道中引入交易ID (tradeId),现在可以协调订单成交(来自订单通道)和仓位。此功能的一个用例是,我们可能希望根据订单成交来推算仓位。
新的订单成交总会伴随一个更新的交易ID,因此我们可以利用这一点来匹配相关的仓位/订单成交,并通过比较交易ID的数量来比较哪个数据更新。
但也存在一些陷阱:
- 并非每个订单更新都可以与仓位更新匹配,因为多个仓位变化可以聚合成一条消息 – 即,仅接收最后一个 tradeId。
- 清算或 ADL 不会生成订单更新(因为订单归系统所有)。
- 因强平或ADL导致的持仓更新不会更新tradeId。
为了正确协调填充和位置,我们需要考虑上述陷阱,除了比较 tradeId 之外,还要比较位置(或利用位置更新时间戳(uTime))。
让我们看一下以下示例序列。假设所有交易都使用相同的工具,相同的保证金模式,并且仓位处于净额模式。
| 序列号 | 渠道 | 数据 | 和解立场 |
| 1 | 命令 | fillSz=20,方向=买入,tradeId=150 | 20 |
| 2 | 职位 | pos=20,tradeId=150,uTime=1614859751636 | 20 |
| 3 | 职位 | pos=18,tradeId=151,uTime=1614859752637 | 18 |
| 4 | 命令 | fillSz=2,卖出方向,tradeId=151 | 18 |
| 5 | 命令 | fillSz=3,方向=卖出,tradeId=156 | 15 |
| 6 | 命令 | fillSz=1,方向=卖出,tradeId=158 | 14 |
| 7 | 职位 | pos=10,tradeId=163,uTime=1614859755037 | 10 |
| 8 | 命令 | fillSz=1,方向=卖出,tradeId=159 | 10 |
| 9 | 命令 | fillSz=3,方向=卖出,tradeId=163 | 10 |
| 10 | 职位 | pos=10,tradeId=163,uTime=1614859755037 | 10 |
| 11 | 职位 | pos=6,tradeId=163,uTime=1614866547430 | 6 |
我们可以观察到:
- 我们收到 tradeId=163 的单个仓位更新 #7,这意味着在核对仓位时可以忽略 tradeId<=163 的订单更新 — — 即,在这种情况下忽略订单更新 #8 和 #9。
- 仓位更新 #10 具有与 #7 相同的 tradeId 和 pos(以及 uTime),我们可以假设 #10 来自固定间隔内的固定时间更新。
- 头寸更新#11 具有相同的 tradeId=163 但不同的头寸(和较新的 uTime),我们可以假设这是由部分清算或 ADL 触发的。
在本指南中,我们介绍了 API v5 中的变更以及如何使用它来配置账户和子账户。我们还展示了交易者如何使用 WebSocket 检索账户和仓位数据,以及如何进行交易和对账。
随着 OKX 统一账户交易系统的持续升级,本文档中的具体内容可能会有所变更。请参阅 API v5 文档以获取最新规范。