WebSocket Market Data
WebSocket market data feed¶
- The base URL for all wss endpoints listed in this document is: wss://sstream.asterdex.com
- Streams have either a single raw stream or a combined stream
- Single raw streams format is **/ws/**
- The URL format for combined streams is **/stream?streams=//**
- When subscribing to combined streams, the event payload is wrapped in this format: **{"stream":"","data":}**
- All trading pairs in stream names are lowercase
- Each link to sstream.asterdex.com is valid for no more than 24 hours; please handle reconnections appropriately
- Every 3 minutes the server sends a ping frame; the client must reply with a pong frame within 10 minutes, otherwise the server will close the connection. The client is allowed to send unpaired pong frames (i.e., the client may send pong frames at a frequency higher than once every 10 minutes to keep the connection alive).
Real-time subscribe/unsubscribe data streams¶
- The following messages can be sent via WebSocket to subscribe or unsubscribe to data streams. Examples are shown below.
- The
idin the response content is an unsigned integer that serves as the unique identifier for exchanges of information. - If the
resultin the response content isnull, it indicates the request was sent successfully.
Subscribe to a stream¶
Response
{
"result": null,
"id": 1
}
- Request { "method": "SUBSCRIBE", "params": [ "btcusdt@aggTrade", "btcusdt@depth" ], "id": 1 }
Unsubscribe from a stream¶
Response
{
"result": null,
"id": 312
}
- Request { "method": "UNSUBSCRIBE", "params": [ "btcusdt@depth" ], "id": 312 }
Subscribed to the feed¶
Response
{
"result": [
"btcusdt@aggTrade"
],
"id": 3
}
- Request
{ "method": "LIST_SUBSCRIPTIONS", "id": 3 }
Set properties¶
Currently, the only configurable property is whether to enable the combined ("combined") stream. When connecting using /ws/ ("raw stream"), the combined property is set to false, while connecting using /stream/ sets the property to true.
Response
{
"result": null,
"id": 5
}
- Request { "method": "SET_PROPERTY" "params": [ "combined", true ], "id": 5 }
Retrieve properties¶
Response
{
"result": true, // Indicates that combined is set to true.
"id": 2
}
- Request
{ "method": "GET_PROPERTY", "params": [ "combined" ], "id": 2 }
### Error message
| Error message | Description |
|---|---|
| {"code": 0, "msg": "Unknown property"} | Parameters applied in SET_PROPERTY or GET_PROPERTY are invalid |
| {"code": 1, "msg": "Invalid value type: expected Boolean", "id": '%s'} | Only true or false are accepted |
| {"code": 2, "msg": "Invalid request: property name must be a string"} | The provided attribute name is invalid |
| {"code": 2, "msg": "Invalid request: request ID must be an unsigned integer"} | Parameter ID not provided or ID has an invalid type |
| {"code": 2, "msg": "Invalid request: unknown variant %s, expected one of SUBSCRIBE, UNSUBSCRIBE, LIST_SUBSCRIPTIONS, SET_PROPERTY, GET_PROPERTY at line 1 column 28"} | Typo warning, or the provided value is not of the expected type |
| {"code": 2, "msg": "Invalid request: too many parameters"} | Unnecessary parameters were provided in the data |
| {"code": 2, "msg": "Invalid request: property name must be a string"} | Property name not provided |
| {"code": 2, "msg": "Invalid request: missing field method at line 1 column 73"} | Data did not provide method |
| {"code":3,"msg":"Invalid JSON: expected value at line %s column %s"} | JSON syntax error |
Collection transaction flow¶
Payload:
{
"e": "aggTrade", // Event type
"E": 123456789, // Event time
"s": "BNBBTC", // Symbol
"a": 12345, // Aggregate trade ID
"p": "0.001", // Price
"q": "100", // Quantity
"f": 100, // First trade ID
"l": 105, // Last trade ID
"T": 123456785, // Trade time
"m": true, // Is the buyer the market maker?
"M": true // Ignore
}
The collection transaction stream pushes transaction information and is an aggregation of a single order.
Stream name: <symbol>@aggTrade
Update speed: real-time
Tick-by-tick trades¶
Payload:
{
"e": "trade", // Event type
"E": 123456789, // Event time
"s": "BNBBTC", // Symbol
"t": 12345, // Trade ID
"p": "0.001", // Price
"q": "100", // Quantity
"T": 123456785, // Trade time
"m": true, // Is the buyer the market maker?
}
Stream name: <symbol>@trade
Each trade stream pushes the details of every individual trade. A trade, also called a transaction, is defined as a match between exactly one taker and one maker.
K-line streams¶
Payload:
{
"e": "kline", // Event type
"E": 123456789, // Event time
"s": "BNBBTC", // Symbol
"k": {
"t": 123400000, // Kline start time
"T": 123460000, // Kline close time
"s": "BNBBTC", // Symbol
"i": "1m", // Interval
"f": 100, // First trade ID
"L": 200, // Last trade ID
"o": "0.0010", // Open price
"c": "0.0020", // Close price
"h": "0.0025", // High price
"l": "0.0015", // Low price
"v": "1000", // Base asset volume
"n": 100, // Number of trades
"x": false, // Is this kline closed?
"q": "1.0000", // Quote asset volume
"V": "500", // Taker buy base asset volume
"Q": "0.500", // Taker buy quote asset volume
"B": "123456" // Ignore
}
}
The K-line stream pushes per-second updates for the requested type of K-line (the latest candle).
Stream name: <symbol>@kline_<interval>
Update speed: 2000ms
K-line interval parameter:
m (minutes), h (hours), d (days), w (weeks), M (months)
- 1m
- 3m
- 5m
- 15m
- 30m
- 1h
- 2h
- 4h
- 6h
- 8h
- 12h
- 1d
- 3d
- 1w
- 1M
Simplified ticker by symbol¶
Payload:
{
"e": "24hrMiniTicker", // Event type
"E": 123456789, // Event time
"s": "BNBBTC", // Symbol
"c": "0.0025", // Close price
"o": "0.0010", // Open price
"h": "0.0025", // High price
"l": "0.0010", // Low price
"v": "10000", // Total traded base asset volume
"q": "18" // Total traded quote asset volume
}
Refreshed simplified 24-hour ticker information by symbol
Stream name: <symbol>@miniTicker
Update speed: 1000ms
Compact tickers for all symbols in the entire market¶
Payload:
[
{
// Same as <symbol>@miniTicker payload
}
]
Same as above, but pushes all trading pairs. Note that only updated tickers will be pushed.
Stream name: !miniTicker@arr
Update speed: 1000ms
Full ticker per symbol¶
Payload:
{
"e": "24hrTicker", // Event type
"E": 123456789, // Event time
"s": "BNBBTC", // Symbol
"p": "0.0015", // Price change
"P": "250.00", // Price change percent
"w": "0.0018", // Weighted average price
"c": "0.0025", // Last price
"Q": "10", // Last quantity
"o": "0.0010", // Open price
"h": "0.0025", // High price
"l": "0.0010", // Low price
"v": "10000", // Total traded base asset volume
"q": "18", // Total traded quote asset volume
"O": 0, // Statistics open time
"C": 86400000, // Statistics close time
"F": 0, // First trade ID
"L": 18150, // Last trade Id
"n": 18151 // Total number of trades
}
Pushes per-second tag statistics for a single trading pair over a rolling 24-hour window.
Stream name: <symbol>@ticker
Update speed: 1000ms
Complete ticker for all trading pairs on the entire market¶
Payload:
[
{
// Same as <symbol>@ticker payload
}
]
Pushes the full 24-hour refreshed ticker information for all trading pairs across the entire market. Note that tickers without updates will not be pushed.
Stream name: !ticker@arr
Update speed: 1000ms
Best order book information by symbol¶
Payload:
{
"u":400900217, // order book updateId
"s":"BNBUSDT", // symbol
"b":"25.35190000", // best bid price
"B":"31.21000000", // best bid qty
"a":"25.36520000", // best ask price
"A":"40.66000000" // best ask qty
}
Real-time push of best order book information for the specified trading pair
Stream name: <symbol>@bookTicker
Update speed: Real-time
Best order book information across the entire market¶
Payload:
{
// 同 <symbol>@bookTicker payload
}
Real-time push of the best order information for all trading pairs
Stream name: !bookTicker
Update speed: Real-time
Limited depth information¶
Payload:
{
"e": "depthUpdate", // Event type
"E": 123456789, // Event time
"T": 123456788, // Transaction time
"s": "BTCUSDT", // Symbol
"U": 100, // First update ID in event
"u": 120, // Final update ID in event
"pu": 99, // Final update Id in last stream(ie `u` in last stream)
"bids": [ // Bids to be updated
[
"0.0024", // Price level to be updated
"10" // Quantity
]
],
"asks": [ // Asks to be updated
[
"0.0026", // Price level to be updated
"100" // Quantity
]
]
}
Limited depth information pushed every second or every 100 milliseconds. Levels indicate how many levels of bid/ask information, optional 5/10/20 levels.
Stream names: <symbol>@depth<levels> or <symbol>@depth<levels>@100ms.
Update speed: 1000ms or 100ms
Incremental depth information¶
Payload:
{
"e": "depthUpdate", // Event type
"E": 123456789, // Event time
"T": 123456788, // Transaction time
"s": "BTCUSDT", // Symbol
"U": 100, // First update ID in event
"u": 120, // Final update ID in event
"pu": 99, // Final update Id in last stream(ie `u` in last stream)
"b": [ // Bids to be updated
[
"5.4", // Price level to be updated
"10" // Quantity
]
],
"a": [ // Asks to be updated
[
"5.6", // Price level to be updated
"100" // Quantity
]
]
}
Pushes the changed parts of the orderbook (if any) every second or every 100 milliseconds
Stream name: <symbol>@depth or <symbol>@depth@100ms
Update speed: 1000ms or 100ms
How to correctly maintain a local copy of an order book¶
- Subscribe to wss://sstream.asterdex.com/ws/bnbbtc@depth
- Start caching the received updates. For the same price level, later updates overwrite earlier ones.
- Fetch the REST endpoint https://sapi.asterdex.com/api/v1/depth?symbol=BNBBTC\&limit=1000 to obtain a 1000-level depth snapshot
- Discard from the currently cached messages those with
u\<= thelastUpdateIdobtained in step 3 (drop older, expired information) - Apply the depth snapshot to your local order book copy, and resume updating the local copy from the first WebSocket event whose
U\<=lastUpdateId+1 andu>=lastUpdateId+1 - Each new event’s
Ushould equal exactly the previous event’su+1; otherwise packets may have been lost - restart initialization from step 3 - The order quantity in each event represents the current order quantity at that price as an absolute value, not a relative change
- If the order quantity at a given price is 0, it means the orders at that price have been canceled or filled, and that price level should be removed