From 880955a277a514563a2e754f19c040a8991718ef Mon Sep 17 00:00:00 2001 From: joaopsilva Date: Wed, 6 Dec 2017 18:11:58 +0100 Subject: [PATCH 01/81] Ignore unknown properties for Orders. --- src/main/java/com/binance/api/client/domain/account/Order.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/binance/api/client/domain/account/Order.java b/src/main/java/com/binance/api/client/domain/account/Order.java index 793d6ee2a..7cf967ba8 100644 --- a/src/main/java/com/binance/api/client/domain/account/Order.java +++ b/src/main/java/com/binance/api/client/domain/account/Order.java @@ -13,6 +13,7 @@ /** * Trade order information. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class Order { /** From af6ab53373d4439c13b9de2b3b7dc42e5bbc6e30 Mon Sep 17 00:00:00 2001 From: joaopsilva Date: Tue, 12 Dec 2017 22:20:46 +0100 Subject: [PATCH 02/81] Fixed #2 - Update account domain object to take into account newly added properties. --- .../api/client/domain/account/Account.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/com/binance/api/client/domain/account/Account.java b/src/main/java/com/binance/api/client/domain/account/Account.java index b160a5d31..189bbd0d1 100644 --- a/src/main/java/com/binance/api/client/domain/account/Account.java +++ b/src/main/java/com/binance/api/client/domain/account/Account.java @@ -1,5 +1,6 @@ package com.binance.api.client.domain.account; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -8,6 +9,7 @@ /** * Account information. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class Account { /** @@ -45,6 +47,14 @@ public class Account { */ private boolean canDeposit; + /** + * Last account update time. + */ + private long updateTime; + + /** + * List of asset balances of this account. + */ private List balances; public int getMakerCommission() { @@ -103,6 +113,14 @@ public void setCanDeposit(boolean canDeposit) { this.canDeposit = canDeposit; } + public long getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(long updateTime) { + this.updateTime = updateTime; + } + public List getBalances() { return balances; } @@ -140,6 +158,7 @@ public String toString() { .append("canTrade", canTrade) .append("canWithdraw", canWithdraw) .append("canDeposit", canDeposit) + .append("updateTime", updateTime) .append("balances", balances) .toString(); } From 432a77d9e040d72a8bc94cf247309da0f3453a01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Silva?= Date: Sat, 16 Dec 2017 22:35:29 +0100 Subject: [PATCH 03/81] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..c28de715e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Binance + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 824b2e4272a6532ccbce606aa997ca0d3e732bdd Mon Sep 17 00:00:00 2001 From: joaopsilva Date: Sun, 24 Dec 2017 00:13:42 +0100 Subject: [PATCH 04/81] Resolves #5 - Support /exchangeInfo endpoint --- .../api/client/BinanceApiAsyncRestClient.java | 6 + .../api/client/BinanceApiRestClient.java | 11 +- .../binance/api/client/domain/OrderType.java | 7 +- .../client/domain/general/ExchangeFilter.java | 42 ++++++ .../client/domain/general/ExchangeInfo.java | 78 ++++++++++ .../api/client/domain/general/FilterType.java | 17 +++ .../api/client/domain/general/RateLimit.java | 49 ++++++ .../domain/general/RateLimitInterval.java | 10 ++ .../client/domain/general/RateLimitType.java | 9 ++ .../client/domain/general/SymbolFilter.java | 139 ++++++++++++++++++ .../api/client/domain/general/SymbolInfo.java | 131 +++++++++++++++++ .../client/domain/general/SymbolStatus.java | 14 ++ .../impl/BinanceApiAsyncRestClientImpl.java | 8 +- .../client/impl/BinanceApiRestClientImpl.java | 6 + .../api/client/impl/BinanceApiService.java | 4 + .../general/ExchangeInfoDeserializerTest.java | 128 ++++++++++++++++ .../api/examples/GeneralEndpointsExample.java | 17 +++ .../GeneralEndpointsExampleAsync.java | 20 ++- 18 files changed, 692 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/binance/api/client/domain/general/ExchangeFilter.java create mode 100644 src/main/java/com/binance/api/client/domain/general/ExchangeInfo.java create mode 100644 src/main/java/com/binance/api/client/domain/general/FilterType.java create mode 100644 src/main/java/com/binance/api/client/domain/general/RateLimit.java create mode 100644 src/main/java/com/binance/api/client/domain/general/RateLimitInterval.java create mode 100644 src/main/java/com/binance/api/client/domain/general/RateLimitType.java create mode 100644 src/main/java/com/binance/api/client/domain/general/SymbolFilter.java create mode 100644 src/main/java/com/binance/api/client/domain/general/SymbolInfo.java create mode 100644 src/main/java/com/binance/api/client/domain/general/SymbolStatus.java create mode 100644 src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java diff --git a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java index 3a77e85c9..f4bbbc700 100644 --- a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java @@ -13,6 +13,7 @@ import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; import com.binance.api.client.domain.event.ListenKey; +import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.ServerTime; import com.binance.api.client.domain.market.AggTrade; import com.binance.api.client.domain.market.BookTicker; @@ -41,6 +42,11 @@ public interface BinanceApiAsyncRestClient { */ void getServerTime(BinanceApiCallback callback); + /** + * Current exchange trading rules and symbol information + */ + void getExchangeInfo(BinanceApiCallback callback); + // Market Data endpoints /** diff --git a/src/main/java/com/binance/api/client/BinanceApiRestClient.java b/src/main/java/com/binance/api/client/BinanceApiRestClient.java index df4749a2e..a6dac9ebc 100644 --- a/src/main/java/com/binance/api/client/BinanceApiRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiRestClient.java @@ -12,6 +12,7 @@ import com.binance.api.client.domain.account.request.CancelOrderRequest; import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; +import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.market.AggTrade; import com.binance.api.client.domain.market.BookTicker; import com.binance.api.client.domain.market.Candlestick; @@ -19,6 +20,7 @@ import com.binance.api.client.domain.market.OrderBook; import com.binance.api.client.domain.market.TickerPrice; import com.binance.api.client.domain.market.TickerStatistics; +import retrofit2.Call; import java.util.List; @@ -35,10 +37,17 @@ public interface BinanceApiRestClient { void ping(); /** - * Check server time. + * Test connectivity to the Rest API and get the current server time. + * + * @return current server time. */ Long getServerTime(); + /** + * @return Current exchange trading rules and symbol information + */ + ExchangeInfo getExchangeInfo(); + // Market Data endpoints /** diff --git a/src/main/java/com/binance/api/client/domain/OrderType.java b/src/main/java/com/binance/api/client/domain/OrderType.java index 1ef7e8974..46eb162c2 100644 --- a/src/main/java/com/binance/api/client/domain/OrderType.java +++ b/src/main/java/com/binance/api/client/domain/OrderType.java @@ -5,5 +5,10 @@ */ public enum OrderType { LIMIT, - MARKET + MARKET, + STOP_LOSS, + STOP_LOSS_LIMIT, + TAKE_PROFIT, + TAKE_PROFIT_LIMIT, + LIMIT_MAKER } diff --git a/src/main/java/com/binance/api/client/domain/general/ExchangeFilter.java b/src/main/java/com/binance/api/client/domain/general/ExchangeFilter.java new file mode 100644 index 000000000..765c616ab --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/general/ExchangeFilter.java @@ -0,0 +1,42 @@ +package com.binance.api.client.domain.general; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * Exchange Filters define trading rules an exchange. + * + * The MAX_NUM_ORDERS filter defines the maximum number of orders an account is allowed to have open on the exchange. Note that both "algo" orders and normal orders are counted for this filter. + * + * The MAX_ALGO_ORDERS filter defines the maximum number of "algo" orders an account is allowed to have open on the exchange. "Algo" orders are STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, and TAKE_PROFIT_LIMIT orders. + */ +public class ExchangeFilter { + + private FilterType filterType; + + private Integer limit; + + public FilterType getFilterType() { + return filterType; + } + + public void setFilterType(FilterType filterType) { + this.filterType = filterType; + } + + public Integer getLimit() { + return limit; + } + + public void setLimit(Integer limit) { + this.limit = limit; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + .append("filterType", filterType) + .append("limit", limit) + .toString(); + } +} diff --git a/src/main/java/com/binance/api/client/domain/general/ExchangeInfo.java b/src/main/java/com/binance/api/client/domain/general/ExchangeInfo.java new file mode 100644 index 000000000..fad53c12d --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/general/ExchangeInfo.java @@ -0,0 +1,78 @@ +package com.binance.api.client.domain.general; + +import com.binance.api.client.exception.BinanceApiException; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.List; + +/** + * Current exchange trading rules and symbol information. + * https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ExchangeInfo { + + private String timezone; + + private Long serverTime; + + private List rateLimits; + + // private List exchangeFilters; + + private List symbols; + + public String getTimezone() { + return timezone; + } + + public void setTimezone(String timezone) { + this.timezone = timezone; + } + + public Long getServerTime() { + return serverTime; + } + + public void setServerTime(Long serverTime) { + this.serverTime = serverTime; + } + + public List getRateLimits() { + return rateLimits; + } + + public void setRateLimits(List rateLimits) { + this.rateLimits = rateLimits; + } + + public List getSymbols() { + return symbols; + } + + public void setSymbols(List symbols) { + this.symbols = symbols; + } + + /** + * @param symbol the symbol to obtain information for (e.g. ETHBTC) + * @return symbol exchange information + */ + public SymbolInfo getSymbolInfo(String symbol) { + return symbols.stream().filter(symbolInfo -> symbolInfo.getSymbol().equals(symbol)) + .findFirst() + .orElseThrow(() -> new BinanceApiException("Unable to obtain information for symbol " + symbol)); + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + .append("timezone", timezone) + .append("serverTime", serverTime) + .append("rateLimits", rateLimits) + .append("symbols", symbols) + .toString(); + } +} diff --git a/src/main/java/com/binance/api/client/domain/general/FilterType.java b/src/main/java/com/binance/api/client/domain/general/FilterType.java new file mode 100644 index 000000000..593b4ae5e --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/general/FilterType.java @@ -0,0 +1,17 @@ +package com.binance.api.client.domain.general; + +/** + * Filters define trading rules on a symbol or an exchange. Filters come in two forms: symbol filters and exchange filters. + */ +public enum FilterType { + // Symbol + PRICE_FILTER, + LOT_SIZE, + MIN_NOTIONAL, + MAX_NUM_ORDERS, + MAX_ALGO_ORDERS, + + // Exchange + EXCHANGE_MAX_NUM_ORDERS, + EXCHANGE_MAX_ALGO_ORDERS +} diff --git a/src/main/java/com/binance/api/client/domain/general/RateLimit.java b/src/main/java/com/binance/api/client/domain/general/RateLimit.java new file mode 100644 index 000000000..75faa1de0 --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/general/RateLimit.java @@ -0,0 +1,49 @@ +package com.binance.api.client.domain.general; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * Rate limits. + */ +public class RateLimit { + + private RateLimitType rateLimitType; + + private RateLimitInterval interval; + + private Integer limit; + + public RateLimitType getRateLimitType() { + return rateLimitType; + } + + public void setRateLimitType(RateLimitType rateLimitType) { + this.rateLimitType = rateLimitType; + } + + public RateLimitInterval getInterval() { + return interval; + } + + public void setInterval(RateLimitInterval interval) { + this.interval = interval; + } + + public Integer getLimit() { + return limit; + } + + public void setLimit(Integer limit) { + this.limit = limit; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + .append("rateLimitType", rateLimitType) + .append("interval", interval) + .append("limit", limit) + .toString(); + } +} diff --git a/src/main/java/com/binance/api/client/domain/general/RateLimitInterval.java b/src/main/java/com/binance/api/client/domain/general/RateLimitInterval.java new file mode 100644 index 000000000..bc316061d --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/general/RateLimitInterval.java @@ -0,0 +1,10 @@ +package com.binance.api.client.domain.general; + +/** + * Rate limit intervals. + */ +public enum RateLimitInterval { + SECOND, + MINUTE, + DAY +} \ No newline at end of file diff --git a/src/main/java/com/binance/api/client/domain/general/RateLimitType.java b/src/main/java/com/binance/api/client/domain/general/RateLimitType.java new file mode 100644 index 000000000..af438bebb --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/general/RateLimitType.java @@ -0,0 +1,9 @@ +package com.binance.api.client.domain.general; + +/** + * Rate limiters. + */ +public enum RateLimitType { + REQUESTS, + ORDERS +} diff --git a/src/main/java/com/binance/api/client/domain/general/SymbolFilter.java b/src/main/java/com/binance/api/client/domain/general/SymbolFilter.java new file mode 100644 index 000000000..8902b1188 --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/general/SymbolFilter.java @@ -0,0 +1,139 @@ +package com.binance.api.client.domain.general; + +/** + * Filters define trading rules on a symbol or an exchange. Filters come in two forms: symbol filters and exchange filters. + * + * The PRICE_FILTER defines the price rules for a symbol. + * + * The LOT_SIZE filter defines the quantity (aka "lots" in auction terms) rules for a symbol. + * + * The MIN_NOTIONAL filter defines the minimum notional value allowed for an order on a symbol. An order's notional value is the price * quantity. + * + * The MAX_NUM_ORDERS filter defines the maximum number of orders an account is allowed to have open on a symbol. Note that both "algo" orders and normal orders are counted for this filter. + * + * The MAX_ALGO_ORDERS filter defines the maximum number of "algo" orders an account is allowed to have open on a symbol. "Algo" orders are STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, and TAKE_PROFIT_LIMIT orders. + */ +public class SymbolFilter { + + // PRICE_FILTER + + private FilterType filterType; + + /** + * Defines the minimum price/stopPrice allowed. + */ + private String minPrice; + + /** + * Defines the maximum price/stopPrice allowed. + */ + private String maxPrice; + + /** + * Defines the intervals that a price/stopPrice can be increased/decreased by. + */ + private String tickSize; + + + // LOT_SIZE + + /** + * Defines the minimum quantity/icebergQty allowed. + */ + private String minQty; + + /** + * Defines the maximum quantity/icebergQty allowed. + */ + private String maxQty; + + /** + * Defines the intervals that a quantity/icebergQty can be increased/decreased by. + */ + private String stepSize; + + // MIN_NOTIONAL + + /** + * Defines the minimum notional value allowed for an order on a symbol. An order's notional value is the price * quantity. + */ + private String minNotional; + + /** + * MAX_NUM_ORDERS filter defines the maximum number of orders an account is allowed to have open on a symbol. Note that both "algo" orders and normal orders are counted for this filter. + * MAX_ALGO_ORDERS filter defines the maximum number of "algo" orders an account is allowed to have open on a symbol. "Algo" orders are STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, and TAKE_PROFIT_LIMIT orders. + */ + private String limit; + + public FilterType getFilterType() { + return filterType; + } + + public void setFilterType(FilterType filterType) { + this.filterType = filterType; + } + + public String getMinPrice() { + return minPrice; + } + + public void setMinPrice(String minPrice) { + this.minPrice = minPrice; + } + + public String getMaxPrice() { + return maxPrice; + } + + public void setMaxPrice(String maxPrice) { + this.maxPrice = maxPrice; + } + + public String getTickSize() { + return tickSize; + } + + public void setTickSize(String tickSize) { + this.tickSize = tickSize; + } + + public String getMinQty() { + return minQty; + } + + public void setMinQty(String minQty) { + this.minQty = minQty; + } + + public String getMaxQty() { + return maxQty; + } + + public void setMaxQty(String maxQty) { + this.maxQty = maxQty; + } + + public String getStepSize() { + return stepSize; + } + + public void setStepSize(String stepSize) { + this.stepSize = stepSize; + } + + public String getMinNotional() { + return minNotional; + } + + public void setMinNotional(String minNotional) { + this.minNotional = minNotional; + } + + public String getLimit() { + return limit; + } + + public void setLimit(String limit) { + this.limit = limit; + } +} diff --git a/src/main/java/com/binance/api/client/domain/general/SymbolInfo.java b/src/main/java/com/binance/api/client/domain/general/SymbolInfo.java new file mode 100644 index 000000000..38a06eb27 --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/general/SymbolInfo.java @@ -0,0 +1,131 @@ +package com.binance.api.client.domain.general; + +import com.binance.api.client.domain.OrderType; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.List; + +/** + * Symbol information (base/quote). + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class SymbolInfo { + + private String symbol; + + private SymbolStatus status; + + private String baseAsset; + + private Integer baseAssetPrecision; + + private String quoteAsset; + + private Integer quotePrecision; + + private List orderTypes; + + private boolean icebergAllowed; + + private List filters; + + public String getSymbol() { + return symbol; + } + + public void setSymbol(String symbol) { + this.symbol = symbol; + } + + public SymbolStatus getStatus() { + return status; + } + + public void setStatus(SymbolStatus status) { + this.status = status; + } + + public String getBaseAsset() { + return baseAsset; + } + + public void setBaseAsset(String baseAsset) { + this.baseAsset = baseAsset; + } + + public Integer getBaseAssetPrecision() { + return baseAssetPrecision; + } + + public void setBaseAssetPrecision(Integer baseAssetPrecision) { + this.baseAssetPrecision = baseAssetPrecision; + } + + public String getQuoteAsset() { + return quoteAsset; + } + + public void setQuoteAsset(String quoteAsset) { + this.quoteAsset = quoteAsset; + } + + public Integer getQuotePrecision() { + return quotePrecision; + } + + public void setQuotePrecision(Integer quotePrecision) { + this.quotePrecision = quotePrecision; + } + + public List getOrderTypes() { + return orderTypes; + } + + public void setOrderTypes(List orderTypes) { + this.orderTypes = orderTypes; + } + + public boolean isIcebergAllowed() { + return icebergAllowed; + } + + public void setIcebergAllowed(boolean icebergAllowed) { + this.icebergAllowed = icebergAllowed; + } + + public List getFilters() { + return filters; + } + + public void setFilters(List filters) { + this.filters = filters; + } + + /** + * @param filterType filter type to filter for. + * @return symbol filter information for the provided filter type. + */ + public SymbolFilter getSymbolFilter(FilterType filterType) { + return filters.stream() + .filter(symbolFilter -> symbolFilter.getFilterType() == filterType) + .findFirst() + .get(); + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + .append("symbol", symbol) + .append("status", status) + .append("baseAsset", baseAsset) + .append("baseAssetPrecision", baseAssetPrecision) + .append("quoteAsset", quoteAsset) + .append("quotePrecision", quotePrecision) + .append("orderTypes", orderTypes) + .append("icebergAllowed", icebergAllowed) + .append("filters", filters) + .toString(); + } +} diff --git a/src/main/java/com/binance/api/client/domain/general/SymbolStatus.java b/src/main/java/com/binance/api/client/domain/general/SymbolStatus.java new file mode 100644 index 000000000..e9ddff627 --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/general/SymbolStatus.java @@ -0,0 +1,14 @@ +package com.binance.api.client.domain.general; + +/** + * Status of a symbol on the exchange. + */ +public enum SymbolStatus { + PRE_TRADING, + TRADING, + POST_TRADING, + END_OF_DAY, + HALT, + AUCTION_MATCH, + BREAK; +} diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java index 73a70c5da..ffdec9ea7 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java @@ -16,6 +16,7 @@ import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; import com.binance.api.client.domain.event.ListenKey; +import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.ServerTime; import com.binance.api.client.domain.market.AggTrade; import com.binance.api.client.domain.market.BookTicker; @@ -49,7 +50,12 @@ public void ping(BinanceApiCallback callback) { @Override public void getServerTime(BinanceApiCallback callback) { - binanceApiService.getServerTime().equals(new BinanceApiCallbackAdapter<>(callback)); + binanceApiService.getServerTime().enqueue(new BinanceApiCallbackAdapter<>(callback)); + } + + @Override + public void getExchangeInfo(BinanceApiCallback callback) { + binanceApiService.getExchangeInfo().enqueue(new BinanceApiCallbackAdapter<>(callback)); } // Market Data endpoints diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java index a536c7666..0390ac7ab 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java @@ -14,6 +14,7 @@ import com.binance.api.client.domain.account.request.CancelOrderRequest; import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; +import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.market.AggTrade; import com.binance.api.client.domain.market.BookTicker; import com.binance.api.client.domain.market.Candlestick; @@ -50,6 +51,11 @@ public Long getServerTime() { return executeSync(binanceApiService.getServerTime()).getServerTime(); } + @Override + public ExchangeInfo getExchangeInfo() { + return executeSync(binanceApiService.getExchangeInfo()); + } + // Market Data endpoints @Override diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiService.java b/src/main/java/com/binance/api/client/impl/BinanceApiService.java index 10ae03c3f..17c089f92 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiService.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiService.java @@ -12,6 +12,7 @@ import com.binance.api.client.domain.account.Trade; import com.binance.api.client.domain.account.WithdrawHistory; import com.binance.api.client.domain.event.ListenKey; +import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.ServerTime; import com.binance.api.client.domain.market.AggTrade; import com.binance.api.client.domain.market.BookTicker; @@ -42,6 +43,9 @@ public interface BinanceApiService { @GET("/api/v1/time") Call getServerTime(); + @GET("/api/v1/exchangeInfo") + Call getExchangeInfo(); + // Market data endpoints @GET("/api/v1/depth") diff --git a/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java b/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java new file mode 100644 index 000000000..af949ff6f --- /dev/null +++ b/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java @@ -0,0 +1,128 @@ +package com.binance.api.domain.general; + +import com.binance.api.client.domain.OrderType; +import com.binance.api.client.domain.general.ExchangeInfo; +import com.binance.api.client.domain.general.FilterType; +import com.binance.api.client.domain.general.RateLimit; +import com.binance.api.client.domain.general.RateLimitInterval; +import com.binance.api.client.domain.general.RateLimitType; +import com.binance.api.client.domain.general.SymbolFilter; +import com.binance.api.client.domain.general.SymbolInfo; +import com.binance.api.client.domain.general.SymbolStatus; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; + +/** + * Test deserialization of exchange information. + */ +public class ExchangeInfoDeserializerTest { + + @Test + public void testExchangeInfoDeserialization() { + final String json = "{\n" + + " \"timezone\": \"UTC\",\n" + + " \"serverTime\": 1508631584636,\n" + + " \"rateLimits\": [{\n" + + " \"rateLimitType\": \"REQUESTS\",\n" + + " \"interval\": \"MINUTE\",\n" + + " \"limit\": 1200\n" + + " },\n" + + " {\n" + + " \"rateLimitType\": \"ORDERS\",\n" + + " \"interval\": \"SECOND\",\n" + + " \"limit\": 10\n" + + " },\n" + + " {\n" + + " \"rateLimitType\": \"ORDERS\",\n" + + " \"interval\": \"DAY\",\n" + + " \"limit\": 100000\n" + + " }\n" + + " ],\n" + + " \"exchangeFilters\": [],\n" + + " \"symbols\": [{\n" + + " \"symbol\": \"ETHBTC\",\n" + + " \"status\": \"TRADING\",\n" + + " \"baseAsset\": \"ETH\",\n" + + " \"baseAssetPrecision\": 8,\n" + + " \"quoteAsset\": \"BTC\",\n" + + " \"quotePrecision\": 8,\n" + + " \"orderTypes\": [\"LIMIT\", \"MARKET\"],\n" + + " \"icebergAllowed\": false,\n" + + " \"filters\": [{\n" + + " \"filterType\": \"PRICE_FILTER\",\n" + + " \"minPrice\": \"0.00000100\",\n" + + " \"maxPrice\": \"100000.00000000\",\n" + + " \"tickSize\": \"0.00000100\"\n" + + " }, {\n" + + " \"filterType\": \"LOT_SIZE\",\n" + + " \"minQty\": \"0.00100000\",\n" + + " \"maxQty\": \"100000.00000000\",\n" + + " \"stepSize\": \"0.00100000\"\n" + + " }, {\n" + + " \"filterType\": \"MIN_NOTIONAL\",\n" + + " \"minNotional\": \"0.00100000\"\n" + + " }]\n" + + " }]" + + "}"; + ObjectMapper mapper = new ObjectMapper(); + try { + ExchangeInfo exchangeInfo = mapper.readValue(json, ExchangeInfo.class); + System.out.println(exchangeInfo); + assertEquals(exchangeInfo.getTimezone(), "UTC"); + assertEquals((long)exchangeInfo.getServerTime(), 1508631584636L); + + List rateLimits = exchangeInfo.getRateLimits(); + assertEquals(rateLimits.size(), 3); + testRateLimit(rateLimits.get(0), RateLimitType.REQUESTS, RateLimitInterval.MINUTE, 1200); + testRateLimit(rateLimits.get(1), RateLimitType.ORDERS, RateLimitInterval.SECOND, 10); + testRateLimit(rateLimits.get(2), RateLimitType.ORDERS, RateLimitInterval.DAY, 100000); + + List symbols = exchangeInfo.getSymbols(); + assertEquals(symbols.size(), 1); + SymbolInfo symbolInfo = symbols.get(0); + assertEquals(symbolInfo.getSymbol(), "ETHBTC"); + assertEquals(symbolInfo.getStatus(), SymbolStatus.TRADING); + assertEquals(symbolInfo.getBaseAsset(), "ETH"); + assertEquals((int)symbolInfo.getBaseAssetPrecision(), 8); + assertEquals(symbolInfo.getQuoteAsset(), "BTC"); + assertEquals((int)symbolInfo.getQuotePrecision(), 8); + assertEquals(symbolInfo.getOrderTypes(), Arrays.asList(OrderType.LIMIT, OrderType.MARKET)); + assertFalse(symbolInfo.isIcebergAllowed()); + + List symbolFilters = symbolInfo.getFilters(); + assertEquals(symbolFilters.size(), 3); + + SymbolFilter priceFilter = symbolFilters.get(0); + assertEquals(priceFilter.getFilterType(), FilterType.PRICE_FILTER); + assertEquals(priceFilter.getMinPrice(), "0.00000100"); + assertEquals(priceFilter.getMaxPrice(), "100000.00000000"); + assertEquals(priceFilter.getTickSize(), "0.00000100"); + + SymbolFilter lotSizeFilter = symbolFilters.get(1); + assertEquals(lotSizeFilter.getFilterType(), FilterType.LOT_SIZE); + assertEquals(lotSizeFilter.getMinQty(), "0.00100000"); + assertEquals(lotSizeFilter.getMaxQty(), "100000.00000000"); + assertEquals(lotSizeFilter.getStepSize(), "0.00100000"); + + SymbolFilter minNotionalFilter = symbolFilters.get(2); + assertEquals(minNotionalFilter.getFilterType(), FilterType.MIN_NOTIONAL); + assertEquals(minNotionalFilter.getMinNotional(), "0.00100000"); + } catch (IOException e) { + fail(); + } + } + + private void testRateLimit(RateLimit rateLimit, RateLimitType expectedRateLimitType, RateLimitInterval expectedInterval, int expectedLimit) { + assertEquals(rateLimit.getRateLimitType(), expectedRateLimitType); + assertEquals(rateLimit.getInterval(), expectedInterval); + assertEquals((long)rateLimit.getLimit(), expectedLimit); + } +} diff --git a/src/test/java/com/binance/api/examples/GeneralEndpointsExample.java b/src/test/java/com/binance/api/examples/GeneralEndpointsExample.java index 656347b26..a97c7ec27 100644 --- a/src/test/java/com/binance/api/examples/GeneralEndpointsExample.java +++ b/src/test/java/com/binance/api/examples/GeneralEndpointsExample.java @@ -2,6 +2,10 @@ import com.binance.api.client.BinanceApiClientFactory; import com.binance.api.client.BinanceApiRestClient; +import com.binance.api.client.domain.general.ExchangeInfo; +import com.binance.api.client.domain.general.FilterType; +import com.binance.api.client.domain.general.SymbolFilter; +import com.binance.api.client.domain.general.SymbolInfo; /** * Examples on how to use the general endpoints. @@ -18,5 +22,18 @@ public static void main(String[] args) { // Check server time long serverTime = client.getServerTime(); System.out.println(serverTime); + + // Exchange info + ExchangeInfo exchangeInfo = client.getExchangeInfo(); + System.out.println(exchangeInfo.getTimezone()); + System.out.println(exchangeInfo.getSymbols()); + + // Obtain symbol information + SymbolInfo symbolInfo = exchangeInfo.getSymbolInfo("ETHBTC"); + System.out.println(symbolInfo.getStatus()); + + SymbolFilter priceFilter = symbolInfo.getSymbolFilter(FilterType.PRICE_FILTER); + System.out.println(priceFilter.getMinPrice()); + System.out.println(priceFilter.getTickSize()); } } diff --git a/src/test/java/com/binance/api/examples/GeneralEndpointsExampleAsync.java b/src/test/java/com/binance/api/examples/GeneralEndpointsExampleAsync.java index 2ec2ab9a1..85a69c7ff 100644 --- a/src/test/java/com/binance/api/examples/GeneralEndpointsExampleAsync.java +++ b/src/test/java/com/binance/api/examples/GeneralEndpointsExampleAsync.java @@ -2,13 +2,17 @@ import com.binance.api.client.BinanceApiAsyncRestClient; import com.binance.api.client.BinanceApiClientFactory; +import com.binance.api.client.domain.general.ExchangeInfo; +import com.binance.api.client.domain.general.FilterType; +import com.binance.api.client.domain.general.SymbolFilter; +import com.binance.api.client.domain.general.SymbolInfo; /** * Examples on how to use the general endpoints. */ public class GeneralEndpointsExampleAsync { - public static void main(String[] args) { + public static void main(String[] args) throws InterruptedException { BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance(); BinanceApiAsyncRestClient client = factory.newAsyncRestClient(); @@ -17,5 +21,19 @@ public static void main(String[] args) { // Check server time client.getServerTime(response -> System.out.println(response.getServerTime())); + + // Exchange info + client.getExchangeInfo(exchangeInfo -> { + System.out.println(exchangeInfo.getTimezone()); + System.out.println(exchangeInfo.getSymbols()); + + // Obtain symbol information + SymbolInfo symbolInfo = exchangeInfo.getSymbolInfo("ETHBTC"); + System.out.println(symbolInfo.getStatus()); + + SymbolFilter priceFilter = symbolInfo.getSymbolFilter(FilterType.PRICE_FILTER); + System.out.println(priceFilter.getMinPrice()); + System.out.println(priceFilter.getTickSize()); + }); } } From 4e87d0c707d90a4b2767b83b69107a909662e9cf Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 2 Jan 2018 20:57:29 +0100 Subject: [PATCH 05/81] Update HmacSHA256Signer.java To avoid java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Hex.encodeHexString on Android due to different versions of commons codec. --- .../java/com/binance/api/client/security/HmacSHA256Signer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/security/HmacSHA256Signer.java b/src/main/java/com/binance/api/client/security/HmacSHA256Signer.java index f4bb3b676..be40e3ab2 100644 --- a/src/main/java/com/binance/api/client/security/HmacSHA256Signer.java +++ b/src/main/java/com/binance/api/client/security/HmacSHA256Signer.java @@ -21,7 +21,7 @@ public static String sign(String message, String secret) { Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secretKeySpec = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); sha256_HMAC.init(secretKeySpec); - return Hex.encodeHexString(sha256_HMAC.doFinal(message.getBytes())); + return new String(Hex.encodeHexString(sha256_HMAC.doFinal(message.getBytes()))); } catch (Exception e) { throw new RuntimeException("Unable to sign message.", e); } From 6b9c775b7939a37c3c4284bdd66d0b658dc1a5c7 Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 2 Jan 2018 20:59:20 +0100 Subject: [PATCH 06/81] Update HmacSHA256Signer.java --- .../java/com/binance/api/client/security/HmacSHA256Signer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/security/HmacSHA256Signer.java b/src/main/java/com/binance/api/client/security/HmacSHA256Signer.java index be40e3ab2..fc5f06702 100644 --- a/src/main/java/com/binance/api/client/security/HmacSHA256Signer.java +++ b/src/main/java/com/binance/api/client/security/HmacSHA256Signer.java @@ -21,7 +21,7 @@ public static String sign(String message, String secret) { Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secretKeySpec = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); sha256_HMAC.init(secretKeySpec); - return new String(Hex.encodeHexString(sha256_HMAC.doFinal(message.getBytes()))); + return new String(Hex.encodeHex(sha256_HMAC.doFinal(message.getBytes()))); } catch (Exception e) { throw new RuntimeException("Unable to sign message.", e); } From f0f4380b179a1957932fbe0eb4166188a11bc1f7 Mon Sep 17 00:00:00 2001 From: xezon Date: Sat, 6 Jan 2018 14:23:28 +0100 Subject: [PATCH 07/81] Fix java compile warnings --- .../java/com/binance/api/client/BinanceApiRestClient.java | 1 - .../com/binance/api/client/BinanceApiWebSocketClient.java | 1 - .../java/com/binance/api/client/domain/account/NewOrder.java | 2 -- .../java/com/binance/api/client/domain/account/Order.java | 2 -- .../com/binance/api/client/exception/BinanceApiException.java | 3 ++- .../api/client/security/AuthenticationInterceptor.java | 4 ++-- .../java/com/binance/api/examples/AggTradesCacheExample.java | 2 -- .../binance/api/examples/GeneralEndpointsExampleAsync.java | 1 - .../com/binance/api/examples/MarketDataEndpointsExample.java | 1 - .../binance/api/examples/MarketDataEndpointsExampleAsync.java | 1 - .../java/com/binance/api/examples/OrdersExampleAsync.java | 1 - .../java/com/binance/api/examples/UserDataStreamExample.java | 1 - 12 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/binance/api/client/BinanceApiRestClient.java b/src/main/java/com/binance/api/client/BinanceApiRestClient.java index a6dac9ebc..d81b05d25 100644 --- a/src/main/java/com/binance/api/client/BinanceApiRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiRestClient.java @@ -20,7 +20,6 @@ import com.binance.api.client.domain.market.OrderBook; import com.binance.api.client.domain.market.TickerPrice; import com.binance.api.client.domain.market.TickerStatistics; -import retrofit2.Call; import java.util.List; diff --git a/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java b/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java index 71670462a..2ba16d61c 100644 --- a/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java @@ -4,7 +4,6 @@ import com.binance.api.client.domain.event.CandlestickEvent; import com.binance.api.client.domain.event.DepthEvent; import com.binance.api.client.domain.event.UserDataUpdateEvent; -import com.binance.api.client.domain.market.Candlestick; import com.binance.api.client.domain.market.CandlestickInterval; /** diff --git a/src/main/java/com/binance/api/client/domain/account/NewOrder.java b/src/main/java/com/binance/api/client/domain/account/NewOrder.java index 84b92ce19..6d611ec78 100644 --- a/src/main/java/com/binance/api/client/domain/account/NewOrder.java +++ b/src/main/java/com/binance/api/client/domain/account/NewOrder.java @@ -7,8 +7,6 @@ import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; -import java.math.BigDecimal; - /** * A trade order to enter or exit a position. */ diff --git a/src/main/java/com/binance/api/client/domain/account/Order.java b/src/main/java/com/binance/api/client/domain/account/Order.java index 7cf967ba8..ae008ff41 100644 --- a/src/main/java/com/binance/api/client/domain/account/Order.java +++ b/src/main/java/com/binance/api/client/domain/account/Order.java @@ -8,8 +8,6 @@ import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; -import java.math.BigDecimal; - /** * Trade order information. */ diff --git a/src/main/java/com/binance/api/client/exception/BinanceApiException.java b/src/main/java/com/binance/api/client/exception/BinanceApiException.java index 55058e27d..a40d9e7a9 100644 --- a/src/main/java/com/binance/api/client/exception/BinanceApiException.java +++ b/src/main/java/com/binance/api/client/exception/BinanceApiException.java @@ -7,7 +7,8 @@ */ public class BinanceApiException extends RuntimeException { - /** + private static final long serialVersionUID = 3788669840036201041L; +/** * Error response object returned by Binance API. */ private BinanceApiError error; diff --git a/src/main/java/com/binance/api/client/security/AuthenticationInterceptor.java b/src/main/java/com/binance/api/client/security/AuthenticationInterceptor.java index c4c5860b2..c7d86af6a 100644 --- a/src/main/java/com/binance/api/client/security/AuthenticationInterceptor.java +++ b/src/main/java/com/binance/api/client/security/AuthenticationInterceptor.java @@ -60,10 +60,10 @@ public Response intercept(Chain chain) throws IOException { * * @return request body as a string */ + @SuppressWarnings("unused") private static String bodyToString(RequestBody request) { - try { + try (final Buffer buffer = new Buffer()) { final RequestBody copy = request; - final Buffer buffer = new Buffer(); if (copy != null) { copy.writeTo(buffer); } else { diff --git a/src/test/java/com/binance/api/examples/AggTradesCacheExample.java b/src/test/java/com/binance/api/examples/AggTradesCacheExample.java index fe1afffd5..8106ba34e 100644 --- a/src/test/java/com/binance/api/examples/AggTradesCacheExample.java +++ b/src/test/java/com/binance/api/examples/AggTradesCacheExample.java @@ -4,8 +4,6 @@ import com.binance.api.client.BinanceApiRestClient; import com.binance.api.client.BinanceApiWebSocketClient; import com.binance.api.client.domain.market.AggTrade; -import com.binance.api.client.domain.market.Candlestick; -import com.binance.api.client.domain.market.CandlestickInterval; import java.util.HashMap; import java.util.List; diff --git a/src/test/java/com/binance/api/examples/GeneralEndpointsExampleAsync.java b/src/test/java/com/binance/api/examples/GeneralEndpointsExampleAsync.java index 85a69c7ff..8823f1824 100644 --- a/src/test/java/com/binance/api/examples/GeneralEndpointsExampleAsync.java +++ b/src/test/java/com/binance/api/examples/GeneralEndpointsExampleAsync.java @@ -2,7 +2,6 @@ import com.binance.api.client.BinanceApiAsyncRestClient; import com.binance.api.client.BinanceApiClientFactory; -import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.FilterType; import com.binance.api.client.domain.general.SymbolFilter; import com.binance.api.client.domain.general.SymbolInfo; diff --git a/src/test/java/com/binance/api/examples/MarketDataEndpointsExample.java b/src/test/java/com/binance/api/examples/MarketDataEndpointsExample.java index 932845488..79a83b11f 100644 --- a/src/test/java/com/binance/api/examples/MarketDataEndpointsExample.java +++ b/src/test/java/com/binance/api/examples/MarketDataEndpointsExample.java @@ -2,7 +2,6 @@ import com.binance.api.client.BinanceApiClientFactory; import com.binance.api.client.BinanceApiRestClient; -import com.binance.api.client.domain.account.Account; import com.binance.api.client.domain.market.AggTrade; import com.binance.api.client.domain.market.BookTicker; import com.binance.api.client.domain.market.Candlestick; diff --git a/src/test/java/com/binance/api/examples/MarketDataEndpointsExampleAsync.java b/src/test/java/com/binance/api/examples/MarketDataEndpointsExampleAsync.java index 71fed11b2..c85330c2b 100644 --- a/src/test/java/com/binance/api/examples/MarketDataEndpointsExampleAsync.java +++ b/src/test/java/com/binance/api/examples/MarketDataEndpointsExampleAsync.java @@ -2,7 +2,6 @@ import com.binance.api.client.BinanceApiAsyncRestClient; import com.binance.api.client.BinanceApiClientFactory; -import com.binance.api.client.domain.account.Account; import com.binance.api.client.domain.market.AggTrade; import com.binance.api.client.domain.market.Candlestick; import com.binance.api.client.domain.market.CandlestickInterval; diff --git a/src/test/java/com/binance/api/examples/OrdersExampleAsync.java b/src/test/java/com/binance/api/examples/OrdersExampleAsync.java index 33ed6d378..9f766ff02 100644 --- a/src/test/java/com/binance/api/examples/OrdersExampleAsync.java +++ b/src/test/java/com/binance/api/examples/OrdersExampleAsync.java @@ -2,7 +2,6 @@ import com.binance.api.client.BinanceApiAsyncRestClient; import com.binance.api.client.BinanceApiClientFactory; -import com.binance.api.client.BinanceApiRestClient; import com.binance.api.client.domain.TimeInForce; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; diff --git a/src/test/java/com/binance/api/examples/UserDataStreamExample.java b/src/test/java/com/binance/api/examples/UserDataStreamExample.java index 071c5895d..8ea5f309a 100644 --- a/src/test/java/com/binance/api/examples/UserDataStreamExample.java +++ b/src/test/java/com/binance/api/examples/UserDataStreamExample.java @@ -6,7 +6,6 @@ import com.binance.api.client.domain.event.AccountUpdateEvent; import com.binance.api.client.domain.event.OrderTradeUpdateEvent; import com.binance.api.client.domain.event.UserDataUpdateEvent.UserDataUpdateEventType; -import com.binance.api.client.impl.BinanceApiWebSocketClientImpl; /** * User data stream endpoints examples. From 59609e0025007864b509108c53edf3d9185b5707 Mon Sep 17 00:00:00 2001 From: xezon Date: Sat, 6 Jan 2018 14:24:05 +0100 Subject: [PATCH 08/81] Ignore any user project files (generally starting with dot) --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index c4d55bb2a..71eae81ce 100644 --- a/.gitignore +++ b/.gitignore @@ -94,3 +94,7 @@ hs_err_pid* # Maven target/ # End of https://www.gitignore.io/api/java,intellij + +# Ignore files and folders starting with dot (except gitignore) +.* +!/.gitignore From 076dc919427b68ca65c72d36f5488dcc091cd427 Mon Sep 17 00:00:00 2001 From: xezon Date: Wed, 10 Jan 2018 20:06:47 +0100 Subject: [PATCH 09/81] Add Json Serializers for CandlestickEvent and OrderBookEntry --- .../client/domain/event/CandlestickEvent.java | 5 +++ .../event/CandlestickEventSerializer.java | 44 +++++++++++++++++++ .../client/domain/market/OrderBookEntry.java | 4 ++ .../market/OrderBookEntrySerializer.java | 21 +++++++++ 4 files changed, 74 insertions(+) create mode 100644 src/main/java/com/binance/api/client/domain/event/CandlestickEventSerializer.java create mode 100644 src/main/java/com/binance/api/client/domain/market/OrderBookEntrySerializer.java diff --git a/src/main/java/com/binance/api/client/domain/event/CandlestickEvent.java b/src/main/java/com/binance/api/client/domain/event/CandlestickEvent.java index e21a5357d..5a6c35b8b 100644 --- a/src/main/java/com/binance/api/client/domain/event/CandlestickEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/CandlestickEvent.java @@ -1,6 +1,8 @@ package com.binance.api.client.domain.event; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -8,6 +10,7 @@ * An interval candlestick for a symbol providing informations on price that can be used to produce candlestick charts. */ @JsonDeserialize(using = CandlestickEventDeserializer.class) +@JsonSerialize(using = CandlestickEventSerializer.class) public class CandlestickEvent { private String eventType; @@ -31,7 +34,9 @@ public class CandlestickEvent { private Long closeTime; private String intervalId; + private Long firstTradeId; + private Long lastTradeId; private String quoteAssetVolume; diff --git a/src/main/java/com/binance/api/client/domain/event/CandlestickEventSerializer.java b/src/main/java/com/binance/api/client/domain/event/CandlestickEventSerializer.java new file mode 100644 index 000000000..34f03370e --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/event/CandlestickEventSerializer.java @@ -0,0 +1,44 @@ +package com.binance.api.client.domain.event; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.JsonSerializer; + +import java.io.IOException; + +/** + * Custom serializer for a candlestick stream event, since the structure of the candlestick json differ from the one in the REST API. + * + * @see CandlestickEvent + */ +public class CandlestickEventSerializer extends JsonSerializer { + + @Override + public void serialize(CandlestickEvent candlestickEvent, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + + // Write header + gen.writeStringField("e", candlestickEvent.getEventType()); + gen.writeNumberField("E", candlestickEvent.getEventTime()); + gen.writeStringField("s", candlestickEvent.getSymbol()); + + // Write candlestick data + gen.writeObjectFieldStart("k"); + gen.writeNumberField("t", candlestickEvent.getOpenTime()); + gen.writeNumberField("T", candlestickEvent.getCloseTime()); + gen.writeStringField("i", candlestickEvent.getIntervalId()); + gen.writeNumberField("f", candlestickEvent.getFirstTradeId()); + gen.writeNumberField("L", candlestickEvent.getLastTradeId()); + gen.writeStringField("o", candlestickEvent.getOpen()); + gen.writeStringField("c", candlestickEvent.getClose()); + gen.writeStringField("h", candlestickEvent.getHigh()); + gen.writeStringField("l", candlestickEvent.getLow()); + gen.writeStringField("v", candlestickEvent.getVolume()); + gen.writeNumberField("n", candlestickEvent.getNumberOfTrades()); + gen.writeBooleanField("x", candlestickEvent.getBarFinal()); + gen.writeStringField("q", candlestickEvent.getQuoteAssetVolume()); + gen.writeStringField("V", candlestickEvent.getTakerBuyBaseAssetVolume()); + gen.writeStringField("Q", candlestickEvent.getTakerBuyQuoteAssetVolume()); + gen.writeEndObject(); + } +} diff --git a/src/main/java/com/binance/api/client/domain/market/OrderBookEntry.java b/src/main/java/com/binance/api/client/domain/market/OrderBookEntry.java index d971b9489..a83b29c1d 100644 --- a/src/main/java/com/binance/api/client/domain/market/OrderBookEntry.java +++ b/src/main/java/com/binance/api/client/domain/market/OrderBookEntry.java @@ -1,6 +1,8 @@ package com.binance.api.client.domain.market; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -8,7 +10,9 @@ * An order book entry consisting of price and quantity. */ @JsonDeserialize(using = OrderBookEntryDeserializer.class) +@JsonSerialize(using = OrderBookEntrySerializer.class) public class OrderBookEntry { + private String price; private String qty; diff --git a/src/main/java/com/binance/api/client/domain/market/OrderBookEntrySerializer.java b/src/main/java/com/binance/api/client/domain/market/OrderBookEntrySerializer.java new file mode 100644 index 000000000..937892d76 --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/market/OrderBookEntrySerializer.java @@ -0,0 +1,21 @@ +package com.binance.api.client.domain.market; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.JsonSerializer; + +import java.io.IOException; + +/** + * Custom serializer for an OrderBookEntry. + */ +public class OrderBookEntrySerializer extends JsonSerializer { + + @Override + public void serialize(OrderBookEntry orderBookEntry, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartArray(); + gen.writeString(orderBookEntry.getPrice()); + gen.writeString(orderBookEntry.getQty()); + gen.writeEndArray(); + } +} From dc1c4f1d17a11060032c303ae08a9c24a36e0945 Mon Sep 17 00:00:00 2001 From: Amirul Zin Date: Fri, 12 Jan 2018 01:25:47 +0800 Subject: [PATCH 10/81] Fix missing Fill or Kill in TimeInForce --- src/main/java/com/binance/api/client/domain/TimeInForce.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/domain/TimeInForce.java b/src/main/java/com/binance/api/client/domain/TimeInForce.java index 79fce3456..49e266431 100644 --- a/src/main/java/com/binance/api/client/domain/TimeInForce.java +++ b/src/main/java/com/binance/api/client/domain/TimeInForce.java @@ -5,10 +5,12 @@ * * GTC (Good-Til-Canceled) orders are effective until they are executed or canceled. * IOC (Immediate or Cancel) orders fills all or part of an order immediately and cancels the remaining part of the order. + * FOK (Fill or Kill) orders fills all in its entirety, otherwise, the entire order will be cancelled. * * @see http://www.investopedia.com/terms/t/timeinforce.asp */ public enum TimeInForce { GTC, - IOC + IOC, + FOK } From a07a578bd2817e378e0120a4197eadd928ba6110 Mon Sep 17 00:00:00 2001 From: Amirul Zin Date: Sat, 13 Jan 2018 18:53:39 +0800 Subject: [PATCH 11/81] Fix ObjectMapper not being cached per response call --- .../api/client/impl/BinanceApiWebSocketListener.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java index 22321685c..607249fb7 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java @@ -18,14 +18,20 @@ public class BinanceApiWebSocketListener extends WebSocketListener { private Class eventClass; + private ObjectMapper mapper; + public BinanceApiWebSocketListener(BinanceApiCallback callback, Class eventClass) { + this(callback, eventClass, new ObjectMapper()); + } + + public BinanceApiWebSocketListener(BinanceApiCallback callback, Class eventClass, ObjectMapper mapper) { this.callback = callback; this.eventClass = eventClass; + this.mapper = mapper; } @Override public void onMessage(WebSocket webSocket, String text) { - ObjectMapper mapper = new ObjectMapper(); try { T event = mapper.readValue(text, eventClass); callback.onResponse(event); From a7184168b64cbbe3f9e872a7e7c69dff20878810 Mon Sep 17 00:00:00 2001 From: Amirul Zin Date: Sat, 13 Jan 2018 18:56:33 +0800 Subject: [PATCH 12/81] Create ObjectMapper lazily on UserDataUpdateEvent deserialization --- .../event/UserDataUpdateEventDeserializer.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEventDeserializer.java b/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEventDeserializer.java index 3198839c3..afc584636 100644 --- a/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEventDeserializer.java +++ b/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEventDeserializer.java @@ -17,8 +17,15 @@ */ public class UserDataUpdateEventDeserializer extends JsonDeserializer { + private ObjectMapper mapper; + @Override public UserDataUpdateEvent deserialize(JsonParser jp, DeserializationContext ctx) throws IOException { + + if (mapper == null){ + mapper = new ObjectMapper(); + } + ObjectCodec oc = jp.getCodec(); JsonNode node = oc.readTree(jp); String json = node.toString(); @@ -32,18 +39,17 @@ public UserDataUpdateEvent deserialize(JsonParser jp, DeserializationContext ctx userDataUpdateEvent.setEventTime(eventTime); if (userDataUpdateEventType == UserDataUpdateEventType.ACCOUNT_UPDATE) { - AccountUpdateEvent accountUpdateEvent = getUserDataUpdateEventDetail(json, AccountUpdateEvent.class); + AccountUpdateEvent accountUpdateEvent = getUserDataUpdateEventDetail(json, AccountUpdateEvent.class, mapper); userDataUpdateEvent.setAccountUpdateEvent(accountUpdateEvent); } else { // userDataUpdateEventType == UserDataUpdateEventType.ORDER_TRADE_UPDATE - OrderTradeUpdateEvent orderTradeUpdateEvent = getUserDataUpdateEventDetail(json, OrderTradeUpdateEvent.class); + OrderTradeUpdateEvent orderTradeUpdateEvent = getUserDataUpdateEventDetail(json, OrderTradeUpdateEvent.class, mapper); userDataUpdateEvent.setOrderTradeUpdateEvent(orderTradeUpdateEvent); } return userDataUpdateEvent; } - public T getUserDataUpdateEventDetail(String json, Class clazz) { - ObjectMapper mapper = new ObjectMapper(); + public T getUserDataUpdateEventDetail(String json, Class clazz, ObjectMapper mapper) { try { return mapper.readValue(json, clazz); } catch (IOException e) { From c25eb80ef9fe8cf51597a97e11ad7a81b2bf5c2c Mon Sep 17 00:00:00 2001 From: Andy Coates Date: Mon, 22 Jan 2018 17:59:20 +0000 Subject: [PATCH 13/81] Expose the 'U' (first update), as well as the 'u' (final update) --- .../api/client/domain/event/DepthEvent.java | 30 ++++++++++++++++--- .../api/examples/DepthCacheExample.java | 8 ++--- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/binance/api/client/domain/event/DepthEvent.java b/src/main/java/com/binance/api/client/domain/event/DepthEvent.java index c868fed41..e9a4a6751 100644 --- a/src/main/java/com/binance/api/client/domain/event/DepthEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/DepthEvent.java @@ -23,11 +23,14 @@ public class DepthEvent { @JsonProperty("s") private String symbol; + @JsonProperty("U") + private long firstUpdateId; + /** * updateId to sync up with updateid in /api/v1/depth */ @JsonProperty("u") - private long updateId; + private long finalUpdateId; /** * Bid depth delta. @@ -65,12 +68,30 @@ public void setSymbol(String symbol) { this.symbol = symbol; } + public long getFirstUpdateId() { + return firstUpdateId; + } + + public void setFirstUpdateId(final long firstUpdateId) { + this.firstUpdateId = firstUpdateId; + } + + public long getFinalUpdateId() { + return finalUpdateId; + } + + public void setFinalUpdateId(long finalUpdateId) { + this.finalUpdateId = finalUpdateId; + } + + @Deprecated // Use getFinalUpdateId public long getUpdateId() { - return updateId; + return finalUpdateId; } + @Deprecated // Use setFinalUpdateId public void setUpdateId(long updateId) { - this.updateId = updateId; + this.finalUpdateId = updateId; } public List getBids() { @@ -95,7 +116,8 @@ public String toString() { .append("eventType", eventType) .append("eventTime", eventTime) .append("symbol", symbol) - .append("updateId", updateId) + .append("firstUpdateId", firstUpdateId) + .append("finalUpdateId", finalUpdateId) .append("bids", bids) .append("asks", asks) .toString(); diff --git a/src/test/java/com/binance/api/examples/DepthCacheExample.java b/src/test/java/com/binance/api/examples/DepthCacheExample.java index 851d8c018..6fbbfdfa8 100644 --- a/src/test/java/com/binance/api/examples/DepthCacheExample.java +++ b/src/test/java/com/binance/api/examples/DepthCacheExample.java @@ -63,9 +63,9 @@ private void startDepthEventStreaming(String symbol) { BinanceApiWebSocketClient client = factory.newWebSocketClient(); client.onDepthEvent(symbol.toLowerCase(), response -> { - if (response.getUpdateId() > lastUpdateId) { + if (response.getFinalUpdateId() > lastUpdateId) { System.out.println(response); - lastUpdateId = response.getUpdateId(); + lastUpdateId = response.getFinalUpdateId(); updateOrderBook(getAsks(), response.getAsks()); updateOrderBook(getBids(), response.getBids()); printDepthCache(); @@ -125,9 +125,9 @@ public Map> getDepthCache() { */ private void printDepthCache() { System.out.println(depthCache); - System.out.println("ASKS:"); + System.out.println("ASKS:(" + getAsks().size() + ")"); getAsks().entrySet().forEach(entry -> System.out.println(toDepthCacheEntryString(entry))); - System.out.println("BIDS:"); + System.out.println("BIDS:(" + getBids().size() + ")"); getBids().entrySet().forEach(entry -> System.out.println(toDepthCacheEntryString(entry))); System.out.println("BEST ASK: " + toDepthCacheEntryString(getBestAsk())); System.out.println("BEST BID: " + toDepthCacheEntryString(getBestBid())); From 299411f5bee06e551d73a67b1e38168f17c22d44 Mon Sep 17 00:00:00 2001 From: Andy Coates Date: Tue, 23 Jan 2018 15:56:46 +0000 Subject: [PATCH 14/81] - added javadocs --- .../binance/api/client/domain/event/DepthEvent.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/binance/api/client/domain/event/DepthEvent.java b/src/main/java/com/binance/api/client/domain/event/DepthEvent.java index e9a4a6751..d94ff7b81 100644 --- a/src/main/java/com/binance/api/client/domain/event/DepthEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/DepthEvent.java @@ -84,12 +84,18 @@ public void setFinalUpdateId(long finalUpdateId) { this.finalUpdateId = finalUpdateId; } - @Deprecated // Use getFinalUpdateId + /** + * @deprecated Use {@link #getFinalUpdateId} + */ + @Deprecated public long getUpdateId() { return finalUpdateId; } - @Deprecated // Use setFinalUpdateId + /** + * @deprecated Use {@link #setFinalUpdateId} + */ + @Deprecated public void setUpdateId(long updateId) { this.finalUpdateId = updateId; } From 18e3b0a3dd2aa78ce0ac3603001ccc4a655e7f5b Mon Sep 17 00:00:00 2001 From: Andy Coates Date: Thu, 25 Jan 2018 11:26:50 +0000 Subject: [PATCH 15/81] Improvements to error handling and the ability to shutdown the client and/or a active web socket. - Optional `onFailure` added to `BinanceApiCallback` to allow user to opt-in to receiving failure info. - `BinanceApiWebSocketClient` enhanced to return `Closeable`s from calls creating web sockets, so that said web sockets can be later closed, if needed. - `BinanceApiWebSocketClient` enhanced to be `Closeable` itself, closing the internal OKHttp dispatcher. - `BinanceApiWebSocketListener` no longer throws an exception from `onFailure`, as this was just being thrown up the stack to the `Thread.uncaughtExceptionHandler`. With these changes I can now: - detect failures on the web socket and choose to do something about them. - shutdown the `BinanceApiWebSocketClient`, and potentially recreate later, without any resource leaks or references being held to my callback objects. --- .../api/client/BinanceApiCallback.java | 13 +++++--- .../api/client/BinanceApiWebSocketClient.java | 14 +++++---- .../impl/BinanceApiWebSocketClientImpl.java | 30 +++++++++++-------- .../impl/BinanceApiWebSocketListener.java | 11 ++++++- 4 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/binance/api/client/BinanceApiCallback.java b/src/main/java/com/binance/api/client/BinanceApiCallback.java index a3b68acae..f492cc1da 100644 --- a/src/main/java/com/binance/api/client/BinanceApiCallback.java +++ b/src/main/java/com/binance/api/client/BinanceApiCallback.java @@ -1,19 +1,24 @@ package com.binance.api.client; -import com.binance.api.client.exception.BinanceApiException; - /** * BinanceApiCallback is a functional interface used together with the BinanceApiAsyncClient to provide a non-blocking REST client. * * @param the return type from the callback */ +@FunctionalInterface public interface BinanceApiCallback { /** * Called whenever a response comes back from the Binance API. * * @param response the expected response object - * @throws BinanceApiException if it is not possible to obtain the expected response object (e.g. incorrect API-KEY). */ - void onResponse(T response) throws BinanceApiException; + void onResponse(T response); + + /** + * Called whenever an error occurs. + * + * @param cause the cause of the failure + */ + default void onFailure(Throwable cause) {} } \ No newline at end of file diff --git a/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java b/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java index 2ba16d61c..5a16a94d9 100644 --- a/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java @@ -6,16 +6,20 @@ import com.binance.api.client.domain.event.UserDataUpdateEvent; import com.binance.api.client.domain.market.CandlestickInterval; +import java.io.Closeable; + /** * Binance API data streaming façade, supporting streaming of events through web sockets. */ -public interface BinanceApiWebSocketClient { +public interface BinanceApiWebSocketClient extends Closeable { + + Closeable onDepthEvent(String symbol, BinanceApiCallback callback); - void onDepthEvent(String symbol, BinanceApiCallback callback); + Closeable onCandlestickEvent(String symbol, CandlestickInterval interval, BinanceApiCallback callback); - void onCandlestickEvent(String symbol, CandlestickInterval interval, BinanceApiCallback callback); + Closeable onAggTradeEvent(String symbol, BinanceApiCallback callback); - void onAggTradeEvent(String symbol, BinanceApiCallback callback); + Closeable onUserDataUpdateEvent(String listenKey, BinanceApiCallback callback); - void onUserDataUpdateEvent(String listenKey, BinanceApiCallback callback); + void close(); } diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java index d4cd1e3d2..6c42b4559 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java @@ -10,9 +10,9 @@ import com.binance.api.client.domain.market.CandlestickInterval; import okhttp3.OkHttpClient; import okhttp3.Request; +import okhttp3.WebSocket; import java.io.Closeable; -import java.io.IOException; /** * Binance API WebSocket client implementation using OkHttp. @@ -25,34 +25,40 @@ public BinanceApiWebSocketClientImpl() { this.client = new OkHttpClient(); } - public void onDepthEvent(String symbol, BinanceApiCallback callback) { + public Closeable onDepthEvent(String symbol, BinanceApiCallback callback) { final String channel = String.format("%s@depth", symbol); - createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, DepthEvent.class)); + return createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, DepthEvent.class)); } @Override - public void onCandlestickEvent(String symbol, CandlestickInterval interval, BinanceApiCallback callback) { + public Closeable onCandlestickEvent(String symbol, CandlestickInterval interval, BinanceApiCallback callback) { final String channel = String.format("%s@kline_%s", symbol, interval.getIntervalId()); - createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, CandlestickEvent.class)); + return createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, CandlestickEvent.class)); } - public void onAggTradeEvent(String symbol, BinanceApiCallback callback) { + public Closeable onAggTradeEvent(String symbol, BinanceApiCallback callback) { final String channel = String.format("%s@aggTrade", symbol); - createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, AggTradeEvent.class)); + return createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, AggTradeEvent.class)); } - public void onUserDataUpdateEvent(String listenKey, BinanceApiCallback callback) { - createNewWebSocket(listenKey, new BinanceApiWebSocketListener<>(callback, UserDataUpdateEvent.class)); + public Closeable onUserDataUpdateEvent(String listenKey, BinanceApiCallback callback) { + return createNewWebSocket(listenKey, new BinanceApiWebSocketListener<>(callback, UserDataUpdateEvent.class)); } - private void createNewWebSocket(String channel, BinanceApiWebSocketListener listener) { + private Closeable createNewWebSocket(String channel, BinanceApiWebSocketListener listener) { String streamingUrl = String.format("%s/%s", BinanceApiConstants.WS_API_BASE_URL, channel); Request request = new Request.Builder().url(streamingUrl).build(); - client.newWebSocket(request, listener); + final WebSocket webSocket = client.newWebSocket(request, listener); + return () -> { + final int code = 1000; + listener.onClosing(webSocket, code, null); + webSocket.close(code, null); + listener.onClosed(webSocket, code, null); + }; } @Override - public void close() throws IOException { + public void close() { client.dispatcher().executorService().shutdown(); } } diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java index 607249fb7..367b1b73c 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java @@ -20,6 +20,8 @@ public class BinanceApiWebSocketListener extends WebSocketListener { private ObjectMapper mapper; + private boolean closing = false; + public BinanceApiWebSocketListener(BinanceApiCallback callback, Class eventClass) { this(callback, eventClass, new ObjectMapper()); } @@ -40,8 +42,15 @@ public void onMessage(WebSocket webSocket, String text) { } } + @Override + public void onClosing(final WebSocket webSocket, final int code, final String reason) { + closing = true; + } + @Override public void onFailure(WebSocket webSocket, Throwable t, Response response) { - throw new BinanceApiException(t); + if (!closing) { + callback.onFailure(t); + } } } \ No newline at end of file From f2b5a83c5f189e7113a904bf8380a72e52bb565a Mon Sep 17 00:00:00 2001 From: Martijn Courteaux Date: Fri, 26 Jan 2018 23:41:15 +0100 Subject: [PATCH 16/81] Allow up to 100 connections to binance. --- .../api/client/impl/BinanceApiWebSocketClientImpl.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java index d4cd1e3d2..65f195464 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java @@ -9,6 +9,7 @@ import com.binance.api.client.domain.event.UserDataUpdateEvent; import com.binance.api.client.domain.market.CandlestickInterval; import okhttp3.OkHttpClient; +import okhttp3.Dispatcher; import okhttp3.Request; import java.io.Closeable; @@ -22,7 +23,9 @@ public class BinanceApiWebSocketClientImpl implements BinanceApiWebSocketClient, private OkHttpClient client; public BinanceApiWebSocketClientImpl() { - this.client = new OkHttpClient(); + Dispatcher d = new Dispatcher(); + d.setMaxRequestsPerHost(100); + this.client = new OkHttpClient.Builder().dispatcher(d).build(); } public void onDepthEvent(String symbol, BinanceApiCallback callback) { From 4a47ca13a4d97ee16c79dd7b37d021948ef9a478 Mon Sep 17 00:00:00 2001 From: Tony Skulk Date: Sat, 27 Jan 2018 17:52:32 +0100 Subject: [PATCH 17/81] Added AllMarketTickers channel --- .../api/client/BinanceApiWebSocketClient.java | 4 + .../domain/event/AllMarketTickersEvent.java | 257 ++++++++++++++++++ .../impl/BinanceApiWebSocketClientImpl.java | 19 +- .../impl/BinanceApiWebSocketListener.java | 28 +- 4 files changed, 291 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java diff --git a/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java b/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java index 2ba16d61c..0525ac725 100644 --- a/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java @@ -1,6 +1,8 @@ package com.binance.api.client; +import java.util.List; import com.binance.api.client.domain.event.AggTradeEvent; +import com.binance.api.client.domain.event.AllMarketTickersEvent; import com.binance.api.client.domain.event.CandlestickEvent; import com.binance.api.client.domain.event.DepthEvent; import com.binance.api.client.domain.event.UserDataUpdateEvent; @@ -18,4 +20,6 @@ public interface BinanceApiWebSocketClient { void onAggTradeEvent(String symbol, BinanceApiCallback callback); void onUserDataUpdateEvent(String listenKey, BinanceApiCallback callback); + + void onAllMarketTickersEvent(BinanceApiCallback> callback); } diff --git a/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java b/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java new file mode 100644 index 000000000..9e65a2bd8 --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java @@ -0,0 +1,257 @@ +package com.binance.api.client.domain.event; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class AllMarketTickersEvent { + + @JsonProperty("e") + private String eventType; + + @JsonProperty("E") + private long eventTime; + + @JsonProperty("s") + private String symbol; + + @JsonProperty("p") + private double priceChange; + + @JsonProperty("P") + private double priceChangePercent; + + @JsonProperty("w") + private double weightedAveragePrice; + + @JsonProperty("x") + private double previousDaysClosePrice; + + @JsonProperty("c") + private double currentDaysClosePrice; + + @JsonProperty("Q") + private long closeTradesQuantity; + + @JsonProperty("a") + private double bestAskPrice; + + @JsonProperty("A") + private long bestAskQuantity; + + @JsonProperty("o") + private double openPrice; + + @JsonProperty("h") + private double highPrice; + + @JsonProperty("l") + private double lowPrice; + + @JsonProperty("v") + private long totalTradedBaseAssetVolume; + + @JsonProperty("q") + private long totalTradedQuoteAssetVolume; + + @JsonProperty("O") + private long statisticesOpenTime; + + @JsonProperty("C") + private long statisticesCloseTime; + + @JsonProperty("F") + private long firstTradeId; + + @JsonProperty("L") + private long lastTradeId; + + @JsonProperty("n") + private long totalNumberOfTrades; + + public String getEventType() { + return eventType; + } + + public void setEventType(String eventType) { + this.eventType = eventType; + } + + public long getEventTime() { + return eventTime; + } + + public void setEventTime(long eventTime) { + this.eventTime = eventTime; + } + + public String getSymbol() { + return symbol; + } + + public void setSymbol(String symbol) { + this.symbol = symbol; + } + + public double getPriceChange() { + return priceChange; + } + + public void setPriceChange(double priceChange) { + this.priceChange = priceChange; + } + + public double getPriceChangePercent() { + return priceChangePercent; + } + + public void setPriceChangePercent(double priceChangePercent) { + this.priceChangePercent = priceChangePercent; + } + + public double getWeightedAveragePrice() { + return weightedAveragePrice; + } + + public void setWeightedAveragePrice(double weightedAveragePrice) { + this.weightedAveragePrice = weightedAveragePrice; + } + + public double getPreviousDaysClosePrice() { + return previousDaysClosePrice; + } + + public void setPreviousDaysClosePrice(double previousDaysClosePrice) { + this.previousDaysClosePrice = previousDaysClosePrice; + } + + public double getCurrentDaysClosePrice() { + return currentDaysClosePrice; + } + + public void setCurrentDaysClosePrice(double currentDaysClosePrice) { + this.currentDaysClosePrice = currentDaysClosePrice; + } + + public long getCloseTradesQuantity() { + return closeTradesQuantity; + } + + public void setCloseTradesQuantity(long closeTradesQuantity) { + this.closeTradesQuantity = closeTradesQuantity; + } + + public double getBestAskPrice() { + return bestAskPrice; + } + + public void setBestAskPrice(double bestAskPrice) { + this.bestAskPrice = bestAskPrice; + } + + public long getBestAskQuantity() { + return bestAskQuantity; + } + + public void setBestAskQuantity(long bestAskQuantity) { + this.bestAskQuantity = bestAskQuantity; + } + + public double getOpenPrice() { + return openPrice; + } + + public void setOpenPrice(double openPrice) { + this.openPrice = openPrice; + } + + public double getHighPrice() { + return highPrice; + } + + public void setHighPrice(double highPrice) { + this.highPrice = highPrice; + } + + public double getLowPrice() { + return lowPrice; + } + + public void setLowPrice(double lowPrice) { + this.lowPrice = lowPrice; + } + + public long getTotalTradedBaseAssetVolume() { + return totalTradedBaseAssetVolume; + } + + public void setTotalTradedBaseAssetVolume(long totalTradedBaseAssetVolume) { + this.totalTradedBaseAssetVolume = totalTradedBaseAssetVolume; + } + + public long getTotalTradedQuoteAssetVolume() { + return totalTradedQuoteAssetVolume; + } + + public void setTotalTradedQuoteAssetVolume(long totalTradedQuoteAssetVolume) { + this.totalTradedQuoteAssetVolume = totalTradedQuoteAssetVolume; + } + + public long getStatisticesOpenTime() { + return statisticesOpenTime; + } + + public void setStatisticesOpenTime(long statisticesOpenTime) { + this.statisticesOpenTime = statisticesOpenTime; + } + + public long getStatisticesCloseTime() { + return statisticesCloseTime; + } + + public void setStatisticesCloseTime(long statisticesCloseTime) { + this.statisticesCloseTime = statisticesCloseTime; + } + + public long getFirstTradeId() { + return firstTradeId; + } + + public void setFirstTradeId(long firstTradeId) { + this.firstTradeId = firstTradeId; + } + + public long getLastTradeId() { + return lastTradeId; + } + + public void setLastTradeId(long lastTradeId) { + this.lastTradeId = lastTradeId; + } + + public long getTotalNumberOfTrades() { + return totalNumberOfTrades; + } + + public void setTotalNumberOfTrades(long totalNumberOfTrades) { + this.totalNumberOfTrades = totalNumberOfTrades; + } + + @Override + public String toString() { + return "AllMarketTickersEvent [eventType=" + eventType + ", eventTime=" + eventTime + + ", symbol=" + symbol + ", priceChange=" + priceChange + ", priceChangePercent=" + + priceChangePercent + ", weightedAveragePrice=" + weightedAveragePrice + + ", previousDaysClosePrice=" + previousDaysClosePrice + ", currentDaysClosePrice=" + + currentDaysClosePrice + ", closeTradesQuantity=" + closeTradesQuantity + + ", bestAskPrice=" + bestAskPrice + ", bestAskQuantity=" + bestAskQuantity + + ", openPrice=" + openPrice + ", highPrice=" + highPrice + ", lowPrice=" + lowPrice + + ", totalTradedBaseAssetVolume=" + totalTradedBaseAssetVolume + + ", totalTradedQuoteAssetVolume=" + totalTradedQuoteAssetVolume + ", statisticesOpenTime=" + + statisticesOpenTime + ", statisticesCloseTime=" + statisticesCloseTime + + ", firstTradeId=" + firstTradeId + ", lastTradeId=" + lastTradeId + + ", totalNumberOfTrades=" + totalNumberOfTrades + "]"; + } +} diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java index 65f195464..f84f10f62 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java @@ -1,19 +1,20 @@ package com.binance.api.client.impl; +import java.io.Closeable; +import java.io.IOException; +import java.util.List; +import okhttp3.Dispatcher; +import okhttp3.OkHttpClient; +import okhttp3.Request; import com.binance.api.client.BinanceApiCallback; import com.binance.api.client.BinanceApiWebSocketClient; import com.binance.api.client.constant.BinanceApiConstants; import com.binance.api.client.domain.event.AggTradeEvent; +import com.binance.api.client.domain.event.AllMarketTickersEvent; import com.binance.api.client.domain.event.CandlestickEvent; import com.binance.api.client.domain.event.DepthEvent; import com.binance.api.client.domain.event.UserDataUpdateEvent; import com.binance.api.client.domain.market.CandlestickInterval; -import okhttp3.OkHttpClient; -import okhttp3.Dispatcher; -import okhttp3.Request; - -import java.io.Closeable; -import java.io.IOException; /** * Binance API WebSocket client implementation using OkHttp. @@ -48,6 +49,11 @@ public void onUserDataUpdateEvent(String listenKey, BinanceApiCallback(callback, UserDataUpdateEvent.class)); } + public void onAllMarketTickersEvent(BinanceApiCallback> callback) { + final String channel = "!ticker@arr"; + createNewWebSocket(channel, new BinanceApiWebSocketListener>(callback)); + } + private void createNewWebSocket(String channel, BinanceApiWebSocketListener listener) { String streamingUrl = String.format("%s/%s", BinanceApiConstants.WS_API_BASE_URL, channel); Request request = new Request.Builder().url(streamingUrl).build(); @@ -58,4 +64,5 @@ private void createNewWebSocket(String channel, BinanceApiWebSocketListener l public void close() throws IOException { client.dispatcher().executorService().shutdown(); } + } diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java index 607249fb7..e74c44ce1 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java @@ -1,13 +1,13 @@ package com.binance.api.client.impl; -import com.binance.api.client.BinanceApiCallback; -import com.binance.api.client.exception.BinanceApiException; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; import okhttp3.Response; import okhttp3.WebSocket; import okhttp3.WebSocketListener; - -import java.io.IOException; +import com.binance.api.client.BinanceApiCallback; +import com.binance.api.client.exception.BinanceApiException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; /** * Binance API WebSocket listener. @@ -18,22 +18,28 @@ public class BinanceApiWebSocketListener extends WebSocketListener { private Class eventClass; - private ObjectMapper mapper; + private TypeReference eventTypeReference; public BinanceApiWebSocketListener(BinanceApiCallback callback, Class eventClass) { - this(callback, eventClass, new ObjectMapper()); + this.callback = callback; + this.eventClass = eventClass; } - public BinanceApiWebSocketListener(BinanceApiCallback callback, Class eventClass, ObjectMapper mapper) { + public BinanceApiWebSocketListener(BinanceApiCallback callback) { this.callback = callback; - this.eventClass = eventClass; - this.mapper = mapper; + this.eventTypeReference = new TypeReference() {}; } @Override public void onMessage(WebSocket webSocket, String text) { + ObjectMapper mapper = new ObjectMapper(); try { - T event = mapper.readValue(text, eventClass); + T event = null; + if (eventClass == null) { + event = mapper.readValue(text, eventTypeReference); + } else { + event = mapper.readValue(text, eventClass); + } callback.onResponse(event); } catch (IOException e) { throw new BinanceApiException(e); From 913056679bfae36e8dd5e31782f80fa222efd601 Mon Sep 17 00:00:00 2001 From: Tony Skulk Date: Sat, 27 Jan 2018 18:18:22 +0100 Subject: [PATCH 18/81] Swicthed to use ToStringBuilder --- .../domain/event/AllMarketTickersEvent.java | 37 +++++++++++++------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java b/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java index 9e65a2bd8..4c888a0d0 100644 --- a/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java @@ -1,5 +1,7 @@ package com.binance.api.client.domain.event; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; @@ -241,17 +243,28 @@ public void setTotalNumberOfTrades(long totalNumberOfTrades) { @Override public String toString() { - return "AllMarketTickersEvent [eventType=" + eventType + ", eventTime=" + eventTime - + ", symbol=" + symbol + ", priceChange=" + priceChange + ", priceChangePercent=" - + priceChangePercent + ", weightedAveragePrice=" + weightedAveragePrice - + ", previousDaysClosePrice=" + previousDaysClosePrice + ", currentDaysClosePrice=" - + currentDaysClosePrice + ", closeTradesQuantity=" + closeTradesQuantity - + ", bestAskPrice=" + bestAskPrice + ", bestAskQuantity=" + bestAskQuantity - + ", openPrice=" + openPrice + ", highPrice=" + highPrice + ", lowPrice=" + lowPrice - + ", totalTradedBaseAssetVolume=" + totalTradedBaseAssetVolume - + ", totalTradedQuoteAssetVolume=" + totalTradedQuoteAssetVolume + ", statisticesOpenTime=" - + statisticesOpenTime + ", statisticesCloseTime=" + statisticesCloseTime - + ", firstTradeId=" + firstTradeId + ", lastTradeId=" + lastTradeId - + ", totalNumberOfTrades=" + totalNumberOfTrades + "]"; + return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + .append("eventType", eventType) + .append("eventTime", eventTime) + .append("symbol", symbol) + .append("priceChange", priceChange) + .append("priceChangePercent", priceChangePercent) + .append("weightedAveragePrice", weightedAveragePrice) + .append("previousDaysClosePrice", previousDaysClosePrice) + .append("currentDaysClosePrice", currentDaysClosePrice) + .append("closeTradesQuantity", closeTradesQuantity) + .append("bestAskPrice", bestAskPrice) + .append("bestAskQuantity", bestAskQuantity) + .append("openPrice", openPrice) + .append("highPrice", highPrice) + .append("lowPrice", lowPrice) + .append("totalTradedBaseAssetVolume", totalTradedBaseAssetVolume) + .append("totalTradedQuoteAssetVolume", totalTradedQuoteAssetVolume) + .append("statisticesOpenTime", statisticesOpenTime) + .append("statisticesCloseTime", statisticesCloseTime) + .append("firstTradeId", firstTradeId) + .append("lastTradeId", lastTradeId) + .append("totalNumberOfTrades", totalNumberOfTrades) + .toString(); } } From 92ae20a4dd5e4dc656d0acf5a6bcd88207baa5d6 Mon Sep 17 00:00:00 2001 From: Tony Skulk Date: Sat, 27 Jan 2018 18:28:47 +0100 Subject: [PATCH 19/81] Add all market tickers example. --- .../api/examples/AllMarketTickersExample.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/test/java/com/binance/api/examples/AllMarketTickersExample.java diff --git a/src/test/java/com/binance/api/examples/AllMarketTickersExample.java b/src/test/java/com/binance/api/examples/AllMarketTickersExample.java new file mode 100644 index 000000000..94880a59e --- /dev/null +++ b/src/test/java/com/binance/api/examples/AllMarketTickersExample.java @@ -0,0 +1,21 @@ +package com.binance.api.examples; + +import com.binance.api.client.BinanceApiClientFactory; +import com.binance.api.client.BinanceApiWebSocketClient; + +/** + * All market tickers channel examples. + * + * It illustrates how to create a stream to obtain all market tickers. + */ +public class AllMarketTickersExample { + + public static void main(String[] args) { + BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance(); + BinanceApiWebSocketClient client = factory.newWebSocketClient(); + + client.onAllMarketTickersEvent(event -> { + System.out.println(event); + }); + } +} From 5995165e6c50a613ed53470636ff0853535d7db9 Mon Sep 17 00:00:00 2001 From: Sai Chaitanya Chitneedi Date: Mon, 29 Jan 2018 03:16:13 +0530 Subject: [PATCH 20/81] Added ability to query 24hr ticker price change statistics for all symbols and to query latest price for single symbol Signed-off-by: Sai Chaitanya Chitneedi --- .../api/client/BinanceApiAsyncRestClient.java | 15 +++++++++++++++ .../binance/api/client/BinanceApiRestClient.java | 12 ++++++++++++ .../impl/BinanceApiAsyncRestClientImpl.java | 10 ++++++++++ .../api/client/impl/BinanceApiRestClientImpl.java | 12 ++++++++++++ .../api/client/impl/BinanceApiService.java | 6 ++++++ 5 files changed, 55 insertions(+) diff --git a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java index f4bbbc700..f8948e808 100644 --- a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java @@ -108,6 +108,13 @@ public interface BinanceApiAsyncRestClient { * @param callback the callback that handles the response */ void get24HrPriceStatistics(String symbol, BinanceApiCallback callback); + + /** + * Get 24 hour price change statistics for all symbols (asynchronous). + * + * @param callback the callback that handles the response + */ + void getAll24HrPriceStatistics(BinanceApiCallback> callback); /** * Get Latest price for all symbols (asynchronous). @@ -115,6 +122,14 @@ public interface BinanceApiAsyncRestClient { * @param callback the callback that handles the response */ void getAllPrices(BinanceApiCallback> callback); + + /** + * Get latest price for symbol (asynchronous). + * + * @param symbol ticker symbol (e.g. ETHBTC) + * @param callback the callback that handles the response + */ + void getSymbolPrice(String symbol , BinanceApiCallback callback); /** * Get best price/qty on the order book for all symbols (asynchronous). diff --git a/src/main/java/com/binance/api/client/BinanceApiRestClient.java b/src/main/java/com/binance/api/client/BinanceApiRestClient.java index d81b05d25..fb20247f4 100644 --- a/src/main/java/com/binance/api/client/BinanceApiRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiRestClient.java @@ -105,11 +105,23 @@ public interface BinanceApiRestClient { * @param symbol ticker symbol (e.g. ETHBTC) */ TickerStatistics get24HrPriceStatistics(String symbol); + + /** + * Get 24 hour price change statistics for all symbols. + */ + List getAll24HrPriceStatistics(); /** * Get Latest price for all symbols. */ List getAllPrices(); + + /** + * Get latest price for symbol. + * + * @param symbol ticker symbol (e.g. ETHBTC) + */ + TickerPrice getSymbolPrice(String symbol); /** * Get best price/qty on the order book for all symbols. diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java index ffdec9ea7..c5d1d2785 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java @@ -89,11 +89,21 @@ public void getCandlestickBars(String symbol, CandlestickInterval interval, Bina public void get24HrPriceStatistics(String symbol, BinanceApiCallback callback) { binanceApiService.get24HrPriceStatistics(symbol).enqueue(new BinanceApiCallbackAdapter<>(callback)); } + + @Override + public void getAll24HrPriceStatistics(BinanceApiCallback> callback) { + binanceApiService.getAll24HrPriceStatistics().enqueue(new BinanceApiCallbackAdapter<>(callback)); + } @Override public void getAllPrices(BinanceApiCallback> callback) { binanceApiService.getLatestPrices().enqueue(new BinanceApiCallbackAdapter<>(callback)); } + + @Override + public void getSymbolPrice(String symbol , BinanceApiCallback callback) { + binanceApiService.getSymbolPrice(symbol).enqueue(new BinanceApiCallbackAdapter<>(callback)); + } @Override public void getBookTickers(BinanceApiCallback> callback) { diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java index 0390ac7ab..3b66785c3 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java @@ -88,6 +88,18 @@ public TickerStatistics get24HrPriceStatistics(String symbol) { return executeSync(binanceApiService.get24HrPriceStatistics(symbol)); } + + @Override + public List getAll24HrPriceStatistics() { + return executeSync(binanceApiService.getAll24HrPriceStatistics()); + } + + @Override + public TickerPrice getSymbolPrice(String symbol) { + return executeSync(binanceApiService.getSymbolPrice(symbol)); + } + + @Override public List getAllPrices() { return executeSync(binanceApiService.getLatestPrices()); diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiService.java b/src/main/java/com/binance/api/client/impl/BinanceApiService.java index 17c089f92..ab91b20fe 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiService.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiService.java @@ -61,9 +61,15 @@ Call> getCandlestickBars(@Query("symbol") String symbol, @Quer @GET("/api/v1/ticker/24hr") Call get24HrPriceStatistics(@Query("symbol") String symbol); + + @GET("/api/v1/ticker/24hr") + Call> getAll24HrPriceStatistics(); @GET("/api/v1/ticker/allPrices") Call> getLatestPrices(); + + @GET("/api/v3/ticker/price") + Call getSymbolPrice(@Query("symbol") String symbol); @GET("/api/v1/ticker/allBookTickers") Call> getBookTickers(); From 1564ffe13ba6c603e53280b2acc3b8c46413d0fb Mon Sep 17 00:00:00 2001 From: joaopsilva Date: Mon, 29 Jan 2018 02:34:14 +0100 Subject: [PATCH 21/81] Fixes #59 Typo in CandlestickInterval enum. --- .../binance/api/client/domain/market/CandlestickInterval.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/domain/market/CandlestickInterval.java b/src/main/java/com/binance/api/client/domain/market/CandlestickInterval.java index 5bb13f733..3bd4887e3 100644 --- a/src/main/java/com/binance/api/client/domain/market/CandlestickInterval.java +++ b/src/main/java/com/binance/api/client/domain/market/CandlestickInterval.java @@ -12,7 +12,7 @@ public enum CandlestickInterval { HALF_HOURLY("30m"), HOURLY("1h"), TWO_HOURLY("2h"), - FOUR_HORLY("4h"), + FOUR_HOURLY("4h"), SIX_HOURLY("6h"), EIGHT_HOURLY("8h"), TWELVE_HOURLY("12h"), From e95b670d26b7b2cbb4b40f9c391b4c1dad3ddbf7 Mon Sep 17 00:00:00 2001 From: smurf Date: Sat, 3 Feb 2018 00:04:41 +0100 Subject: [PATCH 22/81] NewOrder.newClientOrderId() is now passed through to binance when placing a new order. --- .../api/client/impl/BinanceApiAsyncRestClientImpl.java | 8 ++++---- .../binance/api/client/impl/BinanceApiRestClientImpl.java | 8 ++++---- .../com/binance/api/client/impl/BinanceApiService.java | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java index ffdec9ea7..2828016e5 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java @@ -103,15 +103,15 @@ public void getBookTickers(BinanceApiCallback> callback) { @Override public void newOrder(NewOrder order, BinanceApiCallback callback) { binanceApiService.newOrder(order.getSymbol(), order.getSide(), order.getType(), - order.getTimeInForce(), order.getQuantity(), order.getPrice(), order.getStopPrice(), order.getIcebergQty(), - order.getRecvWindow(), order.getTimestamp()).enqueue(new BinanceApiCallbackAdapter<>(callback)); + order.getTimeInForce(), order.getQuantity(), order.getPrice(), order.getNewClientOrderId(), order.getStopPrice(), + order.getIcebergQty(), order.getRecvWindow(), order.getTimestamp()).enqueue(new BinanceApiCallbackAdapter<>(callback)); } @Override public void newOrderTest(NewOrder order, BinanceApiCallback callback) { binanceApiService.newOrderTest(order.getSymbol(), order.getSide(), order.getType(), - order.getTimeInForce(), order.getQuantity(), order.getPrice(), order.getStopPrice(), order.getIcebergQty(), - order.getRecvWindow(), order.getTimestamp()).enqueue(new BinanceApiCallbackAdapter<>(callback)); + order.getTimeInForce(), order.getQuantity(), order.getPrice(), order.getNewClientOrderId(), order.getStopPrice(), + order.getIcebergQty(), order.getRecvWindow(), order.getTimestamp()).enqueue(new BinanceApiCallbackAdapter<>(callback)); } // Account endpoints diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java index 0390ac7ab..5c803ae77 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java @@ -101,15 +101,15 @@ public List getBookTickers() { @Override public NewOrderResponse newOrder(NewOrder order) { return executeSync(binanceApiService.newOrder(order.getSymbol(), order.getSide(), order.getType(), - order.getTimeInForce(), order.getQuantity(), order.getPrice(), order.getStopPrice(), order.getIcebergQty(), - order.getRecvWindow(), order.getTimestamp())); + order.getTimeInForce(), order.getQuantity(), order.getPrice(), order.getNewClientOrderId(), order.getStopPrice(), + order.getIcebergQty(), order.getRecvWindow(), order.getTimestamp())); } @Override public void newOrderTest(NewOrder order) { executeSync(binanceApiService.newOrderTest(order.getSymbol(), order.getSide(), order.getType(), - order.getTimeInForce(), order.getQuantity(), order.getPrice(), order.getStopPrice(), order.getIcebergQty(), - order.getRecvWindow(), order.getTimestamp())); + order.getTimeInForce(), order.getQuantity(), order.getPrice(), order.getNewClientOrderId(), order.getStopPrice(), + order.getIcebergQty(), order.getRecvWindow(), order.getTimestamp())); } // Account endpoints diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiService.java b/src/main/java/com/binance/api/client/impl/BinanceApiService.java index 17c089f92..8f8f8d2c0 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiService.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiService.java @@ -74,15 +74,15 @@ Call> getCandlestickBars(@Query("symbol") String symbol, @Quer @POST("/api/v3/order") Call newOrder(@Query("symbol") String symbol, @Query("side") OrderSide side, @Query("type") OrderType type, @Query("timeInForce") TimeInForce timeInForce, @Query("quantity") String quantity, @Query("price") String price, - @Query("stopPrice") String stopPrice, @Query("icebergQty") String icebergQty, - @Query("recvWindow") Long recvWindow, @Query("timestamp") Long timestamp); + @Query("newClientOrderId") String newClientOrderId, @Query("stopPrice") String stopPrice, + @Query("icebergQty") String icebergQty, @Query("recvWindow") Long recvWindow, @Query("timestamp") Long timestamp); @Headers(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_SIGNED_HEADER) @POST("/api/v3/order/test") Call newOrderTest(@Query("symbol") String symbol, @Query("side") OrderSide side, @Query("type") OrderType type, @Query("timeInForce") TimeInForce timeInForce, @Query("quantity") String quantity, @Query("price") String price, - @Query("stopPrice") String stopPrice, @Query("icebergQty") String icebergQty, - @Query("recvWindow") Long recvWindow, @Query("timestamp") Long timestamp); + @Query("newClientOrderId") String newClientOrderId, @Query("stopPrice") String stopPrice, + @Query("icebergQty") String icebergQty, @Query("recvWindow") Long recvWindow, @Query("timestamp") Long timestamp); @Headers(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_SIGNED_HEADER) @GET("/api/v3/order") From 8080c1fa8807c03a88b895978f9edf68a0f92ca7 Mon Sep 17 00:00:00 2001 From: Sai Chaitanya Chitneedi Date: Sun, 4 Feb 2018 00:09:20 +0530 Subject: [PATCH 23/81] Added symbol name to TickerStatistics --- .../client/domain/market/TickerStatistics.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/domain/market/TickerStatistics.java b/src/main/java/com/binance/api/client/domain/market/TickerStatistics.java index 204ee2147..aab7d57b1 100644 --- a/src/main/java/com/binance/api/client/domain/market/TickerStatistics.java +++ b/src/main/java/com/binance/api/client/domain/market/TickerStatistics.java @@ -10,6 +10,11 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class TickerStatistics { + /** + * Ticker symbol. + */ + private String symbol; + /** * Price change during the last 24 hours. */ @@ -217,10 +222,19 @@ public long getCount() { public void setCount(long count) { this.count = count; } + + public String getSymbol() { + return symbol; + } + + public void setSymbol(String symbol) { + this.symbol = symbol; + } - @Override +@Override public String toString() { return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + .append("symbol", symbol) .append("priceChange", priceChange) .append("priceChangePercent", priceChangePercent) .append("weightedAvgPrice", weightedAvgPrice) From a10dc0c0ab7fd848381af677f93cbf678c831a4e Mon Sep 17 00:00:00 2001 From: Andy Coates Date: Sun, 4 Feb 2018 15:00:57 +0000 Subject: [PATCH 24/81] -Removed unused imports -Added Java docs to make it clear you can close the websocket by calling close on the returned `Closeable` --- .../api/client/BinanceApiWebSocketClient.java | 51 ++++++++-- .../impl/BinanceApiWebSocketClientImpl.java | 94 +++++++++---------- 2 files changed, 88 insertions(+), 57 deletions(-) diff --git a/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java b/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java index 9ff785605..b118efa9d 100644 --- a/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java @@ -1,6 +1,5 @@ package com.binance.api.client; -import java.util.List; import com.binance.api.client.domain.event.AggTradeEvent; import com.binance.api.client.domain.event.AllMarketTickersEvent; import com.binance.api.client.domain.event.CandlestickEvent; @@ -9,21 +8,57 @@ import com.binance.api.client.domain.market.CandlestickInterval; import java.io.Closeable; +import java.util.List; /** * Binance API data streaming façade, supporting streaming of events through web sockets. */ public interface BinanceApiWebSocketClient extends Closeable { - Closeable onDepthEvent(String symbol, BinanceApiCallback callback); + /** + * Open a new web socket to receive {@link DepthEvent depthEvents} on a callback. + * + * @param symbol the market symbol to subscribe to + * @param callback the callback to call on new events + * @return a {@link Closeable} that allows the underlying web socket to be closed. + */ + Closeable onDepthEvent(String symbol, BinanceApiCallback callback); + + /** + * Open a new web socket to receive {@link CandlestickEvent candlestickEvents} on a callback. + * + * @param symbol the market symbol to subscribe to + * @param interval the interval of the candles tick events required + * @param callback the callback to call on new events + * @return a {@link Closeable} that allows the underlying web socket to be closed. + */ + Closeable onCandlestickEvent(String symbol, CandlestickInterval interval, BinanceApiCallback callback); - Closeable onCandlestickEvent(String symbol, CandlestickInterval interval, BinanceApiCallback callback); + /** + * Open a new web socket to receive {@link AggTradeEvent aggTradeEvents} on a callback. + * + * @param symbol the market symbol to subscribe to + * @param callback the callback to call on new events + * @return a {@link Closeable} that allows the underlying web socket to be closed. + */ + Closeable onAggTradeEvent(String symbol, BinanceApiCallback callback); - Closeable onAggTradeEvent(String symbol, BinanceApiCallback callback); + /** + * Open a new web socket to receive {@link UserDataUpdateEvent userDataUpdateEvents} on a callback. + * + * @param listenKey the listen key to subscribe to. + * @param callback the callback to call on new events + * @return a {@link Closeable} that allows the underlying web socket to be closed. + */ + Closeable onUserDataUpdateEvent(String listenKey, BinanceApiCallback callback); - Closeable onUserDataUpdateEvent(String listenKey, BinanceApiCallback callback); + /** + * Open a new web socket to receive {@link AllMarketTickersEvent allMarketTickersEvents} on a callback. + * + * @param callback the callback to call on new events + * @return a {@link Closeable} that allows the underlying web socket to be closed. + */ + Closeable onAllMarketTickersEvent(BinanceApiCallback> callback); - Closeable onAllMarketTickersEvent(BinanceApiCallback> callback); - - void close(); + void close(); } diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java index 1e874b8c7..87ff981ab 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java @@ -1,11 +1,5 @@ package com.binance.api.client.impl; -import java.io.Closeable; -import java.io.IOException; -import java.util.List; -import okhttp3.Dispatcher; -import okhttp3.OkHttpClient; -import okhttp3.Request; import com.binance.api.client.BinanceApiCallback; import com.binance.api.client.BinanceApiWebSocketClient; import com.binance.api.client.constant.BinanceApiConstants; @@ -15,64 +9,66 @@ import com.binance.api.client.domain.event.DepthEvent; import com.binance.api.client.domain.event.UserDataUpdateEvent; import com.binance.api.client.domain.market.CandlestickInterval; +import okhttp3.Dispatcher; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.WebSocket; import java.io.Closeable; +import java.util.List; /** * Binance API WebSocket client implementation using OkHttp. */ public class BinanceApiWebSocketClientImpl implements BinanceApiWebSocketClient, Closeable { - private OkHttpClient client; + private OkHttpClient client; + + public BinanceApiWebSocketClientImpl() { + Dispatcher d = new Dispatcher(); + d.setMaxRequestsPerHost(100); + this.client = new OkHttpClient.Builder().dispatcher(d).build(); + } + + public Closeable onDepthEvent(String symbol, BinanceApiCallback callback) { + final String channel = String.format("%s@depth", symbol); + return createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, DepthEvent.class)); + } - public BinanceApiWebSocketClientImpl() { - Dispatcher d = new Dispatcher(); - d.setMaxRequestsPerHost(100); - this.client = new OkHttpClient.Builder().dispatcher(d).build(); - } + @Override + public Closeable onCandlestickEvent(String symbol, CandlestickInterval interval, BinanceApiCallback callback) { + final String channel = String.format("%s@kline_%s", symbol, interval.getIntervalId()); + return createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, CandlestickEvent.class)); + } - public Closeable onDepthEvent(String symbol, BinanceApiCallback callback) { - final String channel = String.format("%s@depth", symbol); - return createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, DepthEvent.class)); - } + public Closeable onAggTradeEvent(String symbol, BinanceApiCallback callback) { + final String channel = String.format("%s@aggTrade", symbol); + return createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, AggTradeEvent.class)); + } - @Override - public Closeable onCandlestickEvent(String symbol, CandlestickInterval interval, BinanceApiCallback callback) { - final String channel = String.format("%s@kline_%s", symbol, interval.getIntervalId()); - return createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, CandlestickEvent.class)); - } + public Closeable onUserDataUpdateEvent(String listenKey, BinanceApiCallback callback) { + return createNewWebSocket(listenKey, new BinanceApiWebSocketListener<>(callback, UserDataUpdateEvent.class)); + } - public Closeable onAggTradeEvent(String symbol, BinanceApiCallback callback) { - final String channel = String.format("%s@aggTrade", symbol); - return createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, AggTradeEvent.class)); - } + public Closeable onAllMarketTickersEvent(BinanceApiCallback> callback) { + final String channel = "!ticker@arr"; + return createNewWebSocket(channel, new BinanceApiWebSocketListener>(callback)); + } - public Closeable onUserDataUpdateEvent(String listenKey, BinanceApiCallback callback) { - return createNewWebSocket(listenKey, new BinanceApiWebSocketListener<>(callback, UserDataUpdateEvent.class)); - } - - public Closeable onAllMarketTickersEvent(BinanceApiCallback> callback) { - final String channel = "!ticker@arr"; - return createNewWebSocket(channel, new BinanceApiWebSocketListener>(callback)); - } - - @Override - public void close() { - client.dispatcher().executorService().shutdown(); - } + @Override + public void close() { + client.dispatcher().executorService().shutdown(); + } - private Closeable createNewWebSocket(String channel, BinanceApiWebSocketListener listener) { - String streamingUrl = String.format("%s/%s", BinanceApiConstants.WS_API_BASE_URL, channel); - Request request = new Request.Builder().url(streamingUrl).build(); - final WebSocket webSocket = client.newWebSocket(request, listener); - return () -> { - final int code = 1000; - listener.onClosing(webSocket, code, null); - webSocket.close(code, null); - listener.onClosed(webSocket, code, null); - }; - } + private Closeable createNewWebSocket(String channel, BinanceApiWebSocketListener listener) { + String streamingUrl = String.format("%s/%s", BinanceApiConstants.WS_API_BASE_URL, channel); + Request request = new Request.Builder().url(streamingUrl).build(); + final WebSocket webSocket = client.newWebSocket(request, listener); + return () -> { + final int code = 1000; + listener.onClosing(webSocket, code, null); + webSocket.close(code, null); + listener.onClosed(webSocket, code, null); + }; + } } From 8664140b2330453455bf5b31a8ffae3c2bb583f2 Mon Sep 17 00:00:00 2001 From: Andy Coates Date: Mon, 5 Feb 2018 11:50:39 +0000 Subject: [PATCH 25/81] Add error handling and closure of websockets to readme --- README.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/README.md b/README.md index abe0f7c6d..3228627e8 100644 --- a/README.md +++ b/README.md @@ -279,6 +279,40 @@ client.closeUserDataStream(listenKey); BinanceApiWebSocketClient client = BinanceApiClientFactory.newInstance().newWebSocketClient(); ``` +#### Handling web socket errors + +Each of the methods `BinanceApiWebSocketClient` which open a new web socket takes a `BinanceApiCallback`, which is +called for each event received from the Binance servers. + +The `BinanceApiCallback` interface also has a `onFailure(Throwable)` method, which, optionally, can be implemented to +receive notifications if the web-socket fails, e.g. disconnection. + +```java +client.onAggTradeEvent(symbol.toLowerCase(), new BinanceApiCallback() { + @Override + public void onResponse(final AggTradeEvent response) { + System.out.println(response); + } + + @Override + public void onFailure(final Throwable cause) { + System.err.println("Web socket failed"); + cause.printStackTrace(System.err); + } +}); +``` + +#### Closing web sockets + +Each of the methods `BinanceApiWebSocketClient` which open a new web socket also return a `Closeable`. +This `Closeable` can be used to close the underlying web socket and free any associated resources, e.g. + +```java +Closable ws = client.onAggTradeEvent("ethbtc", someCallback); +// some time later... +ws.close(); +``` + #### Listen for aggregated trade events for ETH/BTC ```java client.onAggTradeEvent("ethbtc", (AggTradeEvent response) -> { From 37ef9a05bf738c82584e20e428a9c5a6a1fbfd59 Mon Sep 17 00:00:00 2001 From: Andy Coates Date: Mon, 5 Feb 2018 16:11:51 +0000 Subject: [PATCH 26/81] code review improvements --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3228627e8..46e008f74 100644 --- a/README.md +++ b/README.md @@ -281,7 +281,7 @@ BinanceApiWebSocketClient client = BinanceApiClientFactory.newInstance().newWebS #### Handling web socket errors -Each of the methods `BinanceApiWebSocketClient` which open a new web socket takes a `BinanceApiCallback`, which is +Each of the methods on `BinanceApiWebSocketClient`, which opens a new web socket, takes a `BinanceApiCallback`, which is called for each event received from the Binance servers. The `BinanceApiCallback` interface also has a `onFailure(Throwable)` method, which, optionally, can be implemented to @@ -304,7 +304,7 @@ client.onAggTradeEvent(symbol.toLowerCase(), new BinanceApiCallback Date: Tue, 6 Feb 2018 01:21:27 +0530 Subject: [PATCH 27/81] Pull request changes --- .../com/binance/api/client/BinanceApiAsyncRestClient.java | 2 +- .../java/com/binance/api/client/BinanceApiRestClient.java | 2 +- .../api/client/impl/BinanceApiAsyncRestClientImpl.java | 6 +++--- .../binance/api/client/impl/BinanceApiRestClientImpl.java | 6 ++---- .../java/com/binance/api/client/impl/BinanceApiService.java | 2 +- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java index f8948e808..0b1fd3920 100644 --- a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java @@ -129,7 +129,7 @@ public interface BinanceApiAsyncRestClient { * @param symbol ticker symbol (e.g. ETHBTC) * @param callback the callback that handles the response */ - void getSymbolPrice(String symbol , BinanceApiCallback callback); + void getPrice(String symbol , BinanceApiCallback callback); /** * Get best price/qty on the order book for all symbols (asynchronous). diff --git a/src/main/java/com/binance/api/client/BinanceApiRestClient.java b/src/main/java/com/binance/api/client/BinanceApiRestClient.java index fb20247f4..13de14178 100644 --- a/src/main/java/com/binance/api/client/BinanceApiRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiRestClient.java @@ -121,7 +121,7 @@ public interface BinanceApiRestClient { * * @param symbol ticker symbol (e.g. ETHBTC) */ - TickerPrice getSymbolPrice(String symbol); + TickerPrice getPrice(String symbol); /** * Get best price/qty on the order book for all symbols. diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java index c5d1d2785..370265750 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java @@ -92,7 +92,7 @@ public void get24HrPriceStatistics(String symbol, BinanceApiCallback> callback) { - binanceApiService.getAll24HrPriceStatistics().enqueue(new BinanceApiCallbackAdapter<>(callback)); + binanceApiService.getAll24HrPriceStatistics().enqueue(new BinanceApiCallbackAdapter<>(callback)); } @Override @@ -101,8 +101,8 @@ public void getAllPrices(BinanceApiCallback> callback) { } @Override - public void getSymbolPrice(String symbol , BinanceApiCallback callback) { - binanceApiService.getSymbolPrice(symbol).enqueue(new BinanceApiCallbackAdapter<>(callback)); + public void getPrice(String symbol , BinanceApiCallback callback) { + binanceApiService.getLatestPrice(symbol).enqueue(new BinanceApiCallbackAdapter<>(callback)); } @Override diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java index 3b66785c3..fc5b6d599 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java @@ -88,18 +88,16 @@ public TickerStatistics get24HrPriceStatistics(String symbol) { return executeSync(binanceApiService.get24HrPriceStatistics(symbol)); } - @Override public List getAll24HrPriceStatistics() { return executeSync(binanceApiService.getAll24HrPriceStatistics()); } @Override - public TickerPrice getSymbolPrice(String symbol) { - return executeSync(binanceApiService.getSymbolPrice(symbol)); + public TickerPrice getPrice(String symbol) { + return executeSync(binanceApiService.getLatestPrice(symbol)); } - @Override public List getAllPrices() { return executeSync(binanceApiService.getLatestPrices()); diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiService.java b/src/main/java/com/binance/api/client/impl/BinanceApiService.java index ab91b20fe..6be99c867 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiService.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiService.java @@ -69,7 +69,7 @@ Call> getCandlestickBars(@Query("symbol") String symbol, @Quer Call> getLatestPrices(); @GET("/api/v3/ticker/price") - Call getSymbolPrice(@Query("symbol") String symbol); + Call getLatestPrice(@Query("symbol") String symbol); @GET("/api/v1/ticker/allBookTickers") Call> getBookTickers(); From 8f41f616a7a2db442d04310ed3fe8c13d0afce5b Mon Sep 17 00:00:00 2001 From: Justin Ayers Date: Wed, 7 Feb 2018 09:23:09 -0500 Subject: [PATCH 28/81] issues-52 Fix - Added feature to override the ToStringStyle used by the overloaded toString() methods. There is now a public static ToStringStyle TO_STRING_BUILDER_STYLE located in the Constants class that defaults to the current SHORT_PREFIX_STYLE but can be replaced with another one like JSON_STYLE. I also added a new package for utils and started a CommonUtils class. Here I added a few static prettyPrintJson helper methods. I also created a test class for that file. --- .gitignore | 1 + pom.xml | 6 + .../binance/api/client/BinanceApiError.java | 4 +- .../client/constant/BinanceApiConstants.java | 9 ++ .../api/client/domain/account/Account.java | 4 +- .../client/domain/account/AssetBalance.java | 4 +- .../api/client/domain/account/Deposit.java | 4 +- .../client/domain/account/DepositAddress.java | 4 +- .../client/domain/account/DepositHistory.java | 4 +- .../api/client/domain/account/NewOrder.java | 3 +- .../domain/account/NewOrderResponse.java | 4 +- .../api/client/domain/account/Order.java | 4 +- .../api/client/domain/account/Trade.java | 4 +- .../api/client/domain/account/Withdraw.java | 4 +- .../domain/account/WithdrawHistory.java | 4 +- .../account/request/AllOrdersRequest.java | 4 +- .../account/request/CancelOrderRequest.java | 4 +- .../domain/account/request/OrderRequest.java | 3 +- .../account/request/OrderStatusRequest.java | 4 +- .../domain/event/AccountUpdateEvent.java | 4 +- .../client/domain/event/AggTradeEvent.java | 4 +- .../domain/event/AllMarketTickersEvent.java | 4 +- .../client/domain/event/CandlestickEvent.java | 4 +- .../api/client/domain/event/DepthEvent.java | 4 +- .../domain/event/OrderTradeUpdateEvent.java | 4 +- .../domain/event/UserDataUpdateEvent.java | 4 +- .../client/domain/general/ExchangeFilter.java | 4 +- .../client/domain/general/ExchangeInfo.java | 4 +- .../api/client/domain/general/RateLimit.java | 4 +- .../api/client/domain/general/SymbolInfo.java | 4 +- .../api/client/domain/market/AggTrade.java | 4 +- .../api/client/domain/market/BookTicker.java | 4 +- .../api/client/domain/market/Candlestick.java | 4 +- .../api/client/domain/market/OrderBook.java | 4 +- .../client/domain/market/OrderBookEntry.java | 4 +- .../api/client/domain/market/TickerPrice.java | 4 +- .../domain/market/TickerStatistics.java | 6 +- .../binance/api/client/utils/StringUtils.java | 95 ++++++++++++++ .../api/client/utils/StringUtilsTest.java | 119 ++++++++++++++++++ .../general/ExchangeInfoDeserializerTest.java | 3 + 40 files changed, 300 insertions(+), 69 deletions(-) create mode 100644 src/main/java/com/binance/api/client/utils/StringUtils.java create mode 100644 src/test/java/com/binance/api/client/utils/StringUtilsTest.java diff --git a/.gitignore b/.gitignore index 71eae81ce..6cb0b3806 100644 --- a/.gitignore +++ b/.gitignore @@ -98,3 +98,4 @@ target/ # Ignore files and folders starting with dot (except gitignore) .* !/.gitignore +/nbproject/ \ No newline at end of file diff --git a/pom.xml b/pom.xml index f940bff48..c276aae77 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,12 @@ 4.12 test + + com.google.code.gson + gson + 2.8.2 + jar + diff --git a/src/main/java/com/binance/api/client/BinanceApiError.java b/src/main/java/com/binance/api/client/BinanceApiError.java index 7086768da..c5adc184e 100644 --- a/src/main/java/com/binance/api/client/BinanceApiError.java +++ b/src/main/java/com/binance/api/client/BinanceApiError.java @@ -1,7 +1,7 @@ package com.binance.api.client; +import com.binance.api.client.constant.BinanceApiConstants; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * Binance API error object. @@ -36,7 +36,7 @@ public void setMsg(String msg) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("code", code) .append("msg", msg) .toString(); diff --git a/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java b/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java index 9a3e1ece8..5fe72265b 100644 --- a/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java +++ b/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java @@ -1,5 +1,7 @@ package com.binance.api.client.constant; +import org.apache.commons.lang3.builder.ToStringStyle; + /** * Constants used throughout Binance's API. */ @@ -36,4 +38,11 @@ public class BinanceApiConstants { * Default receiving window. */ public static final long DEFAULT_RECEIVING_WINDOW = 6_000_000L; + + /** + * Default ToStringStyle used by toString methods. + * Override this to change the output format of the overridden toString methods. + * - Example ToStringStyle.JSON_STYLE + */ + public static ToStringStyle TO_STRING_BUILDER_STYLE = ToStringStyle.SHORT_PREFIX_STYLE; } diff --git a/src/main/java/com/binance/api/client/domain/account/Account.java b/src/main/java/com/binance/api/client/domain/account/Account.java index 189bbd0d1..e14edaeaa 100644 --- a/src/main/java/com/binance/api/client/domain/account/Account.java +++ b/src/main/java/com/binance/api/client/domain/account/Account.java @@ -1,8 +1,8 @@ package com.binance.api.client.domain.account; +import com.binance.api.client.constant.BinanceApiConstants; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; import java.util.List; @@ -150,7 +150,7 @@ public AssetBalance getAssetBalance(String symbol) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("makerCommission", makerCommission) .append("takerCommission", takerCommission) .append("buyerCommission", buyerCommission) diff --git a/src/main/java/com/binance/api/client/domain/account/AssetBalance.java b/src/main/java/com/binance/api/client/domain/account/AssetBalance.java index ad2101d46..9f90aafa4 100644 --- a/src/main/java/com/binance/api/client/domain/account/AssetBalance.java +++ b/src/main/java/com/binance/api/client/domain/account/AssetBalance.java @@ -1,7 +1,7 @@ package com.binance.api.client.domain.account; +import com.binance.api.client.constant.BinanceApiConstants; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * An asset balance in an Account. @@ -51,7 +51,7 @@ public void setLocked(String locked) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("asset", asset) .append("free", free) .append("locked", locked) diff --git a/src/main/java/com/binance/api/client/domain/account/Deposit.java b/src/main/java/com/binance/api/client/domain/account/Deposit.java index 8b6e654c1..14e8f779f 100644 --- a/src/main/java/com/binance/api/client/domain/account/Deposit.java +++ b/src/main/java/com/binance/api/client/domain/account/Deposit.java @@ -1,8 +1,8 @@ package com.binance.api.client.domain.account; +import com.binance.api.client.constant.BinanceApiConstants; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * A deposit that was done to a Binance account. @@ -77,7 +77,7 @@ public void setStatus(int status) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("amount", amount) .append("asset", asset) .append("insertTime", insertTime) diff --git a/src/main/java/com/binance/api/client/domain/account/DepositAddress.java b/src/main/java/com/binance/api/client/domain/account/DepositAddress.java index 9279bb76a..2ca99502f 100644 --- a/src/main/java/com/binance/api/client/domain/account/DepositAddress.java +++ b/src/main/java/com/binance/api/client/domain/account/DepositAddress.java @@ -1,7 +1,7 @@ package com.binance.api.client.domain.account; +import com.binance.api.client.constant.BinanceApiConstants; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * A deposit address for a given asset. @@ -50,7 +50,7 @@ public void setAsset(String asset) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("address", address) .append("success", success) .append("addressTag", addressTag) diff --git a/src/main/java/com/binance/api/client/domain/account/DepositHistory.java b/src/main/java/com/binance/api/client/domain/account/DepositHistory.java index 1034cefb0..0d45d32aa 100644 --- a/src/main/java/com/binance/api/client/domain/account/DepositHistory.java +++ b/src/main/java/com/binance/api/client/domain/account/DepositHistory.java @@ -1,8 +1,8 @@ package com.binance.api.client.domain.account; +import com.binance.api.client.constant.BinanceApiConstants; import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; import java.util.List; @@ -36,7 +36,7 @@ public void setSuccess(boolean success) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("depositList", depositList) .append("success", success) .toString(); diff --git a/src/main/java/com/binance/api/client/domain/account/NewOrder.java b/src/main/java/com/binance/api/client/domain/account/NewOrder.java index 6d611ec78..af76a78b2 100644 --- a/src/main/java/com/binance/api/client/domain/account/NewOrder.java +++ b/src/main/java/com/binance/api/client/domain/account/NewOrder.java @@ -5,7 +5,6 @@ import com.binance.api.client.domain.OrderType; import com.binance.api.client.domain.TimeInForce; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * A trade order to enter or exit a position. @@ -225,7 +224,7 @@ public static NewOrder limitSell(String symbol, TimeInForce timeInForce, String @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("symbol", symbol) .append("side", side) .append("type", type) diff --git a/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java b/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java index d8efdffbd..7485f175e 100644 --- a/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java +++ b/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java @@ -1,8 +1,8 @@ package com.binance.api.client.domain.account; +import com.binance.api.client.constant.BinanceApiConstants; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * Response returned when placing a new order on the system. @@ -67,7 +67,7 @@ public void setTransactTime(Long transactTime) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("symbol", symbol) .append("orderId", orderId) .append("clientOrderId", clientOrderId) diff --git a/src/main/java/com/binance/api/client/domain/account/Order.java b/src/main/java/com/binance/api/client/domain/account/Order.java index ae008ff41..a0b5939b7 100644 --- a/src/main/java/com/binance/api/client/domain/account/Order.java +++ b/src/main/java/com/binance/api/client/domain/account/Order.java @@ -1,12 +1,12 @@ package com.binance.api.client.domain.account; +import com.binance.api.client.constant.BinanceApiConstants; import com.binance.api.client.domain.OrderSide; import com.binance.api.client.domain.OrderStatus; import com.binance.api.client.domain.OrderType; import com.binance.api.client.domain.TimeInForce; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * Trade order information. @@ -185,7 +185,7 @@ public void setTime(long time) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("symbol", symbol) .append("orderId", orderId) .append("clientOrderId", clientOrderId) diff --git a/src/main/java/com/binance/api/client/domain/account/Trade.java b/src/main/java/com/binance/api/client/domain/account/Trade.java index 68e449e3f..feb639faa 100644 --- a/src/main/java/com/binance/api/client/domain/account/Trade.java +++ b/src/main/java/com/binance/api/client/domain/account/Trade.java @@ -1,8 +1,8 @@ package com.binance.api.client.domain.account; +import com.binance.api.client.constant.BinanceApiConstants; import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * Represents an executed trade. @@ -132,7 +132,7 @@ public void setOrderId(String orderId) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("id", id) .append("price", price) .append("qty", qty) diff --git a/src/main/java/com/binance/api/client/domain/account/Withdraw.java b/src/main/java/com/binance/api/client/domain/account/Withdraw.java index b6518db34..9d6858fdd 100644 --- a/src/main/java/com/binance/api/client/domain/account/Withdraw.java +++ b/src/main/java/com/binance/api/client/domain/account/Withdraw.java @@ -1,8 +1,8 @@ package com.binance.api.client.domain.account; +import com.binance.api.client.constant.BinanceApiConstants; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * A withdraw that was done to a Binance account. @@ -110,7 +110,7 @@ public void setStatus(int status) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("amount", amount) .append("address", address) .append("asset", asset) diff --git a/src/main/java/com/binance/api/client/domain/account/WithdrawHistory.java b/src/main/java/com/binance/api/client/domain/account/WithdrawHistory.java index d41a42a13..4694c0d09 100644 --- a/src/main/java/com/binance/api/client/domain/account/WithdrawHistory.java +++ b/src/main/java/com/binance/api/client/domain/account/WithdrawHistory.java @@ -1,7 +1,7 @@ package com.binance.api.client.domain.account; +import com.binance.api.client.constant.BinanceApiConstants; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; import java.util.List; @@ -34,7 +34,7 @@ public void setSuccess(boolean success) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("withdrawList", withdrawList) .append("success", success) .toString(); diff --git a/src/main/java/com/binance/api/client/domain/account/request/AllOrdersRequest.java b/src/main/java/com/binance/api/client/domain/account/request/AllOrdersRequest.java index 8ee8af8c7..9a7c455d6 100644 --- a/src/main/java/com/binance/api/client/domain/account/request/AllOrdersRequest.java +++ b/src/main/java/com/binance/api/client/domain/account/request/AllOrdersRequest.java @@ -1,7 +1,7 @@ package com.binance.api.client.domain.account.request; +import com.binance.api.client.constant.BinanceApiConstants; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * A specialized order request with additional filters. @@ -39,7 +39,7 @@ public AllOrdersRequest limit(Integer limit) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SIMPLE_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("orderId", orderId) .append("limit", limit) .toString(); diff --git a/src/main/java/com/binance/api/client/domain/account/request/CancelOrderRequest.java b/src/main/java/com/binance/api/client/domain/account/request/CancelOrderRequest.java index 22cf13ae4..010e23ef8 100644 --- a/src/main/java/com/binance/api/client/domain/account/request/CancelOrderRequest.java +++ b/src/main/java/com/binance/api/client/domain/account/request/CancelOrderRequest.java @@ -1,7 +1,7 @@ package com.binance.api.client.domain.account.request; +import com.binance.api.client.constant.BinanceApiConstants; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * Request object for canceling an order. @@ -56,7 +56,7 @@ public CancelOrderRequest newClientOrderId(String newClientOrderId) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("orderId", orderId) .append("origClientOrderId", origClientOrderId) .append("newClientOrderId", newClientOrderId) diff --git a/src/main/java/com/binance/api/client/domain/account/request/OrderRequest.java b/src/main/java/com/binance/api/client/domain/account/request/OrderRequest.java index 4b9dfad3a..2221af12d 100644 --- a/src/main/java/com/binance/api/client/domain/account/request/OrderRequest.java +++ b/src/main/java/com/binance/api/client/domain/account/request/OrderRequest.java @@ -2,7 +2,6 @@ import com.binance.api.client.constant.BinanceApiConstants; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * Base request parameters for order-related methods. @@ -45,7 +44,7 @@ public OrderRequest timestamp(Long timestamp) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("symbol", symbol) .append("recvWindow", recvWindow) .append("timestamp", timestamp) diff --git a/src/main/java/com/binance/api/client/domain/account/request/OrderStatusRequest.java b/src/main/java/com/binance/api/client/domain/account/request/OrderStatusRequest.java index b5af0b2d2..497eed1b2 100644 --- a/src/main/java/com/binance/api/client/domain/account/request/OrderStatusRequest.java +++ b/src/main/java/com/binance/api/client/domain/account/request/OrderStatusRequest.java @@ -1,7 +1,7 @@ package com.binance.api.client.domain.account.request; +import com.binance.api.client.constant.BinanceApiConstants; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * A specialized order request with additional filters. @@ -42,7 +42,7 @@ public OrderStatusRequest origClientOrderId(String origClientOrderId) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("orderId", orderId) .append("origClientOrderId", origClientOrderId) .toString(); diff --git a/src/main/java/com/binance/api/client/domain/event/AccountUpdateEvent.java b/src/main/java/com/binance/api/client/domain/event/AccountUpdateEvent.java index 63334a286..4deefdbad 100644 --- a/src/main/java/com/binance/api/client/domain/event/AccountUpdateEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/AccountUpdateEvent.java @@ -1,11 +1,11 @@ package com.binance.api.client.domain.event; +import com.binance.api.client.constant.BinanceApiConstants; import com.binance.api.client.domain.account.AssetBalance; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; import java.util.List; @@ -55,7 +55,7 @@ public void setBalances(List balances) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("eventType", eventType) .append("eventTime", eventTime) .append("balances", balances) diff --git a/src/main/java/com/binance/api/client/domain/event/AggTradeEvent.java b/src/main/java/com/binance/api/client/domain/event/AggTradeEvent.java index 4c6a71365..5f608a415 100644 --- a/src/main/java/com/binance/api/client/domain/event/AggTradeEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/AggTradeEvent.java @@ -1,10 +1,10 @@ package com.binance.api.client.domain.event; +import com.binance.api.client.constant.BinanceApiConstants; import com.binance.api.client.domain.market.AggTrade; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * An aggregated trade event for a symbol. @@ -47,7 +47,7 @@ public void setSymbol(String symbol) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("eventType", eventType) .append("eventTime", eventTime) .append("symbol", symbol) diff --git a/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java b/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java index 4c888a0d0..336f0980e 100644 --- a/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java @@ -1,7 +1,7 @@ package com.binance.api.client.domain.event; +import com.binance.api.client.constant.BinanceApiConstants; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; @@ -243,7 +243,7 @@ public void setTotalNumberOfTrades(long totalNumberOfTrades) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("eventType", eventType) .append("eventTime", eventTime) .append("symbol", symbol) diff --git a/src/main/java/com/binance/api/client/domain/event/CandlestickEvent.java b/src/main/java/com/binance/api/client/domain/event/CandlestickEvent.java index 5a6c35b8b..31cbe1e4f 100644 --- a/src/main/java/com/binance/api/client/domain/event/CandlestickEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/CandlestickEvent.java @@ -1,10 +1,10 @@ package com.binance.api.client.domain.event; +import com.binance.api.client.constant.BinanceApiConstants; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * An interval candlestick for a symbol providing informations on price that can be used to produce candlestick charts. @@ -195,7 +195,7 @@ public void setBarFinal(Boolean barFinal) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("eventType", eventType) .append("eventTime", eventTime) .append("symbol", symbol) diff --git a/src/main/java/com/binance/api/client/domain/event/DepthEvent.java b/src/main/java/com/binance/api/client/domain/event/DepthEvent.java index d94ff7b81..4dfe6a77a 100644 --- a/src/main/java/com/binance/api/client/domain/event/DepthEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/DepthEvent.java @@ -1,10 +1,10 @@ package com.binance.api.client.domain.event; +import com.binance.api.client.constant.BinanceApiConstants; import com.binance.api.client.domain.market.OrderBookEntry; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; import java.util.List; @@ -118,7 +118,7 @@ public void setAsks(List asks) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("eventType", eventType) .append("eventTime", eventTime) .append("symbol", symbol) diff --git a/src/main/java/com/binance/api/client/domain/event/OrderTradeUpdateEvent.java b/src/main/java/com/binance/api/client/domain/event/OrderTradeUpdateEvent.java index 88ae37556..0f26008a7 100644 --- a/src/main/java/com/binance/api/client/domain/event/OrderTradeUpdateEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/OrderTradeUpdateEvent.java @@ -1,5 +1,6 @@ package com.binance.api.client.domain.event; +import com.binance.api.client.constant.BinanceApiConstants; import com.binance.api.client.domain.ExecutionType; import com.binance.api.client.domain.OrderRejectReason; import com.binance.api.client.domain.OrderSide; @@ -9,7 +10,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * Order or trade report update event. @@ -292,7 +292,7 @@ public void setTradeId(long tradeId) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("eventType", eventType) .append("eventTime", eventTime) .append("symbol", symbol) diff --git a/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEvent.java b/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEvent.java index 647db9c57..0af50e198 100644 --- a/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEvent.java @@ -1,9 +1,9 @@ package com.binance.api.client.domain.event; +import com.binance.api.client.constant.BinanceApiConstants; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * User data update event which can be of two types: @@ -57,7 +57,7 @@ public void setOrderTradeUpdateEvent(OrderTradeUpdateEvent orderTradeUpdateEvent @Override public String toString() { - ToStringBuilder sb = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + ToStringBuilder sb = new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("eventType", eventType) .append("eventTime", eventTime); if (eventType == UserDataUpdateEventType.ACCOUNT_UPDATE) { diff --git a/src/main/java/com/binance/api/client/domain/general/ExchangeFilter.java b/src/main/java/com/binance/api/client/domain/general/ExchangeFilter.java index 765c616ab..ef4907925 100644 --- a/src/main/java/com/binance/api/client/domain/general/ExchangeFilter.java +++ b/src/main/java/com/binance/api/client/domain/general/ExchangeFilter.java @@ -1,7 +1,7 @@ package com.binance.api.client.domain.general; +import com.binance.api.client.constant.BinanceApiConstants; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * Exchange Filters define trading rules an exchange. @@ -34,7 +34,7 @@ public void setLimit(Integer limit) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("filterType", filterType) .append("limit", limit) .toString(); diff --git a/src/main/java/com/binance/api/client/domain/general/ExchangeInfo.java b/src/main/java/com/binance/api/client/domain/general/ExchangeInfo.java index fad53c12d..ab88f3c5c 100644 --- a/src/main/java/com/binance/api/client/domain/general/ExchangeInfo.java +++ b/src/main/java/com/binance/api/client/domain/general/ExchangeInfo.java @@ -1,9 +1,9 @@ package com.binance.api.client.domain.general; +import com.binance.api.client.constant.BinanceApiConstants; import com.binance.api.client.exception.BinanceApiException; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; import java.util.List; @@ -68,7 +68,7 @@ public SymbolInfo getSymbolInfo(String symbol) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("timezone", timezone) .append("serverTime", serverTime) .append("rateLimits", rateLimits) diff --git a/src/main/java/com/binance/api/client/domain/general/RateLimit.java b/src/main/java/com/binance/api/client/domain/general/RateLimit.java index 75faa1de0..8f0e3fd1a 100644 --- a/src/main/java/com/binance/api/client/domain/general/RateLimit.java +++ b/src/main/java/com/binance/api/client/domain/general/RateLimit.java @@ -1,7 +1,7 @@ package com.binance.api.client.domain.general; +import com.binance.api.client.constant.BinanceApiConstants; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * Rate limits. @@ -40,7 +40,7 @@ public void setLimit(Integer limit) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("rateLimitType", rateLimitType) .append("interval", interval) .append("limit", limit) diff --git a/src/main/java/com/binance/api/client/domain/general/SymbolInfo.java b/src/main/java/com/binance/api/client/domain/general/SymbolInfo.java index 38a06eb27..7eed2e97c 100644 --- a/src/main/java/com/binance/api/client/domain/general/SymbolInfo.java +++ b/src/main/java/com/binance/api/client/domain/general/SymbolInfo.java @@ -1,9 +1,9 @@ package com.binance.api.client.domain.general; +import com.binance.api.client.constant.BinanceApiConstants; import com.binance.api.client.domain.OrderType; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; import java.util.List; @@ -116,7 +116,7 @@ public SymbolFilter getSymbolFilter(FilterType filterType) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("symbol", symbol) .append("status", status) .append("baseAsset", baseAsset) diff --git a/src/main/java/com/binance/api/client/domain/market/AggTrade.java b/src/main/java/com/binance/api/client/domain/market/AggTrade.java index a76f30f0a..75d8c0d23 100644 --- a/src/main/java/com/binance/api/client/domain/market/AggTrade.java +++ b/src/main/java/com/binance/api/client/domain/market/AggTrade.java @@ -1,9 +1,9 @@ package com.binance.api.client.domain.market; +import com.binance.api.client.constant.BinanceApiConstants; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * An aggregated trade event for a symbol. @@ -90,7 +90,7 @@ public void setBuyerMaker(boolean buyerMaker) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("aggregatedTradeId", aggregatedTradeId) .append("price", price) .append("quantity", quantity) diff --git a/src/main/java/com/binance/api/client/domain/market/BookTicker.java b/src/main/java/com/binance/api/client/domain/market/BookTicker.java index d8afccf05..c91f3a76f 100644 --- a/src/main/java/com/binance/api/client/domain/market/BookTicker.java +++ b/src/main/java/com/binance/api/client/domain/market/BookTicker.java @@ -1,7 +1,7 @@ package com.binance.api.client.domain.market; +import com.binance.api.client.constant.BinanceApiConstants; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * Represents the best price/qty on the order book for a given symbol. @@ -75,7 +75,7 @@ public void setAskQty(String askQty) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("symbol", symbol) .append("bidPrice", bidPrice) .append("bidQty", bidQty) diff --git a/src/main/java/com/binance/api/client/domain/market/Candlestick.java b/src/main/java/com/binance/api/client/domain/market/Candlestick.java index 5ecb34f00..275f7cd37 100644 --- a/src/main/java/com/binance/api/client/domain/market/Candlestick.java +++ b/src/main/java/com/binance/api/client/domain/market/Candlestick.java @@ -1,10 +1,10 @@ package com.binance.api.client.domain.market; +import com.binance.api.client.constant.BinanceApiConstants; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * Kline/Candlestick bars for a symbol. Klines are uniquely identified by their open time. @@ -126,7 +126,7 @@ public void setTakerBuyQuoteAssetVolume(String takerBuyQuoteAssetVolume) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("openTime", openTime) .append("open", open) .append("high", high) diff --git a/src/main/java/com/binance/api/client/domain/market/OrderBook.java b/src/main/java/com/binance/api/client/domain/market/OrderBook.java index 7a7697a28..d5054a9e6 100644 --- a/src/main/java/com/binance/api/client/domain/market/OrderBook.java +++ b/src/main/java/com/binance/api/client/domain/market/OrderBook.java @@ -1,7 +1,7 @@ package com.binance.api.client.domain.market; +import com.binance.api.client.constant.BinanceApiConstants; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; import java.util.List; @@ -51,7 +51,7 @@ public void setAsks(List asks) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("lastUpdateId", lastUpdateId) .append("bids", bids) .append("asks", asks) diff --git a/src/main/java/com/binance/api/client/domain/market/OrderBookEntry.java b/src/main/java/com/binance/api/client/domain/market/OrderBookEntry.java index a83b29c1d..3bc946a7d 100644 --- a/src/main/java/com/binance/api/client/domain/market/OrderBookEntry.java +++ b/src/main/java/com/binance/api/client/domain/market/OrderBookEntry.java @@ -1,10 +1,10 @@ package com.binance.api.client.domain.market; +import com.binance.api.client.constant.BinanceApiConstants; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * An order book entry consisting of price and quantity. @@ -34,7 +34,7 @@ public void setQty(String qty) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("price", price) .append("qty", qty) .toString(); diff --git a/src/main/java/com/binance/api/client/domain/market/TickerPrice.java b/src/main/java/com/binance/api/client/domain/market/TickerPrice.java index 08edbb3f7..e2444cbc8 100644 --- a/src/main/java/com/binance/api/client/domain/market/TickerPrice.java +++ b/src/main/java/com/binance/api/client/domain/market/TickerPrice.java @@ -1,7 +1,7 @@ package com.binance.api.client.domain.market; +import com.binance.api.client.constant.BinanceApiConstants; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * Wraps a symbol and its corresponding latest price. @@ -36,7 +36,7 @@ public void setPrice(String price) { @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("symbol", symbol) .append("price", price) .toString(); diff --git a/src/main/java/com/binance/api/client/domain/market/TickerStatistics.java b/src/main/java/com/binance/api/client/domain/market/TickerStatistics.java index aab7d57b1..c23069de0 100644 --- a/src/main/java/com/binance/api/client/domain/market/TickerStatistics.java +++ b/src/main/java/com/binance/api/client/domain/market/TickerStatistics.java @@ -1,8 +1,8 @@ package com.binance.api.client.domain.market; +import com.binance.api.client.constant.BinanceApiConstants; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** * 24 hour price change statistics for a ticker. @@ -231,9 +231,9 @@ public void setSymbol(String symbol) { this.symbol = symbol; } -@Override + @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("symbol", symbol) .append("priceChange", priceChange) .append("priceChangePercent", priceChangePercent) diff --git a/src/main/java/com/binance/api/client/utils/StringUtils.java b/src/main/java/com/binance/api/client/utils/StringUtils.java new file mode 100644 index 000000000..61591824a --- /dev/null +++ b/src/main/java/com/binance/api/client/utils/StringUtils.java @@ -0,0 +1,95 @@ +package com.binance.api.client.utils; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import com.google.gson.stream.MalformedJsonException; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Common static StringUtils used throughout Binance's API. + */ +public class StringUtils { + + /** + * Convert a JSON string to pretty print JSON String + * + * @param jsonString a string already in a proper JSON syntax + * + * @return a pretty print version of the JSON String. If the + * provided String does not contain proper JSON syntax, then + * the original String is returned. + * { + * "symbol": "ETHUSDT", + * "orderId": 12345678, + * "clientOrderId": "smoD6joHgLUGlowNcZQcSf", + * "transactTime": 1511234502823 + * } + */ + public static String toPrettyJsonFormat( String jsonString ) { + String prettyJson = jsonString; + if(jsonString != null) { + try { + JsonParser parser = new JsonParser(); + JsonElement jsonElement = parser.parse(jsonString); + if (jsonElement != null && jsonElement.isJsonObject()) { + JsonObject json = jsonElement.getAsJsonObject(); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + prettyJson = gson.toJson(json); + } + } catch (JsonParseException ex) { + String message = new StringBuilder("Invalid JSON syntax. Cannot use toPrettyJsonFormat with with string [").append(prettyJson).append("]").toString(); + Logger.getLogger(StringUtils.class.getName()).log(Level.WARNING, message); + } + } + return String.valueOf(prettyJson); + } + + /** + * Convert a JSON string to pretty print JSON String + * This assumes you expect the provided object to output a JSON + * string when the toString method is called. + * + * @param jsonString a string already in a proper JSON syntax + * + * @return a pretty print version of the JSON String. If the + * provided String does not contain proper JSON syntax, then + * the original String is returned. + * { + * "symbol": "ETHUSDT", + * "orderId": 12345678, + * "clientOrderId": "smoD6joHgLUGlowNcZQcSf", + * "transactTime": 1511234502823 + * } + */ + public static String toPrettyJsonFormat( Object jsonString ) { + return toPrettyJsonFormat(String.valueOf(jsonString)); + } + + /** + * Convert a JSON string to pretty print version and prints to console. + * This assumes you expect the provided object to output a JSON + * string when the toString method is called. If the resulting toString + * call contains a non JSON syntax string then this will just print the + * original result. + * + * @param jsonString a string already in a proper JSON syntax + * results in a pretty print version of the JSON String. If the + * provided String does not contain proper JSON syntax, then + * the original String is returned. + * { + * "symbol": "ETHUSDT", + * "orderId": 12345678, + * "clientOrderId": "smoD6joHgLUGlowNcZQcSf", + * "transactTime": 1511234502823 + * } + */ + public static void printPrettyJsonFormat( Object jsonString ) { + System.out.println(toPrettyJsonFormat(jsonString)); + } +} diff --git a/src/test/java/com/binance/api/client/utils/StringUtilsTest.java b/src/test/java/com/binance/api/client/utils/StringUtilsTest.java new file mode 100644 index 000000000..2198ac7bc --- /dev/null +++ b/src/test/java/com/binance/api/client/utils/StringUtilsTest.java @@ -0,0 +1,119 @@ +package com.binance.api.client.utils; + +import com.binance.api.client.constant.BinanceApiConstants; +import com.binance.api.client.domain.market.Candlestick; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.apache.commons.lang3.builder.ToStringStyle; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +public class StringUtilsTest { + + private static String candlestickJson; + private static Candlestick candlestick; + private static ToStringStyle DEFAULT_TO_STRING_BUILDER_STYLE; + + public StringUtilsTest() { + } + + @BeforeClass + public static void setUpClass() { + + DEFAULT_TO_STRING_BUILDER_STYLE = BinanceApiConstants.TO_STRING_BUILDER_STYLE; + + candlestickJson = "[\n" + + " 1499040000000,\n" + + " \"0.01634790\",\n" + + " \"0.80000000\",\n" + + " \"0.01575800\",\n" + + " \"0.01577100\",\n" + + " \"148976.11427815\",\n" + + " 1499644799999,\n" + + " \"2434.19055334\",\n" + + " 308,\n" + + " \"1756.87402397\",\n" + + " \"28.46694368\",\n" + + " \"17928899.62484339\"\n" + + " ]"; + ObjectMapper mapper = new ObjectMapper(); + + try { + candlestick = mapper.readValue(candlestickJson, Candlestick.class); + } catch (IOException e) { + fail(); + } + } + + @AfterClass + public static void tearDownClass() { + BinanceApiConstants.TO_STRING_BUILDER_STYLE = DEFAULT_TO_STRING_BUILDER_STYLE; + } + + /** + * Test of toPrettyJsonFormat methods, of class StringUtils. + */ + @Test + public void testToPrettyJsonFormat_String() { + // candlestickJson is not a proper json syntax, this test shows that a malformed string can be + // given to toPrettyPrintJsonFormat and it will just return the string value of the provided object + String expResult = candlestickJson; + String result = StringUtils.toPrettyJsonFormat(candlestickJson); + assertEquals(expResult, result); + + // shows that a no error will happen if the provided object is null + assertEquals("null", StringUtils.toPrettyJsonFormat(null)); + + //show that the toString result a domain object with Default styling cannot be serialized into the same domain object + Logger.getLogger(StringUtilsTest.class.getName()).log(Level.INFO, "The Following Warning is expected and can be ignored"); + String prettyJsonFormat = StringUtils.toPrettyJsonFormat(candlestick); + try { + ObjectMapper mapper = new ObjectMapper(); + mapper.readValue(prettyJsonFormat, Candlestick.class); + fail(); + } catch (JsonParseException ex) { + assertEquals("JsonParseException", ex.getClass().getSimpleName()); + } catch (IOException ex) { + Logger.getLogger(StringUtilsTest.class.getName()).log(Level.WARNING, "Will not see this error here"); + } + + //show that the toString result of a domain object with JSON styling can be serialized into the same domain object again + BinanceApiConstants.TO_STRING_BUILDER_STYLE = ToStringStyle.JSON_STYLE; + prettyJsonFormat = StringUtils.toPrettyJsonFormat(candlestick); + + JsonParser parser = new JsonParser(); + JsonElement tradeElement = parser.parse(prettyJsonFormat); + JsonObject cand = tradeElement.getAsJsonObject(); + + Candlestick candlestick1 = new Candlestick(); + candlestick1.setOpenTime(cand.get("openTime").getAsLong()); + candlestick1.setOpen(cand.get("open").getAsString()); + candlestick1.setHigh(cand.get("high").getAsString()); + candlestick1.setLow(cand.get("low").getAsString()); + candlestick1.setClose(cand.get("close").getAsString()); + candlestick1.setVolume(cand.get("volume").getAsString()); + candlestick1.setCloseTime(cand.get("closeTime").getAsLong()); + candlestick1.setQuoteAssetVolume(cand.get("quoteAssetVolume").getAsString()); + candlestick1.setNumberOfTrades(cand.get("numberOfTrades").getAsLong()); + candlestick1.setTakerBuyBaseAssetVolume(cand.get("takerBuyBaseAssetVolume").getAsString()); + candlestick1.setTakerBuyQuoteAssetVolume(cand.get("takerBuyQuoteAssetVolume").getAsString()); + + Logger.getLogger(StringUtilsTest.class.getName()).log(Level.INFO, "The Following is a Valid pretty printed JSON syntax"); + StringUtils.printPrettyJsonFormat(candlestick1); + + // Clean up + BinanceApiConstants.TO_STRING_BUILDER_STYLE = DEFAULT_TO_STRING_BUILDER_STYLE; + + // Final test to show that the original candlestick tostring is equal to the newly created candlestick after being deseralized, ran though a formatter + // reserialized and had its string styling changed before running a comparison on their equality. + assertEquals(candlestick.toString(), candlestick1.toString()); + } +} diff --git a/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java b/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java index af949ff6f..a79644be6 100644 --- a/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java +++ b/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java @@ -1,5 +1,6 @@ package com.binance.api.domain.general; +import com.binance.api.client.constant.BinanceApiConstants; import com.binance.api.client.domain.OrderType; import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.FilterType; @@ -9,12 +10,14 @@ import com.binance.api.client.domain.general.SymbolFilter; import com.binance.api.client.domain.general.SymbolInfo; import com.binance.api.client.domain.general.SymbolStatus; +import com.binance.api.client.utils.StringUtils; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; import java.io.IOException; import java.util.Arrays; import java.util.List; +import org.apache.commons.lang3.builder.ToStringStyle; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; From 769d8ffedef3179c9e67f9c49ebb0b66a7b0becf Mon Sep 17 00:00:00 2001 From: Justin Ayers Date: Wed, 7 Feb 2018 09:39:10 -0500 Subject: [PATCH 29/81] issues-52 Fix - Added feature to override the ToStringStyle used by the overloaded toString() methods. There is now a public static ToStringStyle TO_STRING_BUILDER_STYLE located in the Constants class that defaults to the current SHORT_PREFIX_STYLE but can be replaced with another one like JSON_STYLE. I also added a new package for utils and started a CommonUtils class. Here I added a few static prettyPrintJson helper methods. I also created a test class for that file. --- .../api/domain/general/ExchangeInfoDeserializerTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java b/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java index a79644be6..af949ff6f 100644 --- a/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java +++ b/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java @@ -1,6 +1,5 @@ package com.binance.api.domain.general; -import com.binance.api.client.constant.BinanceApiConstants; import com.binance.api.client.domain.OrderType; import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.FilterType; @@ -10,14 +9,12 @@ import com.binance.api.client.domain.general.SymbolFilter; import com.binance.api.client.domain.general.SymbolInfo; import com.binance.api.client.domain.general.SymbolStatus; -import com.binance.api.client.utils.StringUtils; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; import java.io.IOException; import java.util.Arrays; import java.util.List; -import org.apache.commons.lang3.builder.ToStringStyle; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; From 25114c58abd133bc7da09f2ec9633bfec9230d98 Mon Sep 17 00:00:00 2001 From: Andy Coates Date: Thu, 8 Feb 2018 14:19:48 +0000 Subject: [PATCH 30/81] fixe issue #54 --- .../security/AuthenticationInterceptor.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/com/binance/api/client/security/AuthenticationInterceptor.java b/src/main/java/com/binance/api/client/security/AuthenticationInterceptor.java index c7d86af6a..3dc5c9b5a 100644 --- a/src/main/java/com/binance/api/client/security/AuthenticationInterceptor.java +++ b/src/main/java/com/binance/api/client/security/AuthenticationInterceptor.java @@ -10,6 +10,7 @@ import org.apache.commons.lang3.StringUtils; import java.io.IOException; +import java.util.Objects; /** * A request interceptor that injects the API Key Header into requests, and signs messages, whenever required. @@ -74,4 +75,18 @@ private static String bodyToString(RequestBody request) { throw new RuntimeException(e); } } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final AuthenticationInterceptor that = (AuthenticationInterceptor) o; + return Objects.equals(apiKey, that.apiKey) && + Objects.equals(secret, that.secret); + } + + @Override + public int hashCode() { + return Objects.hash(apiKey, secret); + } } \ No newline at end of file From d3ef4f37fbd3fd554779b0eb1e4ebe54a16caf8b Mon Sep 17 00:00:00 2001 From: Andy Coates Date: Thu, 8 Feb 2018 14:33:54 +0000 Subject: [PATCH 31/81] - add test --- .../impl/BinanceApiServiceGenerator.java | 2 +- .../impl/BinanceApiServiceGeneratorTest.java | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/binance/api/client/impl/BinanceApiServiceGeneratorTest.java diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java b/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java index 47cf66732..6d7ee2b76 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java @@ -19,7 +19,7 @@ */ public class BinanceApiServiceGenerator { - private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); + static OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); private static Retrofit.Builder builder = new Retrofit.Builder() diff --git a/src/test/java/com/binance/api/client/impl/BinanceApiServiceGeneratorTest.java b/src/test/java/com/binance/api/client/impl/BinanceApiServiceGeneratorTest.java new file mode 100644 index 000000000..132809c75 --- /dev/null +++ b/src/test/java/com/binance/api/client/impl/BinanceApiServiceGeneratorTest.java @@ -0,0 +1,24 @@ +package com.binance.api.client.impl; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author andy coates + * created 08/02/2018. + */ +public class BinanceApiServiceGeneratorTest { + @Test + public void shouldOnlyAddAuthInterceptorOnce() throws Exception { + // Given: + BinanceApiServiceGenerator.createService(BinanceApiService.class, "someKey", "someValue"); + final int initialSize = BinanceApiServiceGenerator.httpClient.interceptors().size(); + + // When: + BinanceApiServiceGenerator.createService(BinanceApiService.class, "someKey", "someValue"); + + // Then + assertEquals(BinanceApiServiceGenerator.httpClient.interceptors().size(), initialSize); + } +} \ No newline at end of file From 8619c19bfcffb92ff9df5546ecd0bb9491cd6d17 Mon Sep 17 00:00:00 2001 From: Andrey Stroganov Date: Fri, 23 Feb 2018 13:12:29 +0700 Subject: [PATCH 32/81] /api/v1/trades and /api/v1/historicalTrades calls support --- .../api/client/BinanceApiRestClient.java | 26 +++-- .../domain/account/TradeHistoryItem.java | 102 ++++++++++++++++++ .../client/impl/BinanceApiRestClientImpl.java | 19 ++-- .../api/client/impl/BinanceApiService.java | 14 +-- 4 files changed, 138 insertions(+), 23 deletions(-) create mode 100644 src/main/java/com/binance/api/client/domain/account/TradeHistoryItem.java diff --git a/src/main/java/com/binance/api/client/BinanceApiRestClient.java b/src/main/java/com/binance/api/client/BinanceApiRestClient.java index 13de14178..1f9b18029 100644 --- a/src/main/java/com/binance/api/client/BinanceApiRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiRestClient.java @@ -1,13 +1,6 @@ package com.binance.api.client; -import com.binance.api.client.domain.account.Account; -import com.binance.api.client.domain.account.DepositAddress; -import com.binance.api.client.domain.account.DepositHistory; -import com.binance.api.client.domain.account.NewOrder; -import com.binance.api.client.domain.account.NewOrderResponse; -import com.binance.api.client.domain.account.Order; -import com.binance.api.client.domain.account.Trade; -import com.binance.api.client.domain.account.WithdrawHistory; +import com.binance.api.client.domain.account.*; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; import com.binance.api.client.domain.account.request.OrderRequest; @@ -57,6 +50,23 @@ public interface BinanceApiRestClient { */ OrderBook getOrderBook(String symbol, Integer limit); + /** + * Get recent trades (up to last 500). Weight: 1 + * + * @param symbol ticker symbol (e.g. ETHBTC) + * @param limit of last trades (Default 500; max 500.) + */ + List getTrades(String symbol, Integer limit); + + /** + * Get older trades. Weight: 5 + * + * @param symbol ticker symbol (e.g. ETHBTC) + * @param limit of last trades (Default 500; max 500.) + * @param fromId TradeId to fetch from. Default gets most recent trades. + */ + List getHistoricalTrades(String symbol, Integer limit, Long fromId); + /** * Get compressed, aggregate trades. Trades that fill at the time, from the same order, with * the same price will have the quantity aggregated. diff --git a/src/main/java/com/binance/api/client/domain/account/TradeHistoryItem.java b/src/main/java/com/binance/api/client/domain/account/TradeHistoryItem.java new file mode 100644 index 000000000..a4470a0c1 --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/account/TradeHistoryItem.java @@ -0,0 +1,102 @@ +package com.binance.api.client.domain.account; + +import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang3.builder.ToStringBuilder; + +/** + * Represents an executed trade history item. + */ +public class TradeHistoryItem { + /** + * Trade id. + */ + private long id; + + /** + * Price. + */ + private String price; + + /** + * Quantity. + */ + private String qty; + + /** + * Trade execution time. + */ + private long time; + + /** + * Is buyer maker ? + */ + @JsonProperty("isBuyerMaker") + private boolean isBuyerMaker; + + /** + * Is best match ? + */ + @JsonProperty("isBestMatch") + private boolean isBestMatch; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } + + public String getQty() { + return qty; + } + + public void setQty(String qty) { + this.qty = qty; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public boolean isBuyerMaker() { + return isBuyerMaker; + } + + public void setBuyerMaker(boolean buyerMaker) { + isBuyerMaker = buyerMaker; + } + + public boolean isBestMatch() { + return isBestMatch; + } + + public void setBestMatch(boolean bestMatch) { + isBestMatch = bestMatch; + } + + @Override + public String toString() { + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) + .append("id", id) + .append("price", price) + .append("qty", qty) + .append("time", time) + .append("isBuyerMaker", isBuyerMaker) + .append("isBestMatch", isBestMatch) + .toString(); + } +} diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java index 61867dfa3..5db4ad3b3 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java @@ -2,14 +2,7 @@ import com.binance.api.client.BinanceApiRestClient; import com.binance.api.client.constant.BinanceApiConstants; -import com.binance.api.client.domain.account.Account; -import com.binance.api.client.domain.account.DepositAddress; -import com.binance.api.client.domain.account.DepositHistory; -import com.binance.api.client.domain.account.NewOrder; -import com.binance.api.client.domain.account.NewOrderResponse; -import com.binance.api.client.domain.account.Order; -import com.binance.api.client.domain.account.Trade; -import com.binance.api.client.domain.account.WithdrawHistory; +import com.binance.api.client.domain.account.*; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; import com.binance.api.client.domain.account.request.OrderRequest; @@ -63,6 +56,16 @@ public OrderBook getOrderBook(String symbol, Integer limit) { return executeSync(binanceApiService.getOrderBook(symbol, limit)); } + @Override + public List getTrades(String symbol, Integer limit) { + return executeSync(binanceApiService.getTrades(symbol, limit)); + } + + @Override + public List getHistoricalTrades(String symbol, Integer limit, Long fromId) { + return executeSync(binanceApiService.getHistoricalTrades(symbol, limit, fromId)); + } + @Override public List getAggTrades(String symbol, String fromId, Integer limit, Long startTime, Long endTime) { return executeSync(binanceApiService.getAggTrades(symbol, fromId, limit, startTime, endTime)); diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiService.java b/src/main/java/com/binance/api/client/impl/BinanceApiService.java index dbfdf43cf..43f3f2297 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiService.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiService.java @@ -4,13 +4,7 @@ import com.binance.api.client.domain.OrderSide; import com.binance.api.client.domain.OrderType; import com.binance.api.client.domain.TimeInForce; -import com.binance.api.client.domain.account.Account; -import com.binance.api.client.domain.account.DepositAddress; -import com.binance.api.client.domain.account.DepositHistory; -import com.binance.api.client.domain.account.NewOrderResponse; -import com.binance.api.client.domain.account.Order; -import com.binance.api.client.domain.account.Trade; -import com.binance.api.client.domain.account.WithdrawHistory; +import com.binance.api.client.domain.account.*; import com.binance.api.client.domain.event.ListenKey; import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.ServerTime; @@ -51,6 +45,12 @@ public interface BinanceApiService { @GET("/api/v1/depth") Call getOrderBook(@Query("symbol") String symbol, @Query("limit") Integer limit); + @GET("/api/v1/trades") + Call> getTrades(@Query("symbol") String symbol, @Query("limit") Integer limit); + + @GET("/api/v1/trades") + Call> getHistoricalTrades(@Query("symbol") String symbol, @Query("limit") Integer limit, @Query("fromId") Long fromId); + @GET("/api/v1/aggTrades") Call> getAggTrades(@Query("symbol") String symbol, @Query("fromId") String fromId, @Query("limit") Integer limit, @Query("startTime") Long startTime, @Query("endTime") Long endTime); From ce283c9fa00a20865bd537f82173f47bcf5848e0 Mon Sep 17 00:00:00 2001 From: Andrey Stroganov Date: Fri, 23 Feb 2018 13:15:49 +0700 Subject: [PATCH 33/81] /api/v1/trades and /api/v1/historicalTrades calls support import style fix --- .../com/binance/api/client/BinanceApiRestClient.java | 10 +++++++++- .../api/client/impl/BinanceApiRestClientImpl.java | 9 ++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/binance/api/client/BinanceApiRestClient.java b/src/main/java/com/binance/api/client/BinanceApiRestClient.java index 1f9b18029..97669356b 100644 --- a/src/main/java/com/binance/api/client/BinanceApiRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiRestClient.java @@ -1,6 +1,14 @@ package com.binance.api.client; -import com.binance.api.client.domain.account.*; +import com.binance.api.client.domain.account.Account; +import com.binance.api.client.domain.account.DepositAddress; +import com.binance.api.client.domain.account.DepositHistory; +import com.binance.api.client.domain.account.NewOrder; +import com.binance.api.client.domain.account.NewOrderResponse; +import com.binance.api.client.domain.account.Order; +import com.binance.api.client.domain.account.Trade; +import com.binance.api.client.domain.account.TradeHistoryItem; +import com.binance.api.client.domain.account.WithdrawHistory; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; import com.binance.api.client.domain.account.request.OrderRequest; diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java index 5db4ad3b3..d5ebaa955 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java @@ -2,7 +2,14 @@ import com.binance.api.client.BinanceApiRestClient; import com.binance.api.client.constant.BinanceApiConstants; -import com.binance.api.client.domain.account.*; +import com.binance.api.client.domain.account.Account; +import com.binance.api.client.domain.account.DepositAddress; +import com.binance.api.client.domain.account.DepositHistory; +import com.binance.api.client.domain.account.NewOrder; +import com.binance.api.client.domain.account.NewOrderResponse; +import com.binance.api.client.domain.account.Order; +import com.binance.api.client.domain.account.Trade; +import com.binance.api.client.domain.account.TradeHistoryItem; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; import com.binance.api.client.domain.account.request.OrderRequest; From b6102846eab263eb6d54526248336471c5f75b7c Mon Sep 17 00:00:00 2001 From: Andrey Stroganov Date: Fri, 23 Feb 2018 13:17:07 +0700 Subject: [PATCH 34/81] /api/v1/trades and /api/v1/historicalTrades calls support import style fix --- .../com/binance/api/client/impl/BinanceApiService.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiService.java b/src/main/java/com/binance/api/client/impl/BinanceApiService.java index 43f3f2297..51b52afa5 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiService.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiService.java @@ -4,7 +4,13 @@ import com.binance.api.client.domain.OrderSide; import com.binance.api.client.domain.OrderType; import com.binance.api.client.domain.TimeInForce; -import com.binance.api.client.domain.account.*; +import com.binance.api.client.domain.account.Account; +import com.binance.api.client.domain.account.DepositAddress; +import com.binance.api.client.domain.account.DepositHistory; +import com.binance.api.client.domain.account.NewOrderResponse; +import com.binance.api.client.domain.account.Order; +import com.binance.api.client.domain.account.Trade; +import com.binance.api.client.domain.account.TradeHistoryItem; import com.binance.api.client.domain.event.ListenKey; import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.ServerTime; From da76f01ffadcc081146cd4b08adda8df171522e5 Mon Sep 17 00:00:00 2001 From: Andrey Stroganov Date: Fri, 23 Feb 2018 13:17:38 +0700 Subject: [PATCH 35/81] /api/v1/trades and /api/v1/historicalTrades calls support import style fix --- .../java/com/binance/api/client/impl/BinanceApiService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiService.java b/src/main/java/com/binance/api/client/impl/BinanceApiService.java index 51b52afa5..03a08010b 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiService.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiService.java @@ -54,7 +54,7 @@ public interface BinanceApiService { @GET("/api/v1/trades") Call> getTrades(@Query("symbol") String symbol, @Query("limit") Integer limit); - @GET("/api/v1/trades") + @GET("/api/v1/historicalTrades") Call> getHistoricalTrades(@Query("symbol") String symbol, @Query("limit") Integer limit, @Query("fromId") Long fromId); @GET("/api/v1/aggTrades") From e7d53bf000d90da5e3fa84463e01ee30d5a81d81 Mon Sep 17 00:00:00 2001 From: Andrey Stroganov Date: Fri, 23 Feb 2018 13:18:35 +0700 Subject: [PATCH 36/81] /api/v1/trades and /api/v1/historicalTrades calls support import style fix --- src/main/java/com/binance/api/client/impl/BinanceApiService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiService.java b/src/main/java/com/binance/api/client/impl/BinanceApiService.java index 03a08010b..2cbc9a873 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiService.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiService.java @@ -11,6 +11,7 @@ import com.binance.api.client.domain.account.Order; import com.binance.api.client.domain.account.Trade; import com.binance.api.client.domain.account.TradeHistoryItem; +import com.binance.api.client.domain.account.WithdrawHistory; import com.binance.api.client.domain.event.ListenKey; import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.ServerTime; From f7f022df9feb744f7748c7d83d71520977addddf Mon Sep 17 00:00:00 2001 From: Andrey Stroganov Date: Fri, 23 Feb 2018 13:30:08 +0700 Subject: [PATCH 37/81] ENDPOINT_SECURITY_TYPE_APIKEY_HEADER for historicalTrades --- .../com/binance/api/client/impl/BinanceApiRestClientImpl.java | 1 + src/main/java/com/binance/api/client/impl/BinanceApiService.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java index d5ebaa955..a88e9d731 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java @@ -10,6 +10,7 @@ import com.binance.api.client.domain.account.Order; import com.binance.api.client.domain.account.Trade; import com.binance.api.client.domain.account.TradeHistoryItem; +import com.binance.api.client.domain.account.WithdrawHistory; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; import com.binance.api.client.domain.account.request.OrderRequest; diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiService.java b/src/main/java/com/binance/api/client/impl/BinanceApiService.java index 2cbc9a873..b2d21cd4c 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiService.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiService.java @@ -55,6 +55,7 @@ public interface BinanceApiService { @GET("/api/v1/trades") Call> getTrades(@Query("symbol") String symbol, @Query("limit") Integer limit); + @Headers(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_APIKEY_HEADER) @GET("/api/v1/historicalTrades") Call> getHistoricalTrades(@Query("symbol") String symbol, @Query("limit") Integer limit, @Query("fromId") Long fromId); From c74e80786e568db84b79bc5fa2482914d11a8d10 Mon Sep 17 00:00:00 2001 From: Andrey Stroganov Date: Fri, 23 Feb 2018 20:06:38 +0700 Subject: [PATCH 38/81] /api/v1/trades and /api/v1/historicalTrades async calls support --- .../api/client/BinanceApiAsyncRestClient.java | 20 +++++++++++++++++++ .../impl/BinanceApiAsyncRestClientImpl.java | 11 ++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java index 0b1fd3920..4916e16e6 100644 --- a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java @@ -7,6 +7,7 @@ import com.binance.api.client.domain.account.NewOrderResponse; import com.binance.api.client.domain.account.Order; import com.binance.api.client.domain.account.Trade; +import com.binance.api.client.domain.account.TradeHistoryItem; import com.binance.api.client.domain.account.WithdrawHistory; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; @@ -58,6 +59,25 @@ public interface BinanceApiAsyncRestClient { */ void getOrderBook(String symbol, Integer limit, BinanceApiCallback callback); + /** + * Get recent trades (up to last 500). Weight: 1 + * + * @param symbol ticker symbol (e.g. ETHBTC) + * @param limit of last trades (Default 500; max 500.) + * @param callback the callback that handles the response + */ + void getTrades(String symbol, Integer limit, BinanceApiCallback> callback); + + /** + * Get older trades. Weight: 5 + * + * @param symbol ticker symbol (e.g. ETHBTC) + * @param limit of last trades (Default 500; max 500.) + * @param fromId TradeId to fetch from. Default gets most recent trades. + * @param callback the callback that handles the response + */ + void getHistoricalTrades(String symbol, Integer limit, Long fromId, BinanceApiCallback> callback); + /** * Get compressed, aggregate trades. Trades that fill at the time, from the same order, with * the same price will have the quantity aggregated. diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java index f495b3595..08b5f9ffd 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java @@ -10,6 +10,7 @@ import com.binance.api.client.domain.account.NewOrderResponse; import com.binance.api.client.domain.account.Order; import com.binance.api.client.domain.account.Trade; +import com.binance.api.client.domain.account.TradeHistoryItem; import com.binance.api.client.domain.account.WithdrawHistory; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; @@ -65,6 +66,16 @@ public void getOrderBook(String symbol, Integer limit, BinanceApiCallback(callback)); } + @Override + public void getTrades(String symbol, Integer limit, BinanceApiCallback> callback) { + binanceApiService.getTrades(symbol, limit).enqueue(new BinanceApiCallbackAdapter<>(callback)); + } + + @Override + public void getHistoricalTrades(String symbol, Integer limit, Long fromId, BinanceApiCallback> callback) { + binanceApiService.getHistoricalTrades(symbol, limit, fromId).enqueue(new BinanceApiCallbackAdapter<>(callback)); + } + @Override public void getAggTrades(String symbol, String fromId, Integer limit, Long startTime, Long endTime, BinanceApiCallback> callback) { binanceApiService.getAggTrades(symbol, fromId, limit, startTime, endTime).enqueue(new BinanceApiCallbackAdapter<>(callback)); From 6d862129fe7989a287ae3a606ab8db9079e8bd18 Mon Sep 17 00:00:00 2001 From: Andy Coates Date: Sat, 24 Feb 2018 21:29:26 +0000 Subject: [PATCH 39/81] Fix the initialization of the depth cache. Old code had a race condition between polling the rest API and subscribing to updates on the web socket. It's possible that updates can be missed between the rest-poll and the ws-subscribe --- .../api/examples/DepthCacheExample.java | 86 +++++++++++++------ 1 file changed, 62 insertions(+), 24 deletions(-) diff --git a/src/test/java/com/binance/api/examples/DepthCacheExample.java b/src/test/java/com/binance/api/examples/DepthCacheExample.java index 6fbbfdfa8..c58e49d00 100644 --- a/src/test/java/com/binance/api/examples/DepthCacheExample.java +++ b/src/test/java/com/binance/api/examples/DepthCacheExample.java @@ -3,6 +3,7 @@ import com.binance.api.client.BinanceApiClientFactory; import com.binance.api.client.BinanceApiRestClient; import com.binance.api.client.BinanceApiWebSocketClient; +import com.binance.api.client.domain.event.DepthEvent; import com.binance.api.client.domain.market.OrderBook; import com.binance.api.client.domain.market.OrderBookEntry; @@ -13,33 +14,60 @@ import java.util.Map; import java.util.NavigableMap; import java.util.TreeMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; /** * Illustrates how to use the depth event stream to create a local cache of bids/asks for a symbol. */ public class DepthCacheExample { - private static final String BIDS = "BIDS"; - private static final String ASKS = "ASKS"; + private static final String BIDS = "BIDS"; + private static final String ASKS = "ASKS"; - private long lastUpdateId; + private final String symbol; + private final BinanceApiRestClient restClient; + private final BinanceApiWebSocketClient wsClient; + private final AtomicReference> wsCallback = new AtomicReference<>(); + private final Map> depthCache = new HashMap<>(); - private Map> depthCache; + private long lastUpdateId = -1; public DepthCacheExample(String symbol) { - initializeDepthCache(symbol); - startDepthEventStreaming(symbol); + this.symbol = symbol; + + BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance(); + wsClient = factory.newWebSocketClient(); + restClient = factory.newRestClient(); + + final List pendingDeltas = startDepthEventStreaming(); + + initializeDepthCache(); + + applyPendingDeltas(pendingDeltas); } /** - * Initializes the depth cache by using the REST API. + * Begins streaming of depth events. + * + * Any events received are cached until the rest API is polled for an initial snapshot. */ - private void initializeDepthCache(String symbol) { - BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance(); - BinanceApiRestClient client = factory.newRestClient(); - OrderBook orderBook = client.getOrderBook(symbol.toUpperCase(), 10); + private List startDepthEventStreaming() { + final List pendingDeltas = new CopyOnWriteArrayList<>(); + wsCallback.set(pendingDeltas::add); + + wsClient.onDepthEvent(symbol.toLowerCase(), event -> wsCallback.get().accept(event)); + + return pendingDeltas; + } + + /** + * Initializes the depth cache by getting a snapshot from the REST API. + */ + private void initializeDepthCache() { + OrderBook orderBook = restClient.getOrderBook(symbol.toUpperCase(), 10); - this.depthCache = new HashMap<>(); this.lastUpdateId = orderBook.getLastUpdateId(); NavigableMap asks = new TreeMap<>(Comparator.reverseOrder()); @@ -56,21 +84,31 @@ private void initializeDepthCache(String symbol) { } /** - * Begins streaming of depth events. + * Apply any deltas received on the web socket that have an update-id indicating they come after + * the snapshot, that the rest client returned, was generated. */ - private void startDepthEventStreaming(String symbol) { - BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance(); - BinanceApiWebSocketClient client = factory.newWebSocketClient(); - - client.onDepthEvent(symbol.toLowerCase(), response -> { - if (response.getFinalUpdateId() > lastUpdateId) { - System.out.println(response); - lastUpdateId = response.getFinalUpdateId(); - updateOrderBook(getAsks(), response.getAsks()); - updateOrderBook(getBids(), response.getBids()); + private void applyPendingDeltas(final List pendingDeltas) { + final Consumer updateOrderBook = newEvent -> { + if (newEvent.getFinalUpdateId() > lastUpdateId) { + System.out.println(newEvent); + lastUpdateId = newEvent.getFinalUpdateId(); + updateOrderBook(getAsks(), newEvent.getAsks()); + updateOrderBook(getBids(), newEvent.getBids()); printDepthCache(); } - }); + }; + + final Consumer drainPending = newEvent -> { + pendingDeltas.add(newEvent); + + pendingDeltas.stream() + .filter(e -> e.getFinalUpdateId() > lastUpdateId) // Ignore any updates before the snapshot + .forEach(updateOrderBook); + + wsCallback.set(updateOrderBook); + }; + + wsCallback.set(drainPending); } /** From 5029b19a3c50ac9bb59122bb68590e5ee964ab12 Mon Sep 17 00:00:00 2001 From: Andy Coates Date: Sat, 24 Feb 2018 21:44:43 +0000 Subject: [PATCH 40/81] Better docs / comments --- .../api/examples/DepthCacheExample.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/binance/api/examples/DepthCacheExample.java b/src/test/java/com/binance/api/examples/DepthCacheExample.java index c58e49d00..e1724e321 100644 --- a/src/test/java/com/binance/api/examples/DepthCacheExample.java +++ b/src/test/java/com/binance/api/examples/DepthCacheExample.java @@ -20,6 +20,19 @@ /** * Illustrates how to use the depth event stream to create a local cache of bids/asks for a symbol. + * + * Snapshots of the order book can be retrieved from the REST API. + * Delta changes to the book can be received by subscribing for updates via the web socket API. + * + * To ensure no updates are missed, it is important to subscribe for updates on the web socket API + * _before_ getting the snapshot from the REST API. Done the other way around it is possible to + * miss one or more updates on the web socket, leaving the local cache in an inconsistent state. + * + * Steps: + * 1. Subscribe to depth events and cache any events that are received. + * 2. Get a snapshot from the rest endpoint and use it to build your initial depth cache. + * 3. Apply any cache events that have a final updateId later than the snapshot's update id. + * 4. Start applying any newly received depth events to the depth cache. */ public class DepthCacheExample { @@ -41,8 +54,10 @@ public DepthCacheExample(String symbol) { wsClient = factory.newWebSocketClient(); restClient = factory.newRestClient(); + // 1. Subscribe to depth events and cache any events that are received. final List pendingDeltas = startDepthEventStreaming(); + // 2. Get a snapshot from the rest endpoint and use it to build your initial depth cache. initializeDepthCache(); applyPendingDeltas(pendingDeltas); @@ -63,7 +78,7 @@ private List startDepthEventStreaming() { } /** - * Initializes the depth cache by getting a snapshot from the REST API. + * 2. Initializes the depth cache by getting a snapshot from the REST API. */ private void initializeDepthCache() { OrderBook orderBook = restClient.getOrderBook(symbol.toUpperCase(), 10); @@ -84,8 +99,7 @@ private void initializeDepthCache() { } /** - * Apply any deltas received on the web socket that have an update-id indicating they come after - * the snapshot, that the rest client returned, was generated. + * Deal with any cached updates and switch to normal running. */ private void applyPendingDeltas(final List pendingDeltas) { final Consumer updateOrderBook = newEvent -> { @@ -101,10 +115,13 @@ private void applyPendingDeltas(final List pendingDeltas) { final Consumer drainPending = newEvent -> { pendingDeltas.add(newEvent); + // 3. Apply any deltas received on the web socket that have an update-id indicating they come + // after the snapshot. pendingDeltas.stream() .filter(e -> e.getFinalUpdateId() > lastUpdateId) // Ignore any updates before the snapshot .forEach(updateOrderBook); + // 4. Start applying any newly received depth events to the depth cache. wsCallback.set(updateOrderBook); }; From 0c9354f7ef970c550ba70cf0a05aa16b136fd99b Mon Sep 17 00:00:00 2001 From: Andy Coates Date: Sun, 25 Feb 2018 20:40:22 +0000 Subject: [PATCH 41/81] Add reconnect & close logic --- .../api/examples/DepthCacheExample.java | 61 ++++++++++++++++--- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/binance/api/examples/DepthCacheExample.java b/src/test/java/com/binance/api/examples/DepthCacheExample.java index e1724e321..eb1975796 100644 --- a/src/test/java/com/binance/api/examples/DepthCacheExample.java +++ b/src/test/java/com/binance/api/examples/DepthCacheExample.java @@ -1,5 +1,6 @@ package com.binance.api.examples; +import com.binance.api.client.BinanceApiCallback; import com.binance.api.client.BinanceApiClientFactory; import com.binance.api.client.BinanceApiRestClient; import com.binance.api.client.BinanceApiWebSocketClient; @@ -7,6 +8,8 @@ import com.binance.api.client.domain.market.OrderBook; import com.binance.api.client.domain.market.OrderBookEntry; +import java.io.Closeable; +import java.io.IOException; import java.math.BigDecimal; import java.util.Comparator; import java.util.HashMap; @@ -33,6 +36,8 @@ * 2. Get a snapshot from the rest endpoint and use it to build your initial depth cache. * 3. Apply any cache events that have a final updateId later than the snapshot's update id. * 4. Start applying any newly received depth events to the depth cache. + * + * The example repeats these steps, on a new web socket, should the web socket connection be lost. */ public class DepthCacheExample { @@ -42,24 +47,30 @@ public class DepthCacheExample { private final String symbol; private final BinanceApiRestClient restClient; private final BinanceApiWebSocketClient wsClient; - private final AtomicReference> wsCallback = new AtomicReference<>(); + private final WsCallback wsCallback = new WsCallback(); private final Map> depthCache = new HashMap<>(); private long lastUpdateId = -1; + private volatile Closeable webSocket; public DepthCacheExample(String symbol) { this.symbol = symbol; BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance(); - wsClient = factory.newWebSocketClient(); - restClient = factory.newRestClient(); + this.wsClient = factory.newWebSocketClient(); + this.restClient = factory.newRestClient(); + + initialize(); + } + private void initialize() { // 1. Subscribe to depth events and cache any events that are received. final List pendingDeltas = startDepthEventStreaming(); // 2. Get a snapshot from the rest endpoint and use it to build your initial depth cache. initializeDepthCache(); + // 3. & 4. handled in here. applyPendingDeltas(pendingDeltas); } @@ -70,9 +81,9 @@ public DepthCacheExample(String symbol) { */ private List startDepthEventStreaming() { final List pendingDeltas = new CopyOnWriteArrayList<>(); - wsCallback.set(pendingDeltas::add); + wsCallback.setHandler(pendingDeltas::add); - wsClient.onDepthEvent(symbol.toLowerCase(), event -> wsCallback.get().accept(event)); + this.webSocket = wsClient.onDepthEvent(symbol.toLowerCase(), wsCallback); return pendingDeltas; } @@ -118,14 +129,15 @@ private void applyPendingDeltas(final List pendingDeltas) { // 3. Apply any deltas received on the web socket that have an update-id indicating they come // after the snapshot. pendingDeltas.stream() - .filter(e -> e.getFinalUpdateId() > lastUpdateId) // Ignore any updates before the snapshot + .filter( + e -> e.getFinalUpdateId() > lastUpdateId) // Ignore any updates before the snapshot .forEach(updateOrderBook); // 4. Start applying any newly received depth events to the depth cache. - wsCallback.set(updateOrderBook); + wsCallback.setHandler(updateOrderBook); }; - wsCallback.set(drainPending); + wsCallback.setHandler(drainPending); } /** @@ -133,7 +145,8 @@ private void applyPendingDeltas(final List pendingDeltas) { * * Whenever the qty specified is ZERO, it means the price should was removed from the order book. */ - private void updateOrderBook(NavigableMap lastOrderBookEntries, List orderBookDeltas) { + private void updateOrderBook(NavigableMap lastOrderBookEntries, + List orderBookDeltas) { for (OrderBookEntry orderBookDelta : orderBookDeltas) { BigDecimal price = new BigDecimal(orderBookDelta.getPrice()); BigDecimal qty = new BigDecimal(orderBookDelta.getQty()); @@ -175,6 +188,10 @@ public Map> getDepthCache() { return depthCache; } + public void close() throws IOException { + webSocket.close(); + } + /** * Prints the cached order book / depth of a symbol as well as the best ask and bid price in the book. */ @@ -198,4 +215,30 @@ private static String toDepthCacheEntryString(Map.Entry public static void main(String[] args) { new DepthCacheExample("ETHBTC"); } + + private final class WsCallback implements BinanceApiCallback { + + private final AtomicReference> handler = new AtomicReference<>(); + + @Override + public void onResponse(DepthEvent depthEvent) { + try { + handler.get().accept(depthEvent); + } catch (final Exception e) { + System.err.println("Exception caught processing depth event"); + e.printStackTrace(System.err); + } + } + + @Override + public void onFailure(Throwable cause) { + System.out.println("WS connection failed. Reconnecting. cause:" + cause.getMessage()); + + initialize(); + } + + private void setHandler(final Consumer handler) { + this.handler.set(handler); + } + } } From 8571a99e76532bbb3f5b84b4a15588525e6ab274 Mon Sep 17 00:00:00 2001 From: TobCar Date: Tue, 13 Mar 2018 18:04:40 -0700 Subject: [PATCH 42/81] Add support for AllAssets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although not a part of the official API, the getAllAsset page on Binance’s website is useful for determining whether an asset can be withdrawn. --- .../api/client/domain/general/AllAssets.java | 123 ++++++++++++++++++ .../api/client/impl/BinanceApiService.java | 10 +- 2 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/binance/api/client/domain/general/AllAssets.java diff --git a/src/main/java/com/binance/api/client/domain/general/AllAssets.java b/src/main/java/com/binance/api/client/domain/general/AllAssets.java new file mode 100644 index 000000000..3923021d7 --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/general/AllAssets.java @@ -0,0 +1,123 @@ +package com.binance.api.client.domain.general; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * All assets Binance supports. + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public class AllAssets { + + @JsonProperty("id") + private String id; + + @JsonProperty("assetCode") + private String assetCode; + + @JsonProperty("assetName") + private String assetName; + + @JsonProperty("unit") + private String unit; + + @JsonProperty("transactionFee") + private long transactionFee; + + @JsonProperty("commissionRate") + private long commissionRate; + + @JsonProperty("freeAuditWithdrawAmt") + private long freeAuditWithdrawAmount; + + @JsonProperty("freeUserChargeAmount") + private long freeUserChargeAmount; + + @JsonProperty("minProductWithdraw") + private long minProductWithdraw; + + @JsonProperty("withdrawIntegerMultiple") + private long withdrawIntegerMultiple; + + @JsonProperty("confirmTimes") + private long confirmTimes; + + @JsonProperty("enableWithdraw") + private boolean enableWithdraw; + + @JsonProperty("isLegalMoney") + private boolean isLegalMoney; + + public String getId() { + return id; + } + + public String getAssetCode() { + return assetCode; + } + + public String getAssetName() { + return assetName; + } + + public String getUnit() { + return unit; + } + + public long getTransactionFee() { + return transactionFee; + } + + public long getCommissionRate() { + return commissionRate; + } + + public long getFreeAuditWithdrawAmount() { + return freeAuditWithdrawAmount; + } + + public long getFreeUserChargeAmount() { + return freeUserChargeAmount; + } + + public long minProductWithdraw() { + return minProductWithdraw; + } + + public long getWithdrawIntegerMultiple() { + return withdrawIntegerMultiple; + } + + public long getConfirmTimes() { + return confirmTimes; + } + + public long canWithraw() { + return enableWithdraw; + } + + public long isLegalMoney() { + return isLegalMoney; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + .append("id", id) + .append("assetCode", assetCode) + .append("assetName", assetName) + .append("unit", unit) + .append("transactionFee", transactionFee) + .append("commissionRate", commissionRate) + .append("freeAuditWithdrawAmount", freeAuditWithdrawAmount) + .append("freeUserChargeAmount", freeUserChargeAmount) + .append("minProductWithdraw", minProductWithdraw) + .append("withdrawIntegerMultiple", withdrawIntegerMultiple) + .append("confirmTimes", confirmTimes) + .append("enableWithdraw", enableWithdraw) + .append("isLegalMoney", isLegalMoney) + .toString(); + } + } diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiService.java b/src/main/java/com/binance/api/client/impl/BinanceApiService.java index b2d21cd4c..794282765 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiService.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiService.java @@ -15,6 +15,7 @@ import com.binance.api.client.domain.event.ListenKey; import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.ServerTime; +import com.binance.api.client.domain.general.AllAssets; import com.binance.api.client.domain.market.AggTrade; import com.binance.api.client.domain.market.BookTicker; import com.binance.api.client.domain.market.Candlestick; @@ -47,6 +48,9 @@ public interface BinanceApiService { @GET("/api/v1/exchangeInfo") Call getExchangeInfo(); + @GET("/assetWithdraw/getAllAsset.html") + Call getAllAssets(); + // Market data endpoints @GET("/api/v1/depth") @@ -69,13 +73,13 @@ Call> getCandlestickBars(@Query("symbol") String symbol, @Quer @GET("/api/v1/ticker/24hr") Call get24HrPriceStatistics(@Query("symbol") String symbol); - + @GET("/api/v1/ticker/24hr") Call> getAll24HrPriceStatistics(); @GET("/api/v1/ticker/allPrices") Call> getLatestPrices(); - + @GET("/api/v3/ticker/price") Call getLatestPrice(@Query("symbol") String symbol); @@ -159,4 +163,4 @@ Call withdraw(@Query("asset") String asset, @Query("address") String addre @Headers(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_APIKEY_HEADER) @DELETE("/api/v1/userDataStream") Call closeAliveUserDataStream(@Query("listenKey") String listenKey); -} \ No newline at end of file +} From 91dd28f957424d13b1cd625cb2303502ee64d49d Mon Sep 17 00:00:00 2001 From: TobCar Date: Sun, 25 Mar 2018 15:19:32 -0700 Subject: [PATCH 43/81] Expose getAllAssets JSON call --- .../binance/api/client/BinanceApiRestClient.java | 14 ++++++++++---- .../client/impl/BinanceApiAsyncRestClientImpl.java | 12 +++++++++--- .../api/client/impl/BinanceApiRestClientImpl.java | 8 +++++++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/binance/api/client/BinanceApiRestClient.java b/src/main/java/com/binance/api/client/BinanceApiRestClient.java index 97669356b..d9cc3b931 100644 --- a/src/main/java/com/binance/api/client/BinanceApiRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiRestClient.java @@ -14,6 +14,7 @@ import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; import com.binance.api.client.domain.general.ExchangeInfo; +import com.binance.api.client.domain.general.AllAssets; import com.binance.api.client.domain.market.AggTrade; import com.binance.api.client.domain.market.BookTicker; import com.binance.api.client.domain.market.Candlestick; @@ -43,6 +44,11 @@ public interface BinanceApiRestClient { */ Long getServerTime(); + /** + * @return All the assets Binance supports and whether or not they can be withdrawn. + */ + AllAssets getAllAssets(); + /** * @return Current exchange trading rules and symbol information */ @@ -123,7 +129,7 @@ public interface BinanceApiRestClient { * @param symbol ticker symbol (e.g. ETHBTC) */ TickerStatistics get24HrPriceStatistics(String symbol); - + /** * Get 24 hour price change statistics for all symbols. */ @@ -133,10 +139,10 @@ public interface BinanceApiRestClient { * Get Latest price for all symbols. */ List getAllPrices(); - + /** * Get latest price for symbol. - * + * * @param symbol ticker symbol (e.g. ETHBTC) */ TickerPrice getPrice(String symbol); @@ -286,4 +292,4 @@ public interface BinanceApiRestClient { * @param listenKey listen key that identifies a data stream */ void closeUserDataStream(String listenKey); -} \ No newline at end of file +} diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java index 08b5f9ffd..e4237a056 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java @@ -17,6 +17,7 @@ import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; import com.binance.api.client.domain.event.ListenKey; +import com.binance.api.client.domain.general.AllAssets; import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.ServerTime; import com.binance.api.client.domain.market.AggTrade; @@ -54,6 +55,11 @@ public void getServerTime(BinanceApiCallback callback) { binanceApiService.getServerTime().enqueue(new BinanceApiCallbackAdapter<>(callback)); } + @Override + public void getAllAssets(BinanceApiCallback callback) { + binanceApiService.getAllAssets().enqueue(new BinanceApiCallbackAdapter<>(callback)); + } + @Override public void getExchangeInfo(BinanceApiCallback callback) { binanceApiService.getExchangeInfo().enqueue(new BinanceApiCallbackAdapter<>(callback)); @@ -100,7 +106,7 @@ public void getCandlestickBars(String symbol, CandlestickInterval interval, Bina public void get24HrPriceStatistics(String symbol, BinanceApiCallback callback) { binanceApiService.get24HrPriceStatistics(symbol).enqueue(new BinanceApiCallbackAdapter<>(callback)); } - + @Override public void getAll24HrPriceStatistics(BinanceApiCallback> callback) { binanceApiService.getAll24HrPriceStatistics().enqueue(new BinanceApiCallbackAdapter<>(callback)); @@ -110,7 +116,7 @@ public void getAll24HrPriceStatistics(BinanceApiCallback> public void getAllPrices(BinanceApiCallback> callback) { binanceApiService.getLatestPrices().enqueue(new BinanceApiCallbackAdapter<>(callback)); } - + @Override public void getPrice(String symbol , BinanceApiCallback callback) { binanceApiService.getLatestPrice(symbol).enqueue(new BinanceApiCallbackAdapter<>(callback)); @@ -230,4 +236,4 @@ public void keepAliveUserDataStream(String listenKey, BinanceApiCallback c public void closeUserDataStream(String listenKey, BinanceApiCallback callback) { binanceApiService.closeAliveUserDataStream(listenKey).enqueue(new BinanceApiCallbackAdapter<>(callback)); } -} \ No newline at end of file +} diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java index a88e9d731..7ba6f97e3 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java @@ -15,6 +15,7 @@ import com.binance.api.client.domain.account.request.CancelOrderRequest; import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; +import com.binance.api.client.domain.general.AllAssets; import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.market.AggTrade; import com.binance.api.client.domain.market.BookTicker; @@ -52,6 +53,11 @@ public Long getServerTime() { return executeSync(binanceApiService.getServerTime()).getServerTime(); } + @Override + public AllAssets getAllAssets() { + return executeSync(binanceApiService.getAllAssets()); + } + @Override public ExchangeInfo getExchangeInfo() { return executeSync(binanceApiService.getExchangeInfo()); @@ -108,7 +114,7 @@ public List getAll24HrPriceStatistics() { public TickerPrice getPrice(String symbol) { return executeSync(binanceApiService.getLatestPrice(symbol)); } - + @Override public List getAllPrices() { return executeSync(binanceApiService.getLatestPrices()); From 69f56f5fcfc8aadf00fdbfe38cd0aaec80aa6da8 Mon Sep 17 00:00:00 2001 From: joaopsilva Date: Mon, 26 Mar 2018 17:43:18 +0200 Subject: [PATCH 44/81] Fixes #103: Add support for fetching all assets. --- .../api/client/BinanceApiAsyncRestClient.java | 6 ++ .../api/client/BinanceApiRestClient.java | 10 +-- .../client/constant/BinanceApiConstants.java | 5 ++ .../general/{AllAssets.java => Asset.java} | 36 +++++----- .../impl/BinanceApiAsyncRestClientImpl.java | 11 ++-- .../client/impl/BinanceApiRestClientImpl.java | 10 +-- .../api/client/impl/BinanceApiService.java | 7 +- .../constant/BinanceApiConstantsTest.java | 65 ++++++++++--------- .../api/examples/GeneralEndpointsExample.java | 7 ++ .../GeneralEndpointsExampleAsync.java | 7 ++ 10 files changed, 98 insertions(+), 66 deletions(-) rename src/main/java/com/binance/api/client/domain/general/{AllAssets.java => Asset.java} (74%) diff --git a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java index 4916e16e6..69416d50a 100644 --- a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java @@ -14,6 +14,7 @@ import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; import com.binance.api.client.domain.event.ListenKey; +import com.binance.api.client.domain.general.Asset; import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.ServerTime; import com.binance.api.client.domain.market.AggTrade; @@ -48,6 +49,11 @@ public interface BinanceApiAsyncRestClient { */ void getExchangeInfo(BinanceApiCallback callback); + /** + * ALL supported assets and whether or not they can be withdrawn. + */ + void getAllAssets(BinanceApiCallback> callback); + // Market Data endpoints /** diff --git a/src/main/java/com/binance/api/client/BinanceApiRestClient.java b/src/main/java/com/binance/api/client/BinanceApiRestClient.java index d9cc3b931..3044363f7 100644 --- a/src/main/java/com/binance/api/client/BinanceApiRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiRestClient.java @@ -14,7 +14,7 @@ import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; import com.binance.api.client.domain.general.ExchangeInfo; -import com.binance.api.client.domain.general.AllAssets; +import com.binance.api.client.domain.general.Asset; import com.binance.api.client.domain.market.AggTrade; import com.binance.api.client.domain.market.BookTicker; import com.binance.api.client.domain.market.Candlestick; @@ -45,14 +45,14 @@ public interface BinanceApiRestClient { Long getServerTime(); /** - * @return All the assets Binance supports and whether or not they can be withdrawn. + * @return Current exchange trading rules and symbol information */ - AllAssets getAllAssets(); + ExchangeInfo getExchangeInfo(); /** - * @return Current exchange trading rules and symbol information + * @return All the supported assets and whether or not they can be withdrawn. */ - ExchangeInfo getExchangeInfo(); + List getAllAssets(); // Market Data endpoints diff --git a/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java b/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java index 5fe72265b..00c4b2f71 100644 --- a/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java +++ b/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java @@ -17,6 +17,11 @@ public class BinanceApiConstants { */ public static final String WS_API_BASE_URL = "wss://stream.binance.com:9443/ws"; + /** + * Asset info base URL. + */ + public static final String ASSET_INFO_API_BASE_URL = "https://binance.com/"; + /** * HTTP Header to be used for API-KEY authentication. */ diff --git a/src/main/java/com/binance/api/client/domain/general/AllAssets.java b/src/main/java/com/binance/api/client/domain/general/Asset.java similarity index 74% rename from src/main/java/com/binance/api/client/domain/general/AllAssets.java rename to src/main/java/com/binance/api/client/domain/general/Asset.java index 3923021d7..4a286acc6 100644 --- a/src/main/java/com/binance/api/client/domain/general/AllAssets.java +++ b/src/main/java/com/binance/api/client/domain/general/Asset.java @@ -1,15 +1,15 @@ package com.binance.api.client.domain.general; +import com.binance.api.client.constant.BinanceApiConstants; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; /** - * All assets Binance supports. + * An asset Binance supports. */ @JsonIgnoreProperties(ignoreUnknown = true) - public class AllAssets { + public class Asset { @JsonProperty("id") private String id; @@ -24,22 +24,22 @@ public class AllAssets { private String unit; @JsonProperty("transactionFee") - private long transactionFee; + private String transactionFee; @JsonProperty("commissionRate") - private long commissionRate; + private String commissionRate; @JsonProperty("freeAuditWithdrawAmt") - private long freeAuditWithdrawAmount; + private String freeAuditWithdrawAmount; @JsonProperty("freeUserChargeAmount") - private long freeUserChargeAmount; + private String freeUserChargeAmount; @JsonProperty("minProductWithdraw") - private long minProductWithdraw; + private String minProductWithdraw; @JsonProperty("withdrawIntegerMultiple") - private long withdrawIntegerMultiple; + private String withdrawIntegerMultiple; @JsonProperty("confirmTimes") private long confirmTimes; @@ -66,27 +66,27 @@ public String getUnit() { return unit; } - public long getTransactionFee() { + public String getTransactionFee() { return transactionFee; } - public long getCommissionRate() { + public String getCommissionRate() { return commissionRate; } - public long getFreeAuditWithdrawAmount() { + public String getFreeAuditWithdrawAmount() { return freeAuditWithdrawAmount; } - public long getFreeUserChargeAmount() { + public String getFreeUserChargeAmount() { return freeUserChargeAmount; } - public long minProductWithdraw() { + public String minProductWithdraw() { return minProductWithdraw; } - public long getWithdrawIntegerMultiple() { + public String getWithdrawIntegerMultiple() { return withdrawIntegerMultiple; } @@ -94,17 +94,17 @@ public long getConfirmTimes() { return confirmTimes; } - public long canWithraw() { + public boolean canWithraw() { return enableWithdraw; } - public long isLegalMoney() { + public boolean isLegalMoney() { return isLegalMoney; } @Override public String toString() { - return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("id", id) .append("assetCode", assetCode) .append("assetName", assetName) diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java index e4237a056..5f97af80c 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java @@ -17,7 +17,7 @@ import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; import com.binance.api.client.domain.event.ListenKey; -import com.binance.api.client.domain.general.AllAssets; +import com.binance.api.client.domain.general.Asset; import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.ServerTime; import com.binance.api.client.domain.market.AggTrade; @@ -56,13 +56,14 @@ public void getServerTime(BinanceApiCallback callback) { } @Override - public void getAllAssets(BinanceApiCallback callback) { - binanceApiService.getAllAssets().enqueue(new BinanceApiCallbackAdapter<>(callback)); + public void getExchangeInfo(BinanceApiCallback callback) { + binanceApiService.getExchangeInfo().enqueue(new BinanceApiCallbackAdapter<>(callback)); } @Override - public void getExchangeInfo(BinanceApiCallback callback) { - binanceApiService.getExchangeInfo().enqueue(new BinanceApiCallbackAdapter<>(callback)); + public void getAllAssets(BinanceApiCallback> callback) { + binanceApiService.getAllAssets(BinanceApiConstants.ASSET_INFO_API_BASE_URL + "assetWithdraw/getAllAsset.html") + .enqueue(new BinanceApiCallbackAdapter<>(callback)); } // Market Data endpoints diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java index 7ba6f97e3..301a08aab 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java @@ -15,7 +15,7 @@ import com.binance.api.client.domain.account.request.CancelOrderRequest; import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; -import com.binance.api.client.domain.general.AllAssets; +import com.binance.api.client.domain.general.Asset; import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.market.AggTrade; import com.binance.api.client.domain.market.BookTicker; @@ -54,13 +54,13 @@ public Long getServerTime() { } @Override - public AllAssets getAllAssets() { - return executeSync(binanceApiService.getAllAssets()); + public ExchangeInfo getExchangeInfo() { + return executeSync(binanceApiService.getExchangeInfo()); } @Override - public ExchangeInfo getExchangeInfo() { - return executeSync(binanceApiService.getExchangeInfo()); + public List getAllAssets() { + return executeSync(binanceApiService.getAllAssets(BinanceApiConstants.ASSET_INFO_API_BASE_URL + "assetWithdraw/getAllAsset.html")); } // Market Data endpoints diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiService.java b/src/main/java/com/binance/api/client/impl/BinanceApiService.java index 794282765..5d7921df8 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiService.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiService.java @@ -13,9 +13,9 @@ import com.binance.api.client.domain.account.TradeHistoryItem; import com.binance.api.client.domain.account.WithdrawHistory; import com.binance.api.client.domain.event.ListenKey; +import com.binance.api.client.domain.general.Asset; import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.ServerTime; -import com.binance.api.client.domain.general.AllAssets; import com.binance.api.client.domain.market.AggTrade; import com.binance.api.client.domain.market.BookTicker; import com.binance.api.client.domain.market.Candlestick; @@ -29,6 +29,7 @@ import retrofit2.http.POST; import retrofit2.http.PUT; import retrofit2.http.Query; +import retrofit2.http.Url; import java.util.List; @@ -48,8 +49,8 @@ public interface BinanceApiService { @GET("/api/v1/exchangeInfo") Call getExchangeInfo(); - @GET("/assetWithdraw/getAllAsset.html") - Call getAllAssets(); + @GET + Call> getAllAssets(@Url String url); // Market data endpoints diff --git a/src/test/java/com/binance/api/client/constant/BinanceApiConstantsTest.java b/src/test/java/com/binance/api/client/constant/BinanceApiConstantsTest.java index a1c7905c1..d003a8d94 100644 --- a/src/test/java/com/binance/api/client/constant/BinanceApiConstantsTest.java +++ b/src/test/java/com/binance/api/client/constant/BinanceApiConstantsTest.java @@ -1,76 +1,81 @@ package com.binance.api.client.constant; -import com.binance.api.client.constant.BinanceApiConstants; import com.binance.api.client.domain.market.Candlestick; import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.IOException; import org.apache.commons.lang3.builder.ToStringStyle; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; -import static org.junit.Assert.*; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +/** + * @see BinanceApiConstants + */ public class BinanceApiConstantsTest { - + private static String candlestickRaw; private static Candlestick candlestick; private static ToStringStyle DEFAULT_TO_STRING_BUILDER_STYLE; - - public BinanceApiConstantsTest() { + + public BinanceApiConstantsTest() { } - + @BeforeClass public static void setUpClass() { - + DEFAULT_TO_STRING_BUILDER_STYLE = BinanceApiConstants.TO_STRING_BUILDER_STYLE; - + candlestickRaw = "[\n" - + " 1499040000000,\n" - + " \"0.01634790\",\n" - + " \"0.80000000\",\n" - + " \"0.01575800\",\n" - + " \"0.01577100\",\n" - + " \"148976.11427815\",\n" - + " 1499644799999,\n" - + " \"2434.19055334\",\n" - + " 308,\n" - + " \"1756.87402397\",\n" - + " \"28.46694368\",\n" - + " \"17928899.62484339\"\n" - + " ]"; + + " 1499040000000,\n" + + " \"0.01634790\",\n" + + " \"0.80000000\",\n" + + " \"0.01575800\",\n" + + " \"0.01577100\",\n" + + " \"148976.11427815\",\n" + + " 1499644799999,\n" + + " \"2434.19055334\",\n" + + " 308,\n" + + " \"1756.87402397\",\n" + + " \"28.46694368\",\n" + + " \"17928899.62484339\"\n" + + " ]"; ObjectMapper mapper = new ObjectMapper(); - + try { candlestick = mapper.readValue(candlestickRaw, Candlestick.class); } catch (IOException e) { fail(); } } - + @AfterClass public static void tearDownClass() { BinanceApiConstants.TO_STRING_BUILDER_STYLE = DEFAULT_TO_STRING_BUILDER_STYLE; } - + @Test public void testToStringBuilderStyleChange() { String binaceApiDefaultStyle = "Candlestick[openTime=1499040000000,open=0.01634790,high=0.80000000,low=0.01575800,close=0.01577100,volume=148976.11427815,closeTime=1499644799999,quoteAssetVolume=2434.19055334,numberOfTrades=308,takerBuyBaseAssetVolume=1756.87402397,takerBuyQuoteAssetVolume=28.46694368]"; assertEquals(candlestick.toString(), binaceApiDefaultStyle); - + BinanceApiConstants.TO_STRING_BUILDER_STYLE = ToStringStyle.JSON_STYLE; String jsonSyle = "{\"openTime\":1499040000000,\"open\":\"0.01634790\",\"high\":\"0.80000000\",\"low\":\"0.01575800\",\"close\":\"0.01577100\",\"volume\":\"148976.11427815\",\"closeTime\":1499644799999,\"quoteAssetVolume\":\"2434.19055334\",\"numberOfTrades\":308,\"takerBuyBaseAssetVolume\":\"1756.87402397\",\"takerBuyQuoteAssetVolume\":\"28.46694368\"}"; assertEquals(candlestick.toString(), jsonSyle); - + BinanceApiConstants.TO_STRING_BUILDER_STYLE = ToStringStyle.NO_CLASS_NAME_STYLE; String noClassNameSyle = "[openTime=1499040000000,open=0.01634790,high=0.80000000,low=0.01575800,close=0.01577100,volume=148976.11427815,closeTime=1499644799999,quoteAssetVolume=2434.19055334,numberOfTrades=308,takerBuyBaseAssetVolume=1756.87402397,takerBuyQuoteAssetVolume=28.46694368]"; assertEquals(candlestick.toString(), noClassNameSyle); - + BinanceApiConstants.TO_STRING_BUILDER_STYLE = ToStringStyle.SHORT_PREFIX_STYLE; String shortPrefixSyle = "Candlestick[openTime=1499040000000,open=0.01634790,high=0.80000000,low=0.01575800,close=0.01577100,volume=148976.11427815,closeTime=1499644799999,quoteAssetVolume=2434.19055334,numberOfTrades=308,takerBuyBaseAssetVolume=1756.87402397,takerBuyQuoteAssetVolume=28.46694368]"; assertEquals(candlestick.toString(), shortPrefixSyle); - + BinanceApiConstants.TO_STRING_BUILDER_STYLE = ToStringStyle.SIMPLE_STYLE; String simpleSyle = "1499040000000,0.01634790,0.80000000,0.01575800,0.01577100,148976.11427815,1499644799999,2434.19055334,308,1756.87402397,28.46694368"; assertEquals(candlestick.toString(), simpleSyle); } -} +} \ No newline at end of file diff --git a/src/test/java/com/binance/api/examples/GeneralEndpointsExample.java b/src/test/java/com/binance/api/examples/GeneralEndpointsExample.java index a97c7ec27..911cab374 100644 --- a/src/test/java/com/binance/api/examples/GeneralEndpointsExample.java +++ b/src/test/java/com/binance/api/examples/GeneralEndpointsExample.java @@ -2,11 +2,14 @@ import com.binance.api.client.BinanceApiClientFactory; import com.binance.api.client.BinanceApiRestClient; +import com.binance.api.client.domain.general.Asset; import com.binance.api.client.domain.general.ExchangeInfo; import com.binance.api.client.domain.general.FilterType; import com.binance.api.client.domain.general.SymbolFilter; import com.binance.api.client.domain.general.SymbolInfo; +import java.util.List; + /** * Examples on how to use the general endpoints. */ @@ -35,5 +38,9 @@ public static void main(String[] args) { SymbolFilter priceFilter = symbolInfo.getSymbolFilter(FilterType.PRICE_FILTER); System.out.println(priceFilter.getMinPrice()); System.out.println(priceFilter.getTickSize()); + + // Obtain asset information + List allAssets = client.getAllAssets(); + System.out.println(allAssets.stream().filter(asset -> asset.getAssetCode().equals("BNB")).findFirst().get()); } } diff --git a/src/test/java/com/binance/api/examples/GeneralEndpointsExampleAsync.java b/src/test/java/com/binance/api/examples/GeneralEndpointsExampleAsync.java index 8823f1824..77bfd238e 100644 --- a/src/test/java/com/binance/api/examples/GeneralEndpointsExampleAsync.java +++ b/src/test/java/com/binance/api/examples/GeneralEndpointsExampleAsync.java @@ -2,10 +2,13 @@ import com.binance.api.client.BinanceApiAsyncRestClient; import com.binance.api.client.BinanceApiClientFactory; +import com.binance.api.client.domain.general.Asset; import com.binance.api.client.domain.general.FilterType; import com.binance.api.client.domain.general.SymbolFilter; import com.binance.api.client.domain.general.SymbolInfo; +import java.util.List; + /** * Examples on how to use the general endpoints. */ @@ -34,5 +37,9 @@ public static void main(String[] args) throws InterruptedException { System.out.println(priceFilter.getMinPrice()); System.out.println(priceFilter.getTickSize()); }); + + // Obtain asset information + client.getAllAssets(allAssets -> + System.out.println(allAssets.stream().filter(asset -> asset.getAssetCode().equals("BNB")).findFirst().get())); } } From 97a08b04196588a7a357518a7cf55a0adef757d9 Mon Sep 17 00:00:00 2001 From: Nils Wiersema Date: Wed, 25 Apr 2018 23:04:26 +0200 Subject: [PATCH 45/81] Route exceptions via onFailure callback rather than throwing them --- .../api/client/impl/BinanceApiCallbackAdapter.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiCallbackAdapter.java b/src/main/java/com/binance/api/client/impl/BinanceApiCallbackAdapter.java index 6ec5a3614..10b896ac6 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiCallbackAdapter.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiCallbackAdapter.java @@ -33,15 +33,19 @@ public void onResponse(Call call, Response response) { } try { BinanceApiError apiError = getBinanceApiError(response); - throw new BinanceApiException(apiError); + onFailure(call, new BinanceApiException(apiError)); } catch (IOException e) { - throw new BinanceApiException(e); + onFailure(call, new BinanceApiException(e)); } } } @Override public void onFailure(Call call, Throwable throwable) { - throw new BinanceApiException(throwable); + if (throwable instanceof BinanceApiException) { + callback.onFailure(throwable); + } else { + callback.onFailure(new BinanceApiException(throwable)); + } } } From 1c90686d4e915c3e6ab67b27ebcdb524776817c3 Mon Sep 17 00:00:00 2001 From: Nils Wiersema Date: Sun, 29 Apr 2018 20:06:49 +0200 Subject: [PATCH 46/81] Add support for newOrderRespType (v3 API) --- .../api/client/domain/account/NewOrder.java | 16 ++++ .../domain/account/NewOrderResponse.java | 84 +++++++++++++++++++ .../domain/account/NewOrderResponseType.java | 12 +++ .../impl/BinanceApiAsyncRestClientImpl.java | 4 +- .../client/impl/BinanceApiRestClientImpl.java | 4 +- .../api/client/impl/BinanceApiService.java | 7 +- 6 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/binance/api/client/domain/account/NewOrderResponseType.java diff --git a/src/main/java/com/binance/api/client/domain/account/NewOrder.java b/src/main/java/com/binance/api/client/domain/account/NewOrder.java index af76a78b2..635e1ddac 100644 --- a/src/main/java/com/binance/api/client/domain/account/NewOrder.java +++ b/src/main/java/com/binance/api/client/domain/account/NewOrder.java @@ -56,6 +56,11 @@ public class NewOrder { */ private String icebergQty; + /** + * Set the response JSON. ACK, RESULT, or FULL; default: RESULT. + */ + private NewOrderResponseType newOrderRespType; + /** * Receiving window. */ @@ -75,6 +80,7 @@ public NewOrder(String symbol, OrderSide side, OrderType type, TimeInForce timeI this.type = type; this.timeInForce = timeInForce; this.quantity = quantity; + this.newOrderRespType = NewOrderResponseType.RESULT; this.timestamp = System.currentTimeMillis(); this.recvWindow = BinanceApiConstants.DEFAULT_RECEIVING_WINDOW; } @@ -168,6 +174,15 @@ public NewOrder icebergQty(String icebergQty) { return this; } + public NewOrderResponseType getNewOrderRespType() { + return newOrderRespType; + } + + public NewOrder newOrderRespType(NewOrderResponseType newOrderRespType) { + this.newOrderRespType = newOrderRespType; + return this; + } + public Long getRecvWindow() { return recvWindow; } @@ -234,6 +249,7 @@ public String toString() { .append("newClientOrderId", newClientOrderId) .append("stopPrice", stopPrice) .append("icebergQty", icebergQty) + .append("newOrderRespType", newOrderRespType) .append("recvWindow", recvWindow) .append("timestamp", timestamp) .toString(); diff --git a/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java b/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java index 7485f175e..c42246057 100644 --- a/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java +++ b/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java @@ -1,9 +1,16 @@ package com.binance.api.client.domain.account; import com.binance.api.client.constant.BinanceApiConstants; +import com.binance.api.client.domain.OrderSide; +import com.binance.api.client.domain.OrderStatus; +import com.binance.api.client.domain.OrderType; +import com.binance.api.client.domain.TimeInForce; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; +import java.util.List; +import java.util.stream.Collectors; + /** * Response returned when placing a new order on the system. * @@ -28,6 +35,20 @@ public class NewOrderResponse { */ private String clientOrderId; + private String price; + + private String executedQty; + + private OrderStatus status; + + private TimeInForce timeInForce; + + private OrderType type; + + private OrderSide side; + + private List fills; + /** * Transact time for this order. */ @@ -65,6 +86,62 @@ public void setTransactTime(Long transactTime) { this.transactTime = transactTime; } + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } + + public String getExecutedQty() { + return executedQty; + } + + public void setExecutedQty(String executedQty) { + this.executedQty = executedQty; + } + + public OrderStatus getStatus() { + return status; + } + + public void setStatus(OrderStatus status) { + this.status = status; + } + + public TimeInForce getTimeInForce() { + return timeInForce; + } + + public void setTimeInForce(TimeInForce timeInForce) { + this.timeInForce = timeInForce; + } + + public OrderType getType() { + return type; + } + + public void setType(OrderType type) { + this.type = type; + } + + public OrderSide getSide() { + return side; + } + + public void setSide(OrderSide side) { + this.side = side; + } + + public List getFills() { + return fills; + } + + public void setFills(List fills) { + this.fills = fills; + } + @Override public String toString() { return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) @@ -72,6 +149,13 @@ public String toString() { .append("orderId", orderId) .append("clientOrderId", clientOrderId) .append("transactTime", transactTime) + .append("price", price) + .append("executedQty", executedQty) + .append("status", status) + .append("timeInForce", timeInForce) + .append("type", type) + .append("side", side) + .append("fills", fills.stream().map(Object::toString).collect(Collectors.joining(", "))) .toString(); } } diff --git a/src/main/java/com/binance/api/client/domain/account/NewOrderResponseType.java b/src/main/java/com/binance/api/client/domain/account/NewOrderResponseType.java new file mode 100644 index 000000000..c465f85a7 --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/account/NewOrderResponseType.java @@ -0,0 +1,12 @@ +package com.binance.api.client.domain.account; + +/** + * Desired response type of NewOrder requests. + * @see NewOrderResponse + */ +public enum NewOrderResponseType { + ACK, + RESULT, + FULL +} + diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java index 5f97af80c..e35a29e85 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java @@ -132,14 +132,14 @@ public void getBookTickers(BinanceApiCallback> callback) { public void newOrder(NewOrder order, BinanceApiCallback callback) { binanceApiService.newOrder(order.getSymbol(), order.getSide(), order.getType(), order.getTimeInForce(), order.getQuantity(), order.getPrice(), order.getNewClientOrderId(), order.getStopPrice(), - order.getIcebergQty(), order.getRecvWindow(), order.getTimestamp()).enqueue(new BinanceApiCallbackAdapter<>(callback)); + order.getIcebergQty(), order.getNewOrderRespType(), order.getRecvWindow(), order.getTimestamp()).enqueue(new BinanceApiCallbackAdapter<>(callback)); } @Override public void newOrderTest(NewOrder order, BinanceApiCallback callback) { binanceApiService.newOrderTest(order.getSymbol(), order.getSide(), order.getType(), order.getTimeInForce(), order.getQuantity(), order.getPrice(), order.getNewClientOrderId(), order.getStopPrice(), - order.getIcebergQty(), order.getRecvWindow(), order.getTimestamp()).enqueue(new BinanceApiCallbackAdapter<>(callback)); + order.getIcebergQty(), order.getNewOrderRespType(), order.getRecvWindow(), order.getTimestamp()).enqueue(new BinanceApiCallbackAdapter<>(callback)); } // Account endpoints diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java index 301a08aab..364f48a58 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java @@ -129,14 +129,14 @@ public List getBookTickers() { public NewOrderResponse newOrder(NewOrder order) { return executeSync(binanceApiService.newOrder(order.getSymbol(), order.getSide(), order.getType(), order.getTimeInForce(), order.getQuantity(), order.getPrice(), order.getNewClientOrderId(), order.getStopPrice(), - order.getIcebergQty(), order.getRecvWindow(), order.getTimestamp())); + order.getIcebergQty(), order.getNewOrderRespType(), order.getRecvWindow(), order.getTimestamp())); } @Override public void newOrderTest(NewOrder order) { executeSync(binanceApiService.newOrderTest(order.getSymbol(), order.getSide(), order.getType(), order.getTimeInForce(), order.getQuantity(), order.getPrice(), order.getNewClientOrderId(), order.getStopPrice(), - order.getIcebergQty(), order.getRecvWindow(), order.getTimestamp())); + order.getIcebergQty(), order.getNewOrderRespType(), order.getRecvWindow(), order.getTimestamp())); } // Account endpoints diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiService.java b/src/main/java/com/binance/api/client/impl/BinanceApiService.java index 5d7921df8..37b4cc881 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiService.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiService.java @@ -8,6 +8,7 @@ import com.binance.api.client.domain.account.DepositAddress; import com.binance.api.client.domain.account.DepositHistory; import com.binance.api.client.domain.account.NewOrderResponse; +import com.binance.api.client.domain.account.NewOrderResponseType; import com.binance.api.client.domain.account.Order; import com.binance.api.client.domain.account.Trade; import com.binance.api.client.domain.account.TradeHistoryItem; @@ -94,14 +95,16 @@ Call> getCandlestickBars(@Query("symbol") String symbol, @Quer Call newOrder(@Query("symbol") String symbol, @Query("side") OrderSide side, @Query("type") OrderType type, @Query("timeInForce") TimeInForce timeInForce, @Query("quantity") String quantity, @Query("price") String price, @Query("newClientOrderId") String newClientOrderId, @Query("stopPrice") String stopPrice, - @Query("icebergQty") String icebergQty, @Query("recvWindow") Long recvWindow, @Query("timestamp") Long timestamp); + @Query("icebergQty") String icebergQty, @Query("newOrderRespType") NewOrderResponseType newOrderRespType, + @Query("recvWindow") Long recvWindow, @Query("timestamp") Long timestamp); @Headers(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_SIGNED_HEADER) @POST("/api/v3/order/test") Call newOrderTest(@Query("symbol") String symbol, @Query("side") OrderSide side, @Query("type") OrderType type, @Query("timeInForce") TimeInForce timeInForce, @Query("quantity") String quantity, @Query("price") String price, @Query("newClientOrderId") String newClientOrderId, @Query("stopPrice") String stopPrice, - @Query("icebergQty") String icebergQty, @Query("recvWindow") Long recvWindow, @Query("timestamp") Long timestamp); + @Query("icebergQty") String icebergQty, @Query("newOrderRespType") NewOrderResponseType newOrderRespType, + @Query("recvWindow") Long recvWindow, @Query("timestamp") Long timestamp); @Headers(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_SIGNED_HEADER) @GET("/api/v3/order") From 7b92e7a40f13c7a77710fc894d1eca354a5580dd Mon Sep 17 00:00:00 2001 From: Nils Wiersema Date: Sun, 29 Apr 2018 20:11:33 +0200 Subject: [PATCH 47/81] Demonstrate use of newOrderRespType in OrdersExample --- src/test/java/com/binance/api/examples/OrdersExample.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/binance/api/examples/OrdersExample.java b/src/test/java/com/binance/api/examples/OrdersExample.java index 0b8be5256..c133e7432 100644 --- a/src/test/java/com/binance/api/examples/OrdersExample.java +++ b/src/test/java/com/binance/api/examples/OrdersExample.java @@ -4,6 +4,7 @@ import com.binance.api.client.BinanceApiRestClient; import com.binance.api.client.domain.TimeInForce; import com.binance.api.client.domain.account.NewOrderResponse; +import com.binance.api.client.domain.account.NewOrderResponseType; import com.binance.api.client.domain.account.Order; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; @@ -51,7 +52,7 @@ public static void main(String[] args) { client.newOrderTest(marketBuy("LINKETH", "1000")); // Placing a real LIMIT order - NewOrderResponse newOrderResponse = client.newOrder(limitBuy("LINKETH", TimeInForce.GTC, "1000", "0.0001")); + NewOrderResponse newOrderResponse = client.newOrder(limitBuy("LINKETH", TimeInForce.GTC, "1000", "0.0001").newOrderRespType(NewOrderResponseType.FULL)); System.out.println(newOrderResponse); } From ce38cb8c0903585de8e1bf2230afda32318242c3 Mon Sep 17 00:00:00 2001 From: Nils Wiersema Date: Sun, 29 Apr 2018 21:24:35 +0200 Subject: [PATCH 48/81] Parse both 'id' and 'tradeId' into Trade#id to deal with inconsistent API models on Binance --- .../com/binance/api/client/domain/account/Trade.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/binance/api/client/domain/account/Trade.java b/src/main/java/com/binance/api/client/domain/account/Trade.java index feb639faa..c64431118 100644 --- a/src/main/java/com/binance/api/client/domain/account/Trade.java +++ b/src/main/java/com/binance/api/client/domain/account/Trade.java @@ -2,6 +2,7 @@ import com.binance.api.client.constant.BinanceApiConstants; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; import org.apache.commons.lang3.builder.ToStringBuilder; /** @@ -54,10 +55,18 @@ public Long getId() { return id; } + @JsonSetter("id") public void setId(Long id) { this.id = id; } + @JsonSetter("tradeId") + public void setTradeId(Long id) { + if (this.id == null) { + setId(id); + } + } + public String getPrice() { return price; } From d7835f50356e3553235b5824039a0bcc63d5a814 Mon Sep 17 00:00:00 2001 From: Nils Wiersema Date: Sun, 29 Apr 2018 21:24:53 +0200 Subject: [PATCH 49/81] Add NewOrderResponse#origQty --- .../api/client/domain/account/NewOrderResponse.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java b/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java index c42246057..e1c1e7569 100644 --- a/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java +++ b/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java @@ -37,6 +37,8 @@ public class NewOrderResponse { private String price; + private String origQty; + private String executedQty; private OrderStatus status; @@ -94,6 +96,14 @@ public void setPrice(String price) { this.price = price; } + public String getOrigQty() { + return origQty; + } + + public void setOrigQty(String origQty) { + this.origQty = origQty; + } + public String getExecutedQty() { return executedQty; } @@ -150,6 +160,7 @@ public String toString() { .append("clientOrderId", clientOrderId) .append("transactTime", transactTime) .append("price", price) + .append("origQty", origQty) .append("executedQty", executedQty) .append("status", status) .append("timeInForce", timeInForce) From 16e94f36983b0768811912c23affd2d847dd8396 Mon Sep 17 00:00:00 2001 From: Nils Wiersema Date: Sun, 29 Apr 2018 21:39:32 +0200 Subject: [PATCH 50/81] Demonstrate use of newOrderRespType in README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 46e008f74..102a0b1ac 100644 --- a/README.md +++ b/README.md @@ -186,7 +186,8 @@ System.out.println(order.getExecutedQty()); #### Placing a MARKET order ```java -NewOrderResponse newOrderResponse = client.newOrder(marketBuy("LINKETH", "1000")); +NewOrderResponse newOrderResponse = client.newOrder(marketBuy("LINKETH", "1000").orderRespType(OrderResponseType.FULL)); +List fills = newOrderResponse.getFills(); System.out.println(newOrderResponse.getClientOrderId()); ```
From 6067b086f3d2d84d650a1b16a467c664753f802b Mon Sep 17 00:00:00 2001 From: Igor Ustinov Date: Fri, 4 May 2018 11:55:29 -0400 Subject: [PATCH 51/81] withdrawal status added, conflicts resolved --- .../api/client/BinanceApiAsyncRestClient.java | 4 +- .../api/client/BinanceApiRestClient.java | 4 +- .../client/domain/account/DepositHistory.java | 11 ++++ .../client/domain/account/WithdrawResult.java | 62 +++++++++++++++++++ .../impl/BinanceApiAsyncRestClientImpl.java | 5 +- .../client/impl/BinanceApiRestClientImpl.java | 5 +- .../api/client/impl/BinanceApiService.java | 5 +- .../api/examples/AccountEndpointsExample.java | 2 +- .../AccountEndpointsExampleAsync.java | 2 +- 9 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/binance/api/client/domain/account/WithdrawResult.java diff --git a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java index 69416d50a..3bf9317cb 100644 --- a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java @@ -9,6 +9,7 @@ import com.binance.api.client.domain.account.Trade; import com.binance.api.client.domain.account.TradeHistoryItem; import com.binance.api.client.domain.account.WithdrawHistory; +import com.binance.api.client.domain.account.WithdrawResult; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; import com.binance.api.client.domain.account.request.OrderRequest; @@ -260,8 +261,9 @@ public interface BinanceApiAsyncRestClient { * @param address address to withdraw to * @param amount amount to withdraw * @param name description/alias of the address + * @param addressTag Secondary address identifier for coins like XRP,XMR etc. */ - void withdraw(String asset, String address, String amount, String name, BinanceApiCallback callback); + void withdraw(String asset, String address, String amount, String name, String addressTag, BinanceApiCallback callback); /** * Fetch account deposit history. diff --git a/src/main/java/com/binance/api/client/BinanceApiRestClient.java b/src/main/java/com/binance/api/client/BinanceApiRestClient.java index 3044363f7..b0f1d165c 100644 --- a/src/main/java/com/binance/api/client/BinanceApiRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiRestClient.java @@ -9,6 +9,7 @@ import com.binance.api.client.domain.account.Trade; import com.binance.api.client.domain.account.TradeHistoryItem; import com.binance.api.client.domain.account.WithdrawHistory; +import com.binance.api.client.domain.account.WithdrawResult; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; import com.binance.api.client.domain.account.request.OrderRequest; @@ -246,8 +247,9 @@ public interface BinanceApiRestClient { * @param address address to withdraw to * @param amount amount to withdraw * @param name description/alias of the address + * @param addressTag Secondary address identifier for coins like XRP,XMR etc. */ - void withdraw(String asset, String address, String amount, String name); + WithdrawResult withdraw(String asset, String address, String amount, String name, String addressTag); /** * Fetch account deposit history. diff --git a/src/main/java/com/binance/api/client/domain/account/DepositHistory.java b/src/main/java/com/binance/api/client/domain/account/DepositHistory.java index 0d45d32aa..792f3fa9d 100644 --- a/src/main/java/com/binance/api/client/domain/account/DepositHistory.java +++ b/src/main/java/com/binance/api/client/domain/account/DepositHistory.java @@ -18,6 +18,16 @@ public class DepositHistory { private boolean success; + private String msg; + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + public List getDepositList() { return depositList; } @@ -39,6 +49,7 @@ public String toString() { return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("depositList", depositList) .append("success", success) + .append("msg", msg) .toString(); } } diff --git a/src/main/java/com/binance/api/client/domain/account/WithdrawResult.java b/src/main/java/com/binance/api/client/domain/account/WithdrawResult.java new file mode 100644 index 000000000..fac00deba --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/account/WithdrawResult.java @@ -0,0 +1,62 @@ +package com.binance.api.client.domain.account; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * A withdraw result that was done to a Binance account. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class WithdrawResult { + + /** + * Withdraw message. + */ + private String msg; + + /** + * Withdraw success. + */ + private boolean success; + + /** + * Withdraw id. + */ + private String id; + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + .append("msg", msg) + .append("success", success) + .append("id", id) + .toString(); + } + + +} diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java index 5f97af80c..a7c0ce575 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java @@ -12,6 +12,7 @@ import com.binance.api.client.domain.account.Trade; import com.binance.api.client.domain.account.TradeHistoryItem; import com.binance.api.client.domain.account.WithdrawHistory; +import com.binance.api.client.domain.account.WithdrawResult; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; import com.binance.api.client.domain.account.request.OrderRequest; @@ -198,8 +199,8 @@ public void getMyTrades(String symbol, BinanceApiCallback> callback) } @Override - public void withdraw(String asset, String address, String amount, String name, BinanceApiCallback callback) { - binanceApiService.withdraw(asset, address, amount, name, BinanceApiConstants.DEFAULT_RECEIVING_WINDOW, System.currentTimeMillis()) + public void withdraw(String asset, String address, String amount, String name, String addressTag, BinanceApiCallback callback) { + binanceApiService.withdraw(asset, address, amount, name, addressTag, BinanceApiConstants.DEFAULT_RECEIVING_WINDOW, System.currentTimeMillis()) .enqueue(new BinanceApiCallbackAdapter<>(callback)); } diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java index 301a08aab..539fda0ab 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java @@ -11,6 +11,7 @@ import com.binance.api.client.domain.account.Trade; import com.binance.api.client.domain.account.TradeHistoryItem; import com.binance.api.client.domain.account.WithdrawHistory; +import com.binance.api.client.domain.account.WithdrawResult; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; import com.binance.api.client.domain.account.request.OrderRequest; @@ -193,8 +194,8 @@ public List getMyTrades(String symbol) { } @Override - public void withdraw(String asset, String address, String amount, String name) { - executeSync(binanceApiService.withdraw(asset, address, amount, name, BinanceApiConstants.DEFAULT_RECEIVING_WINDOW, System.currentTimeMillis())); + public WithdrawResult withdraw(String asset, String address, String amount, String name, String addressTag) { + return executeSync(binanceApiService.withdraw(asset, address, amount, name, addressTag, BinanceApiConstants.DEFAULT_RECEIVING_WINDOW, System.currentTimeMillis())); } @Override diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiService.java b/src/main/java/com/binance/api/client/impl/BinanceApiService.java index 5d7921df8..b26ae8b07 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiService.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiService.java @@ -12,6 +12,7 @@ import com.binance.api.client.domain.account.Trade; import com.binance.api.client.domain.account.TradeHistoryItem; import com.binance.api.client.domain.account.WithdrawHistory; +import com.binance.api.client.domain.account.WithdrawResult; import com.binance.api.client.domain.event.ListenKey; import com.binance.api.client.domain.general.Asset; import com.binance.api.client.domain.general.ExchangeInfo; @@ -135,8 +136,8 @@ Call> getMyTrades(@Query("symbol") String symbol, @Query("limit") In @Headers(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_SIGNED_HEADER) @POST("/wapi/v3/withdraw.html") - Call withdraw(@Query("asset") String asset, @Query("address") String address, @Query("amount") String amount, @Query("name") String name, - @Query("recvWindow") Long recvWindow, @Query("timestamp") Long timestamp); + Call withdraw(@Query("asset") String asset, @Query("address") String address, @Query("amount") String amount, @Query("name") String name, @Query("addressTag") String addressTag, + @Query("recvWindow") Long recvWindow, @Query("timestamp") Long timestamp); @Headers(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_SIGNED_HEADER) diff --git a/src/test/java/com/binance/api/examples/AccountEndpointsExample.java b/src/test/java/com/binance/api/examples/AccountEndpointsExample.java index bdbaf7469..a859ca8f1 100644 --- a/src/test/java/com/binance/api/examples/AccountEndpointsExample.java +++ b/src/test/java/com/binance/api/examples/AccountEndpointsExample.java @@ -35,6 +35,6 @@ public static void main(String[] args) { System.out.println(client.getDepositAddress("ETH")); // Withdraw - client.withdraw("ETH", "0x123", "0.1", null); + client.withdraw("ETH", "0x123", "0.1", null, null); } } diff --git a/src/test/java/com/binance/api/examples/AccountEndpointsExampleAsync.java b/src/test/java/com/binance/api/examples/AccountEndpointsExampleAsync.java index 560b4f27f..7e924fdf5 100644 --- a/src/test/java/com/binance/api/examples/AccountEndpointsExampleAsync.java +++ b/src/test/java/com/binance/api/examples/AccountEndpointsExampleAsync.java @@ -26,6 +26,6 @@ public static void main(String[] args) { client.getDepositHistory("ETH", response -> System.out.println(response)); // Withdraw (async) - client.withdraw("ETH", "0x123", "0.1", null, response -> {}); + client.withdraw("ETH", "0x123", "0.1", null, null, response -> {}); } } From bf55921e292c19ad02e2fff6e6e31fee896c69fa Mon Sep 17 00:00:00 2001 From: joaopsilva Date: Fri, 4 May 2018 18:36:07 +0200 Subject: [PATCH 52/81] Fix #125: Avoid 301 redirect for asset info API. --- .../com/binance/api/client/constant/BinanceApiConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java b/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java index 00c4b2f71..8dddf6be8 100644 --- a/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java +++ b/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java @@ -20,7 +20,7 @@ public class BinanceApiConstants { /** * Asset info base URL. */ - public static final String ASSET_INFO_API_BASE_URL = "https://binance.com/"; + public static final String ASSET_INFO_API_BASE_URL = "https://www.binance.com/"; /** * HTTP Header to be used for API-KEY authentication. From ff7db64d33b4b113c27bcccfef197a0853a20739 Mon Sep 17 00:00:00 2001 From: joaopsilva Date: Sun, 6 May 2018 16:59:01 +0200 Subject: [PATCH 53/81] Fix #127 Remove meta header. --- .../binance/api/client/security/AuthenticationInterceptor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/security/AuthenticationInterceptor.java b/src/main/java/com/binance/api/client/security/AuthenticationInterceptor.java index 3dc5c9b5a..a2eff2281 100644 --- a/src/main/java/com/binance/api/client/security/AuthenticationInterceptor.java +++ b/src/main/java/com/binance/api/client/security/AuthenticationInterceptor.java @@ -33,7 +33,7 @@ public Response intercept(Chain chain) throws IOException { boolean isApiKeyRequired = original.header(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_APIKEY) != null; boolean isSignatureRequired = original.header(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_SIGNED) != null; - newRequestBuilder.removeHeader(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_SIGNED) + newRequestBuilder.removeHeader(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_APIKEY) .removeHeader(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_SIGNED); // Endpoint requires sending a valid API-KEY From aebcf157771d35357b06e0015778dc4393a93e88 Mon Sep 17 00:00:00 2001 From: Nils Wiersema Date: Tue, 15 May 2018 17:52:11 +0200 Subject: [PATCH 54/81] Cleanup the client/interceptor and errorBody converter mess in BinanceApiServiceGenerator --- .../impl/BinanceApiServiceGenerator.java | 38 +++++++++++-------- .../impl/BinanceApiServiceGeneratorTest.java | 24 ------------ 2 files changed, 22 insertions(+), 40 deletions(-) delete mode 100644 src/test/java/com/binance/api/client/impl/BinanceApiServiceGeneratorTest.java diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java b/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java index 6d7ee2b76..13c982b9e 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java @@ -5,8 +5,11 @@ import com.binance.api.client.exception.BinanceApiException; import com.binance.api.client.security.AuthenticationInterceptor; import okhttp3.OkHttpClient; +import okhttp3.RequestBody; +import okhttp3.ResponseBody; import org.apache.commons.lang3.StringUtils; import retrofit2.Call; +import retrofit2.Converter; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.jackson.JacksonConverterFactory; @@ -18,29 +21,33 @@ * Generates a Binance API implementation based on @see {@link BinanceApiService}. */ public class BinanceApiServiceGenerator { + private static final OkHttpClient sharedClient = new OkHttpClient.Builder().build(); + private static final Converter.Factory converterFactory = JacksonConverterFactory.create(); - static OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); - - private static Retrofit.Builder builder = - new Retrofit.Builder() - .baseUrl(BinanceApiConstants.API_BASE_URL) - .addConverterFactory(JacksonConverterFactory.create()); - - private static Retrofit retrofit = builder.build(); + @SuppressWarnings("unchecked") + private static final Converter errorBodyConverter = + (Converter)converterFactory.responseBodyConverter( + BinanceApiError.class, new Annotation[0], null); public static S createService(Class serviceClass) { return createService(serviceClass, null, null); } public static S createService(Class serviceClass, String apiKey, String secret) { - if (!StringUtils.isEmpty(apiKey) && !StringUtils.isEmpty(secret)) { + Retrofit.Builder retrofitBuilder = new Retrofit.Builder() + .baseUrl(BinanceApiConstants.API_BASE_URL) + .addConverterFactory(converterFactory); + + if (StringUtils.isEmpty(apiKey) || StringUtils.isEmpty(secret)) { + retrofitBuilder.client(sharedClient); + } else { + // `adaptedClient` will use its own interceptor, but share thread pool etc with the 'parent' client AuthenticationInterceptor interceptor = new AuthenticationInterceptor(apiKey, secret); - if (!httpClient.interceptors().contains(interceptor)) { - httpClient.addInterceptor(interceptor); - builder.client(httpClient.build()); - retrofit = builder.build(); - } + OkHttpClient adaptedClient = sharedClient.newBuilder().addInterceptor(interceptor).build(); + retrofitBuilder.client(adaptedClient); } + + Retrofit retrofit = retrofitBuilder.build(); return retrofit.create(serviceClass); } @@ -65,7 +72,6 @@ public static T executeSync(Call call) { * Extracts and converts the response error body into an object. */ public static BinanceApiError getBinanceApiError(Response response) throws IOException, BinanceApiException { - return (BinanceApiError)retrofit.responseBodyConverter(BinanceApiError.class, new Annotation[0]) - .convert(response.errorBody()); + return errorBodyConverter.convert(response.errorBody()); } } \ No newline at end of file diff --git a/src/test/java/com/binance/api/client/impl/BinanceApiServiceGeneratorTest.java b/src/test/java/com/binance/api/client/impl/BinanceApiServiceGeneratorTest.java deleted file mode 100644 index 132809c75..000000000 --- a/src/test/java/com/binance/api/client/impl/BinanceApiServiceGeneratorTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.binance.api.client.impl; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -/** - * @author andy coates - * created 08/02/2018. - */ -public class BinanceApiServiceGeneratorTest { - @Test - public void shouldOnlyAddAuthInterceptorOnce() throws Exception { - // Given: - BinanceApiServiceGenerator.createService(BinanceApiService.class, "someKey", "someValue"); - final int initialSize = BinanceApiServiceGenerator.httpClient.interceptors().size(); - - // When: - BinanceApiServiceGenerator.createService(BinanceApiService.class, "someKey", "someValue"); - - // Then - assertEquals(BinanceApiServiceGenerator.httpClient.interceptors().size(), initialSize); - } -} \ No newline at end of file From bed23c0e95d0c009bbf36486a4259420856f593c Mon Sep 17 00:00:00 2001 From: Nils Wiersema Date: Tue, 15 May 2018 18:09:36 +0200 Subject: [PATCH 55/81] Improve web socket creation: use the process-wide shared HTTP client and connection/thread pool --- .../api/client/BinanceApiClientFactory.java | 4 +++- .../api/client/BinanceApiWebSocketClient.java | 4 ++++ .../client/impl/BinanceApiServiceGenerator.java | 7 +++++++ .../impl/BinanceApiWebSocketClientImpl.java | 17 ++++++++--------- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/binance/api/client/BinanceApiClientFactory.java b/src/main/java/com/binance/api/client/BinanceApiClientFactory.java index b00d986c2..7c05f83bf 100644 --- a/src/main/java/com/binance/api/client/BinanceApiClientFactory.java +++ b/src/main/java/com/binance/api/client/BinanceApiClientFactory.java @@ -4,6 +4,8 @@ import com.binance.api.client.impl.BinanceApiRestClientImpl; import com.binance.api.client.impl.BinanceApiWebSocketClientImpl; +import static com.binance.api.client.impl.BinanceApiServiceGenerator.getSharedClient; + /** * A factory for creating BinanceApi client objects. */ @@ -68,6 +70,6 @@ public BinanceApiRestClient newRestClient() { * Creates a new web socket client used for handling data streams. */ public BinanceApiWebSocketClient newWebSocketClient() { - return new BinanceApiWebSocketClientImpl(); + return new BinanceApiWebSocketClientImpl(getSharedClient()); } } diff --git a/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java b/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java index b118efa9d..0b7f2446d 100644 --- a/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java @@ -60,5 +60,9 @@ public interface BinanceApiWebSocketClient extends Closeable { */ Closeable onAllMarketTickersEvent(BinanceApiCallback> callback); + /** + * @deprecated This method is no longer functional. Please use the returned {@link Closeable} from any of the other methods to close the web socket. + */ + @Deprecated void close(); } diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java b/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java index 13c982b9e..c312a4162 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java @@ -74,4 +74,11 @@ public static T executeSync(Call call) { public static BinanceApiError getBinanceApiError(Response response) throws IOException, BinanceApiException { return errorBodyConverter.convert(response.errorBody()); } + + /** + * Returns the shared OkHttpClient instance. + */ + public static OkHttpClient getSharedClient() { + return sharedClient; + } } \ No newline at end of file diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java index 87ff981ab..2822779f9 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java @@ -9,7 +9,7 @@ import com.binance.api.client.domain.event.DepthEvent; import com.binance.api.client.domain.event.UserDataUpdateEvent; import com.binance.api.client.domain.market.CandlestickInterval; -import okhttp3.Dispatcher; + import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.WebSocket; @@ -22,12 +22,10 @@ */ public class BinanceApiWebSocketClientImpl implements BinanceApiWebSocketClient, Closeable { - private OkHttpClient client; + private final OkHttpClient client; - public BinanceApiWebSocketClientImpl() { - Dispatcher d = new Dispatcher(); - d.setMaxRequestsPerHost(100); - this.client = new OkHttpClient.Builder().dispatcher(d).build(); + public BinanceApiWebSocketClientImpl(OkHttpClient client) { + this.client = client; } public Closeable onDepthEvent(String symbol, BinanceApiCallback callback) { @@ -55,10 +53,11 @@ public Closeable onAllMarketTickersEvent(BinanceApiCallback>(callback)); } + /** + * @deprecated This method is no longer functional. Please use the returned {@link Closeable} from any of the other methods to close the web socket. + */ @Override - public void close() { - client.dispatcher().executorService().shutdown(); - } + public void close() { } private Closeable createNewWebSocket(String channel, BinanceApiWebSocketListener listener) { String streamingUrl = String.format("%s/%s", BinanceApiConstants.WS_API_BASE_URL, channel); From 95ab6bf6f0a161f6eb94f46da08457514d52e897 Mon Sep 17 00:00:00 2001 From: Nils Wiersema Date: Tue, 15 May 2018 18:16:34 +0200 Subject: [PATCH 56/81] Upgrade Retrofit, which upgrades OkHttp, which now properly honors pingInterval (to detect websocket disconnections) --- pom.xml | 2 +- .../binance/api/client/impl/BinanceApiServiceGenerator.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f940bff48..7ad829cbd 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 1.0.0 - 2.3.0 + 2.4.0 diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java b/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java index c312a4162..490dd23dc 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java @@ -16,12 +16,16 @@ import java.io.IOException; import java.lang.annotation.Annotation; +import java.util.concurrent.TimeUnit; /** * Generates a Binance API implementation based on @see {@link BinanceApiService}. */ public class BinanceApiServiceGenerator { - private static final OkHttpClient sharedClient = new OkHttpClient.Builder().build(); + private static final OkHttpClient sharedClient = new OkHttpClient.Builder() + .pingInterval(20, TimeUnit.SECONDS) + .build(); + private static final Converter.Factory converterFactory = JacksonConverterFactory.create(); @SuppressWarnings("unchecked") From a10a0e9ab8470f095a471a96f8c4a61e23fcf806 Mon Sep 17 00:00:00 2001 From: Miroslav Hruz Date: Thu, 19 Jul 2018 15:58:56 +0200 Subject: [PATCH 57/81] Cannot deserialize value of type `com.binance.api.client.domain.general.RateLimitType` from String "REQUEST_WEIGHT": value not one of declared Enum instance names: [REQUESTS, ORDERS] --- .../com/binance/api/client/domain/general/FilterType.java | 1 + .../com/binance/api/client/domain/general/RateLimitType.java | 2 +- .../api/domain/general/ExchangeInfoDeserializerTest.java | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/binance/api/client/domain/general/FilterType.java b/src/main/java/com/binance/api/client/domain/general/FilterType.java index 593b4ae5e..6a31f49b0 100644 --- a/src/main/java/com/binance/api/client/domain/general/FilterType.java +++ b/src/main/java/com/binance/api/client/domain/general/FilterType.java @@ -10,6 +10,7 @@ public enum FilterType { MIN_NOTIONAL, MAX_NUM_ORDERS, MAX_ALGO_ORDERS, + MAX_NUM_ALGO_ORDERS, // Exchange EXCHANGE_MAX_NUM_ORDERS, diff --git a/src/main/java/com/binance/api/client/domain/general/RateLimitType.java b/src/main/java/com/binance/api/client/domain/general/RateLimitType.java index af438bebb..4ca0fadb8 100644 --- a/src/main/java/com/binance/api/client/domain/general/RateLimitType.java +++ b/src/main/java/com/binance/api/client/domain/general/RateLimitType.java @@ -4,6 +4,6 @@ * Rate limiters. */ public enum RateLimitType { - REQUESTS, + REQUEST_WEIGHT, ORDERS } diff --git a/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java b/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java index af949ff6f..b865a8b68 100644 --- a/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java +++ b/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java @@ -31,7 +31,7 @@ public void testExchangeInfoDeserialization() { " \"timezone\": \"UTC\",\n" + " \"serverTime\": 1508631584636,\n" + " \"rateLimits\": [{\n" + - " \"rateLimitType\": \"REQUESTS\",\n" + + " \"rateLimitType\": \"REQUEST_WEIGHT\",\n" + " \"interval\": \"MINUTE\",\n" + " \"limit\": 1200\n" + " },\n" + @@ -81,7 +81,7 @@ public void testExchangeInfoDeserialization() { List rateLimits = exchangeInfo.getRateLimits(); assertEquals(rateLimits.size(), 3); - testRateLimit(rateLimits.get(0), RateLimitType.REQUESTS, RateLimitInterval.MINUTE, 1200); + testRateLimit(rateLimits.get(0), RateLimitType.REQUEST_WEIGHT, RateLimitInterval.MINUTE, 1200); testRateLimit(rateLimits.get(1), RateLimitType.ORDERS, RateLimitInterval.SECOND, 10); testRateLimit(rateLimits.get(2), RateLimitType.ORDERS, RateLimitInterval.DAY, 100000); From 84adddb9716c40ff19813998450ba4d7bd509099 Mon Sep 17 00:00:00 2001 From: joaopsilva Date: Thu, 19 Jul 2018 17:33:13 +0200 Subject: [PATCH 58/81] Add support for ICEBERG_PARTS and MAX_NUM_ALGO_ORDERS filter. --- .../api/client/domain/general/FilterType.java | 1 + .../client/domain/general/SymbolFilter.java | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/main/java/com/binance/api/client/domain/general/FilterType.java b/src/main/java/com/binance/api/client/domain/general/FilterType.java index 6a31f49b0..63fef1659 100644 --- a/src/main/java/com/binance/api/client/domain/general/FilterType.java +++ b/src/main/java/com/binance/api/client/domain/general/FilterType.java @@ -11,6 +11,7 @@ public enum FilterType { MAX_NUM_ORDERS, MAX_ALGO_ORDERS, MAX_NUM_ALGO_ORDERS, + ICEBERG_PARTS, // Exchange EXCHANGE_MAX_NUM_ORDERS, diff --git a/src/main/java/com/binance/api/client/domain/general/SymbolFilter.java b/src/main/java/com/binance/api/client/domain/general/SymbolFilter.java index 8902b1188..4ad81163a 100644 --- a/src/main/java/com/binance/api/client/domain/general/SymbolFilter.java +++ b/src/main/java/com/binance/api/client/domain/general/SymbolFilter.java @@ -59,9 +59,18 @@ public class SymbolFilter { */ private String minNotional; + + // MAX_NUM_ALGO_ORDERS + + /** + * Defines the maximum number of "algo" orders an account is allowed to have open on a symbol. "Algo" orders are STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, and TAKE_PROFIT_LIMIT orders. + */ + private String maxNumAlgoOrders; + /** * MAX_NUM_ORDERS filter defines the maximum number of orders an account is allowed to have open on a symbol. Note that both "algo" orders and normal orders are counted for this filter. * MAX_ALGO_ORDERS filter defines the maximum number of "algo" orders an account is allowed to have open on a symbol. "Algo" orders are STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, and TAKE_PROFIT_LIMIT orders. + * ICEBERG_PARTS filter defines the maximum parts an iceberg order can have. The number of ICEBERG_PARTS is defined as CEIL(qty / icebergQty). */ private String limit; @@ -129,6 +138,15 @@ public void setMinNotional(String minNotional) { this.minNotional = minNotional; } + public String getMaxNumAlgoOrders() { + return maxNumAlgoOrders; + } + + public SymbolFilter setMaxNumAlgoOrders(String maxNumAlgoOrders) { + this.maxNumAlgoOrders = maxNumAlgoOrders; + return this; + } + public String getLimit() { return limit; } From 9dd24773c02566b0a3aea1e83c578b72205f4ea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20G=C3=BCng=C3=B6ren?= Date: Fri, 20 Jul 2018 10:27:57 +0300 Subject: [PATCH 59/81] ignore properties add for avoiding new fields deserialization exception --- .../java/com/binance/api/client/domain/ExecutionType.java | 3 +++ .../com/binance/api/client/domain/OrderRejectReason.java | 3 +++ src/main/java/com/binance/api/client/domain/OrderSide.java | 3 +++ src/main/java/com/binance/api/client/domain/OrderStatus.java | 3 +++ src/main/java/com/binance/api/client/domain/OrderType.java | 3 +++ src/main/java/com/binance/api/client/domain/TimeInForce.java | 3 +++ .../com/binance/api/client/domain/account/AssetBalance.java | 2 ++ .../binance/api/client/domain/account/DepositAddress.java | 2 ++ .../binance/api/client/domain/account/DepositHistory.java | 2 ++ .../java/com/binance/api/client/domain/account/NewOrder.java | 2 ++ .../api/client/domain/account/NewOrderResponseType.java | 3 +++ .../java/com/binance/api/client/domain/account/Trade.java | 2 ++ .../binance/api/client/domain/account/TradeHistoryItem.java | 2 ++ .../binance/api/client/domain/account/WithdrawHistory.java | 2 ++ .../api/client/domain/account/request/OrderRequest.java | 2 ++ .../binance/api/client/domain/event/CandlestickEvent.java | 2 ++ .../java/com/binance/api/client/domain/event/ListenKey.java | 3 +++ .../binance/api/client/domain/general/ExchangeFilter.java | 2 ++ .../com/binance/api/client/domain/general/FilterType.java | 3 +++ .../com/binance/api/client/domain/general/RateLimit.java | 2 ++ .../binance/api/client/domain/general/RateLimitInterval.java | 3 +++ .../com/binance/api/client/domain/general/RateLimitType.java | 5 ++++- .../com/binance/api/client/domain/general/ServerTime.java | 3 +++ .../com/binance/api/client/domain/general/SymbolFilter.java | 3 +++ .../com/binance/api/client/domain/general/SymbolStatus.java | 3 +++ .../com/binance/api/client/domain/market/BookTicker.java | 2 ++ .../api/client/domain/market/CandlestickInterval.java | 3 +++ .../java/com/binance/api/client/domain/market/OrderBook.java | 2 ++ .../com/binance/api/client/domain/market/OrderBookEntry.java | 2 ++ .../com/binance/api/client/domain/market/TickerPrice.java | 2 ++ .../api/domain/general/ExchangeInfoDeserializerTest.java | 4 ++-- 31 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/binance/api/client/domain/ExecutionType.java b/src/main/java/com/binance/api/client/domain/ExecutionType.java index b6760b794..4da14d863 100644 --- a/src/main/java/com/binance/api/client/domain/ExecutionType.java +++ b/src/main/java/com/binance/api/client/domain/ExecutionType.java @@ -1,8 +1,11 @@ package com.binance.api.client.domain; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Order execution type. */ +@JsonIgnoreProperties(ignoreUnknown = true) public enum ExecutionType { NEW, CANCELED, diff --git a/src/main/java/com/binance/api/client/domain/OrderRejectReason.java b/src/main/java/com/binance/api/client/domain/OrderRejectReason.java index 7da9173b4..29f5e47f0 100644 --- a/src/main/java/com/binance/api/client/domain/OrderRejectReason.java +++ b/src/main/java/com/binance/api/client/domain/OrderRejectReason.java @@ -1,8 +1,11 @@ package com.binance.api.client.domain; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Order reject reason values. */ +@JsonIgnoreProperties(ignoreUnknown = true) public enum OrderRejectReason { NONE, UNKNOWN_INSTRUMENT, diff --git a/src/main/java/com/binance/api/client/domain/OrderSide.java b/src/main/java/com/binance/api/client/domain/OrderSide.java index c477436bd..db74f9373 100644 --- a/src/main/java/com/binance/api/client/domain/OrderSide.java +++ b/src/main/java/com/binance/api/client/domain/OrderSide.java @@ -1,8 +1,11 @@ package com.binance.api.client.domain; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Buy/Sell order side. */ +@JsonIgnoreProperties(ignoreUnknown = true) public enum OrderSide { BUY, SELL diff --git a/src/main/java/com/binance/api/client/domain/OrderStatus.java b/src/main/java/com/binance/api/client/domain/OrderStatus.java index 478dd4d56..81656c722 100644 --- a/src/main/java/com/binance/api/client/domain/OrderStatus.java +++ b/src/main/java/com/binance/api/client/domain/OrderStatus.java @@ -1,8 +1,11 @@ package com.binance.api.client.domain; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Status of a submitted order. */ +@JsonIgnoreProperties(ignoreUnknown = true) public enum OrderStatus { NEW, PARTIALLY_FILLED, diff --git a/src/main/java/com/binance/api/client/domain/OrderType.java b/src/main/java/com/binance/api/client/domain/OrderType.java index 46eb162c2..11d484e5e 100644 --- a/src/main/java/com/binance/api/client/domain/OrderType.java +++ b/src/main/java/com/binance/api/client/domain/OrderType.java @@ -1,8 +1,11 @@ package com.binance.api.client.domain; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Type of order to submit to the system. */ +@JsonIgnoreProperties(ignoreUnknown = true) public enum OrderType { LIMIT, MARKET, diff --git a/src/main/java/com/binance/api/client/domain/TimeInForce.java b/src/main/java/com/binance/api/client/domain/TimeInForce.java index 49e266431..2d2f50db1 100644 --- a/src/main/java/com/binance/api/client/domain/TimeInForce.java +++ b/src/main/java/com/binance/api/client/domain/TimeInForce.java @@ -1,5 +1,7 @@ package com.binance.api.client.domain; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Time in force to indicate how long an order will remain active before it is executed or expires. * @@ -9,6 +11,7 @@ * * @see http://www.investopedia.com/terms/t/timeinforce.asp */ +@JsonIgnoreProperties(ignoreUnknown = true) public enum TimeInForce { GTC, IOC, diff --git a/src/main/java/com/binance/api/client/domain/account/AssetBalance.java b/src/main/java/com/binance/api/client/domain/account/AssetBalance.java index 9f90aafa4..3dae789ec 100644 --- a/src/main/java/com/binance/api/client/domain/account/AssetBalance.java +++ b/src/main/java/com/binance/api/client/domain/account/AssetBalance.java @@ -1,6 +1,7 @@ package com.binance.api.client.domain.account; import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; /** @@ -8,6 +9,7 @@ * * @see Account */ +@JsonIgnoreProperties(ignoreUnknown = true) public class AssetBalance { /** diff --git a/src/main/java/com/binance/api/client/domain/account/DepositAddress.java b/src/main/java/com/binance/api/client/domain/account/DepositAddress.java index 2ca99502f..0aba6dc05 100644 --- a/src/main/java/com/binance/api/client/domain/account/DepositAddress.java +++ b/src/main/java/com/binance/api/client/domain/account/DepositAddress.java @@ -1,11 +1,13 @@ package com.binance.api.client.domain.account; import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; /** * A deposit address for a given asset. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class DepositAddress { private String address; diff --git a/src/main/java/com/binance/api/client/domain/account/DepositHistory.java b/src/main/java/com/binance/api/client/domain/account/DepositHistory.java index 792f3fa9d..4ac86ee7c 100644 --- a/src/main/java/com/binance/api/client/domain/account/DepositHistory.java +++ b/src/main/java/com/binance/api/client/domain/account/DepositHistory.java @@ -1,6 +1,7 @@ package com.binance.api.client.domain.account; import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -11,6 +12,7 @@ * * @see Deposit */ +@JsonIgnoreProperties(ignoreUnknown = true) public class DepositHistory { @JsonProperty("depositList") diff --git a/src/main/java/com/binance/api/client/domain/account/NewOrder.java b/src/main/java/com/binance/api/client/domain/account/NewOrder.java index 635e1ddac..221c07d36 100644 --- a/src/main/java/com/binance/api/client/domain/account/NewOrder.java +++ b/src/main/java/com/binance/api/client/domain/account/NewOrder.java @@ -4,11 +4,13 @@ import com.binance.api.client.domain.OrderSide; import com.binance.api.client.domain.OrderType; import com.binance.api.client.domain.TimeInForce; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; /** * A trade order to enter or exit a position. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class NewOrder { /** diff --git a/src/main/java/com/binance/api/client/domain/account/NewOrderResponseType.java b/src/main/java/com/binance/api/client/domain/account/NewOrderResponseType.java index c465f85a7..836a571d5 100644 --- a/src/main/java/com/binance/api/client/domain/account/NewOrderResponseType.java +++ b/src/main/java/com/binance/api/client/domain/account/NewOrderResponseType.java @@ -1,9 +1,12 @@ package com.binance.api.client.domain.account; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Desired response type of NewOrder requests. * @see NewOrderResponse */ +@JsonIgnoreProperties(ignoreUnknown = true) public enum NewOrderResponseType { ACK, RESULT, diff --git a/src/main/java/com/binance/api/client/domain/account/Trade.java b/src/main/java/com/binance/api/client/domain/account/Trade.java index c64431118..a3bad8ec5 100644 --- a/src/main/java/com/binance/api/client/domain/account/Trade.java +++ b/src/main/java/com/binance/api/client/domain/account/Trade.java @@ -1,6 +1,7 @@ package com.binance.api.client.domain.account; import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSetter; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -8,6 +9,7 @@ /** * Represents an executed trade. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class Trade { /** diff --git a/src/main/java/com/binance/api/client/domain/account/TradeHistoryItem.java b/src/main/java/com/binance/api/client/domain/account/TradeHistoryItem.java index a4470a0c1..68d017754 100644 --- a/src/main/java/com/binance/api/client/domain/account/TradeHistoryItem.java +++ b/src/main/java/com/binance/api/client/domain/account/TradeHistoryItem.java @@ -1,12 +1,14 @@ package com.binance.api.client.domain.account; import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.lang3.builder.ToStringBuilder; /** * Represents an executed trade history item. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class TradeHistoryItem { /** * Trade id. diff --git a/src/main/java/com/binance/api/client/domain/account/WithdrawHistory.java b/src/main/java/com/binance/api/client/domain/account/WithdrawHistory.java index 4694c0d09..3a3d50f12 100644 --- a/src/main/java/com/binance/api/client/domain/account/WithdrawHistory.java +++ b/src/main/java/com/binance/api/client/domain/account/WithdrawHistory.java @@ -1,6 +1,7 @@ package com.binance.api.client.domain.account; import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; import java.util.List; @@ -10,6 +11,7 @@ * * @see Withdraw */ +@JsonIgnoreProperties(ignoreUnknown = true) public class WithdrawHistory { private List withdrawList; diff --git a/src/main/java/com/binance/api/client/domain/account/request/OrderRequest.java b/src/main/java/com/binance/api/client/domain/account/request/OrderRequest.java index 2221af12d..c890a01d9 100644 --- a/src/main/java/com/binance/api/client/domain/account/request/OrderRequest.java +++ b/src/main/java/com/binance/api/client/domain/account/request/OrderRequest.java @@ -1,11 +1,13 @@ package com.binance.api.client.domain.account.request; import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; /** * Base request parameters for order-related methods. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class OrderRequest { private final String symbol; diff --git a/src/main/java/com/binance/api/client/domain/event/CandlestickEvent.java b/src/main/java/com/binance/api/client/domain/event/CandlestickEvent.java index 31cbe1e4f..1019eb6f3 100644 --- a/src/main/java/com/binance/api/client/domain/event/CandlestickEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/CandlestickEvent.java @@ -1,6 +1,7 @@ package com.binance.api.client.domain.event; import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; @@ -11,6 +12,7 @@ */ @JsonDeserialize(using = CandlestickEventDeserializer.class) @JsonSerialize(using = CandlestickEventSerializer.class) +@JsonIgnoreProperties(ignoreUnknown = true) public class CandlestickEvent { private String eventType; diff --git a/src/main/java/com/binance/api/client/domain/event/ListenKey.java b/src/main/java/com/binance/api/client/domain/event/ListenKey.java index 555d0af16..cfce64396 100644 --- a/src/main/java/com/binance/api/client/domain/event/ListenKey.java +++ b/src/main/java/com/binance/api/client/domain/event/ListenKey.java @@ -1,8 +1,11 @@ package com.binance.api.client.domain.event; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Dummy type to wrap a listen key from a server response. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class ListenKey { private String listenKey; diff --git a/src/main/java/com/binance/api/client/domain/general/ExchangeFilter.java b/src/main/java/com/binance/api/client/domain/general/ExchangeFilter.java index ef4907925..e492111a8 100644 --- a/src/main/java/com/binance/api/client/domain/general/ExchangeFilter.java +++ b/src/main/java/com/binance/api/client/domain/general/ExchangeFilter.java @@ -1,6 +1,7 @@ package com.binance.api.client.domain.general; import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; /** @@ -10,6 +11,7 @@ * * The MAX_ALGO_ORDERS filter defines the maximum number of "algo" orders an account is allowed to have open on the exchange. "Algo" orders are STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, and TAKE_PROFIT_LIMIT orders. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class ExchangeFilter { private FilterType filterType; diff --git a/src/main/java/com/binance/api/client/domain/general/FilterType.java b/src/main/java/com/binance/api/client/domain/general/FilterType.java index 593b4ae5e..928fb47b4 100644 --- a/src/main/java/com/binance/api/client/domain/general/FilterType.java +++ b/src/main/java/com/binance/api/client/domain/general/FilterType.java @@ -1,8 +1,11 @@ package com.binance.api.client.domain.general; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Filters define trading rules on a symbol or an exchange. Filters come in two forms: symbol filters and exchange filters. */ +@JsonIgnoreProperties(ignoreUnknown = true) public enum FilterType { // Symbol PRICE_FILTER, diff --git a/src/main/java/com/binance/api/client/domain/general/RateLimit.java b/src/main/java/com/binance/api/client/domain/general/RateLimit.java index 8f0e3fd1a..e8d963c33 100644 --- a/src/main/java/com/binance/api/client/domain/general/RateLimit.java +++ b/src/main/java/com/binance/api/client/domain/general/RateLimit.java @@ -1,11 +1,13 @@ package com.binance.api.client.domain.general; import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; /** * Rate limits. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class RateLimit { private RateLimitType rateLimitType; diff --git a/src/main/java/com/binance/api/client/domain/general/RateLimitInterval.java b/src/main/java/com/binance/api/client/domain/general/RateLimitInterval.java index bc316061d..0c8f65fca 100644 --- a/src/main/java/com/binance/api/client/domain/general/RateLimitInterval.java +++ b/src/main/java/com/binance/api/client/domain/general/RateLimitInterval.java @@ -1,8 +1,11 @@ package com.binance.api.client.domain.general; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Rate limit intervals. */ +@JsonIgnoreProperties(ignoreUnknown = true) public enum RateLimitInterval { SECOND, MINUTE, diff --git a/src/main/java/com/binance/api/client/domain/general/RateLimitType.java b/src/main/java/com/binance/api/client/domain/general/RateLimitType.java index af438bebb..db43d5d39 100644 --- a/src/main/java/com/binance/api/client/domain/general/RateLimitType.java +++ b/src/main/java/com/binance/api/client/domain/general/RateLimitType.java @@ -1,9 +1,12 @@ package com.binance.api.client.domain.general; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Rate limiters. */ +@JsonIgnoreProperties(ignoreUnknown = true) public enum RateLimitType { - REQUESTS, + REQUEST_WEIGHT, ORDERS } diff --git a/src/main/java/com/binance/api/client/domain/general/ServerTime.java b/src/main/java/com/binance/api/client/domain/general/ServerTime.java index 9b7475271..ec4880313 100644 --- a/src/main/java/com/binance/api/client/domain/general/ServerTime.java +++ b/src/main/java/com/binance/api/client/domain/general/ServerTime.java @@ -1,8 +1,11 @@ package com.binance.api.client.domain.general; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Time of the server running Binance's REST API. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class ServerTime { private Long serverTime; diff --git a/src/main/java/com/binance/api/client/domain/general/SymbolFilter.java b/src/main/java/com/binance/api/client/domain/general/SymbolFilter.java index 8902b1188..4789e78f6 100644 --- a/src/main/java/com/binance/api/client/domain/general/SymbolFilter.java +++ b/src/main/java/com/binance/api/client/domain/general/SymbolFilter.java @@ -1,5 +1,7 @@ package com.binance.api.client.domain.general; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Filters define trading rules on a symbol or an exchange. Filters come in two forms: symbol filters and exchange filters. * @@ -13,6 +15,7 @@ * * The MAX_ALGO_ORDERS filter defines the maximum number of "algo" orders an account is allowed to have open on a symbol. "Algo" orders are STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, and TAKE_PROFIT_LIMIT orders. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class SymbolFilter { // PRICE_FILTER diff --git a/src/main/java/com/binance/api/client/domain/general/SymbolStatus.java b/src/main/java/com/binance/api/client/domain/general/SymbolStatus.java index e9ddff627..c12647540 100644 --- a/src/main/java/com/binance/api/client/domain/general/SymbolStatus.java +++ b/src/main/java/com/binance/api/client/domain/general/SymbolStatus.java @@ -1,8 +1,11 @@ package com.binance.api.client.domain.general; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Status of a symbol on the exchange. */ +@JsonIgnoreProperties(ignoreUnknown = true) public enum SymbolStatus { PRE_TRADING, TRADING, diff --git a/src/main/java/com/binance/api/client/domain/market/BookTicker.java b/src/main/java/com/binance/api/client/domain/market/BookTicker.java index c91f3a76f..67b007ea8 100644 --- a/src/main/java/com/binance/api/client/domain/market/BookTicker.java +++ b/src/main/java/com/binance/api/client/domain/market/BookTicker.java @@ -1,11 +1,13 @@ package com.binance.api.client.domain.market; import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; /** * Represents the best price/qty on the order book for a given symbol. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class BookTicker { /** diff --git a/src/main/java/com/binance/api/client/domain/market/CandlestickInterval.java b/src/main/java/com/binance/api/client/domain/market/CandlestickInterval.java index 3bd4887e3..b34334977 100644 --- a/src/main/java/com/binance/api/client/domain/market/CandlestickInterval.java +++ b/src/main/java/com/binance/api/client/domain/market/CandlestickInterval.java @@ -1,9 +1,12 @@ package com.binance.api.client.domain.market; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Kline/Candlestick intervals. * m -> minutes; h -> hours; d -> days; w -> weeks; M -> months */ +@JsonIgnoreProperties(ignoreUnknown = true) public enum CandlestickInterval { ONE_MINUTE("1m"), THREE_MINUTES("3m"), diff --git a/src/main/java/com/binance/api/client/domain/market/OrderBook.java b/src/main/java/com/binance/api/client/domain/market/OrderBook.java index d5054a9e6..98ffb10e1 100644 --- a/src/main/java/com/binance/api/client/domain/market/OrderBook.java +++ b/src/main/java/com/binance/api/client/domain/market/OrderBook.java @@ -1,6 +1,7 @@ package com.binance.api.client.domain.market; import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; import java.util.List; @@ -8,6 +9,7 @@ /** * Order book of a symbol in Binance. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class OrderBook { /** diff --git a/src/main/java/com/binance/api/client/domain/market/OrderBookEntry.java b/src/main/java/com/binance/api/client/domain/market/OrderBookEntry.java index 3bc946a7d..7d4d2635b 100644 --- a/src/main/java/com/binance/api/client/domain/market/OrderBookEntry.java +++ b/src/main/java/com/binance/api/client/domain/market/OrderBookEntry.java @@ -1,6 +1,7 @@ package com.binance.api.client.domain.market; import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; @@ -11,6 +12,7 @@ */ @JsonDeserialize(using = OrderBookEntryDeserializer.class) @JsonSerialize(using = OrderBookEntrySerializer.class) +@JsonIgnoreProperties(ignoreUnknown = true) public class OrderBookEntry { private String price; diff --git a/src/main/java/com/binance/api/client/domain/market/TickerPrice.java b/src/main/java/com/binance/api/client/domain/market/TickerPrice.java index e2444cbc8..2c7a036ac 100644 --- a/src/main/java/com/binance/api/client/domain/market/TickerPrice.java +++ b/src/main/java/com/binance/api/client/domain/market/TickerPrice.java @@ -1,11 +1,13 @@ package com.binance.api.client.domain.market; import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; /** * Wraps a symbol and its corresponding latest price. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class TickerPrice { /** diff --git a/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java b/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java index af949ff6f..b865a8b68 100644 --- a/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java +++ b/src/test/java/com/binance/api/domain/general/ExchangeInfoDeserializerTest.java @@ -31,7 +31,7 @@ public void testExchangeInfoDeserialization() { " \"timezone\": \"UTC\",\n" + " \"serverTime\": 1508631584636,\n" + " \"rateLimits\": [{\n" + - " \"rateLimitType\": \"REQUESTS\",\n" + + " \"rateLimitType\": \"REQUEST_WEIGHT\",\n" + " \"interval\": \"MINUTE\",\n" + " \"limit\": 1200\n" + " },\n" + @@ -81,7 +81,7 @@ public void testExchangeInfoDeserialization() { List rateLimits = exchangeInfo.getRateLimits(); assertEquals(rateLimits.size(), 3); - testRateLimit(rateLimits.get(0), RateLimitType.REQUESTS, RateLimitInterval.MINUTE, 1200); + testRateLimit(rateLimits.get(0), RateLimitType.REQUEST_WEIGHT, RateLimitInterval.MINUTE, 1200); testRateLimit(rateLimits.get(1), RateLimitType.ORDERS, RateLimitInterval.SECOND, 10); testRateLimit(rateLimits.get(2), RateLimitType.ORDERS, RateLimitInterval.DAY, 100000); From 137cfd478052b49530d766302458699d6e068c64 Mon Sep 17 00:00:00 2001 From: fferez Date: Fri, 20 Jul 2018 16:41:36 +0100 Subject: [PATCH 60/81] Issue 157: Exception when getting all trades of a symbol --- .../binance/api/client/domain/account/Trade.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/com/binance/api/client/domain/account/Trade.java b/src/main/java/com/binance/api/client/domain/account/Trade.java index c64431118..574e16b7b 100644 --- a/src/main/java/com/binance/api/client/domain/account/Trade.java +++ b/src/main/java/com/binance/api/client/domain/account/Trade.java @@ -40,6 +40,11 @@ public class Trade { */ private long time; + /** + * The symbol of the trade. + */ + private String symbol; + @JsonProperty("isBuyer") private boolean buyer; @@ -107,6 +112,14 @@ public void setTime(long time) { this.time = time; } + public String getSymbol() { + return symbol; + } + + public void setSymbol(String symbol) { + this.symbol = symbol; + } + public boolean isBuyer() { return buyer; } @@ -143,6 +156,7 @@ public void setOrderId(String orderId) { public String toString() { return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) .append("id", id) + .append("symbol", symbol) .append("price", price) .append("qty", qty) .append("commission", commission) From bb8a3b6d2a127d128d2fea4ee76f7872d320d02b Mon Sep 17 00:00:00 2001 From: brintal Date: Sat, 21 Jul 2018 00:14:48 +0200 Subject: [PATCH 61/81] binance api change 2018-07-18: added param cummulativeQuoteQty to the order response --- .../api/client/domain/account/NewOrderResponse.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java b/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java index e1c1e7569..c317bba55 100644 --- a/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java +++ b/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java @@ -41,6 +41,8 @@ public class NewOrderResponse { private String executedQty; + private String cummulativeQuoteQty; + private OrderStatus status; private TimeInForce timeInForce; @@ -112,6 +114,14 @@ public void setExecutedQty(String executedQty) { this.executedQty = executedQty; } + public String getCummulativeQuoteQty() { + return cummulativeQuoteQty; + } + + public void setCummulativeQuoteQty(String cummulativeQuoteQty) { + this.cummulativeQuoteQty = cummulativeQuoteQty; + } + public OrderStatus getStatus() { return status; } From 6b4de682094b1e376c2a3f0dda26e754f3466b77 Mon Sep 17 00:00:00 2001 From: brintal Date: Sat, 21 Jul 2018 00:14:58 +0200 Subject: [PATCH 62/81] binance api change 2018-07-18: updated javadoc to reflect the new limits for max results o --- .../api/client/BinanceApiAsyncRestClient.java | 12 ++++++------ .../com/binance/api/client/BinanceApiRestClient.java | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java index 3bf9317cb..6a20c2cdf 100644 --- a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java @@ -70,7 +70,7 @@ public interface BinanceApiAsyncRestClient { * Get recent trades (up to last 500). Weight: 1 * * @param symbol ticker symbol (e.g. ETHBTC) - * @param limit of last trades (Default 500; max 500.) + * @param limit of last trades (Default 500; max 1000.) * @param callback the callback that handles the response */ void getTrades(String symbol, Integer limit, BinanceApiCallback> callback); @@ -79,7 +79,7 @@ public interface BinanceApiAsyncRestClient { * Get older trades. Weight: 5 * * @param symbol ticker symbol (e.g. ETHBTC) - * @param limit of last trades (Default 500; max 500.) + * @param limit of last trades (Default 500; max 1000.) * @param fromId TradeId to fetch from. Default gets most recent trades. * @param callback the callback that handles the response */ @@ -94,7 +94,7 @@ public interface BinanceApiAsyncRestClient { * * @param symbol symbol to aggregate (mandatory) * @param fromId ID to get aggregate trades from INCLUSIVE (optional) - * @param limit Default 500; max 500 (optional) + * @param limit Default 500; max 1000 (optional) * @param startTime Timestamp in ms to get aggregate trades from INCLUSIVE (optional). * @param endTime Timestamp in ms to get aggregate trades until INCLUSIVE (optional). * @param callback the callback that handles the response @@ -114,7 +114,7 @@ public interface BinanceApiAsyncRestClient { * * @param symbol symbol to aggregate (mandatory) * @param interval candlestick interval (mandatory) - * @param limit Default 500; max 500 (optional) + * @param limit Default 500; max 1000 (optional) * @param startTime Timestamp in ms to get candlestick bars from INCLUSIVE (optional). * @param endTime Timestamp in ms to get candlestick bars until INCLUSIVE (optional). * @param callback the callback that handles the response containing a candlestick bar for the given symbol and interval @@ -229,7 +229,7 @@ public interface BinanceApiAsyncRestClient { * Get trades for a specific account and symbol. * * @param symbol symbol to get trades from - * @param limit default 500; max 500 + * @param limit default 500; max 1000 * @param fromId TradeId to fetch from. Default gets most recent trades. * @param callback the callback that handles the response with a list of trades */ @@ -239,7 +239,7 @@ public interface BinanceApiAsyncRestClient { * Get trades for a specific account and symbol. * * @param symbol symbol to get trades from - * @param limit default 500; max 500 + * @param limit default 500; max 1000 * @param callback the callback that handles the response with a list of trades */ void getMyTrades(String symbol, Integer limit, BinanceApiCallback> callback); diff --git a/src/main/java/com/binance/api/client/BinanceApiRestClient.java b/src/main/java/com/binance/api/client/BinanceApiRestClient.java index b0f1d165c..6c6cdec48 100644 --- a/src/main/java/com/binance/api/client/BinanceApiRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiRestClient.java @@ -69,7 +69,7 @@ public interface BinanceApiRestClient { * Get recent trades (up to last 500). Weight: 1 * * @param symbol ticker symbol (e.g. ETHBTC) - * @param limit of last trades (Default 500; max 500.) + * @param limit of last trades (Default 500; max 1000.) */ List getTrades(String symbol, Integer limit); @@ -77,7 +77,7 @@ public interface BinanceApiRestClient { * Get older trades. Weight: 5 * * @param symbol ticker symbol (e.g. ETHBTC) - * @param limit of last trades (Default 500; max 500.) + * @param limit of last trades (Default 500; max 1000.) * @param fromId TradeId to fetch from. Default gets most recent trades. */ List getHistoricalTrades(String symbol, Integer limit, Long fromId); @@ -91,7 +91,7 @@ public interface BinanceApiRestClient { * * @param symbol symbol to aggregate (mandatory) * @param fromId ID to get aggregate trades from INCLUSIVE (optional) - * @param limit Default 500; max 500 (optional) + * @param limit Default 500; max 1000 (optional) * @param startTime Timestamp in ms to get aggregate trades from INCLUSIVE (optional). * @param endTime Timestamp in ms to get aggregate trades until INCLUSIVE (optional). * @return a list of aggregate trades for the given symbol @@ -110,7 +110,7 @@ public interface BinanceApiRestClient { * * @param symbol symbol to aggregate (mandatory) * @param interval candlestick interval (mandatory) - * @param limit Default 500; max 500 (optional) + * @param limit Default 500; max 1000 (optional) * @param startTime Timestamp in ms to get candlestick bars from INCLUSIVE (optional). * @param endTime Timestamp in ms to get candlestick bars until INCLUSIVE (optional). * @return a candlestick bar for the given symbol and interval @@ -215,7 +215,7 @@ public interface BinanceApiRestClient { * Get trades for a specific account and symbol. * * @param symbol symbol to get trades from - * @param limit default 500; max 500 + * @param limit default 500; max 1000 * @param fromId TradeId to fetch from. Default gets most recent trades. * @return a list of trades */ @@ -225,7 +225,7 @@ public interface BinanceApiRestClient { * Get trades for a specific account and symbol. * * @param symbol symbol to get trades from - * @param limit default 500; max 500 + * @param limit default 500; max 1000 * @return a list of trades */ List getMyTrades(String symbol, Integer limit); From 9a6cd16dba1822a21fe350012a988d5d60babd47 Mon Sep 17 00:00:00 2001 From: Krasks Date: Tue, 24 Jul 2018 02:26:23 +0300 Subject: [PATCH 63/81] fixed market ticker event --- .../domain/event/AllMarketTickersEvent.java | 122 +++++++++--------- .../impl/BinanceApiWebSocketClientImpl.java | 3 +- .../impl/BinanceApiWebSocketListener.java | 4 +- 3 files changed, 65 insertions(+), 64 deletions(-) diff --git a/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java b/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java index 336f0980e..8c07cb29a 100644 --- a/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java @@ -20,43 +20,43 @@ public class AllMarketTickersEvent { private String symbol; @JsonProperty("p") - private double priceChange; + private String priceChange; @JsonProperty("P") - private double priceChangePercent; + private String priceChangePercent; @JsonProperty("w") - private double weightedAveragePrice; + private String weightedAveragePrice; @JsonProperty("x") - private double previousDaysClosePrice; + private String previousDaysClosePrice; @JsonProperty("c") - private double currentDaysClosePrice; + private String currentDaysClosePrice; @JsonProperty("Q") - private long closeTradesQuantity; + private String closeTradesQuantity; @JsonProperty("a") - private double bestAskPrice; + private String bestAskPrice; @JsonProperty("A") - private long bestAskQuantity; + private String bestAskQuantity; @JsonProperty("o") - private double openPrice; + private String openPrice; @JsonProperty("h") - private double highPrice; + private String highPrice; @JsonProperty("l") - private double lowPrice; + private String lowPrice; @JsonProperty("v") - private long totalTradedBaseAssetVolume; + private String totalTradedBaseAssetVolume; @JsonProperty("q") - private long totalTradedQuoteAssetVolume; + private String totalTradedQuoteAssetVolume; @JsonProperty("O") private long statisticesOpenTime; @@ -97,107 +97,107 @@ public void setSymbol(String symbol) { this.symbol = symbol; } - public double getPriceChange() { + public String getPriceChange() { return priceChange; } - public void setPriceChange(double priceChange) { + public void setPriceChange(String priceChange) { this.priceChange = priceChange; } - public double getPriceChangePercent() { + public String getPriceChangePercent() { return priceChangePercent; } - public void setPriceChangePercent(double priceChangePercent) { + public void setPriceChangePercent(String priceChangePercent) { this.priceChangePercent = priceChangePercent; } - public double getWeightedAveragePrice() { + public String getWeightedAveragePrice() { return weightedAveragePrice; } - public void setWeightedAveragePrice(double weightedAveragePrice) { + public void setWeightedAveragePrice(String weightedAveragePrice) { this.weightedAveragePrice = weightedAveragePrice; } - public double getPreviousDaysClosePrice() { + public String getPreviousDaysClosePrice() { return previousDaysClosePrice; } - public void setPreviousDaysClosePrice(double previousDaysClosePrice) { + public void setPreviousDaysClosePrice(String previousDaysClosePrice) { this.previousDaysClosePrice = previousDaysClosePrice; } - public double getCurrentDaysClosePrice() { + public String getCurrentDaysClosePrice() { return currentDaysClosePrice; } - public void setCurrentDaysClosePrice(double currentDaysClosePrice) { + public void setCurrentDaysClosePrice(String currentDaysClosePrice) { this.currentDaysClosePrice = currentDaysClosePrice; } - public long getCloseTradesQuantity() { + public String getCloseTradesQuantity() { return closeTradesQuantity; } - public void setCloseTradesQuantity(long closeTradesQuantity) { + public void setCloseTradesQuantity(String closeTradesQuantity) { this.closeTradesQuantity = closeTradesQuantity; } - public double getBestAskPrice() { + public String getBestAskPrice() { return bestAskPrice; } - public void setBestAskPrice(double bestAskPrice) { + public void setBestAskPrice(String bestAskPrice) { this.bestAskPrice = bestAskPrice; } - public long getBestAskQuantity() { + public String getBestAskQuantity() { return bestAskQuantity; } - public void setBestAskQuantity(long bestAskQuantity) { + public void setBestAskQuantity(String bestAskQuantity) { this.bestAskQuantity = bestAskQuantity; } - public double getOpenPrice() { + public String getOpenPrice() { return openPrice; } - public void setOpenPrice(double openPrice) { + public void setOpenPrice(String openPrice) { this.openPrice = openPrice; } - public double getHighPrice() { + public String getHighPrice() { return highPrice; } - public void setHighPrice(double highPrice) { + public void setHighPrice(String highPrice) { this.highPrice = highPrice; } - public double getLowPrice() { + public String getLowPrice() { return lowPrice; } - public void setLowPrice(double lowPrice) { + public void setLowPrice(String lowPrice) { this.lowPrice = lowPrice; } - public long getTotalTradedBaseAssetVolume() { + public String getTotalTradedBaseAssetVolume() { return totalTradedBaseAssetVolume; } - public void setTotalTradedBaseAssetVolume(long totalTradedBaseAssetVolume) { + public void setTotalTradedBaseAssetVolume(String totalTradedBaseAssetVolume) { this.totalTradedBaseAssetVolume = totalTradedBaseAssetVolume; } - public long getTotalTradedQuoteAssetVolume() { + public String getTotalTradedQuoteAssetVolume() { return totalTradedQuoteAssetVolume; } - public void setTotalTradedQuoteAssetVolume(long totalTradedQuoteAssetVolume) { + public void setTotalTradedQuoteAssetVolume(String totalTradedQuoteAssetVolume) { this.totalTradedQuoteAssetVolume = totalTradedQuoteAssetVolume; } @@ -244,27 +244,27 @@ public void setTotalNumberOfTrades(long totalNumberOfTrades) { @Override public String toString() { return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) - .append("eventType", eventType) - .append("eventTime", eventTime) - .append("symbol", symbol) - .append("priceChange", priceChange) - .append("priceChangePercent", priceChangePercent) - .append("weightedAveragePrice", weightedAveragePrice) - .append("previousDaysClosePrice", previousDaysClosePrice) - .append("currentDaysClosePrice", currentDaysClosePrice) - .append("closeTradesQuantity", closeTradesQuantity) - .append("bestAskPrice", bestAskPrice) - .append("bestAskQuantity", bestAskQuantity) - .append("openPrice", openPrice) - .append("highPrice", highPrice) - .append("lowPrice", lowPrice) - .append("totalTradedBaseAssetVolume", totalTradedBaseAssetVolume) - .append("totalTradedQuoteAssetVolume", totalTradedQuoteAssetVolume) - .append("statisticesOpenTime", statisticesOpenTime) - .append("statisticesCloseTime", statisticesCloseTime) - .append("firstTradeId", firstTradeId) - .append("lastTradeId", lastTradeId) - .append("totalNumberOfTrades", totalNumberOfTrades) - .toString(); + .append("eventType", eventType) + .append("eventTime", eventTime) + .append("symbol", symbol) + .append("priceChange", priceChange) + .append("priceChangePercent", priceChangePercent) + .append("weightedAveragePrice", weightedAveragePrice) + .append("previousDaysClosePrice", previousDaysClosePrice) + .append("currentDaysClosePrice", currentDaysClosePrice) + .append("closeTradesQuantity", closeTradesQuantity) + .append("bestAskPrice", bestAskPrice) + .append("bestAskQuantity", bestAskQuantity) + .append("openPrice", openPrice) + .append("highPrice", highPrice) + .append("lowPrice", lowPrice) + .append("totalTradedBaseAssetVolume", totalTradedBaseAssetVolume) + .append("totalTradedQuoteAssetVolume", totalTradedQuoteAssetVolume) + .append("statisticesOpenTime", statisticesOpenTime) + .append("statisticesCloseTime", statisticesCloseTime) + .append("firstTradeId", firstTradeId) + .append("lastTradeId", lastTradeId) + .append("totalNumberOfTrades", totalNumberOfTrades) + .toString(); } } diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java index 87ff981ab..24c251ff0 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java @@ -9,6 +9,7 @@ import com.binance.api.client.domain.event.DepthEvent; import com.binance.api.client.domain.event.UserDataUpdateEvent; import com.binance.api.client.domain.market.CandlestickInterval; +import com.fasterxml.jackson.core.type.TypeReference; import okhttp3.Dispatcher; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -52,7 +53,7 @@ public Closeable onUserDataUpdateEvent(String listenKey, BinanceApiCallback> callback) { final String channel = "!ticker@arr"; - return createNewWebSocket(channel, new BinanceApiWebSocketListener>(callback)); + return createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, new TypeReference>() {})); } @Override diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java index 978317c08..8eb9df304 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java @@ -27,9 +27,9 @@ public BinanceApiWebSocketListener(BinanceApiCallback callback, Class even this.eventClass = eventClass; } - public BinanceApiWebSocketListener(BinanceApiCallback callback) { + public BinanceApiWebSocketListener(BinanceApiCallback callback, TypeReference eventTypeReference) { this.callback = callback; - this.eventTypeReference = new TypeReference() {}; + this.eventTypeReference = eventTypeReference; } @Override From abe4e31c388f72ea166362601aae34ce461395f9 Mon Sep 17 00:00:00 2001 From: Lukasz Wolynczuk Date: Mon, 20 Aug 2018 18:56:18 +0200 Subject: [PATCH 64/81] Fix for ORDER_WOULD_TRIGGER_IMMEDIATELY --- .../java/com/binance/api/client/domain/OrderRejectReason.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/domain/OrderRejectReason.java b/src/main/java/com/binance/api/client/domain/OrderRejectReason.java index 29f5e47f0..ff9374e8a 100644 --- a/src/main/java/com/binance/api/client/domain/OrderRejectReason.java +++ b/src/main/java/com/binance/api/client/domain/OrderRejectReason.java @@ -16,5 +16,6 @@ public enum OrderRejectReason { UNKNOWN_ACCOUNT, INSUFFICIENT_BALANCE, ACCOUNT_INACTIVE, - ACCOUNT_CANNOT_SETTLE + ACCOUNT_CANNOT_SETTLE, + ORDER_WOULD_TRIGGER_IMMEDIATELY } \ No newline at end of file From f0cf925458ea929e514506c8ccf9e4e2611d81c1 Mon Sep 17 00:00:00 2001 From: miron Date: Sun, 26 Aug 2018 20:32:56 +0100 Subject: [PATCH 65/81] multi-channel subscription on single websocket --- README.md | 34 +++++++++++++++++++ .../api/client/BinanceApiWebSocketClient.java | 20 +++++------ .../impl/BinanceApiWebSocketClientImpl.java | 26 ++++++++++---- 3 files changed, 63 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 102a0b1ac..bf74d5d02 100644 --- a/README.md +++ b/README.md @@ -280,6 +280,9 @@ client.closeUserDataStream(listenKey); BinanceApiWebSocketClient client = BinanceApiClientFactory.newInstance().newWebSocketClient(); ``` +User needs to be aware that REST symbols which are `upper case` differ from WebSocket symbols which must be `lower case`. +In scenario of subscription with upper case styled symbol, server will return no error and subscribe to given channel - however, no events will be pushed. + #### Handling web socket errors Each of the methods on `BinanceApiWebSocketClient`, which opens a new web socket, takes a `BinanceApiCallback`, which is @@ -431,6 +434,37 @@ client.onUserDataUpdateEvent(listenKey, response -> { }); ``` +#### Multi-channel subscription +Client provides a way for user to subscribe to multiple channels using same websocket - to achieve that user needs to coma-separate symbols as it is in following examples. + +````java +client.onAggTradeEvent("ethbtc,ethusdt", (AggTradeEvent response) -> { + if (Objects.equals(response.getSymbol(),"ethbtc")) { + // handle ethbtc event + } else if(Objects.equals(response.getSymbol()),"ethusdt")) { + // handle ethusdt event + } +}); +```` +````java +client.onDepthEvent("ethbtc,ethusdt", (DepthEvent response) -> { + if (Objects.equals(response.getSymbol(),"ethbtc")) { + // handle ethbtc event + } else if(Objects.equals(response.getSymbol()),"ethusdt")) { + // handle ethusdt event + } +}); +```` +````java +client.onCandlestickEvent("ethbtc,ethusdt", CandlestickInterval.ONE_MINUTE, (CandlestickEvent response) -> { + if (Objects.equals(response.getSymbol(),"ethbtc")) { + // handle ethbtc event + } else if(Objects.equals(response.getSymbol()),"ethusdt")) { + // handle ethusdt event + } +}); +```` + ### Asynchronous requests To make an asynchronous request it is necessary to use the `BinanceApiAsyncRestClient`, and call the method with the same name as in the synchronous version, but passing a callback [`BinanceApiCallback`](https://github.com/joaopsilva/binance-java-api/blob/master/src/main/java/com/binance/api/client/BinanceApiCallback.java) that handles the response whenever it arrives. diff --git a/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java b/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java index b118efa9d..631bb6b06 100644 --- a/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiWebSocketClient.java @@ -18,30 +18,30 @@ public interface BinanceApiWebSocketClient extends Closeable { /** * Open a new web socket to receive {@link DepthEvent depthEvents} on a callback. * - * @param symbol the market symbol to subscribe to - * @param callback the callback to call on new events + * @param symbols market (one or coma-separated) symbol(s) to subscribe to + * @param callback the callback to call on new events * @return a {@link Closeable} that allows the underlying web socket to be closed. */ - Closeable onDepthEvent(String symbol, BinanceApiCallback callback); + Closeable onDepthEvent(String symbols, BinanceApiCallback callback); /** * Open a new web socket to receive {@link CandlestickEvent candlestickEvents} on a callback. * - * @param symbol the market symbol to subscribe to - * @param interval the interval of the candles tick events required - * @param callback the callback to call on new events + * @param symbols market (one or coma-separated) symbol(s) to subscribe to + * @param interval the interval of the candles tick events required + * @param callback the callback to call on new events * @return a {@link Closeable} that allows the underlying web socket to be closed. */ - Closeable onCandlestickEvent(String symbol, CandlestickInterval interval, BinanceApiCallback callback); + Closeable onCandlestickEvent(String symbols, CandlestickInterval interval, BinanceApiCallback callback); /** * Open a new web socket to receive {@link AggTradeEvent aggTradeEvents} on a callback. * - * @param symbol the market symbol to subscribe to - * @param callback the callback to call on new events + * @param symbols market (one or coma-separated) symbol(s) to subscribe to + * @param callback the callback to call on new events * @return a {@link Closeable} that allows the underlying web socket to be closed. */ - Closeable onAggTradeEvent(String symbol, BinanceApiCallback callback); + Closeable onAggTradeEvent(String symbols, BinanceApiCallback callback); /** * Open a new web socket to receive {@link UserDataUpdateEvent userDataUpdateEvents} on a callback. diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java index 87ff981ab..df0df2466 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketClientImpl.java @@ -15,14 +15,16 @@ import okhttp3.WebSocket; import java.io.Closeable; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; /** * Binance API WebSocket client implementation using OkHttp. */ public class BinanceApiWebSocketClientImpl implements BinanceApiWebSocketClient, Closeable { - private OkHttpClient client; + private final OkHttpClient client; public BinanceApiWebSocketClientImpl() { Dispatcher d = new Dispatcher(); @@ -30,19 +32,29 @@ public BinanceApiWebSocketClientImpl() { this.client = new OkHttpClient.Builder().dispatcher(d).build(); } - public Closeable onDepthEvent(String symbol, BinanceApiCallback callback) { - final String channel = String.format("%s@depth", symbol); + @Override + public Closeable onDepthEvent(String symbols, BinanceApiCallback callback) { + final String channel = Arrays.stream(symbols.split(",")) + .map(String::trim) + .map(s -> String.format("%s@depth", s)) + .collect(Collectors.joining("/")); return createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, DepthEvent.class)); } @Override - public Closeable onCandlestickEvent(String symbol, CandlestickInterval interval, BinanceApiCallback callback) { - final String channel = String.format("%s@kline_%s", symbol, interval.getIntervalId()); + public Closeable onCandlestickEvent(String symbols, CandlestickInterval interval, BinanceApiCallback callback) { + final String channel = Arrays.stream(symbols.split(",")) + .map(String::trim) + .map(s -> String.format("%s@kline_%s", s, interval.getIntervalId())) + .collect(Collectors.joining("/")); return createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, CandlestickEvent.class)); } - public Closeable onAggTradeEvent(String symbol, BinanceApiCallback callback) { - final String channel = String.format("%s@aggTrade", symbol); + public Closeable onAggTradeEvent(String symbols, BinanceApiCallback callback) { + final String channel = Arrays.stream(symbols.split(",")) + .map(String::trim) + .map(s -> String.format("%s@aggTrade", s)) + .collect(Collectors.joining("/")); return createNewWebSocket(channel, new BinanceApiWebSocketListener<>(callback, AggTradeEvent.class)); } From 429c70453447901270ade80e88b4b09bda19e45c Mon Sep 17 00:00:00 2001 From: Miron Balcerzak Date: Mon, 3 Sep 2018 00:30:07 +0100 Subject: [PATCH 66/81] Preventing NPE while boxing/unboxing --- .../domain/event/OrderTradeUpdateEvent.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/binance/api/client/domain/event/OrderTradeUpdateEvent.java b/src/main/java/com/binance/api/client/domain/event/OrderTradeUpdateEvent.java index 0f26008a7..cf7ab86e3 100644 --- a/src/main/java/com/binance/api/client/domain/event/OrderTradeUpdateEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/OrderTradeUpdateEvent.java @@ -25,7 +25,7 @@ public class OrderTradeUpdateEvent { private String eventType; @JsonProperty("E") - private long eventTime; + private Long eventTime; @JsonProperty("s") private String symbol; @@ -137,11 +137,11 @@ public void setEventType(String eventType) { this.eventType = eventType; } - public long getEventTime() { + public Long getEventTime() { return eventTime; } - public void setEventTime(long eventTime) { + public void setEventTime(Long eventTime) { this.eventTime = eventTime; } @@ -225,7 +225,7 @@ public void setOrderRejectReason(OrderRejectReason orderRejectReason) { this.orderRejectReason = orderRejectReason; } - public long getOrderId() { + public Long getOrderId() { return orderId; } @@ -273,19 +273,19 @@ public void setCommissionAsset(String commissionAsset) { this.commissionAsset = commissionAsset; } - public long getOrderTradeTime() { + public Long getOrderTradeTime() { return orderTradeTime; } - public void setOrderTradeTime(long orderTradeTime) { + public void setOrderTradeTime(Long orderTradeTime) { this.orderTradeTime = orderTradeTime; } - public long getTradeId() { + public Long getTradeId() { return tradeId; } - public void setTradeId(long tradeId) { + public void setTradeId(Long tradeId) { this.tradeId = tradeId; } From 8055ac1c560d152898c56ed84e52187f3380e8a7 Mon Sep 17 00:00:00 2001 From: Miron Balcerzak Date: Mon, 3 Sep 2018 00:36:39 +0100 Subject: [PATCH 67/81] Preventing NPE while boxing/unboxing - JUnit fix --- .../api/domain/event/UserDataUpdateEventDeserializerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/binance/api/domain/event/UserDataUpdateEventDeserializerTest.java b/src/test/java/com/binance/api/domain/event/UserDataUpdateEventDeserializerTest.java index 36346b1ea..23b1ced98 100644 --- a/src/test/java/com/binance/api/domain/event/UserDataUpdateEventDeserializerTest.java +++ b/src/test/java/com/binance/api/domain/event/UserDataUpdateEventDeserializerTest.java @@ -70,8 +70,8 @@ public void testOrderUpdateEventDeserializer() { assertEquals(orderTradeUpdateEvent.getOrderStatus(), OrderStatus.CANCELED); assertEquals(orderTradeUpdateEvent.getOrderRejectReason(), OrderRejectReason.NONE); - assertEquals(orderTradeUpdateEvent.getOrderId(), 123456L); - assertEquals(orderTradeUpdateEvent.getOrderTradeTime(), 1L); + assertEquals(orderTradeUpdateEvent.getOrderId(), new Long(123456)); + assertEquals(orderTradeUpdateEvent.getOrderTradeTime(), new Long(1)); } catch (IOException e) { fail(); } From 4363070508c6ea8fc02ad2fc1477cef309efc60c Mon Sep 17 00:00:00 2001 From: joaopsilva Date: Thu, 13 Sep 2018 01:21:54 +0200 Subject: [PATCH 68/81] Add support for cancel order response. --- .../api/client/BinanceApiAsyncRestClient.java | 3 +- .../api/client/BinanceApiRestClient.java | 3 +- .../account/request/CancelOrderResponse.java | 68 +++++++++++++++++++ .../impl/BinanceApiAsyncRestClientImpl.java | 3 +- .../client/impl/BinanceApiRestClientImpl.java | 5 +- .../api/client/impl/BinanceApiService.java | 7 +- .../binance/api/examples/OrdersExample.java | 4 +- .../api/examples/OrdersExampleAsync.java | 2 +- 8 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/binance/api/client/domain/account/request/CancelOrderResponse.java diff --git a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java index 6a20c2cdf..a6e7fe7ad 100644 --- a/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiAsyncRestClient.java @@ -12,6 +12,7 @@ import com.binance.api.client.domain.account.WithdrawResult; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; +import com.binance.api.client.domain.account.request.CancelOrderResponse; import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; import com.binance.api.client.domain.event.ListenKey; @@ -197,7 +198,7 @@ public interface BinanceApiAsyncRestClient { * @param cancelOrderRequest order status request parameters * @param callback the callback that handles the response */ - void cancelOrder(CancelOrderRequest cancelOrderRequest, BinanceApiCallback callback); + void cancelOrder(CancelOrderRequest cancelOrderRequest, BinanceApiCallback callback); /** * Get all open orders on a symbol (asynchronous). diff --git a/src/main/java/com/binance/api/client/BinanceApiRestClient.java b/src/main/java/com/binance/api/client/BinanceApiRestClient.java index 6c6cdec48..e405d4a7f 100644 --- a/src/main/java/com/binance/api/client/BinanceApiRestClient.java +++ b/src/main/java/com/binance/api/client/BinanceApiRestClient.java @@ -12,6 +12,7 @@ import com.binance.api.client.domain.account.WithdrawResult; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; +import com.binance.api.client.domain.account.request.CancelOrderResponse; import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; import com.binance.api.client.domain.general.ExchangeInfo; @@ -183,7 +184,7 @@ public interface BinanceApiRestClient { * * @param cancelOrderRequest order status request parameters */ - void cancelOrder(CancelOrderRequest cancelOrderRequest); + CancelOrderResponse cancelOrder(CancelOrderRequest cancelOrderRequest); /** * Get all open orders on a symbol. diff --git a/src/main/java/com/binance/api/client/domain/account/request/CancelOrderResponse.java b/src/main/java/com/binance/api/client/domain/account/request/CancelOrderResponse.java new file mode 100644 index 000000000..88ede0268 --- /dev/null +++ b/src/main/java/com/binance/api/client/domain/account/request/CancelOrderResponse.java @@ -0,0 +1,68 @@ +package com.binance.api.client.domain.account.request; + +import com.binance.api.client.constant.BinanceApiConstants; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.apache.commons.lang3.builder.ToStringBuilder; + +/** + * Response object returned when an order is canceled. + * + * @see CancelOrderRequest for the request + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class CancelOrderResponse { + + private String symbol; + + private String origClientOrderId; + + private String orderId; + + private String clientOrderId; + + public String getSymbol() { + return symbol; + } + + public CancelOrderResponse setSymbol(String symbol) { + this.symbol = symbol; + return this; + } + + public String getOrigClientOrderId() { + return origClientOrderId; + } + + public CancelOrderResponse setOrigClientOrderId(String origClientOrderId) { + this.origClientOrderId = origClientOrderId; + return this; + } + + public String getOrderId() { + return orderId; + } + + public CancelOrderResponse setOrderId(String orderId) { + this.orderId = orderId; + return this; + } + + public String getClientOrderId() { + return clientOrderId; + } + + public CancelOrderResponse setClientOrderId(String clientOrderId) { + this.clientOrderId = clientOrderId; + return this; + } + + @Override + public String toString() { + return new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE) + .append("symbol", symbol) + .append("origClientOrderId", origClientOrderId) + .append("orderId", orderId) + .append("clientOrderId", clientOrderId) + .toString(); + } +} diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java index 40104238f..97f02148c 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiAsyncRestClientImpl.java @@ -15,6 +15,7 @@ import com.binance.api.client.domain.account.WithdrawResult; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; +import com.binance.api.client.domain.account.request.CancelOrderResponse; import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; import com.binance.api.client.domain.event.ListenKey; @@ -153,7 +154,7 @@ public void getOrderStatus(OrderStatusRequest orderStatusRequest, BinanceApiCall } @Override - public void cancelOrder(CancelOrderRequest cancelOrderRequest, BinanceApiCallback callback) { + public void cancelOrder(CancelOrderRequest cancelOrderRequest, BinanceApiCallback callback) { binanceApiService.cancelOrder(cancelOrderRequest.getSymbol(), cancelOrderRequest.getOrderId(), cancelOrderRequest.getOrigClientOrderId(), cancelOrderRequest.getNewClientOrderId(), cancelOrderRequest.getRecvWindow(), cancelOrderRequest.getTimestamp()).enqueue(new BinanceApiCallbackAdapter<>(callback)); diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java index 6ac012dac..aceb3799a 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiRestClientImpl.java @@ -14,6 +14,7 @@ import com.binance.api.client.domain.account.WithdrawResult; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; +import com.binance.api.client.domain.account.request.CancelOrderResponse; import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; import com.binance.api.client.domain.general.Asset; @@ -150,8 +151,8 @@ public Order getOrderStatus(OrderStatusRequest orderStatusRequest) { } @Override - public void cancelOrder(CancelOrderRequest cancelOrderRequest) { - executeSync(binanceApiService.cancelOrder(cancelOrderRequest.getSymbol(), + public CancelOrderResponse cancelOrder(CancelOrderRequest cancelOrderRequest) { + return executeSync(binanceApiService.cancelOrder(cancelOrderRequest.getSymbol(), cancelOrderRequest.getOrderId(), cancelOrderRequest.getOrigClientOrderId(), cancelOrderRequest.getNewClientOrderId(), cancelOrderRequest.getRecvWindow(), cancelOrderRequest.getTimestamp())); } diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiService.java b/src/main/java/com/binance/api/client/impl/BinanceApiService.java index 77331890e..9643c8e90 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiService.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiService.java @@ -14,6 +14,7 @@ import com.binance.api.client.domain.account.TradeHistoryItem; import com.binance.api.client.domain.account.WithdrawHistory; import com.binance.api.client.domain.account.WithdrawResult; +import com.binance.api.client.domain.account.request.CancelOrderResponse; import com.binance.api.client.domain.event.ListenKey; import com.binance.api.client.domain.general.Asset; import com.binance.api.client.domain.general.ExchangeInfo; @@ -115,9 +116,9 @@ Call getOrderStatus(@Query("symbol") String symbol, @Query("orderId") Lon @Headers(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_SIGNED_HEADER) @DELETE("/api/v3/order") - Call cancelOrder(@Query("symbol") String symbol, @Query("orderId") Long orderId, - @Query("origClientOrderId") String origClientOrderId, @Query("newClientOrderId") String newClientOrderId, - @Query("recvWindow") Long recvWindow, @Query("timestamp") Long timestamp); + Call cancelOrder(@Query("symbol") String symbol, @Query("orderId") Long orderId, + @Query("origClientOrderId") String origClientOrderId, @Query("newClientOrderId") String newClientOrderId, + @Query("recvWindow") Long recvWindow, @Query("timestamp") Long timestamp); @Headers(BinanceApiConstants.ENDPOINT_SECURITY_TYPE_SIGNED_HEADER) @GET("/api/v3/openOrders") diff --git a/src/test/java/com/binance/api/examples/OrdersExample.java b/src/test/java/com/binance/api/examples/OrdersExample.java index c133e7432..fc2185497 100644 --- a/src/test/java/com/binance/api/examples/OrdersExample.java +++ b/src/test/java/com/binance/api/examples/OrdersExample.java @@ -8,6 +8,7 @@ import com.binance.api.client.domain.account.Order; import com.binance.api.client.domain.account.request.AllOrdersRequest; import com.binance.api.client.domain.account.request.CancelOrderRequest; +import com.binance.api.client.domain.account.request.CancelOrderResponse; import com.binance.api.client.domain.account.request.OrderRequest; import com.binance.api.client.domain.account.request.OrderStatusRequest; import com.binance.api.client.exception.BinanceApiException; @@ -40,7 +41,8 @@ public static void main(String[] args) { // Canceling an order try { - client.cancelOrder(new CancelOrderRequest("LINKETH", 756762l)); + CancelOrderResponse cancelOrderResponse = client.cancelOrder(new CancelOrderRequest("LINKETH", 756762l)); + System.out.println(cancelOrderResponse); } catch (BinanceApiException e) { System.out.println(e.getError().getMsg()); } diff --git a/src/test/java/com/binance/api/examples/OrdersExampleAsync.java b/src/test/java/com/binance/api/examples/OrdersExampleAsync.java index 9f766ff02..cadb53a58 100644 --- a/src/test/java/com/binance/api/examples/OrdersExampleAsync.java +++ b/src/test/java/com/binance/api/examples/OrdersExampleAsync.java @@ -32,7 +32,7 @@ public static void main(String[] args) { // Canceling an order client.cancelOrder(new CancelOrderRequest("LINKETH", 756703L), - response -> System.out.println("Order has been canceled.")); + response -> System.out.println(response)); // Placing a test LIMIT order client.newOrderTest(limitBuy("LINKETH", TimeInForce.GTC, "1000", "0.0001"), From 2da945391f5728adafb2100aca43f71239a4ec67 Mon Sep 17 00:00:00 2001 From: joaopsilva Date: Thu, 13 Sep 2018 02:15:27 +0200 Subject: [PATCH 69/81] Make fills toString null-safe. --- .../api/client/domain/account/NewOrderResponse.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java b/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java index c317bba55..f9ae9e447 100644 --- a/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java +++ b/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java @@ -8,7 +8,9 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.apache.commons.lang3.builder.ToStringBuilder; +import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; /** @@ -176,7 +178,10 @@ public String toString() { .append("timeInForce", timeInForce) .append("type", type) .append("side", side) - .append("fills", fills.stream().map(Object::toString).collect(Collectors.joining(", "))) + .append("fills", Optional.ofNullable(fills).orElse(Collections.emptyList()) + .stream() + .map(Object::toString) + .collect(Collectors.joining(", "))) .toString(); } } From e7995c0eeb65e5877c82d8d4ca209c0b331e9e0c Mon Sep 17 00:00:00 2001 From: joaopsilva Date: Thu, 13 Sep 2018 02:24:31 +0200 Subject: [PATCH 70/81] Add unit tests for NewOrderResponse. --- .../domain/account/NewOrderResponse.java | 1 + .../domain/account/NewOrderResponseTest.java | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 src/test/java/com/binance/api/client/domain/account/NewOrderResponseTest.java diff --git a/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java b/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java index f9ae9e447..281e0361e 100644 --- a/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java +++ b/src/main/java/com/binance/api/client/domain/account/NewOrderResponse.java @@ -53,6 +53,7 @@ public class NewOrderResponse { private OrderSide side; + // @JsonSetter(nulls = Nulls.AS_EMPTY) private List fills; /** diff --git a/src/test/java/com/binance/api/client/domain/account/NewOrderResponseTest.java b/src/test/java/com/binance/api/client/domain/account/NewOrderResponseTest.java new file mode 100644 index 000000000..277a86162 --- /dev/null +++ b/src/test/java/com/binance/api/client/domain/account/NewOrderResponseTest.java @@ -0,0 +1,49 @@ +package com.binance.api.client.domain.account; + +import org.junit.Before; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +/** + * @see NewOrderResponse + */ +public class NewOrderResponseTest { + + private NewOrderResponse newOrderResponse; + private Trade trade; + + @Before + public void setUp() { + newOrderResponse = new NewOrderResponse(); + trade = new Trade(); + trade.setId(123L); + } + + @Test + public void shouldHandleToStringWithNullFills() { + assertThat(newOrderResponse.toString(), containsString(",fills=")); + } + + @Test + public void shouldHandleToStringWithNoFills() { + newOrderResponse.setFills(Collections.emptyList()); + assertThat(newOrderResponse.toString(), containsString(",fills=")); + } + + @Test + public void shouldHandleToStringWithFills() { + newOrderResponse.setFills(trades(trade)); + assertThat(newOrderResponse.toString(), containsString(",fills=Trade[id=123,")); + } + + private static List trades(final Trade... trades) { + return Arrays.asList(trades); + } +} \ No newline at end of file From d39139a78620862657f220c26ce9e3dd38ca25dd Mon Sep 17 00:00:00 2001 From: brintal Date: Thu, 15 Nov 2018 00:05:19 +0100 Subject: [PATCH 71/81] configure custom dispatcher for sharedClient to allow for more parallel requests --- .../client/impl/BinanceApiServiceGenerator.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java b/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java index 490dd23dc..8307f48b9 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiServiceGenerator.java @@ -4,6 +4,7 @@ import com.binance.api.client.constant.BinanceApiConstants; import com.binance.api.client.exception.BinanceApiException; import com.binance.api.client.security.AuthenticationInterceptor; +import okhttp3.Dispatcher; import okhttp3.OkHttpClient; import okhttp3.RequestBody; import okhttp3.ResponseBody; @@ -22,12 +23,20 @@ * Generates a Binance API implementation based on @see {@link BinanceApiService}. */ public class BinanceApiServiceGenerator { - private static final OkHttpClient sharedClient = new OkHttpClient.Builder() - .pingInterval(20, TimeUnit.SECONDS) - .build(); + private static final OkHttpClient sharedClient; private static final Converter.Factory converterFactory = JacksonConverterFactory.create(); + static { + Dispatcher dispatcher = new Dispatcher(); + dispatcher.setMaxRequestsPerHost(500); + dispatcher.setMaxRequests(500); + sharedClient = new OkHttpClient.Builder() + .dispatcher(dispatcher) + .pingInterval(20, TimeUnit.SECONDS) + .build(); + } + @SuppressWarnings("unchecked") private static final Converter errorBodyConverter = (Converter)converterFactory.responseBodyConverter( From d6801c2ab2cf5884b4722ef78db4760b109b9192 Mon Sep 17 00:00:00 2001 From: igorustinov Date: Tue, 4 Dec 2018 20:56:20 +0100 Subject: [PATCH 72/81] adds new filter type values --- .../java/com/binance/api/client/domain/general/FilterType.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/binance/api/client/domain/general/FilterType.java b/src/main/java/com/binance/api/client/domain/general/FilterType.java index 0ddedda51..1959f8ec5 100644 --- a/src/main/java/com/binance/api/client/domain/general/FilterType.java +++ b/src/main/java/com/binance/api/client/domain/general/FilterType.java @@ -15,6 +15,9 @@ public enum FilterType { MAX_ALGO_ORDERS, MAX_NUM_ALGO_ORDERS, ICEBERG_PARTS, + PERCENT_PRICE, + MARKET_LOT_SIZE, + MAX_NUM_ICEBERG_ORDERS, // Exchange EXCHANGE_MAX_NUM_ORDERS, From 7c2a4f42d5630cd2f03c8401d6cdce90d66ab3ea Mon Sep 17 00:00:00 2001 From: Tofig Hasanov Date: Sat, 12 Jan 2019 15:19:46 +0000 Subject: [PATCH 73/81] Add bid price and quantity to AllMarketTickersEvent --- .../domain/event/AllMarketTickersEvent.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java b/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java index 8c07cb29a..85a14db29 100644 --- a/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/AllMarketTickersEvent.java @@ -37,6 +37,12 @@ public class AllMarketTickersEvent { @JsonProperty("Q") private String closeTradesQuantity; + @JsonProperty("b") + private String bestBidPrice; + + @JsonProperty("B") + private String bestBidQuantity; + @JsonProperty("a") private String bestAskPrice; @@ -145,6 +151,22 @@ public void setCloseTradesQuantity(String closeTradesQuantity) { this.closeTradesQuantity = closeTradesQuantity; } + public String getBestBidPrice() { + return bestBidPrice; + } + + public void setBestBidPrice(String bestBidPrice) { + this.bestBidPrice = bestBidPrice; + } + + public String getBestBidQuantity() { + return bestBidQuantity; + } + + public void setBestBidQuantity(String bestBidQuantity) { + this.bestBidQuantity = bestBidQuantity; + } + public String getBestAskPrice() { return bestAskPrice; } @@ -253,6 +275,8 @@ public String toString() { .append("previousDaysClosePrice", previousDaysClosePrice) .append("currentDaysClosePrice", currentDaysClosePrice) .append("closeTradesQuantity", closeTradesQuantity) + .append("bestBidPrice", bestBidPrice) + .append("bestBidQuantity", bestBidQuantity) .append("bestAskPrice", bestAskPrice) .append("bestAskQuantity", bestAskQuantity) .append("openPrice", openPrice) From dd121acfa025ab7608d50921a4e5bbd48f62dbc3 Mon Sep 17 00:00:00 2001 From: joaopsilva Date: Sun, 10 Mar 2019 11:43:20 +0100 Subject: [PATCH 74/81] Cache ObjectMapper. --- .../binance/api/client/impl/BinanceApiWebSocketListener.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java index 8eb9df304..e22bb8641 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java @@ -16,6 +16,8 @@ public class BinanceApiWebSocketListener extends WebSocketListener { private BinanceApiCallback callback; + private static final ObjectMapper mapper = new ObjectMapper(); + private Class eventClass; private TypeReference eventTypeReference; @@ -34,7 +36,6 @@ public BinanceApiWebSocketListener(BinanceApiCallback callback, TypeReference @Override public void onMessage(WebSocket webSocket, String text) { - ObjectMapper mapper = new ObjectMapper(); try { T event = null; if (eventClass == null) { From 96bbbd155ff74aed76c901d97dfc9a4e2022ea6f Mon Sep 17 00:00:00 2001 From: joaopsilva Date: Sun, 10 Mar 2019 16:12:49 +0100 Subject: [PATCH 75/81] Use ObjectReader instance for processing JSON. --- .../impl/BinanceApiWebSocketListener.java | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java index e22bb8641..8c84dbe3f 100644 --- a/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java +++ b/src/main/java/com/binance/api/client/impl/BinanceApiWebSocketListener.java @@ -1,13 +1,15 @@ package com.binance.api.client.impl; -import java.io.IOException; -import okhttp3.Response; -import okhttp3.WebSocket; -import okhttp3.WebSocketListener; import com.binance.api.client.BinanceApiCallback; import com.binance.api.client.exception.BinanceApiException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import okhttp3.Response; +import okhttp3.WebSocket; +import okhttp3.WebSocketListener; + +import java.io.IOException; /** * Binance API WebSocket listener. @@ -18,31 +20,24 @@ public class BinanceApiWebSocketListener extends WebSocketListener { private static final ObjectMapper mapper = new ObjectMapper(); - private Class eventClass; - - private TypeReference eventTypeReference; + private final ObjectReader objectReader; private boolean closing = false; public BinanceApiWebSocketListener(BinanceApiCallback callback, Class eventClass) { this.callback = callback; - this.eventClass = eventClass; + this.objectReader = mapper.readerFor(eventClass); } public BinanceApiWebSocketListener(BinanceApiCallback callback, TypeReference eventTypeReference) { this.callback = callback; - this.eventTypeReference = eventTypeReference; + this.objectReader = mapper.readerFor(eventTypeReference); } @Override public void onMessage(WebSocket webSocket, String text) { try { - T event = null; - if (eventClass == null) { - event = mapper.readValue(text, eventTypeReference); - } else { - event = mapper.readValue(text, eventClass); - } + T event = objectReader.readValue(text); callback.onResponse(event); } catch (IOException e) { throw new BinanceApiException(e); From 5c4451c57b63b73a062fd60da4084e28a293b544 Mon Sep 17 00:00:00 2001 From: Marc Deveaux Date: Sat, 30 Mar 2019 20:08:27 -0400 Subject: [PATCH 76/81] add status and executedQty to CancelOrderResponse --- .../domain/account/request/CancelOrderResponse.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/binance/api/client/domain/account/request/CancelOrderResponse.java b/src/main/java/com/binance/api/client/domain/account/request/CancelOrderResponse.java index 88ede0268..7b96a01eb 100644 --- a/src/main/java/com/binance/api/client/domain/account/request/CancelOrderResponse.java +++ b/src/main/java/com/binance/api/client/domain/account/request/CancelOrderResponse.java @@ -20,6 +20,9 @@ public class CancelOrderResponse { private String clientOrderId; + private String status; + private String executedQty; + public String getSymbol() { return symbol; } @@ -38,10 +41,16 @@ public CancelOrderResponse setOrigClientOrderId(String origClientOrderId) { return this; } + public String getStatus() { + return status; + } + public String getExecutedQty() { + return executedQty; + } + public String getOrderId() { return orderId; } - public CancelOrderResponse setOrderId(String orderId) { this.orderId = orderId; return this; From 22df744f0e29589824e84a1572328a2f727350de Mon Sep 17 00:00:00 2001 From: Ben Alex Date: Fri, 14 Jun 2019 12:15:50 +1000 Subject: [PATCH 77/81] Add license to POM for license-maven-plugin compatibility License metadata is useful for http://www.mojohaus.org/license-maven-plugin/ interoperability as well as a requirement of eventual listing in Maven Central (OSSHR) as per https://central.sonatype.org/pages/requirements.html. --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 7ad829cbd..93401e33c 100644 --- a/pom.xml +++ b/pom.xml @@ -7,6 +7,12 @@ com.binance.api binance-api-client 1.0.0 + + + The MIT License + https://opensource.org/licenses/MIT + + 2.4.0 From 54bc694a158b9cd57698b0697468e988e5b32fe5 Mon Sep 17 00:00:00 2001 From: Ardiansyah Putra Date: Mon, 12 Aug 2019 14:18:15 +0700 Subject: [PATCH 78/81] Add Cummulative Quote Quantity `cummulativeQuoteQty` is needed to calculate the average price, for example when using market order --- .../binance/api/client/domain/account/Order.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/com/binance/api/client/domain/account/Order.java b/src/main/java/com/binance/api/client/domain/account/Order.java index a0b5939b7..88beb54d7 100644 --- a/src/main/java/com/binance/api/client/domain/account/Order.java +++ b/src/main/java/com/binance/api/client/domain/account/Order.java @@ -78,6 +78,11 @@ public class Order { * Order timestamp. */ private long time; + + /** + * Used to calculate the average price + */ + private String cummulativeQuoteQty; public String getSymbol() { return symbol; @@ -182,6 +187,14 @@ public long getTime() { public void setTime(long time) { this.time = time; } + + public String getCummulativeQuoteQty() { + return cummulativeQuoteQty; + } + + public void setCummulativeQuoteQty(String cummulativeQuoteQty) { + this.cummulativeQuoteQty = cummulativeQuoteQty; + } @Override public String toString() { @@ -199,6 +212,7 @@ public String toString() { .append("stopPrice", stopPrice) .append("icebergQty", icebergQty) .append("time", time) + .append("cummulativeQuoteQty", cummulativeQuoteQty) .toString(); } } From 25a23ce9de4a7cf2a8e2d8204acfc521efa97e82 Mon Sep 17 00:00:00 2001 From: Martijn Courteaux Date: Sat, 17 Aug 2019 00:37:59 +0200 Subject: [PATCH 79/81] Fixed parsing of UserDataUpdateEvents with regard to the new 'outboundAccountPosition' events. --- .../api/client/domain/event/UserDataUpdateEvent.java | 8 +++++++- .../domain/event/UserDataUpdateEventDeserializer.java | 5 +++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEvent.java b/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEvent.java index 0af50e198..e0cd92bf2 100644 --- a/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEvent.java +++ b/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEvent.java @@ -9,7 +9,8 @@ * User data update event which can be of two types: * * 1) outboundAccountInfo, whenever there is a change in the account (e.g. balance of an asset) - * 2) executionReport, whenever there is a trade or an order + * 2) outboundAccountPosition, the change in account balances caused by an event. + * 3) executionReport, whenever there is a trade or an order */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonDeserialize(using = UserDataUpdateEventDeserializer.class) @@ -62,6 +63,8 @@ public String toString() { .append("eventTime", eventTime); if (eventType == UserDataUpdateEventType.ACCOUNT_UPDATE) { sb.append("accountUpdateEvent", accountUpdateEvent); + } else if (eventType == UserDataUpdateEventType.ACCOUNT_POSITION_UPDATE) { + sb.append("accountPositionUpdateEvent", accountUpdateEvent); } else { sb.append("orderTradeUpdateEvent", orderTradeUpdateEvent); } @@ -70,6 +73,7 @@ public String toString() { public enum UserDataUpdateEventType { ACCOUNT_UPDATE("outboundAccountInfo"), + ACCOUNT_POSITION_UPDATE("outboundAccountPosition"), ORDER_TRADE_UPDATE("executionReport"); private final String eventTypeId; @@ -87,6 +91,8 @@ public static UserDataUpdateEventType fromEventTypeId(String eventTypeId) { return ACCOUNT_UPDATE; } else if (ORDER_TRADE_UPDATE.eventTypeId.equals(eventTypeId)) { return ORDER_TRADE_UPDATE; + } else if (ACCOUNT_POSITION_UPDATE.eventTypeId.equals(eventTypeId)) { + return ACCOUNT_POSITION_UPDATE; } throw new IllegalArgumentException("Unrecognized user data update event type id: " + eventTypeId); } diff --git a/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEventDeserializer.java b/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEventDeserializer.java index afc584636..8ef548e39 100644 --- a/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEventDeserializer.java +++ b/src/main/java/com/binance/api/client/domain/event/UserDataUpdateEventDeserializer.java @@ -38,7 +38,8 @@ public UserDataUpdateEvent deserialize(JsonParser jp, DeserializationContext ctx userDataUpdateEvent.setEventType(userDataUpdateEventType); userDataUpdateEvent.setEventTime(eventTime); - if (userDataUpdateEventType == UserDataUpdateEventType.ACCOUNT_UPDATE) { + if (userDataUpdateEventType == UserDataUpdateEventType.ACCOUNT_UPDATE || + userDataUpdateEventType == UserDataUpdateEventType.ACCOUNT_POSITION_UPDATE) { AccountUpdateEvent accountUpdateEvent = getUserDataUpdateEventDetail(json, AccountUpdateEvent.class, mapper); userDataUpdateEvent.setAccountUpdateEvent(accountUpdateEvent); } else { // userDataUpdateEventType == UserDataUpdateEventType.ORDER_TRADE_UPDATE @@ -56,4 +57,4 @@ public T getUserDataUpdateEventDetail(String json, Class clazz, ObjectMap throw new BinanceApiException(e); } } -} \ No newline at end of file +} From a15902ab8b7f87bffde31aedda41b34d6d5bf10d Mon Sep 17 00:00:00 2001 From: joaopsilva Date: Sat, 17 Aug 2019 20:54:46 +0200 Subject: [PATCH 80/81] Adjusted recvWindow to 60000. --- .../api/client/constant/BinanceApiConstants.java | 2 +- .../binance/api/client/domain/account/Trade.java | 15 +++++++++++++++ .../api/examples/AccountEndpointsExample.java | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java b/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java index 8dddf6be8..bcc39452d 100644 --- a/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java +++ b/src/main/java/com/binance/api/client/constant/BinanceApiConstants.java @@ -42,7 +42,7 @@ public class BinanceApiConstants { /** * Default receiving window. */ - public static final long DEFAULT_RECEIVING_WINDOW = 6_000_000L; + public static final long DEFAULT_RECEIVING_WINDOW = 60_000L; /** * Default ToStringStyle used by toString methods. diff --git a/src/main/java/com/binance/api/client/domain/account/Trade.java b/src/main/java/com/binance/api/client/domain/account/Trade.java index df0d14e3b..aa38a17b6 100644 --- a/src/main/java/com/binance/api/client/domain/account/Trade.java +++ b/src/main/java/com/binance/api/client/domain/account/Trade.java @@ -27,6 +27,12 @@ public class Trade { */ private String qty; + + /** + * Quote quantity for the trade (price * qty). + */ + private String quoteQty; + /** * Commission. */ @@ -90,6 +96,14 @@ public void setQty(String qty) { this.qty = qty; } + public String getQuoteQty() { + return quoteQty; + } + + public void setQuoteQty(String quoteQty) { + this.quoteQty = quoteQty; + } + public String getCommission() { return commission; } @@ -161,6 +175,7 @@ public String toString() { .append("symbol", symbol) .append("price", price) .append("qty", qty) + .append("quoteQty", quoteQty) .append("commission", commission) .append("commissionAsset", commissionAsset) .append("time", time) diff --git a/src/test/java/com/binance/api/examples/AccountEndpointsExample.java b/src/test/java/com/binance/api/examples/AccountEndpointsExample.java index a859ca8f1..bd7d56364 100644 --- a/src/test/java/com/binance/api/examples/AccountEndpointsExample.java +++ b/src/test/java/com/binance/api/examples/AccountEndpointsExample.java @@ -17,7 +17,7 @@ public static void main(String[] args) { BinanceApiRestClient client = factory.newRestClient(); // Get account balances - Account account = client.getAccount(6000000L, System.currentTimeMillis()); + Account account = client.getAccount(60_000L, System.currentTimeMillis()); System.out.println(account.getBalances()); System.out.println(account.getAssetBalance("ETH")); From 93a55cd20b486c970cd40c2aee8fc3e1eb0d6e1f Mon Sep 17 00:00:00 2001 From: Martin Laubre Date: Mon, 19 Aug 2019 12:46:34 +0300 Subject: [PATCH 81/81] force source encoding to UTF-8 --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 93401e33c..e559f1634 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,7 @@ 2.4.0 + UTF-8 @@ -55,6 +56,7 @@ 1.8 1.8 + UTF-8