导航
V3
V5
English

产品配置

用户可以通过 GET /api/v5/public/instruments 获取交易所的产品配置。

后续的产品更新,例如最小变动价位变化、新上市,将通过websocket 产品 频道发布。

市场数据

用户能够从websocket频道接收实时的市场数据更新。

bbo-tbtbooks5是每10毫秒和100毫秒发布一次的深度快照。当订单簿没有变化时,系统不会发送新的快照。

booksbooks-l2-tbtbooks50-l2-tbt是增量订单簿频道,books每100毫秒发布订单簿的变化,books-l2-tbtbooks50-l2-tbt每10毫秒发布订单簿的变化。为使用books-l2-tbtbooks50-l2-tbt,用户需要在订阅之前登录,该功能分别限制VIP5或VIP4以上用户使用。

在系统内部,订单簿数据每10毫秒被创建一次,并根据用户订阅的频道发送相关数据。用户从所有websocket连接和频道接收到的订单簿数据都是相同的。

如果深度在间隔期间发生了如A->B->A一样的改变,则不会发送更新。如果订单簿长时间没有更新,快照频道会重推订单簿数据,增量订单簿频道会推送没有更新的信息,以通知用户连接仍处于活动状态。

订单管理

交易模式

交易账户交易系统的全仓/逐仓设置更为弹性,用户可以同时以全仓和逐仓交易同一产品。因此,用户需要在下单时指定该订单的交易模式(tdMode字段)。

各种情景下tdMode所需的值:

持仓模式 产品类型 交易模式(tdMode)
现货模式 币币 cash

订阅订单频道

下单前,用户应先使用 WebSocket 订阅 订单 频道,这样才能够监察订单状态(如等待成交、完全成交)和作出相应的操作(如在完全成交后下新单)。

订单频道提供多种维度的订阅。要订阅以上 BTC-JPY 订单的数据,用户可在连接到和登入私有 WebSocket 后,传送下表任一请求:

产品类型 产品类型 + 产品 ID
请求 {
  "op": "subscribe",
  "args": [
    {
      "channel": "orders",
      "instType": "SPOT"
    }
  ]
}
{
  "op": "subscribe",
  "args": [
    {
      "channel": "orders",
      "instType": "SPOT",
      "instId": "BTC"
    }
  ]
}
成功返回 {
  "event": "subscribe",
  "arg": {
    "channel": "orders",
    "instType": "SPOT"
  }
}
{
  "event": "subscribe",
  "args": [
    {
      "channel": "orders",
      "instType": "SPOT",
      "instId": "BTC"
    }
  ]
}

注:订单频道不设首次订阅全量数据推送,只会在订单状态改变时(如由等待成交到撤单成功)推送该订单的更新。

换言之,用户无法在订阅订单频道时得知当时的订单数据。要获取订阅订单频道前未完成订单的数据,可通过以下的 REST API 查看:

GET /api/v5/trade/orders-pending

下单

为了系统能够更容易地识别订单,我们建议用户在下单时填上客户自定义订单 ID(clOrdId字段)。客户自定义订单 ID 需由字母与数字组成,区分大小写,最长 32 位。

cloOrdId唯一性检查仅适用于所有挂单,但我们扔推荐用户始终使用唯一的cloOrdId以便于故障排除等工作。

此示例我们会在clOrdId字段填上 testBTC0123

在订阅订单频道后,用户便可以准备 BTC-JPY 订单的下单。

用户可通过 REST 和 WebSocket 去下单。

REST API

用户可以通过以下的 REST API 下单,服务器收到请求后会返回订单 ID(ordId)。

REST API POST /api/v5/trade/order
请求体 {
  "instId": "BTC-JPY",
  "tdMode": "cash",
  "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 更有效率及节约资源。

由于 WebSocket 操作为异步通信,用户需要提供信息 ID(id)以便识别其返回。

于私有 WebSocket 登录后,传送以下 WebSocket 信息:

{
  "id": "NEWtestBTC0123",
  "op": "order",
  "args": [
    {
      "instId": "BTC-JPY",
      "tdMode": "cash",
      "clOrdId": "testBTC0123",
      "side": "buy",
      "ordType": "limit",
      "px": "50912.4",
      "sz": "1"
    }
  ]
}

服务器收到请求后,会连同信息 ID(即 NEWtestBTC012)返回结果,并附上交易所指派的订单 ID(ordId):

{
  "id": "NEWtestBTC0123",
  "op": "order",
  "data": [
    {
      "clOrdId": "",
      "ordId": "288981657420439575",
      "tag": "",
      "sCode": "0",
      "sMsg": ""
    }
  ],
  "code": "0",
  "msg": ""
}

注:这只代表交易所已成功收取请求,并把订单 ID 指派到该订单。此时订单有可能还没到撮合系统,用户需要进一步检查订单状态去确认。

检查订单状态

下单后,若订单未返回任何错误 ("sCode": "0")。用户会在 WebSocket 订单频道收到该订单状态为live的信息。

信息示例(以产品类型 + 产品 ID 维度订阅订单频道):

{
  "arg": {
    "channel": "orders",
    "instType": "SPOT",
    "instId": "BTC-JPY",
    "uid": "614488474791936"
  },
  "data": [
    {
      "accFillSz": "0",
      "algoClOrdId": "",
      "algoId": "",
      "amendResult": "",
      "amendSource": "",
      "avgPx": "",
      "cancelSource": "",
      "category": "normal",
      "clOrdId": "testBTC0123",
      "code": "0",
      "cTime": "1615170596148",
      "execType": "",
      "fee": "0",
      "feeCcy": "BTC",
      "fillFee": "0",
      "fillFeeCcy": "BTC",
      "fillPx": "",
      "fillSz": "0",
      "fillTime": "",
      "instId": "BTC-JPY",
      "instType": "SPOT",
      "msg": "",
      "ordId": "288981657420439575",
      "ordType": "limit",
      "px": "50912.4",
      "rebate": "0",
      "rebateCcy": "JPY",
      "reqId": "",
      "side": "buy",
      "attachAlgoClOrdId": "",
      "slOrdPx": "",
      "slTriggerPx": "",
      "slTriggerPxType": "last",
      "source": "",
      "state": "live",
      "sz": "1",
      "tag": "",
      "tdMode": "cash",
      "tgtCcy": "",
      "tpOrdPx": "",
      "tpTriggerPx": "",
      "tpTriggerPxType": "last",
      "attachAlgoOrds": [],
      "tradeId": "",
      "lastPx": "",
      "uTime": "1615170596148",
      "isTpLimit": "false",
      "linkedAlgoOrd": {"algoId": ""}
    }
  ]
}

订单完全成交后,用户会收到以下的推送信息示例,订单状态变更为filled,并填上其他有关成交的字段。

如果订单部分或全部成交,websocket将分别返回 state = partially_filled and filled

对于立即成交并取消剩余(IOC)、全部成交或立即取消(FOK)以及仅挂单的订单(post only),这些订单可能会被撮合引擎拒绝,用户将收到live然后是canceled的状态。

用户订单可能会由于各种原因被系统取消,例如清算或自成交。用户可以参考 cancelSource 以确定订单被取消的原因。

一个订单的终止状态为canceledfilled

订单的每一笔成交都会被系统赋予一个成交 ID (tradeId),用于与持仓对账。

{
  "arg": {
    "channel": "orders",
    "instType": "SPOT",
    "instId": "BTC-JPY",
    "uid": "614488474791936"
  },
  "data": [
    {
      "accFillSz": "1",
      "algoClOrdId": "",
      "algoId": "",
      "amendResult": "",
      "amendSource": "",
      "avgPx": "50912.4",
      "cancelSource": "",
      "category": "normal",
      "clOrdId": "testBTC0123",
      "code": "0",
      "cTime": "1615170596148",
      "execType": "M",
      "fee": "-0.001",
      "feeCcy": "BTC",
      "fillFee": "-0.001",
      "fillFeeCcy": "BTC",
      "fillPx": "50912.4",
      "fillSz": "1",
      "fillTime": "1615170598021",
      "instId": "BTC-JPY",
      "instType": "SPOT",
      "msg": "",
      "ordId": "288981657420439575",
      "ordType": "limit",
      "px": "50912.4",
      "rebate": "0",
      "rebateCcy": "JPY",
      "reqId": "",
      "side": "buy",
      "attachAlgoClOrdId": "",
      "slOrdPx": "",
      "slTriggerPx": "",
      "slTriggerPxType": "last",
      "source": "",
      "state": "filled",
      "sz": "1",
      "tag": "",
      "tdMode": "cash",
      "tgtCcy": "",
      "tpOrdPx": "",
      "tpTriggerPx": "",
      "tpTriggerPxType": "last",
      "attachAlgoOrds": [],
      "tradeId": "60477021",
      "lastPx": "50912.4",
      "uTime": "1615170598021",
      "isTpLimit": "false",
      "linkedAlgoOrd": {"algoId": ""}
    }
  ]
}

可能的订单状态:

  1. 在入口处被拒绝,sCode不为零,websocket订单频道无更新推送
  2. 下单并立即全部成交: live -> filled
  3. 下单并立即通过多笔交易成交: live -> partially_filled -> ... -> filled
  4. 下单但立即被撮合引擎取消(如 IOC、FOK、仅挂单): live -> canceled (取消原因可从 cancelSource 查询)
  5. 下单为 IOC,部分成交后因价格深度不足而被系统取消: live -> partially_filled -> canceled

改单

改单接口支持所有产品类型的改单,允许用户修改订单的价格(newPx字段)和/或数量(newSz字段)。另外 API 也提供cxlOnFail参数,设置订单修改失败时自动撤单的操作。

REST:

POST /api/v5/trade/amend-order

WebSocket 业务操作请求参数:

"op": "amend-order"

与下单相似,用户应会收到服务器相应 REST / WebSocket 的成功返回,然后于 WebSocket 订单频道收到已填上amendResult字段的订单推送更新。

注:订单完全成交或撤单已成功时不能改单。

成功响应仅表示交易所已收到该请求,用户应参考websocket订单频道以进行确认。

撤单

用户可以以类似的方式,通过 REST 或 WebSocket 撤单。

REST:

POST /api/v5/trade/cancel-order

WebSocket 业务操作请求参数:

"op": "cancel-order"

同样,用户应会收到服务器相应 REST / WebSocket 的成功返回。当用户从 WebSocket 订单频道收到订单状态为 canceled 的推送更新时,才代表订单撤单成功。

注:订单完全成交或撤单已成功时不能撤单。

成功响应仅表示交易所已收到该请求,用户应参考websocket订单频道以进行确认。

批量操作

下单、改单、撤单均支持批量操作,每次最多 20 张订单。批量操作的订单可包括不同的产品类型。

REST:

下单 POST /api/v5/trade/batch-orders
改单 POST /api/v5/trade/amend-batch-orders
撤单 POST /api/v5/trade/cancel-batch-orders

WebSocket 业务操作请求参数:

下单 "op": "batch-orders"
改单 "op": "batch-amend-orders"
撤单 "op": "batch-cancel-orders"

批量操作容许部分订单操作成功。在收到返回后,用户应检查返回结果内每个订单的sCodesMsg字段来判段订单的执行结果。

订单时间戳

订单数据中有多个时间戳,供用户跟踪订单状态和延迟。

cTime 是订单管理系统在风险检查后的订单创建时间。
uTime 是订单管理系统最后一次更新订单的时间。在订单修改、成交和取消后进行更新。
fillTime 是订单成交的时间。fillTime 与公共交易数据的时间相同。
inTime 是 WebSocket / REST 网关接收请求时的时间戳。REST接口返回的时间是请求验证后的时间。
outTime 是 WebSocket / REST 网关发送响应时的时间戳。

分页

okj提供分页功能,以帮助用户从海量数据中轻松获得他们想要的数据。相关的请求参数如下:

参数名 类型 是否必须 描述
before String 请求此ID之后(更新的数据)的分页内容,传的值为对应接口的ordId, billId, tradeId, ts etc.
after String 请求此ID之前(更旧的数据)的分页内容,传的值为对应接口的ordId, billId, tradeId, ts etc.
limit String 返回结果的数量,最大为100,默认100条

请参阅以下功能提示及示例,以便更好地理解该功能。假设原始数据为 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]。

提示 示例
无论用户如何输入请求参数,总是返回最新数据 我们总是在最开始返回新数据,例如 [10, 9, 8, 7, ...]
分页时,不包含before以及after 若 before=6,after=10,返回的数据将会是 [9, 8, 7]
若before及after之间的数据量超过limit,返回靠近after的数据记录 若 before=2,after=9,limit=3,返回的数据将会是 [8, 7, 6]
若仅传入before,不传入after,靠近before的数据将被返回 若 before=6,limit=3,返回的数据将会是 [9, 8, 7]

该功能不适用于仓位历史接口,相同参数,仓位历史接口将返回 [10, 9, 8],不靠近before返回


为了获取特定时间范围内的数据,我们还提供了时间戳过滤功能,应用于before/after已被用于ID分页的场景。请求参数如下:

参数名 类型 是否必须 描述
begin String No 筛选的开始时间戳,Unix 时间戳为毫秒数格式,如 1597026383085
end String No 筛选的结束时间戳,Unix 时间戳为毫秒数格式,如 1597027383085
limit String No 分页返回的结果集数量,最大为100,不填默认返回100条

begin/end的使用方法与before/after略有不同。

提示 示例
过滤时间戳时,包含begin以及end 若 begin=6,end=10,返回的数据将会是 [10, 9, 8, 7, 6]
若begin及end之间的数据量超过limit,返回靠近end的数据记录。
若仅传入begin,不传入end,靠近begin的数据将被返回
若 begin=6,limit=3,返回的数据将会是 [8, 7, 6]

该功能不适用于成交明细接口,相同参数,成交明细接口将返回[10, 9, 8],不靠近begin返回。


若begin/end以及before/after被同时传入,我们将先根据begin/end进行时间戳过滤,并根据before/after对结果进行分页。


拥有分页功能的交易接口罗列如下。

自成交保护

交易系统会以母账户维度实施强制自成交保护,同一母账户下所有账户,包括母账户本身和所有子账户,都无法进行自成交。订单的默认STP模式为Cancel Maker

自成交保护模式

取消maker单

这是默认的 STP 模式。为防止自成交,maker单将被取消,然后taker单将继续与深度中的下一个订单成交。

交易账户和持仓

账户

WebSocket 订阅

我们建议使用 WebSocket 订阅 账户 频道收取账户更新。账户频道设有可选参数ccy,让用户可以仅收取指定账户币种的信息。

该端点返回用户以美元为单元的资产价值,以及其他由于标识价格变化而持续更新的参数。OKJ在估值变化时定期向用户发送更新数据。

连接到私有 WebScoket 和登入后的请求和返回示例:

账户 账户(仅指定的币种)
请求 {
  "op": "subscribe",
  "args": [
    {
      "channel": "account"
    }
  ]
}
{
  "op": "subscribe",
  "args": [
    {
      "channel": "account",
      "ccy": "BTC"
    }
  ]
}
成功返回 {
  "event": "subscribe",
  "arg": {
    "channel": "account"
  }
}
{
  "event": "subscribe",
  "arg": {
    "channel": "account",
    "ccy": "BTC"
  }
}

首次订阅全量数据

与订单频道不同,账户频道首次订阅会推送全量数据,推送币种层面资产不为 0 的账户信息。币种层面资产不为 0 指币种总权益(eq)、可用保证金(availEq)、可用余额(availBal)任一字段不为 0。

假设账户的 BTC 和 JPY 币种层面资产不为 0,用户应收到账户频道以下的信息示例:

账户 账户(仅指定的币种)
{
  "arg": {
    "channel": "account"
  },
  "data": [
    {
      "adjEq": "30979.1086748182657014",
      "details": [
        {
          "availBal": "",
          "availEq": "18962.59868274799",
          "ccy": "JPY",
          "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",
          "interest": "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": "account",
    "ccy": "BTC"
  },
  "data": [
    {
      "adjEq": "30979.1086748182657014",
      "details": [
        {
          "availBal": "",
          "availEq": "0",
          "ccy": "BTC",
          "crossLiab": "0.509575622217854",
          "disEq": "-25408.4180739947324516",
          "eq": "-0.5096053466363398",
          "frozenBal": "0",
          "interest": "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"
    }
  ]
}

后续推送

之后,用户会根据以下情况收到账户数据推送:

事件触发推送 下单、撤单等事件会触发推送。多项事件(如同时间有多个订单成交)有可能会聚合成单个账户信息推送。仅推送受事件变更的币种,包括币种资产变为 0。
定时推送 定时推送,目前为每 5 秒推送一次。与首次订阅一样,推送全量数据,即推送所有币种(或ccy参数指定的币种)层面资产不为 0 的账户信息。

REST API

用户亦可以通过 REST API 查看币种层面资产不为 0 的账户余额:

GET /api/v5/account/balance

REST API 亦提供可选参数ccy,支持单个币种(如BTC)或多个以逗号分隔的币种(如 BTC,JPY,ETH)查询,最多 20 个。

示例:

GET /api/v5/account/balance?ccy=BTC,JPY,ETH

当用户于ccy参数指定币种时,无论该币种层面资产是否为 0,REST API 均会返回该币种的数据,与 WebSocket 账户频道不同。这只适用于曾经持有的币种。

最大可用数量

用户可以轮询以下的 REST API 得知最大可用数量(包括可用余额和交易所的最大可借):

GET /api/v5/account/max-avail-size

BTC-JPY 全仓的请求和返回示例:

请求 GET /api/v5/account/max-avail-size?instId=BTC-JPY&tdMode=cash
成功返回 {
  "code": "0",
  "data": [
    {
      "availBuy": "213800.4239369798722052",
      "availSell": "1.3539405224369181",
      "instId": "BTC-JPY"
    }
  ],
  "msg": ""
}

币币的availBuy为计价货币,availSell为交易货币。

以上的返回结果表示 BTC-JPY 最大买入可用数量为 213,800.42 JPY,最大卖出可用数量为 1.35394052 BTC。这应与网页上交易时显示的数量一样。

最大可转余额

为了获得交易账户或是某个子账户的最大可转余额,用户可以通过 GET /api/v5/account/max-withdrawal 获取余额。

此端点返回的数据考虑了未偿还的贷款和使用中的保证金。

余额和持仓

当特定事件(如订单成交、资金转移)被触发时,数据将被推送。

账户余额和持仓频道适用于获取账户余额和仓位资产的变化。

如果用户拥有了太多货币,且数据太大以至于无法在单个推送中发送,它将被拆分为多个消息。

在账户余额和持仓发生变化时,与账户频道和持仓频道相比,此频道的字段较少,以便以最低延迟将更改推送给客户。

标识符

标识符 描述
ordId 订单ID,全局唯一
clOrdId 客户自定义订单ID,所有交易产品挂单维度唯一
billId 账单ID,全局唯一
tradeId 最新成交ID,交易产品维度唯一
在强平、自动减仓场景下,tradeId字段的值为负数,以便和其他撮合成交场景区分