Websocket
Description
Binance4j-websocket is a set of Java connectors for the Binance Websocket API.
Installation
- Maven
- Gradle
<dependency>
<groupId>{{groupId}}</groupId>
<artifactId>{{artifactId}}</artifactId>
<version>{{version}}</version>
</dependency>
implementation '{{groupId}}:{{artifactId}}:{{version}}'
Dependencies
- binance4j-core : The core of every binance4j artifact
- Lombok : Prevent boilerplate code.
- OkHttp : HTTP && Websocket clients
- Retrofit : Map API endpoints with annotations.
- Jackson : Payload deserialization
- Apache Common Codecs : Encode/decode urls
- RxJava : asynchronous and event-based programs by using observable sequences.
How does it work?
The goal of a websocket client is to receive real time data from the Binance API through a persistent, bi-directional stream.
This can be market or user/balance data. Every client share the same methods as they inherit from the WebsocketClient
class.
Event handlers
//The connection with the server is opened.
client.onOpen(response -> {
// ...
});
//The connection with the server is closing.
client.onClosing(cb -> {
// ...
});
//The connection with the server is closed.
client.onClosed(cb -> {
// ...
});
//Connection failed, deserialization failed, the server has not sent data for a long time (timeout)
client.onFailure(cb -> {
// ...
});
//The server pushed data
client.onMessage(cb -> {
// ...
});
Open/Close the stream
//When the connection will open, the `onOpen` handler will be called.
client.open();
//Before closing, the `onClosing` handler will be called, then `onClosed` once the connection is closed.
client.close();
Stream lifespan
From Binance documentation:
A single connection to stream.binance.com is only valid for 24 hours; expect to be disconnected at the 24 hour mark.
The websocket server will send a ping frame every 3 minutes. If the websocket server does not receive a pong frame back from the connection within a 10 minute period, the connection will be disconnected. Unsolicited pong frames are allowed.
Ping the server
Websocket clients automatically ping the server every 3 minutes. You don't need to do anything! But if you want to change that interval, just call:
client.setPingInterval(java.time.Duration)
The stream must be closed or this won't work. If you need to change this interval, close and reopen the stream.
Ping the server back
Again, websocket clients automatically pings back. You don't need to do anything!
Reconnect after a disconnection
Every websocket client is by default configured to automatically reconnect if the stream is closed by the server. If you don't like this behaviour, just call:
client.setKeepAlive(false);
Next time the client is disconnected, it won't try to reconnect.
Reconnect after a connection failure
Every websocket client is by default configured to automatically reconnect after a connection failure. If you don't like this behaviour, just call:
client.retryOnConnectionFailure(false);
The stream must be closed or this won't work. If you need to change this interval, close and reopen the stream.
Reconnect after no response for some time
It can happen that after some time, the server stops sending data to the client. Every websocket client is by default configured to automatically disconnect and reconnect after a not receiving data for some time (3 minutes by default). To change this interval call:
client.setNoResponseTimeout(time.Duration);
The stream must be closed or this won't work. If you need to change this interval, close and reopen the stream.
Since Binance recommends a 30 minutes interval, i wouldn't recommend to change this value.
Available Websocket clients
Individual Symbol Ticker Streams
Handles 24hr rolling window ticker statistics for a single symbol.
- One symbol
- Multiple symbols (String)
- Multiple symbols (List)
WebsocketTickerClient client = new WebsocketTickerClient("BNBBTC");
WebsocketTickerClient client = new WebsocketTickerClient("BNBBTC, BNBBUSD");
WebsocketTickerClient client = new WebsocketTickerClient(List.of("BNBBTC", "BNBBUSD"));
These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs.
Individual Symbol Mini Ticker Stream
24hr rolling window mini-ticker statistics.
These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs.
- One symbol
- Multiple symbols (String)
- Multiple symbols (List)
WebsocketMiniTickerClient client = new WebsocketMiniTickerClient("BNBBTC");
WebsocketMiniTickerClient client = new WebsocketMiniTickerClient("BNBBTC, BNBBUSD");
WebsocketMiniTickerClient client = new WebsocketMiniTickerClient(List.of("BNBBTC", "BNBBUSD"));
All Market Tickers Stream
24hr rolling window ticker statistics for all symbols that changed.
WebsocketAllTickersClient client = new WebsocketAllTickersClient();
These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs.
All Market Mini Tickers Stream
24hr rolling window mini-ticker statistics for all symbols that changed.
WebsocketAllMiniTickersClient client = new WebsocketAllMiniTickersClient();
These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs.
Individual Symbol Book Ticker Streams
Pushes any update to the best bid or ask's price or quantity in real-time for a specified symbol.
- One symbol
- Multiple symbols (String)
- Multiple symbols (List)
WebsocketBookTickerClient client = new WebsocketBookTickerClient("BNBBTC");
WebsocketBookTickerClient client = new WebsocketBookTickerClient("BNBBTC, BNBBUSD");
WebsocketBookTickerClient client = new WebsocketBookTickerClient(List.of("BNBBTC", "BNBBUSD"));
All Book Tickers Stream
Pushes any update to the best bid or ask's price or quantity in real-time for all symbols.
WebsocketAllBookTickersClient client = new WebsocketAllBookTickersClient();
Kline/Candlestick Streams
The Kline/Candlestick Stream push updates to the current klines/candlestick every second.
- One symbol
- Multiple symbols (String)
- Multiple symbols (List)
WebsocketCandlestickClient client = new WebsocketCandlestickClient("BNBBTC", CandlestickInterval.FIVE_MINUTE);
WebsocketCandlestickClient client = new WebsocketCandlestickClient("BNBBTC, BNBBUSD", CandlestickInterval.FIVE_MINUTE);
WebsocketCandlestickClient client = new WebsocketCandlestickClient(List.of("BNBBTC", "BNBBUSD", CandlestickInterval.FIVE_MINUTE));
Diff. Depth Stream
Order book price and quantity depth updates used to locally manage an order book.
- One symbol
- Multiple symbols (String)
- Multiple symbols (List)
WebsocketDepthClient client = new WebsocketDepthClient("BNBBTC");
WebsocketDepthClient client = new WebsocketDepthClient("BNBBTC, BNBBUSD");
WebsocketDepthClient client = new WebsocketDepthClient(List.of("BNBBTC", "BNBBUSD"));
Partial Book Depth Streams
Top bids and asks, Valid are 5, 10, or 20.
- One symbol
- Multiple symbols (String)
- Multiple symbols (List)
WebsocketMiniDepthClient client = new WebsocketMiniDepthClient("BNBBTC");
WebsocketMiniDepthClient client = new WebsocketMiniDepthClient("BNBBTC, BNBBUSD");
WebsocketMiniDepthClient client = new WebsocketMiniDepthClient(List.of("BNBBTC", "BNBBUSD"));
Trade Streams
The Trade Streams push raw trade information; each trade has a unique buyer and seller.
- One symbol
- Multiple symbols (String)
- Multiple symbols (List)
WebsocketTradeClient client = new WebsocketTradeClient("BNBBTC");
WebsocketTradeClient client = new WebsocketTradeClient("BNBBTC, BNBBUSD");
WebsocketTradeClient client = new WebsocketTradeClient(List.of("BNBBTC", "BNBBUSD"));
Aggregate Trade Streams
The Aggregate Trade Streams push trade information that is aggregated for a single taker order.
- One symbol
- Multiple symbols (String)
- Multiple symbols (List)
WebsocketAggTradeClient client = new WebsocketAggTradeClient("BNBBTC");
WebsocketAggTradeClient client = new WebsocketAggTradeClient("BNBBTC, BNBBUSD");
WebsocketAggTradeClient client = new WebsocketAggTradeClient(List.of("BNBBTC", "BNBBUSD"));
User Data Streams
The User Data Streams push account, balance and order update infos.
// Instantiate a UserDataClient
UserDataClient userDataClient = new UserDataClient(key,secret);
// instantiate the ws client
WebsocketUserDataClient client = new WebsocketUserDataClient(userDataClient);
Account Update : outboundAccountPosition is sent any time an account balance has changed and contains the assets that were possibly changed by the event that generated the balance change.
Balance Update: Balance Update occurs during the following:
- Deposits or withdrawals from the account
- Transfer of funds between accounts (e.g. Spot to Margin)
Order Update: Orders are updated with the executionReport event. Check the Public API Definitions and below for relevant enum definitions. Execution types:
- NEW - The order has been accepted into the engine.
- CANCELED - The order has been canceled by the user.
- REPLACED (currently unused)
- REJECTED - The order has been rejected and was not processed. (This is never pushed into the User Data Stream)
- TRADE - Part of the order or all of the order's quantity has filled.
- EXPIRED - The order was canceled according to the order type's rules (e.g. LIMIT FOK orders with no fill, LIMIT IOC or MARKET orders that partially fill) or by the exchange, (e.g. orders canceled during liquidation, orders canceled during maintenance)
Keep the User data Stream open
From Binance documentation:
The stream will close after 60 minutes unless a keepalive is sent. It's recommended to send a ping about every 30 minutes.
The WebsocketUserDataClient constructor takes a UserDataCLient
instance as parameter. In this way, it will automatically ask a listen key to the API and extends its lifespan by pinging the server every 30 minutes.
The interval can be changed by calling:
client.setKeepAliveInterval(java.time.Duration);
The stream must be closed or this won't work. If you need to change this interval, close and reopen the stream.
Since Binance recommends a 30 minutes interval, i wouldn't recommend to change this value.
User data endpoints
Start user data stream
Returns a listen key to open a user data websocket stream.
- Sync
- Async (lambda)
- Async (ApiCallback)
UserDataClient client = new UserDataClient(key, secret);
try{
ListenKey response = client.startUserDataStream().execute();
}catch(ApiException e){
//...
}
UserDataClient client = new UserDataClient(key, secret);
client.startUserDataStream().then(response->{
//...
});
UserDataClient client = new UserDataClient(key, secret);
client.startUserDataStream().then(new ApiCallback<ListenKey>() {
@Override
public void onResponse(ListenKey response) {
//...
}
@Override
public void onFailure(ApiException exception) {
//...
}
});
The stream will close after 60 minutes unless a keepalive is sent.
If the account has an active listenKey, that listenKey will be returned and its validity will be extended for 60 minutes.
Keep alive user data stream
Keepalive a user data stream to prevent a time out.
- Sync
- Async (lambda)
- Async (ApiCallback)
UserDataClient client = new UserDataClient(key, secret);
String request = new String(/** listenKey */);
try{
client.keepAliveUserDataStream(request).execute();
}catch(ApiException e){
//...
}
UserDataClient client = new UserDataClient(key, secret);
String request = new String(/** listenKey */);
client.keepAliveUserDataStream(request).then(response->{
//...
});
UserDataClient client = new UserDataClient(key, secret);
String request = new String(/** listenKey */);
client.keepAliveUserDataStream().then(new ApiCallback<Void>() {
@Override
public void onResponse() {
//...
}
@Override
public void onFailure(ApiException exception) {
//...
}
});
User data streams will close after 60 minutes.
It's recommended to send a ping about every 30 minutes.
Close out a user data stream
- Sync
- Async (lambda)
- Async (ApiCallback)
UserDataClient client = new UserDataClient(key, secret);
String request = new String(/** listenKey */);
try{
client.loseUserDataStream(request).execute();
}catch(ApiException e){
//...
}
UserDataClient client = new UserDataClient(key, secret);
String request = new String(/** listenKey */);
client.loseUserDataStream(request).then(response->{
//...
});
UserDataClient client = new UserDataClient(key, secret);
String request = new String(/** listenKey */);
client.loseUserDataStream().then(new ApiCallback<Void>() {
@Override
public void onResponse() {
//...
}
@Override
public void onFailure(ApiException exception) {
//...
}
});