引言
欧易在推出统一账户交易系统的同时,亦把 API 由 V3 升级到了 V5,带来了更多和更完善的功能。在第 1 部分,我们讲解了 V5 API 相对于 V3 API 有什么改动和交易前设置账户时的技巧和诀窍。这次,我们会讲解在使用 V5 API 交易时有哪些技巧和诀窍。
交易
交易模式
欧易统一账户交易系统的全仓/逐仓设置更为弹性,我们可以同时以全仓和逐仓交易同一产品。因此,我们需要在下单时指定该订单的交易模式(tdMode 字段)。
各种情景下 tdMode 所需的值:
我们亦可以把 instType 参数填上 ANY,一次性订阅所有产品类型的订单更新。
注:订单频道不设首次订阅全量数据推送,只会在订单状态改变时(如由等待成交到撤单成功)推送该订单的更新。
换言之,我们无法在订阅订单频道时得知当时的订单数据。要获取订阅订单频道前未完成订单的数据,可通过以下的 REST API 查看:
GET /api/v5/trade/orders-pending |
下单
在订阅订单频道后,我们便可以准备 BTC-USDT-SWAP 订单的下单。
V5 API 提供 REST 和 WebSocket 两种协议去下单。
REST
我们可以通过以下的 REST API 下单,服务器收到请求后会返回订单 ID(ordId 字段)。
服务器收到请求后,会连同信息 ID(即 NEWtestBTC012)返回结果,并附上交易所指派的订单 ID(ordId 字段):
订单完全成交后,我们会收到以下的推送信息示例,订单状态变更为“filled”,并填上其他有关成交的字段。
信息还会附上最新成交 ID (tradeId 字段)。这字段可用于与持仓对账,会在稍后的章节讲解。
首次订阅全量数据
与订单频道不同,账户频道首次订阅会推送全量数据,推送币种层面资产不为 0 的账户信息。币种层面资产不为 0 指币种总权益(eq 字段)、可用保证金(availEq 字段)、可用余额(availBal 字段)任一字段不为 0。
假设账户的 BTC 和 USDT 币种层面资产不为 0,而账户模式为跨币种保证金模式,我们应收到账户频道以下的信息示例:
币币的 availBuy 为计价货币,availSell 为交易货币。
以上的返回结果表示 BTC-USDT 最大买入可用数量为 213,800.42 USDT,最大卖出可用数量为 1.35394052 BTC。这应与网页上交易时显示的数量一样。
持仓
V5 API 下所有产品也共用统一的持仓 API。我们建议您使用 WebSocket 获取持仓信息更新。
WebSocket 订阅
与订单频道类似,V5 API 的持仓频道提供多种维度的订阅。
要订阅以上 BTC-USDT-SWAP 持仓的数据,我们可在连接到和登入私有 WebSocket 后,传送下表任一请求:
后续推送
之后,与账户频道相似,我们会根据以下情况收到持仓数据推送:
事件触发推送 | 开仓、平仓等事件会触发推送。多项事件(如同时间有多个订单成交)有可能会聚合成单个持仓信息推送。 仅推送受事件变更的持仓,包括平仓(即持仓数量变为 0)。 |
定时推送 | 定时推送,目前为每 10 秒推送一次。 与首次订阅一样,推送全量数据,即推送订阅维度上指定的所有不为 0 的持仓。 |
持仓 ID
您可能会发现每项持仓数据均设有持仓 ID 字段(posId)。这字段可以用作填写 REST API 可选查询参数,会在下一章节讲解。
持仓 ID 由 mgnMode + posSide + instId + ccy 这几个字段所产生,可让您唯一地识别同一个账户内的持仓。持仓 ID 不会因平仓及再开仓而变动。
REST
我们亦可以通过 REST API 查看持仓数量不为 0 的持仓信息:
GET /api/v5/account/positions |
REST API 提供以下维度查询:
维度 | 示例 |
产品类型 | GET /api/v5/account/positions?instType=SWAP |
产品 ID | GET /api/v5/account/positions?instId=BTC-USDT-SWAP |
持仓 ID(单个) | GET /api/v5/account/positions?posId=287999792370819074 |
持仓 ID(多个,最多 20 个) | GET /api/v5/account/positions?posId=287999792370819074,289098391880081414 |
值得一提的是,当我们于 posId 参数指定持仓时,无论持仓是否已平仓,REST API 均会返回该持仓的数据,与 WebSocket 持仓频道不同。这只适用于曾经开仓的持仓。
订单成交推送与持仓的对账
运用持仓频道新增的最新成交 ID (tradeId 字段),我们可以进行订单频道成交推送与持仓的对账。这样做法其中一个案例就是我们想从订单成交推算出现有的持仓数量。
新的订单成交均会指派较新的成交 ID。利用这一特性,我们可用成交 ID 匹配相应的持仓/订单成交,并以成交 ID 的数字比较哪项数据较新。
不过,我们需要注意下列事项:
- 多个持仓变化有可能会聚合成单个持仓信息推送,即持仓信息只有最新的成交 ID,并非每一个订单成交更新均能与持仓信息匹配
- 强平/强减或 ADL 不会推送订单更新(因订单为系统所拥有)
- 因强平/强减或 ADL 而触发的持仓更新不会更新 tradeId
要准确地进行订单成交推送与持仓的对账,我们必需考虑以上的注意事项,除比较 tradeId 外还需比较持仓数量(或比较持仓更新时间 uTime 字段)。
我们来看看以下的推送序列示例。假设下列都是同样产品及同样保证金模式的数据,持仓模式为单向持仓。
序列 | 频道 | 数据 | 对账后的持仓 |
1 | order (订单) | fillSz=20, side=buy, tradeId=150 | 20 |
2 | positions (持仓) | pos=20, tradeId=150, uTime=1614859751636 | 20 |
3 | positions (持仓) | pos=18, tradeId=151, uTime=1614859752637 | 18 |
4 | order (订单) | fillSz=2, side=sell, tradeId=151 | 18 |
5 | order (订单) | fillSz=3, side=sell, tradeId=156 | 15 |
6 | order (订单) | fillSz=1, side=sell, tradeId=158 | 14 |
7 | positions (持仓) | pos=10, tradeId=163, uTime=1614859755037 | 10 |
8 | order (订单) | fillSz=1, side=sell, tradeId=159 | 10 |
9 | order (订单) | fillSz=3, side=sell, tradeId=163 | 10 |
10 | positions (持仓) | pos=10, tradeId=163, uTime=1614859755037 | 10 |
11 | positions (持仓) | pos=6, tradeId=163, uTime=1614866547430 | 6 |
从中观察,我们得知:
- 收到 tradeId=163 的单个持仓推送 #7,即代表与持仓对账时,可忽略 tradeId<=163 的订单推送。换言之,我们可忽略订单推送 #8 和 #9
- 持仓推送 #10 与 #7 的 tradeId 和 pos(和 uTime)一样,这表示我们可以认为 #10 为持仓每 10 秒的定时推送
- 持仓推送 #11 具同样的 tradeId=163 但持仓数量有变化(uTime 也较新),我们可推断这推送是由强减或 ADL 触发
总结
在这篇文章中我们学习了如何使用 V5 API 交易,在订阅订单频道后通过 REST 或 WebSocket 进行订单操作。
我们亦从本文理解了如何使用 WebSocket 订阅账户和持仓数据,接收首次订阅全量数据,及事件解发推送和定时推送更新。
在跨币种保证金账户模式启用自动借币的情况下,我们可通过 REST API 获取产品的最大可用数量。
最后,本文亦讲解了如何使用成交 ID(tradeId 字段),进行订单成交推送与持仓的对账。
希望这些技巧和诀窍能够令您更了解 V5 API,让您在 欧易 统一账户交易系统中更得心应手!
由于 欧易 会持续不断地改进统一账户交易系统,上文提到的这些想法均会随之发生变动。请查阅 V5 API 文档以得知最新的规范:做市商申请