跳至主要内容

SBE 基本信息

僅限 MMWS / Gateway

本節中所描述的所有基於 SBE 的行情資料頻道,只能透過 Market Maker WebSocket (MMWS) / Market Maker Gateway (GW) 基礎設施使用。

如需接入方式與架構細節,請參考官方公告: 做市商網關

本頁提供 Bybit 基於 SBE 的市場數據 通道在 MMWS/GW 環境中的統一介紹。關於各功能的詳細行為與程式碼範例,請參考以下子頁面:

  • BBO SBE (Level 1, 含 RPI 欄位)
  • Level-50 SBE (50 檔深度訂單簿快照 + 增量更新)
  • PublicTrade SBE (現貨 & 合約)
  • WS下單 SBE (現貨 & 合約 & 期權)

SBE 服務路徑

  • 現貨行情: wss://{MMWS url}/v5/public-sbe/spot
  • USDT/USDC合約行情: wss://{MMWS url}/v5/public-sbe/linear
  • 幣本位合約行情: wss://{MMWS url}/v5/public-sbe/inverse
  • WS下單: wss://{MMWS url}/v5/sbe/trade

什麼是 SBE?

Bybit 採用符合 FIX/SBE 1.0 規範的 Simple Binary Encoding (SBE):

  • 二進位資料, little-endian 編碼
  • 儘可能使用固定長度欄位
  • 明確區分 訊息標頭 (message header)訊息主體 (message body) 佈局
  • 高效率解碼, 適用於高頻交易 (HFT) 與做市策略

與 JSON WebSocket 行情相比, SBE 具備以下優點:

  • 較小的訊息負載 (相較等價 JSON 資料可降低約 30–50%)
  • 決定性的二進位結構
  • 微秒級時間戳精度
  • 在編碼與解碼時皆有較低的 CPU 消耗

SBE 連接數限制

  • 現貨: 每個專屬 MMWS host 限制 1500 條連接.
  • 合約 (linear + inverse): 每個專屬 MMWS host 限制 3000 條連接.
  • 一旦超過連接上限, 新連接會返回 HTTP 429

盤前合約的推送行為

  • 直到ContinuousTrading(連續競價)階段, orderbook 和 publicTrade 數據才會下發

行情 SBE XML Template

<?xml version="1.0" encoding="UTF-8"?>
<sbe:messageSchema xmlns:sbe="http://fixprotocol.io/2016/sbe" xmlns:mbx="https://bybit-exchange.github.io/docs/v5/intro" package="quote.sbe" id="1" version="0" semanticVersion="1.0.0" description="Bybit market data streams SBE message schema" byteOrder="littleEndian" headerType="messageHeader">
<types>
<composite name="messageHeader" description="Template ID and length of message root">
<type name="blockLength" primitiveType="uint16"/>
<type name="templateId" primitiveType="uint16"/>
<type name="schemaId" primitiveType="uint16"/>
<type name="version" primitiveType="uint16"/>
</composite>
<composite name="varString8" description="Variable length UTF-8 string.">
<type name="length" primitiveType="uint8"/>
<type name="varData" length="0" primitiveType="uint8" semanticType="String" characterEncoding="UTF-8"/>
</composite>
<composite name="groupSize16Encoding" description="Repeating group dimensions.">
<type name="blockLength" primitiveType="uint16"/>
<type name="numInGroup" primitiveType="uint16"/>
</composite>
<enum name="pkgTypeEnum" encodingType="uint8">
<validValue name="SNAPSHOT">0</validValue>
<validValue name="DELTA">1</validValue>
</enum>
<enum name="SideType" encodingType="uint8">
<validValue name="UNKNOWN">0</validValue>
<validValue name="BUY">1</validValue>
<validValue name="SELL">2</validValue>
<validValue name="NON_REPRESENTABLE">254</validValue>
</enum>
<enum name="BoolEnum" encodingType="uint8">
<validValue name="FALSE">0</validValue>
<validValue name="TRUE">1</validValue>
<validValue name="NON_REPRESENTABLE">254</validValue>
</enum>
</types>
<!-- Stream event for "ob.rpi.1.sbe.<symbol>" channel -->
<sbe:message name="BestOBRpiEvent" id="20000">
<field id="1" name="ts" type="int64" description="The timestamp in microseconds that the system generates the data"/>
<field id="2" name="seq" type="int64" description="Cross sequence ID"/>
<field id="3" name="cts" type="int64" description="The timestamp in microseconds from the matching engine when this orderbook data is produced."/>
<field id="4" name="u" type="int64" description="Update Id"/>
<field id="5" name="askNormalPrice" type="int64" mbx:exponent="priceExponent" description="Mantissa for the best ask normal price"/>
<field id="6" name="askNormalSize" type="int64" mbx:exponent="sizeExponent" description="Mantissa for the best ask normal size"/>
<field id="7" name="askRpiPrice" type="int64" mbx:exponent="priceExponent" description="Mantissa for the best ask rpi price"/>
<field id="8" name="askRpiSize" type="int64" mbx:exponent="sizeExponent" description="Mantissa for the best ask rpi size"/>
<field id="9" name="bidNormalPrice" type="int64" mbx:exponent="priceExponent" description="Mantissa for the best bid normal price"/>
<field id="10" name="bidNormalSize" type="int64" mbx:exponent="sizeExponent" description="Mantissa for the best bid normal size"/>
<field id="11" name="bidRpiPrice" type="int64" mbx:exponent="priceExponent" description="Mantissa for the best bid rpi price"/>
<field id="12" name="bidRpiSize" type="int64" mbx:exponent="sizeExponent" description="Mantissa for the best bid rpi size"/>
<field id="13" name="priceExponent" type="int8" description="Price exponent for decimal point positioning"/>
<field id="14" name="sizeExponent" type="int8" description="Size exponent for decimal point positioning"/>
<data id="55" name="symbol" type="varString8"/>
</sbe:message>
<!-- Stream event for "ob.50.sbe.<symbol>" channel -->
<sbe:message name="OBL50Event" id="20001">
<field id="1" name="ts" type="int64" description="The timestamp in microseconds that the system generates the data"/>
<field id="2" name="seq" type="int64" description="Cross sequence ID"/>
<field id="3" name="cts" type="int64" description="The timestamp in microseconds from the matching engine when this orderbook data is produced."/>
<field id="4" name="u" type="int64" description="Update Id"/>
<field id="5" name="priceExponent" type="int8" description="Price exponent for decimal point positioning"/>
<field id="6" name="sizeExponent" type="int8" description="Size exponent for decimal point positioning"/>
<field id="7" name="pkgType" type="pkgTypeEnum" description="Package type"/>
<group id="40" name="asks" dimensionType="groupSize16Encoding" description="Sell side order book updates">
<field id="1" name="price" type="int64" description="Price mantissa"/>
<field id="2" name="size" type="int64" description="Size mantissa"/>
</group>
<group id="41" name="bids" dimensionType="groupSize16Encoding" description="Buy side order book updates">
<field id="1" name="price" type="int64" description="Price mantissa"/>
<field id="2" name="size" type="int64" description="Size mantissa"/>
</group>
<data id="55" name="symbol" type="varString8"/>
</sbe:message>
<!-- Stream event for "publicTrade.sbe.<symbol>" channel -->
<sbe:message name="PublicTradeEvent" id="20002">
<field id="1" name="ts" type="int64" description="The timestamp in microseconds that the system generates the data"/>
<field id="2" name="priceExponent" type="int8" description="Price exponent for decimal point positioning"/>
<field id="3" name="sizeExponent" type="int8" description="Size exponent for decimal point positioning"/>
<group id="40" name="tradeItems" dimensionType="groupSize16Encoding" description="trade items">
<field id="1" name="fillTime" type="int64" description="The timestamp in microseconds that the order is filled"/>
<field id="2" name="price" type="int64" description="Price mantissa"/>
<field id="3" name="size" type="int64" description="Size mantissa"/>
<field id="4" name="seq" type="int64" description="Cross sequence ID"/>
<field id="5" name="side" type="SideType" description="Side of taker"/>
<field id="6" name="isBlockTrade" type="BoolEnum" description="Whether it is a block trade order or not"/>
<field id="7" name="isRPI" type="BoolEnum" description="Whether it is a RPI trade or not"/>
<data id="100" name="execId" type="varString8" description="Trade ID"/>
</group>
<data id="55" name="symbol" type="varString8"/>
</sbe:message>
</sbe:messageSchema>

交易 SBE XML Template

<?xml version="1.0" encoding="UTF-8"?>
<sbe:messageSchema xmlns:sbe="http://fixprotocol.io/2016/sbe"
package="order.trading.api.sbe"
id="2"
version="1"
semanticVersion="1.0.0"
description="Order Trading API SBE Schema"
byteOrder="littleEndian">
<types>
<composite name="messageHeader" description="Standard message header">
<type name="blockLength" primitiveType="uint16"/>
<type name="templateId" primitiveType="uint16"/>
<type name="schemaId" primitiveType="uint16"/>
<type name="version" primitiveType="uint16"/>
</composite>
<composite name="groupSize16Encoding" description="Repeating group dimensions">
<type name="blockLength" primitiveType="uint16"/>
<type name="numInGroup" primitiveType="uint16"/>
</composite>
<type name="String8" primitiveType="char" length="8"/>
<type name="String16" primitiveType="char" length="16"/>
<type name="String32" primitiveType="char" length="32"/>
<type name="String64" primitiveType="char" length="64"/>
<composite name="varString8" description="Variable length UTF-8 string">
<type name="length" primitiveType="uint8"/>
<type name="varData" length="0" primitiveType="uint8" semanticType="String" characterEncoding="UTF-8"/>
</composite>
<composite name="Decimal64" description="Decimal floating point: value = mantissa × 10^exponent">
<type name="exponent" primitiveType="int8"/>
<type name="mantissa" primitiveType="int64"/>
</composite>
<enum name="CategoryType" encodingType="uint8">
<validValue name="UNKNOWN">0</validValue>
<validValue name="SPOT">1</validValue>
<validValue name="LINEAR">2</validValue>
<validValue name="INVERSE">3</validValue>
<validValue name="OPTION">4</validValue>
<validValue name="NON_REPRESENTABLE">254</validValue>
</enum>
<enum name="PositionIdxType" encodingType="uint8">
<validValue name="ONE_WAY">0</validValue>
<validValue name="HEDGE_BUY">1</validValue>
<validValue name="HEDGE_SELL">2</validValue>
<validValue name="UNKNOWN">253</validValue>
<validValue name="NON_REPRESENTABLE">254</validValue>
</enum>
<enum name="OrderType" encodingType="uint8">
<validValue name="UNKNOWN">0</validValue>
<validValue name="MARKET">1</validValue>
<validValue name="LIMIT">2</validValue>
<validValue name="NON_REPRESENTABLE">254</validValue>
</enum>
<enum name="SideType" encodingType="uint8">
<validValue name="UNKNOWN">0</validValue>
<validValue name="BUY">1</validValue>
<validValue name="SELL">2</validValue>
<validValue name="NON_REPRESENTABLE">254</validValue>
</enum>
<enum name="TimeInForceType" encodingType="uint8">
<validValue name="UNKNOWN">0</validValue>
<validValue name="GOOD_TILL_CANCEL">1</validValue>
<validValue name="POST_ONLY">2</validValue>
<validValue name="IMMEDIATE_OR_CANCEL">3</validValue>
<validValue name="FILL_OR_KILL">4</validValue>
<validValue name="RPI">5</validValue>
<validValue name="NON_REPRESENTABLE">254</validValue>
</enum>
<enum name="SmpType" encodingType="uint8">
<validValue name="UNKNOWN">0</validValue>
<validValue name="CANCEL_TAKER">1</validValue>
<validValue name="CANCEL_MAKER">2</validValue>
<validValue name="CANCEL_BOTH">3</validValue>
<validValue name="NON_REPRESENTABLE">254</validValue>
</enum>
<enum name="MarketUnitType" encodingType="uint8">
<validValue name="UNKNOWN">0</validValue>
<validValue name="BASE_COIN">1</validValue>
<validValue name="QUOTE_COIN">2</validValue>
<validValue name="NON_REPRESENTABLE">254</validValue>
</enum>
<enum name="BoolEnum" encodingType="uint8">
<validValue name="FALSE">0</validValue>
<validValue name="TRUE">1</validValue>
<validValue name="NON_REPRESENTABLE">254</validValue>
</enum>
<composite name="ApiRequestHeader" description="API Request header">
<type name="reqId" primitiveType="char" length="64"/>
<type name="timestamp" primitiveType="uint64"/>
<type name="recvWindow" primitiveType="uint32"/>
<type name="referer" primitiveType="char" length="64"/>
</composite>
<composite name="ApiRespHeader" description="Response header">
<type name="reqId" primitiveType="char" length="64"/>
<type name="connId" primitiveType="char" length="64"/>
<type name="traceId" primitiveType="char" length="64"/>
<type name="timeNow" primitiveType="int64"/>
<type name="inTime" primitiveType="int64"/>
<type name="bapiLimit" primitiveType="int64"/>
<type name="bapiLimitStatus" primitiveType="int64"/>
<type name="bapiLimitResetTimestamp" primitiveType="int64"/>
</composite>
<composite name="CommonOrderRespData" description="Common order response data">
<type name="orderId" primitiveType="char" length="64"/>
<type name="orderLinkId" primitiveType="char" length="64"/>
</composite>
</types>

<message name="AuthReq" id="1" description="Authentication request">
<field name="reqId" id="1" type="String64"/>
<field name="apiKey" id="2" type="String64"/>
<field name="expires" id="3" type="uint64"/>
<field name="signature" id="4" type="String64"/>
</message>
<message name="AuthResp" id="2" description="Authentication response">
<field name="reqId" id="1" type="String64"/>
<field name="retCode" id="2" type="int32"/>
<field name="connId" id="3" type="String64"/>
<data name="retMsg" id="20" type="varString8"/>
</message>
<message name="PingReq" id="3" description="Ping request">
<field name="timestamp" id="1" type="uint64"/>
</message>
<message name="PongResp" id="4" description="Pong response">
<field name="timestamp" id="1" type="uint64"/>
<field name="pongTime" id="2" type="uint64"/>
</message>
<message name="CreateOrderReqV5" id="5" description="Create order request">
<field name="header" id="1" type="ApiRequestHeader"/>
<field name="category" id="2" type="CategoryType"/>
<field name="symbolId" id="3" type="int64"/>
<field name="side" id="4" type="SideType"/>
<field name="orderType" id="5" type="OrderType"/>
<field name="qty" id="6" type="Decimal64"/>
<field name="price" id="7" type="Decimal64"/>
<field name="orderLinkId" id="8" type="String64"/>
<field name="timeInForce" id="9" type="TimeInForceType"/>
<field name="positionIdx" id="10" type="PositionIdxType"/>
<field name="marketUnit" id="11" type="MarketUnitType"/>
<field name="isLeverage" id="12" type="BoolEnum"/>
<field name="reduceOnly" id="13" type="BoolEnum"/>
<field name="closeOnTrigger" id="14" type="BoolEnum"/>
<field name="mmp" id="15" type="BoolEnum"/>
<field name="smpType" id="16" type="SmpType"/>
</message>
<message name="CreateOrderRespV5" id="6" description="Create order response">
<field name="respHeader" id="1" type="ApiRespHeader"/>
<field name="retCode" id="2" type="int32"/>
<field name="result" id="3" type="CommonOrderRespData"/>
<data name="retMsg" id="20" type="varString8"/>
</message>
<message name="ReplaceOrderReqV5" id="7" description="Replace order request">
<field name="header" id="1" type="ApiRequestHeader"/>
<field name="category" id="2" type="CategoryType"/>
<field name="symbolId" id="3" type="int64"/>
<field name="orderId" id="4" type="String64"/>
<field name="orderLinkId" id="5" type="String64"/>
<field name="qty" id="6" type="Decimal64"/>
<field name="price" id="7" type="Decimal64"/>
</message>
<message name="ReplaceOrderRespV5" id="8" description="Replace order response">
<field name="respHeader" id="1" type="ApiRespHeader"/>
<field name="retCode" id="2" type="int32"/>
<field name="result" id="3" type="CommonOrderRespData"/>
<data name="retMsg" id="20" type="varString8"/>
</message>
<message name="CancelOrderReqV5" id="9" description="Cancel order request">
<field name="header" id="1" type="ApiRequestHeader"/>
<field name="category" id="2" type="CategoryType"/>
<field name="symbolId" id="3" type="int64"/>
<field name="orderId" id="4" type="String64"/>
<field name="orderLinkId" id="5" type="String64"/>
</message>
<message name="CancelOrderRespV5" id="10" description="Cancel order response">
<field name="respHeader" id="1" type="ApiRespHeader"/>
<field name="retCode" id="2" type="int32"/>
<field name="result" id="3" type="CommonOrderRespData"/>
<data name="retMsg" id="20" type="varString8"/>
</message>
<message name="BatchCreateOrderReqV5" id="11" description="Batch create order request">
<field name="header" id="1" type="ApiRequestHeader"/>
<field name="category" id="2" type="CategoryType"/>
<group name="request" id="200" dimensionType="groupSize16Encoding">
<field name="symbolId" id="1" type="int64"/>
<field name="side" id="2" type="SideType"/>
<field name="orderType" id="3" type="OrderType"/>
<field name="qty" id="4" type="Decimal64"/>
<field name="price" id="5" type="Decimal64"/>
<field name="orderLinkId" id="6" type="String64"/>
<field name="timeInForce" id="7" type="TimeInForceType"/>
<field name="positionIdx" id="8" type="PositionIdxType"/>
<field name="marketUnit" id="9" type="MarketUnitType"/>
<field name="isLeverage" id="10" type="BoolEnum"/>
<field name="reduceOnly" id="11" type="BoolEnum"/>
<field name="closeOnTrigger" id="12" type="BoolEnum"/>
<field name="mmp" id="13" type="BoolEnum"/>
<field name="smpType" id="14" type="SmpType"/>
</group>
</message>
<message name="BatchCreateOrderRespV5" id="12" description="Batch create order response">
<field name="respHeader" id="1" type="ApiRespHeader"/>
<field name="retCode" id="2" type="int32"/>
<group name="list" id="100" dimensionType="groupSize16Encoding">
<field name="code" id="1" type="int32"/>
<field name="category" id="2" type="CategoryType"/>
<field name="symbolId" id="3" type="int64"/>
<field name="orderId" id="4" type="String64"/>
<field name="orderLinkId" id="5" type="String64"/>
<data name="msg" id="20" type="varString8"/>
<data name="createAt" id="21" type="varString8"/>
</group>
<data name="retMsg" id="200" type="varString8"/>
</message>
<message name="BatchReplaceOrderReqV5" id="13" description="Batch replace order request">
<field name="header" id="1" type="ApiRequestHeader"/>
<field name="category" id="2" type="CategoryType"/>
<group name="request" id="200" dimensionType="groupSize16Encoding">
<field name="symbolId" id="1" type="int64"/>
<field name="orderId" id="2" type="String64"/>
<field name="orderLinkId" id="3" type="String64"/>
<field name="qty" id="4" type="Decimal64"/>
<field name="price" id="5" type="Decimal64"/>
</group>
</message>
<message name="BatchReplaceOrderRespV5" id="14" description="Batch replace order response">
<field name="respHeader" id="1" type="ApiRespHeader"/>
<field name="retCode" id="2" type="int32"/>
<group name="list" id="100" dimensionType="groupSize16Encoding">
<field name="code" id="1" type="int32"/>
<field name="category" id="2" type="CategoryType"/>
<field name="symbolId" id="3" type="int64"/>
<field name="orderId" id="4" type="String64"/>
<field name="orderLinkId" id="5" type="String64"/>
<data name="msg" id="20" type="varString8"/>
</group>
<data name="retMsg" id="200" type="varString8"/>
</message>
<message name="BatchCancelOrderReqV5" id="15" description="Batch cancel order request">
<field name="header" id="1" type="ApiRequestHeader"/>
<field name="category" id="2" type="CategoryType"/>
<group name="request" id="200" dimensionType="groupSize16Encoding">
<field name="symbolId" id="1" type="int64"/>
<field name="orderId" id="2" type="String64"/>
<field name="orderLinkId" id="3" type="String64"/>
</group>
</message>
<message name="BatchCancelOrderRespV5" id="16" description="Batch cancel order response">
<field name="respHeader" id="1" type="ApiRespHeader"/>
<field name="retCode" id="2" type="int32"/>
<group name="list" id="100" dimensionType="groupSize16Encoding">
<field name="code" id="1" type="int32"/>
<field name="category" id="2" type="CategoryType"/>
<field name="symbolId" id="3" type="int64"/>
<field name="orderId" id="4" type="String64"/>
<field name="orderLinkId" id="5" type="String64"/>
<data name="msg" id="20" type="varString8"/>
</group>
<data name="retMsg" id="200" type="varString8"/>
</message>
<message name="CommonErrResp" id="17" description="Common error response">
<field name="respHeader" id="1" type="ApiRespHeader"/>
<field name="retCode" id="2" type="int32"/>
<data name="retMsg" id="20" type="varString8"/>
</message>
</sbe:messageSchema>