Skip to main content
用户推送投递你账户范围内的更新(订单、成交、取消)。

消息

用户推送将每条更新作为裸 JSON 对象发送(无元组包装)。所有更新共用同一结构;动作由 unmatched / matched 哪个被填充以及 origin 决定。

通用结构

messageID 是 streaming-api 在发送前添加的流条目 id。请持久化你已处理的最新一条 — 它就是你的回放游标。参见下方回放错过的消息。

matched 块

只要更新表示一笔成交(matched != null),就会出现该块。除非标明为有条件,下列每个字段都会在每笔成交上发送。所有取值都从你的视角出发 — 作为 taker 你看到自己吃到的方向,作为 maker 你看到自己挂出的方向。
不要用 risk 推导 win。 risk 和 win 各自从未经四舍五入的本金独立保留到 2 位小数,因此 risk x odds 可能与 win 相差一分钱。请按下发的 win 入账;若该字段缺失,应将消息视为格式错误,而不是自行重建。不要把 amount 当作 risk 的同义词。 在 taker 成交上,amount 不含亏损时收取的佣金,而 risk 包含它。把 amount 当作风险金额入账,会在每次吃单时少计佣金。
REST 上的相同数量(获取已撮合投注)以保留 2 位小数的字符串而非数字给出,且佣金与舍入顺序略有不同。对账时请允许一分钱的容差,不要要求精确相等。

unmatched 块

只要更新涉及留在(或离开)订单簿的订单 — 下单、取消,以及成交的 maker 一侧 — 就会出现该块。赔率和方向来自 maker 视角,即你挂出的内容,而不是订单簿向他人展示的报价。
filled 和 remaining 不是同一类数字。remaining 是运行时状态 — 此刻订单簿上还剩多少 — 但在成交上 filled 只描述该事件。跨多笔部分成交时它们不会相加:filled + remaining 在第一笔成交时等于 offered,之后会逐渐偏离。要跟踪一笔挂单已成交多少,请使用 offered - remaining,或自行累加 filled。不要把两者混用。

如何识别动作

  • unmatched.filled === 0 && unmatched.offered > 0 -> 已下单
  • unmatched.offered === 0 -> 已取消
  • matched != null && unmatched == null -> 作为 taker 成交
  • matched != null && unmatched != null -> 作为 maker 成交(若 unmatched.remaining > 0 则为部分成交)
以 orderType: "postArb" 下的订单,其更新还会在 matched / unmatched 内带有 isPostArb: true(下单、成交和取消更新均如此);否则省略该字段。

按投注类型区分的 side 与 market 语义

matched / unmatched 内 side 的含义(以及会出现哪些额外字段)取决于 type: market 仅出现在 moneyline1x2 更新中:它指明该盘口所针对的三项结果(主队、客队或平局),side 则表示对该结果是 yes 还是 no。所有字段都从你的视角出发 — 作为 maker 你看到自己挂出的方向;作为 taker 你看到自己吃到的方向。

动作:已下单

一笔新挂单进入订单簿。unmatched.filled 为 0,unmatched.offered > 0,且 matched 为 null。

动作:已取消

用户(或系统代其)取消了一笔挂单。区分字段是 unmatched.offered === 0。

动作:订单成交(taker)

用户吃掉了他人的挂单。unmatched 为 null,matched 携带成交,origin 为 "wager"。

动作:订单成交(maker,部分成交)

有人吃到了用户挂出的报价。matched 和 unmatched 均被填充;unmatched.remaining 显示订单簿上仍剩余的数量。因为设置了 unmatched,origin 为 "offer"。

动作:订单成交(moneyline1x2)

足球三项盘上的成交携带上文所述的 market + side 组合,而不是参赛者十六进制 side。此处用户以 +120 吃了主队的 “yes”(投注阿森纳获胜):
注意同一笔成交的两个视角:taker 看到同一 market 上 side: "yes"、赔率 +120,maker 看到 side: "no"、赔率 -120。

回放错过的消息

v2 用户推送支持连接中断后的缺口恢复。每条消息都带有 messageID(单调递增的流条目 id,例如 "1751552702114-0")。若连接断开,你可以精确拉取错过的消息。

接口

鉴权方式与 WebSocket 相同:在 Authorization 请求头、Auth 请求头或 token 查询参数中携带 token。仅返回属于已鉴权用户的消息。

响应:success

你的 afterID 仍在保留历史中,因此返回的列表是完整的缺口填充 — afterID 与 beforeID 之间没有任何丢失:
按顺序应用这些消息,然后继续处理实时消息。

响应:cache_expired

你的 afterID 已超出保留历史,因此服务器无法证明回放是完整的:
availableMessages 是仍被保留的内容,最旧的在前。超出保留窗口的更早消息无法通过回放恢复 — 请及时重连,而不要依赖过长的回看。

示例:带回放的重连客户端

完整的 Node.js 客户端(为简洁起见省略 keepalive ping/pong — 参见本页顶部的快速入门)。正确性依赖两点:每条消息 — 实时、缓冲或回放 — 都经过同一套只向前推进的游标检查;回放失败时重连,而不是带着缺口进入实时。