SBE Encoding

JSON is human-readable and works everywhere, but it is verbose. Decimal values encoded as strings are particularly wasteful. The Market Data Adapter also publishes the same data over SBE (https://www.fixtrading.org/standards/sbe/) for clients that want something denser and faster to parse.

Characteristics

  • Every SBE message is semantically identical to its JSON counterpart and exposes the same fields.

  • Encoders and decoders are generated automatically from the SBE schema.

  • Most schema-defined data maps directly to the JSON documentation.

  • One exception: decimals (mostly prices and quantities) need a custom encoding. See below.

Schema metadata

Field Value
id 1
version 7
byteOrder littleEndian
package com.cryptostruct.commons.events.marketdata.sbe.v6

Each message starts with a fixed messageHeader composite, six 16-bit unsigned integers in this order:

Field Type Description
blockLength uint16 Size of the fixed-length root block in bytes
templateId uint16 Identifies the message type (see table below)
schemaId uint16 Always 1
version uint16 Schema version of the encoded message
numGroups uint16 Number of repeating groups in the root block
numVarDataFields uint16 Number of variable-length fields after groups

Template IDs

ID Message Direction
1000 snapshotEvent Server -> Client
1001 snapshotUpdateEvent Server -> Client
1002 tradesEvent Server -> Client
1005 stateEvent Server -> Client
1006 tobEvent Server -> Client
1007 markPriceEvent Server -> Client
1008 indexPriceEvent Server -> Client
1009 fundingRateEvent Server -> Client
1011 subscribeRequestMessage Client -> Server
1012 unsubscribeRequestMessage Client -> Server
1013 loginRequestMessage Client -> Server
1014 loginResponseMessage Server -> Client
1017 liquidationsEvent Server -> Client

Using SBE

To consume SBE instead of JSON:

  1. Connect to the SBE endpoint or domain socket (see Accessing Data for endpoint discovery).

  2. Flag your messages as binary. WebSockets do this natively. For domain sockets, see Binary Framing.


Decimal encoding

The CryptoStruct trading system handles numbers with up to 18 decimal places. SBE's primitive number types (and most languages' primitive types) cannot represent that range reliably, so decimals get a custom encoding.

Representation

A decimal is a pair:

  • Unscaled value: an arbitrarily large integer.
  • Scale: an integer.

The number is reconstructed as:

number = unscaled * (10 ^ -scale)

SBE storage

Example

unscaled value: [4, 1]
scale: 2

The two bytes of the unscaled value form a 16-bit integer with value 1025:

1025 * (10 ^ -2) = 10.25