package com.webcerebrium.binance.api; /* ============================================================ * java-binance-api * https://github.com/webcerebrium/java-binance-api * ============================================================ * Copyright 2017-, Viktor Lopata, Web Cerebrium OÜ * Released under the MIT License * ============================================================ */ import com.google.common.base.Strings; import com.google.common.collect.ImmutableSet; import com.google.common.escape.Escaper; import com.google.common.net.UrlEscapers; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; import com.webcerebrium.binance.datatype.BinanceAggregatedTrades; import com.webcerebrium.binance.datatype.BinanceCandlestick; import com.webcerebrium.binance.datatype.BinanceExchangeInfo; import com.webcerebrium.binance.datatype.BinanceExchangeStats; import com.webcerebrium.binance.datatype.BinanceHistoryFilter; import com.webcerebrium.binance.datatype.BinanceInterval; import com.webcerebrium.binance.datatype.BinanceOrder; import com.webcerebrium.binance.datatype.BinanceOrderPlacement; import com.webcerebrium.binance.datatype.BinanceSymbol; import com.webcerebrium.binance.datatype.BinanceTicker; import com.webcerebrium.binance.datatype.BinanceTrade; import com.webcerebrium.binance.datatype.BinanceWalletAsset; import com.webcerebrium.binance.websocket.*; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.eclipse.jetty.websocket.client.WebSocketClient; import java.lang.reflect.Type; import java.math.BigDecimal; import java.net.URI; import java.net.URISyntaxException; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @Slf4j @Data public class BinanceApi { /* Actual API key and Secret Key that will be used */ public String apiKey; public String secretKey; /** * API Base URL */ public String baseUrl = "https://www.binance.com/api/"; /** * Old W-API Base URL. Might not function well at that moment, please use modern wapi3 API instead */ public String baseWapiUrl = "https://www.binance.com/wapi/"; /** * W-API3 Base URL. */ public String baseWapi3 = "https://api.binance.com/wapi/v3"; /** * Base URL for websockets */ public String websocketBaseUrl = "wss://stream.binance.com:9443/ws/"; /** * Guava Class Instance for escaping */ private Escaper esc = UrlEscapers.urlFormParameterEscaper(); /** * Constructor of API when you exactly know the keys * @param apiKey Public API Key * @param secretKey Secret API Key * @throws BinanceApiException in case of any error */ public BinanceApi(String apiKey, String secretKey) throws BinanceApiException { this.apiKey = apiKey; this.secretKey = secretKey; validateCredentials(); } /** * Constructor of API - keys are loaded from VM options, environment variables, resource files */ public BinanceApi() { BinanceConfig config = new BinanceConfig(); this.apiKey = config.getVariable("BINANCE_API_KEY"); this.secretKey = config.getVariable("BINANCE_SECRET_KEY"); } /** * Validation we have API keys set up * @throws BinanceApiException in case of any error */ protected void validateCredentials() throws BinanceApiException { String humanMessage = "Please check environment variables or VM options"; if (Strings.isNullOrEmpty(this.getApiKey())) throw new BinanceApiException("Missing BINANCE_API_KEY. " + humanMessage); if (Strings.isNullOrEmpty(this.getSecretKey())) throw new BinanceApiException("Missing BINANCE_SECRET_KEY. " + humanMessage); } // - - - - - - - - - - - - - - - - - - - - - - - - // GENERAL ENDPOINTS // - - - - - - - - - - - - - - - - - - - - - - - - /** * Checking connectivity, * @return empty object * @throws BinanceApiException in case of any error */ public JsonObject ping() throws BinanceApiException { return (new BinanceRequest(baseUrl + "v1/ping")) .read().asJsonObject(); } /** * Checking server time, * @return JsonObject, expected { serverTime: 00000 } * @throws BinanceApiException in case of any error */ public JsonObject time() throws BinanceApiException { return (new BinanceRequest(baseUrl + "v1/time")) .read().asJsonObject(); } // - - - - - - - - - - - - - - - - - - - - - - - - // MARKET ENDPOINTS // - - - - - - - - - - - - - - - - - - - - - - - - /** * 24hr ticker price change statistics * @param symbol Symbol pair, i.e. BNBBTC * @return result in JSON * @throws BinanceApiException in case of any error */ public JsonObject depth(BinanceSymbol symbol) throws BinanceApiException { return (new BinanceRequest(baseUrl + "v1/depth?symbol=" + symbol.get())) .read().asJsonObject(); } /** * 24hr ticker price change statistics, with limit explicitly set * @param symbol Symbol pair, i.e. BNBBTC * @param limit numeric limit of results * @return result in JSON * @throws BinanceApiException in case of any error */ public JsonObject depth(BinanceSymbol symbol, int limit) throws BinanceApiException { return (new BinanceRequest(baseUrl + "v1/depth?symbol=" + symbol.get() + "&limit=" + limit)) .read().asJsonObject(); } /** * Get compressed, aggregate trades and map result into BinanceAggregatedTrades type for better readability * Trades that fill at the time, from the same order, with the same price will have the quantity aggregated. * Allowed options - fromId, startTime, endTime. * If both startTime and endTime are sent, limit should not be sent AND the distance between startTime and endTime must be less than 24 hours. * If fromId, startTime, and endTime are not sent, the most recent aggregate trades will be returned. * @param symbol Symbol pair, i.e. BNBBTC * @param limit numeric limit of results * @param options map of additional properties. leave null if not needed * @return list of aggregated trades * @throws BinanceApiException in case of any error */ public List<BinanceAggregatedTrades> aggTrades(BinanceSymbol symbol, int limit, Map<String, Long> options) throws BinanceApiException { String u = baseUrl + "v1/aggTrades?symbol=" + symbol.get() + "&limit=" + limit; if (options != null) { for (String optionKey : options.keySet()) { if (!optionKey.equals("fromId") && !optionKey.equals("startTime") && !optionKey.equals("endTime")) { throw new BinanceApiException("Invalid aggTrades option, only fromId, startTime, endTime are allowed"); } u += "&" + optionKey + "=" + options.get(optionKey); } } String lastResponse = (new BinanceRequest(u)).read().getLastResponse(); Type listType = new TypeToken<List<BinanceAggregatedTrades>>() { }.getType(); return new Gson().fromJson(lastResponse, listType); } /** * short version of aggTrades with less parameters * * @param symbol Symbol pair, i.e. BNBBTC * @param options map of additional properties. leave null if not needed * @return list of aggregated trades * @throws BinanceApiException in case of any error */ public List<BinanceAggregatedTrades> aggTrades(BinanceSymbol symbol, Map<String, Long> options) throws BinanceApiException { return this.aggTrades(symbol, 500, options); } /** * short version of aggTrades with less parameters * * @param symbol Symbol pair, i.e. BNBBTC * @return list of aggregated trades * @throws BinanceApiException in case of any error */ public List<BinanceAggregatedTrades> aggTrades(BinanceSymbol symbol) throws BinanceApiException { return this.aggTrades(symbol, 500, null); } /** * Kline/candlestick bars for a symbol. Klines are uniquely identified by their open time. * if startTime and endTime are not sent, the most recent klines are returned. * @param symbol Symbol pair, i.e. BNBBTC * @param interval valid time interval, see BinanceInterval enum * @param limit numeric limit of results * @param options options map of additional properties. leave null if not needed * @return list of candlesticks * @throws BinanceApiException in case of any error */ public List<BinanceCandlestick> klines(BinanceSymbol symbol, BinanceInterval interval, int limit, Map<String, Long> options) throws BinanceApiException { String u = baseUrl + "v1/klines?symbol=" + symbol.get() + "&interval=" + interval.toString() + "&limit=" + limit; if (options != null) { for (String optionKey : options.keySet()) { if (!optionKey.equals("startTime") && !optionKey.equals("endTime")) { throw new BinanceApiException("Invalid klines option, only startTime, endTime are allowed"); } u += "&" + optionKey + "=" + options.get(optionKey); } } JsonArray jsonElements = (new BinanceRequest(u)).read().asJsonArray(); List<BinanceCandlestick> list = new LinkedList<>(); for (JsonElement e : jsonElements) list.add(new BinanceCandlestick(e.getAsJsonArray())); return list; } /** * short version of klines() with less parameters * @param symbol Symbol pair, i.e. BNBBTC * @param interval valid time interval, see BinanceInterval enum * @return list of candlesticks * @throws BinanceApiException in case of any error */ public List<BinanceCandlestick> klines(BinanceSymbol symbol, BinanceInterval interval) throws BinanceApiException { return klines(symbol, interval, 500, null); } /** * get public statistics on Binance markets * This is stated to be a temporary solution - not a part of API documentation yet * @return BinanceExchangeStat * @throws BinanceApiException in case of any error */ public BinanceExchangeStats publicStats() throws BinanceApiException { JsonObject jsonObject = (new BinanceRequest("https://www.binance.com/exchange/public/product")) .read().asJsonObject(); return new BinanceExchangeStats(jsonObject); } /** * Exchange info - information about open markets * @return BinanceExchangeInfo * @throws BinanceApiException in case of any error */ public BinanceExchangeInfo exchangeInfo() throws BinanceApiException { JsonObject jsonObject = (new BinanceRequest(baseUrl + "v1/exchangeInfo")) .read().asJsonObject(); return new BinanceExchangeInfo(jsonObject); } /** * 24hr ticker price change statistics * @return json array with prices for all symbols * @throws BinanceApiException in case of any error */ public JsonArray ticker24hr() throws BinanceApiException { return (new BinanceRequest(baseUrl + "v1/ticker/24hr" )) .read().asJsonArray(); } /** * 24hr ticker price change statistics * @param symbol Symbol pair, i.e. BNBBTC * @return json with prices * @throws BinanceApiException in case of any error */ public JsonObject ticker24hr(BinanceSymbol symbol) throws BinanceApiException { return (new BinanceRequest(baseUrl + "v1/ticker/24hr?symbol=" + symbol.get())) .read().asJsonObject(); } /** * Latest price for all symbols * * @return raw JSON Array of all prices * @throws BinanceApiException in case of any error */ public JsonArray allPrices() throws BinanceApiException { return (new BinanceRequest(baseUrl + "v1/ticker/allPrices")) .read().asJsonArray(); } /** * Latest price for all symbols - * * @return Map of big decimals * @throws BinanceApiException in case of any error */ public Map<String, BigDecimal> pricesMap() throws BinanceApiException { Map<String, BigDecimal> map = new ConcurrentHashMap<>(); for (JsonElement elem : allPrices()) { JsonObject obj = elem.getAsJsonObject(); map.put(obj.get("symbol").getAsString(), obj.get("price").getAsBigDecimal()); } return map; } /** * Get best price/qty on the order book for all symbols. * * @return JsonArray * @throws BinanceApiException in case of any error */ public JsonArray allBookTickers() throws BinanceApiException { return (new BinanceRequest(baseUrl + "v1/ticker/allBookTickers")) .read().asJsonArray(); } /** * Get best price/qty on the order book for all symbols. * * @return map of BinanceTicker * @throws BinanceApiException in case of any error */ public Map<String, BinanceTicker> allBookTickersMap() throws BinanceApiException { String lastResponse = (new BinanceRequest(baseUrl + "v1/ticker/allBookTickers")).read().getLastResponse(); Type listType = new TypeToken<List<BinanceTicker>>() { }.getType(); Map<String, BinanceTicker> mapTickers = new ConcurrentHashMap<>(); List<BinanceTicker> ticker = new Gson().fromJson(lastResponse, listType); for (BinanceTicker t : ticker) mapTickers.put(t.getSymbol(), t); return mapTickers; } public Set<String> getCoinsOf(String coin) { try { BinanceExchangeStats binanceExchangeStats = this.publicStats(); return binanceExchangeStats.getCoinsOf(coin.toUpperCase()); } catch (Exception e) { log.error("BINANCE UNCAUGHT EXCEPTION {}", e); } catch (BinanceApiException e) { log.warn("BINANCE ERROR {}", e.getMessage()); } return ImmutableSet.of(); } // - - - - - - - - - - - - - - - - - - - - - - - - // ACCOUNT READ-ONLY ENDPOINTS // - - - - - - - - - - - - - - - - - - - - - - - - /** * Getting account information * @return JsonObject * @throws BinanceApiException in case of any error */ public JsonObject account() throws BinanceApiException { return (new BinanceRequest(baseUrl + "v3/account")) .sign(apiKey, secretKey, null).read().asJsonObject(); } /** * Getting balances - part of account information * @return JsonArray * @throws BinanceApiException in case of any error */ public JsonArray balances() throws BinanceApiException { return account().get("balances").getAsJsonArray(); } /** * Getting balances - part of account information * @return map of wallet assets structure * @throws BinanceApiException in case of any error */ public Map<String, BinanceWalletAsset> balancesMap() throws BinanceApiException { Map<String, BinanceWalletAsset> mapAssets = new ConcurrentHashMap<>(); for (JsonElement el : balances()) { BinanceWalletAsset w = new BinanceWalletAsset(el.getAsJsonObject()); mapAssets.put(w.getAsset(), w); } return mapAssets; } /** * Get all my open orders. <strong>Can use up a lot of Binance Weight. Use with caution.</strong> * <p> * {@link https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#current-open-orders-user_data} * * @return List of Orders * @throws BinanceApiException in case of any error */ public List<BinanceOrder> allOpenOrders() throws BinanceApiException { String u = baseUrl + "v3/openOrders"; String lastResponse = (new BinanceRequest(u)).sign(apiKey, secretKey, null).read().getLastResponse(); Type listType = new TypeToken<List<BinanceOrder>>() { }.getType(); return new Gson().fromJson(lastResponse, listType); } /** * Get all open orders on a symbol. * @param symbol i.e. BNBBTC * @return List of Orders * @throws BinanceApiException in case of any error */ public List<BinanceOrder> openOrders(BinanceSymbol symbol) throws BinanceApiException { String u = baseUrl + "v3/openOrders?symbol=" + symbol.toString(); String lastResponse = (new BinanceRequest(u)).sign(apiKey, secretKey, null).read().getLastResponse(); Type listType = new TypeToken<List<BinanceOrder>>() { }.getType(); return new Gson().fromJson(lastResponse, listType); } /** * Get all orders on a symbol; active, canceled, or filled. * If orderId is set (not null and greater than 0), it will get orders greater or equal than orderId. * Otherwise most recent orders are returned. * @param symbol i.e. BNBBTC * @param orderId numeric Order ID * @param limit numeric limit of orders in result * @return List of Orders * @throws BinanceApiException in case of any error */ public List<BinanceOrder> allOrders(BinanceSymbol symbol, Long orderId, int limit) throws BinanceApiException { String u = baseUrl + "v3/allOrders?symbol=" + symbol.toString() + "&limit=" + limit; if (orderId != null && orderId > 0) u += "&orderId=" + orderId; String lastResponse = (new BinanceRequest(u)).sign(apiKey, secretKey, null).read().getLastResponse(); Type listType = new TypeToken<List<BinanceOrder>>() {}.getType(); return new Gson().fromJson(lastResponse, listType); } /** * short version of allOrders * @param symbol i.e. BNBBTC * @return list of orders * @throws BinanceApiException in case of any error */ public List<BinanceOrder> allOrders(BinanceSymbol symbol) throws BinanceApiException { return allOrders(symbol, 0L, 500); } /** * Get trades for a specific account and symbol. * @param symbol i.e. BNBBTC * @param orderId numeric order ID * @param limit numeric limit of results * @return list of trades * @throws BinanceApiException in case of any error */ public List<BinanceTrade> myTrades(BinanceSymbol symbol, Long orderId, int limit) throws BinanceApiException { String u = baseUrl + "v3/myTrades?symbol=" + symbol.toString() + "&limit=" + limit; if (orderId != null && orderId > 0) u += "&orderId=" + orderId; String lastResponse = (new BinanceRequest(u)).sign(apiKey, secretKey, null).read().getLastResponse(); Type listType = new TypeToken<List<BinanceTrade>>() {}.getType(); return new Gson().fromJson(lastResponse, listType); } /** * short version of myTrades(symbol, orderId, limit) * @param symbol i.e. BNBBTC * @return list of trades * @throws BinanceApiException in case of any error */ public List<BinanceTrade> myTrades(BinanceSymbol symbol) throws BinanceApiException { return myTrades(symbol, 0L, 500); } /** * Get Order Status * @param symbol i.e. BNBBTC * @param orderId numeric order ID * @return BinanceOrder object if successfull * @throws BinanceApiException in case of any error */ public BinanceOrder getOrderById(BinanceSymbol symbol, Long orderId ) throws BinanceApiException { String u = baseUrl + "v3/order?symbol=" + symbol.toString() + "&orderId=" + orderId; String lastResponse = (new BinanceRequest(u)).sign(apiKey, secretKey, null).read().getLastResponse(); return (new Gson()).fromJson(lastResponse, BinanceOrder.class); } /** * @param symbol i.e. BNBBTC * @param origClientOrderId Custom Order ID, generated by client * @return BinanceOrder object if successfull * @throws BinanceApiException in case of any error */ public BinanceOrder getOrderByOrigClientId(BinanceSymbol symbol, String origClientOrderId) throws BinanceApiException { String u = baseUrl + "v3/order?symbol=" + symbol.toString() + "&origClientOrderId=" + esc.escape(origClientOrderId); String lastResponse = (new BinanceRequest(u)).sign(apiKey, secretKey, null).read().getLastResponse(); return (new Gson()).fromJson(lastResponse, BinanceOrder.class); } /** * Getting order from order object. A wrapper for getOrderById(symbol, orderId) * In face, used to refresh information on existing order * * @param order existing order structure * @return existing BinanceOrder record * @throws BinanceApiException in case of any error */ public BinanceOrder getOrder(BinanceOrder order) throws BinanceApiException { return getOrderById(BinanceSymbol.valueOf(order.getSymbol()), order.getOrderId() ); } // - - - - - - - - - - - - - - - - - - - - - - - - // TRADING ENDPOINTS // - - - - - - - - - - - - - - - - - - - - - - - - /** * @param orderPlacement class for order placement * @return json result from order placement * @throws BinanceApiException in case of any error */ public JsonObject createOrder(BinanceOrderPlacement orderPlacement) throws BinanceApiException { String u = baseUrl + "v3/order?" + orderPlacement.getAsQuery(); return (new BinanceRequest(u)).sign(apiKey, secretKey, null).post().read().asJsonObject(); } /** * @param orderPlacement class for order placement * @return json result from order placement * @throws BinanceApiException in case of any error */ public JsonObject testOrder(BinanceOrderPlacement orderPlacement) throws BinanceApiException { String u = baseUrl + "v3/order/test?" + orderPlacement.getAsQuery(); return (new BinanceRequest(u)).sign(apiKey, secretKey, null).post().read().asJsonObject(); } /** * Deletes order by order ID * @param symbol i.e. "BNBBTC" * @param orderId numeric Order ID * @return json result from order placement * @throws BinanceApiException in case of any error */ public JsonObject deleteOrderById(BinanceSymbol symbol, Long orderId) throws BinanceApiException { String u = baseUrl + "v3/order?symbol=" + symbol.toString() + "&orderId=" + orderId; return (new BinanceRequest(u)).sign(apiKey, secretKey, null).delete().read().asJsonObject(); } /** * Deletes order by original client ID * @param symbol i.e. "BNBBTC" * @param origClientOrderId string order ID, generated by client * @return json result * @throws BinanceApiException in case of any error */ public JsonObject deleteOrderByOrigClientId(BinanceSymbol symbol, String origClientOrderId) throws BinanceApiException { String u = baseUrl + "v3/order?symbol=" + symbol.toString() + "&origClientOrderId=" + esc.escape(origClientOrderId); return (new BinanceRequest(u)).sign(apiKey, secretKey, null).delete().read().asJsonObject(); } /** * Deletes order by new client ID * @param symbol i.e. "BNBBTC" * @param newClientOrderId string order ID, generated by server * @return json result * @throws BinanceApiException in case of any error */ public JsonObject deleteOrderByNewClientId(BinanceSymbol symbol, String newClientOrderId ) throws BinanceApiException { String u = baseUrl + "v3/order?symbol=" + symbol.toString() + "&newClientOrderId=" + esc.escape(newClientOrderId); return (new BinanceRequest(u)).sign(apiKey, secretKey, null).delete().read().asJsonObject(); } /**` * Deletes order by BinanceOrder object * @param order object of existing order * @return json result * @throws BinanceApiException in case of any error */ public JsonObject deleteOrder(BinanceOrder order) throws BinanceApiException { BinanceSymbol symbol = BinanceSymbol.valueOf(order.getSymbol()); if (!Strings.isNullOrEmpty(order.getClientOrderId())) { return deleteOrderByOrigClientId(symbol, order.getClientOrderId()); } return deleteOrderById(symbol, order.getOrderId()); } // - - - - - - - - - - - - - - - - - - - - - - - - // USER DATA STREAM // - - - - - - - - - - - - - - - - - - - - - - - - /** * Start user data stream, get a key for websocket * @return listenKey - key that could be used to manage stream * @throws BinanceApiException in case of any error */ public String startUserDataStream() throws BinanceApiException { JsonObject jsonObject = (new BinanceRequest(baseUrl + "v1/userDataStream")) .sign(apiKey).post().read().asJsonObject(); return jsonObject.get("listenKey").getAsString(); } /** * Keep user data stream alive * @param listenKey - key that could be used to manage stream * @return json result * @throws BinanceApiException in case of any error */ public JsonObject keepUserDataStream(String listenKey) throws BinanceApiException { return (new BinanceRequest(baseUrl + "v1/userDataStream?listenKey=" + esc.escape(listenKey))) .sign(apiKey).put().read().asJsonObject(); } /** * Close user data stream * @param listenKey key for user stream management * @return json result * @throws BinanceApiException in case of any error */ public JsonObject deleteUserDataStream(String listenKey) throws BinanceApiException { return (new BinanceRequest(baseUrl + "v1/userDataStream?listenKey=" + esc.escape(listenKey))) .sign(apiKey).delete().read().asJsonObject(); } // - - - - - - - - - - - - - - - - - - - - - - - - // WEBSOCKET ENDPOINTS // - - - - - - - - - - - - - - - - - - - - - - - - /** * Base method for all websockets streams * @param url derived methods will use unique base url * @param adapter class to handle the event * @return web socket session * @throws BinanceApiException in case of any error */ public Session getWebsocketSession(String url, WebSocketAdapter adapter) throws BinanceApiException { try { URI uri = new URI(websocketBaseUrl + url); SslContextFactory sslContextFactory = new SslContextFactory(); sslContextFactory.setTrustAll(true); // The magic WebSocketClient client = new WebSocketClient(sslContextFactory); client.start(); return client.connect(adapter, uri).get(); } catch (URISyntaxException e) { throw new BinanceApiException("URL Syntax error: " + e.getMessage()); } catch (Throwable e) { throw new BinanceApiException("Websocket error: " + e.getMessage()); } } /** * Depth Websocket Stream Listener * @param symbol i.e. "BNBBTC" * @param adapter class to handle the event * @return web socket session * @throws BinanceApiException in case of any error */ public Session websocketDepth(BinanceSymbol symbol, BinanceWebSocketAdapterDepth adapter) throws BinanceApiException { return getWebsocketSession(symbol.toString().toLowerCase() + "@depth", adapter); } /** * Depth Websocket Stream Listener - best 20 levels * @param symbol i.e. "BNBBTC" * @param adapter class to handle the events * @return web socket session * @throws BinanceApiException in case of any error */ public Session websocketDepth20(BinanceSymbol symbol, BinanceWebSocketAdapterDepthLevel adapter) throws BinanceApiException { return getWebsocketSession(symbol.toString().toLowerCase() + "@depth20", adapter); } /** * Depth Websocket Stream Listener - best 10 levels * @param symbol i.e. "BNBBTC" * @param adapter class to handle the events * @return web socket session * @throws BinanceApiException in case of any error */ public Session websocketDepth10(BinanceSymbol symbol, BinanceWebSocketAdapterDepthLevel adapter) throws BinanceApiException { return getWebsocketSession(symbol.toString().toLowerCase() + "@depth10", adapter); } /** * Depth Websocket Stream Listener - best 5 lavels * @param symbol i.e. "BNBBTC" * @param adapter class to handle the events * @return web socket session * @throws BinanceApiException in case of any error */ public Session websocketDepth5(BinanceSymbol symbol, BinanceWebSocketAdapterDepthLevel adapter) throws BinanceApiException { return getWebsocketSession(symbol.toString().toLowerCase() + "@depth5", adapter); } /** * Klines Websocket Stream Listener * @param symbol i.e. "BNBBTC" * @param interval valid time interval, see BinanceInterval enum * @param adapter class to handle the events * @return web socket session * @throws BinanceApiException in case of any error */ public Session websocketKlines(BinanceSymbol symbol, BinanceInterval interval, BinanceWebSocketAdapterKline adapter) throws BinanceApiException { return getWebsocketSession(symbol.toString().toLowerCase() + "@kline_" + interval.toString(), adapter); } /** * Trades Websocket Stream Listener * @param symbol i.e. "BNBBTC" * @param adapter class to handle the events * @return web socket session * @throws BinanceApiException in case of any error */ public Session websocketTrades(BinanceSymbol symbol, BinanceWebSocketAdapterAggTrades adapter) throws BinanceApiException { return getWebsocketSession(symbol.toString().toLowerCase() + "@aggTrade", adapter); } /** * User Data Websocket Stream Listener * @param listenKey string, received in startUserDataStream() * @param adapter class to handle the event * @return web socket session * @throws BinanceApiException in case of any error */ public Session websocket(String listenKey, BinanceWebSocketAdapterUserData adapter) throws BinanceApiException { return getWebsocketSession(listenKey, adapter); } /** * Withdrawal APIs - might not work yet * * @param asset string of asset name, i.e. "BNB" * @param address string of destination wallet address * @param amount amount to be withdrawn * @param name label of destination address, can be left empty * @return empty json object if success * @throws BinanceApiException in case of any error */ public JsonObject withdraw(String asset, String address, long amount, String name) throws BinanceApiException { String u = baseWapiUrl + "/v1/withdraw.html?asset=" + esc.escape(asset) + "&address=" + esc.escape(address) + "&amount=" + amount; if (!Strings.isNullOrEmpty(name)) { u += "name=" + esc.escape(name); } return (new BinanceRequest(u)) .sign(apiKey).post().read().asJsonObject(); } /** * Getting history of withdrawals - might not work yet. * So far response is string. at the moment of writing * there is a response in Chinese about parameter exception (which cannot be parsed by JSON), * and someone seems to still work on that part of server side * @param historyFilter structure for user's history filtration * @return Temporary returns String until WAPI will be fixed * @throws BinanceApiException in case of any error */ public String getWithdrawHistory(BinanceHistoryFilter historyFilter) throws BinanceApiException { String q = historyFilter.getAsQuery(); String u = baseWapiUrl + "v1/getWithdrawHistory.html" + (Strings.isNullOrEmpty(q) ? "": ("?" + q)); return (new BinanceRequest(u)).sign(apiKey).post().read().getLastResponse(); } /** * Getting history of deposits - might not work yet * So far response is string. at the moment of writing * there is a response in Chinese about parameter exception (which cannot be parsed by JSON), * and someone seems to still work on that part of server side * @param historyFilter structure for user's history filtration * @return Temporary returns String until WAPI will be fixed * @throws BinanceApiException in case of any error */ public String getDepositHistory(BinanceHistoryFilter historyFilter) throws BinanceApiException { String q = historyFilter.getAsQuery(); String u = baseWapiUrl + "v1/getDepositHistory.html" + (Strings.isNullOrEmpty(q) ? "": ("?" + q)); return (new BinanceRequest(u)).sign(apiKey).post().read().getLastResponse(); } /** * Getting status of the system * @return Temporary returns JsonObject * @throws BinanceApiException in case of any error */ public JsonObject getSystemStatus() throws BinanceApiException { String u = baseWapi3 + "/systemStatus.html"; return (new BinanceRequest(u)).read().asJsonObject(); } }