Websocket API
This schema defines the Protobuf messages used for communication with the Cube Market Data Service (Mendelev, MD). The proto
definition file can be found here.
Order Book Data
The market data service exposes a websocket endpoint for order book data for a given market at wss://api.cube.exchange/md/book/:market_id
. The order book can be consumed by both price level through the Market by Price (MBP) and order-by-order through the Market by Order (MBO). In addition, clients can subscribe to the trade stream and price candlesticks.
Upon connection, clients should submit a Config
and then process a stream of MdMessages
. Note that this message type is distinct from the MdMessage
, where the former is a wrapper containing one or more of the latter.
Aggregate Book Tops Data
The market data service exposes a websocket endpoint for aggregated tops-of-book for all markets at wss://api.cube.exchange/md/tops
. Client should process AggMessage
.
Heartbeats
Application-level heartbeats are expected every 30 seconds. If more than one interval is missed, the market data service will disconnect the websocket.
MdMessage
Every exchange message from /book/:market_id
will be wrapped as an MdMessages
which contains multiple MdMessage
's.
MarketByPrice
Market by price snapshot message. This is chunked into num_chunks
and starts with chunk = 0
. A snapshot is sent on first connect. Level
's should be concatened until chunk = num_chunks - 1
. Currently, the chunks and levels are streamed from tightest price level outwards with interleaved Bid and Ask levels, but no ordering is guaranteed.
MarketByPrice.Level
Each price level is the aggregate total quantity of orders placed at that price.
MarketByPriceDiff
Market by price diff message. Book updates for the MBP feed are sent as diffs after the initial snapshot. The number of total side levels are for reconciliation.
MarketByPriceDiff.Diff
A price level diff overwrites the existing price level.
MarketByOrder
Market by order snapshot message. This is chunked into num_chunks
and starts with chunk = 0
. A snapshot is sent on first connect. Level
's should be concatened until chunk = num_chunks - 1
. Orders are sent in order of FIFO queue priority so the first order of a level should be the first order to be matched when that level is aggressed.
MarketByOrder.Order
A resting order.
priority
Order priority for execution. Valid within a price level and side. That is, orders must first be sorted by side and price (in descending order for bids and ascending for asks), and then the OrderPriority within the level. A lower value is a higher priority.
MarketByOrderDiff
Market by order diff message. Book updates for the MBO feed are sent as diffs after the initial snapshot. The number of total side levels and orders are for reconciliation.
Note that for orders that are cancel-replace'd (a modify that lost queue priority), the new price and quantity will be reported as a REPLACE
but the exchange order ID will not change.
MarketByOrderDiff.Diff
An order diff creates, updates, or deletes a resting order based on the exchange_order_id
MarketStatus
FundingCalculation
predicted_funding_rate
Predicted funding rate percentage for the next funding interval. See FundingApplication.funding_rate
for details on calculation.
next_funding_application_time
The server target time for the next funding application. Expressed in nanoseconds.
countdown = next_funding_application_time - transact_time
premium_index
Premium (or discount) percentage relative to the index price.
premium_index = (MAX(impact_bid_price - index_price, 0) - MAX(index_price - impact_ask_price, 0)) / index_price
Expressed with 9 decimals.
FundingApplication
funding_rate
Funding rate percentage for this interval, calculated based on the average premium index over the funding interval.
funding_rate = premium_index + clamp(interest_rate - premium_index, -clamp, +clamp)
funding_delta
The quote amount to be paid (or received) based on the given funding rate, funding interval duration, and current index price.
ContractStatistics
Statistics for the contract.
ContractPrice
Latest contract price information.
Trades
Trades since the latest Trades
message. The result of the trades will also appear in the MBP and MBO feeds independently as updates to the resting orders and levels, respectively.
Trades.Trade
tradeId
The ID assigned to this trade. All trades that occur from the same event will be assigned the same ID, and are considered to be an atomic batch.
transact_time
The transact time assigned by the matching engine for this trade. All trades that occur from the same event will be assigned the same transact time.
Summary
Rolling 24h stats.
Kline
Candlestick bar.
Heartbeat
A client and server heartbeat. The heartbeat reply, including the timestamp value, comes from the market data service.
MdMessages
A wrapper containing one or more Market Data messages, each of which will be an MdMessage
.
AggMessage
Every exchange message from /tops
will be wrapped as an AggMessage
.
TopOfBook
Top of book
TopOfBooks
Top of books for all books that were updates since the last top-of-books message.
RateUpdate
Rate update. Used in conjuction with another rate update to get the price of that divisor. Rate's should not be used alone. For example, given a RateUpdate for assetId = BTC, updateSide = BASE
of r1
, and assetId = EUR, updateSide = QUOTE
of r2
, the BTC-EUR price estimate is r1 * r2
.
RateUpdates
Rates for all assets. Published on connect and updates since the last rate-updates message.
ClientMessage
Client heartbeats and configs. This wrapper is used for both /book/:market_id
and /tops
, but config
messages are ignored on the latter.
Config
Set the message subscriptions for /book/:market_id
. At most one of mbp
and mbo
can be set.
Numeric Types
FundingDelta
Funding delta to be applied per open contract unit, for a particular funding interval. The delta is expressed as a signed (twos-complement) fixed point number with 18 decimal places.
Enums
Side
Side specifies whether the level, order, or diff, is for buying or selling the base asset.
BID
0
Bids buy the base asset with the quote asset.
ASK
1
Asks (or offers) sell the base asset and get the quote asset.
KlineInterval
The candlestick interval.
S1
0
1 second
M1
1
1 minute
M15
2
15 minutes
H1
3
1 hour
H4
4
4 hours
D1
5
1 day
MarketState
The per-market matching engine state. Affects order-entry.
UNSPECIFIED
0
Sentinel
NORMAL_OPERATION
1
The market is in its normal operating state. All order operations are supported.
CANCEL_ONLY
2
The market is in cancel-only mode. Existing orders are not automatically canceled, and may be filled when the market transitions back to normal-operation.
AggressingSide
The side of the aggressing order. This also indicates if the aggressing order was an implied order (i.e aggressed into a different market and executed into this one through implieds)
AGGRESSING_BID
0
AGGRESSING_ASK
1
AGGRESSING_IMPLIED_BID
2
AGGRESSING_IMPLIED_ASK
3
RateUpdateSide
The side of the rate update. Given a BASE
rate of r
, the QUOTE
rate is 1 / r
, and vice versa.
BASE
0
The asset serves as the base asset for the given rate.
QUOTE
1
The asset serves as the quote asset for the given rate.
MarketByPriceDiff.DiffOp
The operation to apply for this price level. Currently, new price levels are created with REPLACE
.
ADD
0
This operation is NOT used for MBP. The operation of adding a new price level is specified as REPLACE
.
REMOVE
1
This operation is used when a price level is removed from the book.
REPLACE
2
This operation is used when a new price level is added or an existing price level is modified.
MarketByOrderDiff.DiffOp
The operation to apply for this price level. For example, an resting order that gets filled will be REPLACE
'd with the new resting quantity. An order is REMOVE
'd when it is fully filled or canceled.
ADD
0
REMOVE
1
REPLACE
2
Scalar Value Types
double
f64
double
float
float64
float
f32
float
float
float32
int32
Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.
i32
int32
int
int32
int64
Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.
i64
int64
int/long
int64
uint32
Uses variable-length encoding.
u32
uint32
int/long
uint32
uint64
Uses variable-length encoding.
u64
uint64
int/long
uint64
sint32
Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.
i32
int32
int
int32
sint64
Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.
i64
int64
int/long
int64
fixed32
Always four bytes. More efficient than uint32 if values are often greater than 2^28.
u64
uint32
int
uint32
fixed64
Always eight bytes. More efficient than uint64 if values are often greater than 2^56.
u64
uint64
int/long
uint64
sfixed32
Always four bytes.
i32
int32
int
int32
sfixed64
Always eight bytes.
i64
int64
int/long
int64
bool
bool
bool
boolean
bool
string
A string must always contain UTF-8 encoded or 7-bit ASCII text.
String
string
str/unicode
string
bytes
May contain any arbitrary sequence of bytes.
Vec
string
str
[]byte
Last updated