Bitget APIBitget API
统一账户经典账户
旧文档
  • 概览
  • API 文档
  • WebSocket
  • Agent Hub
  • SDK
  • 更新日志
Copied to clipboard
Websocket
公共频道
私有频道
Reality
SBE
    SBE 基本信息SBE BBO 接入指南SBE Level 50 接入指南SBE Public Trade 接入指南
SBE

SBE Public Trade 接入指南

总览

字段说明
TopicpublicTrade
TemplateId1003
FormatSBE 二进制 frame (opcode = 2), little-endian
Units时间戳为 microseconds (µs) ,但是仅精确到毫秒。毫秒时间加上 000 得到微秒格式时间。比如:毫秒时间 1726233600001 对应的微秒格式时间 (µs) 为 1726233600001000
推送内容平台公开成交记录(批量推送,一帧可包含多笔成交)
更新频率实时

连接

  • WebSocket URL: wss://ws.bitget.com/v3/ws/public/sbe
  • 心跳: 每 30 秒发送文本帧 "ping", 服务端返回 "pong"
  • 报文机制: 订阅阶段使用 JSON 文本帧;行情推送阶段使用 SBE 二进制帧,通过 WebSocket opCode 区分(opCode=1 文本, opCode=2 二进制)

订阅流程

1. 发送订阅请求

Code
{ "op": "subscribe", "args": [ { "instType": "usdt-futures", "topic": "publicTrade", "symbol": "BTCUSDT" } ] }

参数说明:

参数类型说明
instTypestring产品类型: spot
usdt-futures
usdc-futures
coin-futures
topicstring固定值: publicTrade
symbolstring交易对, 如 BTCUSDT, ETHUSDT

2. 订阅确认

Code
{ "event": "subscribe", "arg": { "instType": "usdt-futures", "topic": "publicTrade", "symbol": "BTCUSDT" } }

3. 接收数据

订阅确认后, 每次有成交即实时推送 SBE 二进制帧。单帧可包含多笔成交(batch)。

4. 取消订阅

Code
{ "op": "unsubscribe", "args": [ { "instType": "usdt-futures", "topic": "publicTrade", "symbol": "BTCUSDT" } ] }

SBE 消息结构

价格/数量计算公式

Code
实际值 = mantissa × 10^exponent

示例: 尾数为 123456,指数为 -4,表示 12.3456(实际值 = 尾数 × 10 ^ 指数)

公共消息头 (8 bytes)

所有 SBE 消息必须包含固定 8 字节的头部,以便解析识别后续数据。

字段名类型 (Type)长度 (Byte)说明
blockLengthuint162Root 块长度
templateIduint162频道唯一标识,固定值 = 1003
schemaIduint162Schema ID
versionuint162Schema 版本

消息字段定义

Root block

id字段名类型说明
-messageHeaderComposite固定头部
1priceExponentint8价格指数
2sizeExponentint8数量指数
100paddinguint8填充字节

Group: trades (id=200)

id字段名类型说明
1tsuint64撮合引擎时间戳
µs 微秒时间戳,但是仅精确到毫秒。毫秒时间加上 000 得到微秒格式时间。比如:毫秒时间 1726233600001 对应的微秒格式时间 (µs) 为 1726233600001000
2execIduint64成交 ID
3priceint64成交价格尾数
4sizeint64成交数量尾数
5sideuint8成交方向,Buy 买入 / Sell 卖出
6isRPIuint8 (BooleanType)零售价格改善标记(Retail Price Improvement flag):T / F(自 schema version 4 起支持)
7stsuint64流服务推送时间戳,微秒(µs)
8categoryuint8业务线:spot 现货 / usdt-futures U本位合约 / coin-futures 币本位合约 / usdc-futures USDC合约
50paddinguint8填充字节

Data

id字段名类型说明
300symbolvarString[8]交易对名称,UTF-8 格式

二进制布局总览

Code
┌─────────────┬─────────────┬──────────────────────────────────────────┬──────────┐ │ Header (8B) │ Root (8B) │ Trades: GrpHdr(4B) + N×40B │ Symbol │ └─────────────┴─────────────┴──────────────────────────────────────────┴──────────┘

单笔成交消息大小: 8 + 8 + 4 + 40 + 1 + len(symbol) = 约 69 字节 N 笔成交消息大小: 8 + 8 + 4 + 40×N + 1 + len(symbol)


成交方向 (tradeSide)

值名称说明
0Buy主动买入(Taker 买方)
1Sell主动卖出(Taker 卖方)

解码示例

原始二进制 (单笔成交, hex)

Code
08 00 EB 03 01 00 04 00 <- header: blockLength=8, templateId=1003, schemaId=1, version=4 FE <- priceExponent = -2 FC <- sizeExponent = -4 00 00 00 00 00 00 <- padding6 28 00 01 00 <- trades group: entryBlockLength=40, numInGroup=1 02 80 C6 A7 86 3E 06 00 <- trades[0].ts (uint64 LE) 0F 27 00 00 00 00 00 00 <- trades[0].execId = 9999 52 39 64 00 00 00 00 00 <- trades[0].price = 6566738 88 13 00 00 00 00 00 00 <- trades[0].size = 5000 00 <- trades[0].side = 0 (Buy) 00 00 00 00 00 00 00 <- padding7 07 42 54 43 55 53 44 54 <- symbol: length=7, "BTCUSDT"

解码后 JSON

Code
{ "header": { "block_length": 8, "template_id": 1003, "schema_id": 1, "version": 4 }, "price_exponent": -2, "size_exponent": -4, "trades": [ { "ts": 1700000000000002, "exec_id": 9999, "price": "65667.38", "size": "0.5000", "side": "Buy", "isRPI": "F", "sts": 1700000000001002, "category": 1 } ], "symbol": "BTCUSDT" }

批量成交解码后 JSON (多笔)

Code
{ "header": { "block_length": 8, "template_id": 1003, "schema_id": 1, "version": 4 }, "price_exponent": -2, "size_exponent": -4, "trades": [ { "ts": 1700000000000002, "exec_id": 10001, "price": "65665.78", "size": "0.5000", "side": "Buy", "isRPI": "F", "sts": 1700000000001002, "category": 1 }, { "ts": 1700000000000003, "exec_id": 10002, "price": "65666.00", "size": "1.2000", "side": "Sell", "isRPI": "T", "sts": 1700000000001003, "category": 1 }, { "ts": 1700000000000004, "exec_id": 10003, "price": "65664.50", "size": "0.3000", "side": "Buy", "isRPI": "F", "sts": 1700000000001004, "category": 1 } ], "symbol": "BTCUSDT" }

Python 接入示例

Code
"""Bitget publicTrade SBE WebSocket 订阅示例""" import asyncio import json import struct from decimal import Decimal import websockets WS_URL = "wss://ws.bitget.com/v3/ws/public/sbe" INST_TYPE = "usdt-futures" SYMBOL = "BTCUSDT" TOPIC = "publicTrade" SIDE_MAP = {0: "Buy", 1: "Sell"} BOOLEAN_MAP = {0: "F", 1: "T"} def decode_trade(data: bytes) -> dict: """解码 Trade (templateId=1003) SBE 帧""" block_length, template_id, schema_id, version = struct.unpack_from('<HHHH', data, 0) assert template_id == 1003, f"unexpected templateId: {template_id}" offset = 8 base = offset price_exp, = struct.unpack_from('<b', data, offset); offset += 1 size_exp, = struct.unpack_from('<b', data, offset); offset += 1 # 跳过 padding,以 blockLength 为准 offset = base + block_length # trades group entry_bl, num = struct.unpack_from('<HH', data, offset); offset += 4 has_is_rpi = version >= 4 # sinceVersion=4:entry 携带 isRPI 字段(entryBlockLength 因 padding 补齐后固定不变,无法用它判断,改用 schema version 判断) to_dec = lambda m, e: Decimal(m) * Decimal(10) ** e trades = [] for _ in range(num): entry_start = offset ts, = struct.unpack_from('<Q', data, offset); offset += 8 exec_id, = struct.unpack_from('<Q', data, offset); offset += 8 price, = struct.unpack_from('<q', data, offset); offset += 8 size, = struct.unpack_from('<q', data, offset); offset += 8 side_raw, = struct.unpack_from('<B', data, offset); offset += 1 if has_is_rpi: is_rpi_raw, = struct.unpack_from('<B', data, offset); offset += 1 sts, = struct.unpack_from('<Q', data, offset); offset += 8 category, = struct.unpack_from('<B', data, offset); offset += 1 # 跳过 padding,以 entry_bl 为准 offset = entry_start + entry_bl trade = { "ts": ts, "exec_id": exec_id, "price": str(to_dec(price, price_exp)), "size": str(to_dec(size, size_exp)), "side": SIDE_MAP.get(side_raw, str(side_raw)), } if has_is_rpi: trade["isRPI"] = BOOLEAN_MAP.get(is_rpi_raw, str(is_rpi_raw)) trade["sts"] = sts trade["category"] = category trades.append(trade) # symbol (varString8) sym_len, = struct.unpack_from('<B', data, offset); offset += 1 symbol = data[offset:offset + sym_len].decode('utf-8') return { "price_exponent": price_exp, "size_exponent": size_exp, "trades": trades, "symbol": symbol, } async def main(): async with websockets.connect(WS_URL) as ws: # 订阅 await ws.send(json.dumps({ "op": "subscribe", "args": [{"instType": INST_TYPE, "topic": TOPIC, "symbol": SYMBOL}] })) print(f"[SUB] {INST_TYPE} {TOPIC} {SYMBOL}") # 心跳 async def ping_loop(): while True: await asyncio.sleep(20) await ws.send("ping") print("[PING] sent") asyncio.create_task(ping_loop()) async for message in ws: if isinstance(message, bytes): try: msg = decode_trade(message) print(f"\n[Trade] {msg['symbol']} ({len(msg['trades'])} trades)") for t in msg['trades']: ts_ms = t['ts'] // 1000 print(f" [{t['side']:4s}] price={t['price']} size={t['size']} " f"ts={ts_ms}ms execId={t['exec_id']}") except Exception as e: print(f"[ERROR] {e} raw={message.hex()}") else: if message == "pong": print("[PONG] received") else: print(f"[TEXT] {message}") if __name__ == "__main__": asyncio.run(main())
SBE Level 50 接入指南
On this page
  • 总览
  • 连接
  • 订阅流程
    • 1. 发送订阅请求
    • 2. 订阅确认
    • 3. 接收数据
    • 4. 取消订阅
  • SBE 消息结构
    • 价格/数量计算公式
    • 公共消息头 (8 bytes)
    • 消息字段定义
    • 二进制布局总览
  • 成交方向 (tradeSide)
  • 解码示例
    • 原始二进制 (单笔成交, hex)
    • 解码后 JSON
    • 批量成交解码后 JSON (多笔)
  • Python 接入示例
JSON
JSON
JSON
Javascript
Javascript
Javascript
Javascript