diff --git a/LICENSE b/LICENSE
index dd0e8235ce4..547b7d2e140 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright 2015-2021 Knowm Inc. (http://knowm.org) and contributors.
+Copyright 2015-2023 Knowm Inc. (http://knowm.org) and contributors.
Copyright 2012-2015 Xeiam LLC (http://xeiam.com) and contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -19,4 +19,4 @@ 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.
\ No newline at end of file
+THE SOFTWARE.
diff --git a/pom.xml b/pom.xml
index 18c55b9b4e8..72dfce6f48a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -201,6 +201,7 @@
xchange-stream-hitbtc
xchange-stream-huobi
xchange-stream-kraken
+ xchange-stream-kucoin
xchange-stream-lgo
xchange-stream-okcoin
xchange-stream-okex
diff --git a/xchange-binance/src/main/java/org/knowm/xchange/binance/BinanceExchange.java b/xchange-binance/src/main/java/org/knowm/xchange/binance/BinanceExchange.java
index 29d7e4b2e1e..2e2364b9615 100644
--- a/xchange-binance/src/main/java/org/knowm/xchange/binance/BinanceExchange.java
+++ b/xchange-binance/src/main/java/org/knowm/xchange/binance/BinanceExchange.java
@@ -16,6 +16,7 @@
public class BinanceExchange extends BaseExchange implements Exchange {
public static final String SPECIFIC_PARAM_USE_SANDBOX = "Use_Sandbox";
public static final String SPECIFIC_PARAM_USE_FUTURES_SANDBOX = "Use_Sandbox_Futures";
+ public static final String SPECIFIC_PARAM_FUTURES_ENABLED = "Futures_Enabled";
private static final String SPOT_URL = "https://api.binance.com";
public static final String FUTURES_URL = "https://fapi.binance.com";
@@ -77,6 +78,11 @@ public boolean isFuturesSandbox(){
exchangeSpecification.getExchangeSpecificParametersItem(SPECIFIC_PARAM_USE_FUTURES_SANDBOX));
}
+ public boolean isFuturesEnabled(){
+ return Boolean.TRUE.equals(
+ exchangeSpecification.getExchangeSpecificParametersItem(SPECIFIC_PARAM_FUTURES_ENABLED));
+ }
+
public boolean usingSandbox() {
return enabledSandbox(exchangeSpecification);
}
@@ -101,7 +107,9 @@ public void remoteInit() {
}
} else {
exchangeMetaData = BinanceAdapters.adaptExchangeMetaData(marketDataService.getExchangeInfo(), assetDetailMap);
- BinanceAdapters.adaptFutureExchangeMetaData(exchangeMetaData, marketDataService.getFutureExchangeInfo());
+ if(isFuturesEnabled()){
+ BinanceAdapters.adaptFutureExchangeMetaData(exchangeMetaData, marketDataService.getFutureExchangeInfo());
+ }
}
} catch (Exception e) {
diff --git a/xchange-binance/src/main/java/org/knowm/xchange/binance/dto/trade/TrailingFlag.java b/xchange-binance/src/main/java/org/knowm/xchange/binance/dto/trade/TrailingFlag.java
new file mode 100644
index 00000000000..deeb43d52e3
--- /dev/null
+++ b/xchange-binance/src/main/java/org/knowm/xchange/binance/dto/trade/TrailingFlag.java
@@ -0,0 +1,43 @@
+package org.knowm.xchange.binance.dto.trade;
+
+import org.knowm.xchange.dto.Order.IOrderFlags;
+
+/**
+ * @see trailing-stop-faq
+ * @author mrmx
+ */
+public enum TrailingFlag implements IOrderFlags {
+ /** Trailing of 0.01% */
+ P0_01(1),
+ /** Trailing of 0.1% */
+ P0_1(10),
+ /** Trailing of 1% */
+ P1(100),
+ /** Trailing of 10% */
+ P10(1000);
+ /** Basis Points, also known as BIP or BIPS, are used to indicate a percentage change. */
+ private final long trailingBip;
+
+ private TrailingFlag(long trailingBip) {
+ this.trailingBip = trailingBip;
+ }
+
+ public long getTrailingBip() {
+ return trailingBip;
+ }
+
+ static TrailingFlag of(Number percent) {
+ switch (percent.toString()) {
+ case "0.01":
+ return P0_01;
+ case "0.1":
+ return P0_1;
+ case "1":
+ return P1;
+ case "10":
+ return P10;
+ }
+ throw new IllegalArgumentException("Invalid trailing " + percent);
+ }
+}
\ No newline at end of file
diff --git a/xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceAccountService.java b/xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceAccountService.java
index f73ee801f5f..6aab63f855e 100644
--- a/xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceAccountService.java
+++ b/xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceAccountService.java
@@ -104,11 +104,12 @@ public AccountInfo getAccountInfo() throws IOException {
wallets.add(BinanceAdapters.adaptBinanceSpotWallet(account()));
}
} else {
- BinanceFutureAccountInformation futureAccountInformation = futuresAccount();
+ if(exchange.isFuturesEnabled()){
+ BinanceFutureAccountInformation futureAccountInformation = futuresAccount();
+ wallets.add(BinanceAdapters.adaptBinanceFutureWallet(futureAccountInformation));
+ openPositions.addAll(BinanceAdapters.adaptOpenPositions(futureAccountInformation.getPositions()));
+ }
wallets.add(BinanceAdapters.adaptBinanceSpotWallet(account()));
- wallets.add(BinanceAdapters.adaptBinanceFutureWallet(futureAccountInformation));
- openPositions.addAll(BinanceAdapters.adaptOpenPositions(futureAccountInformation.getPositions()));
-
}
return new AccountInfo(
exchange.getExchangeSpecification().getUserName(),
diff --git a/xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceTradeService.java b/xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceTradeService.java
index d8cc20299f8..357b6d9aef4 100644
--- a/xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceTradeService.java
+++ b/xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceTradeService.java
@@ -7,7 +7,6 @@
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
-
import lombok.Value;
import org.knowm.xchange.binance.BinanceAdapters;
import org.knowm.xchange.binance.BinanceErrorAdapter;
@@ -35,9 +34,7 @@
public class BinanceTradeService extends BinanceTradeServiceRaw implements TradeService {
- public BinanceTradeService(
- BinanceExchange exchange,
- ResilienceRegistries resilienceRegistries) {
+ public BinanceTradeService(BinanceExchange exchange, ResilienceRegistries resilienceRegistries) {
super(exchange, resilienceRegistries);
}
@@ -54,13 +51,14 @@ public OpenOrders getOpenOrders(CurrencyPair pair) throws IOException {
public OpenOrders getOpenOrders(OpenOrdersParams params) throws IOException {
try {
Instrument pair = null;
- if(params instanceof OpenOrdersParamInstrument){
+ if (params instanceof OpenOrdersParamInstrument) {
pair = ((OpenOrdersParamInstrument) params).getInstrument();
- } else if(params instanceof OpenOrdersParamCurrencyPair){
+ } else if (params instanceof OpenOrdersParamCurrencyPair) {
pair = ((OpenOrdersParamCurrencyPair) params).getCurrencyPair();
}
- return BinanceAdapters.adaptOpenOrders(openOrdersAllProducts(pair), pair instanceof FuturesContract);
+ return BinanceAdapters.adaptOpenOrders(
+ openOrdersAllProducts(pair), pair instanceof FuturesContract);
} catch (BinanceException e) {
throw BinanceErrorAdapter.adapt(e);
@@ -69,12 +67,12 @@ public OpenOrders getOpenOrders(OpenOrdersParams params) throws IOException {
@Override
public String placeMarketOrder(MarketOrder mo) throws IOException {
- return placeOrderAllProducts(OrderType.MARKET, mo, null, null, null, null, null,null);
+ return placeOrderAllProducts(OrderType.MARKET, mo, null, null, null, null, null, null);
}
@Override
public String placeLimitOrder(LimitOrder limitOrder) throws IOException {
- TimeInForce tif = timeInForceFromOrder(limitOrder).orElse(TimeInForce.GTC);
+ TimeInForce tif = getOrderFlag(limitOrder, TimeInForce.class).orElse(TimeInForce.GTC);
OrderType type;
if (limitOrder.hasFlag(org.knowm.xchange.binance.dto.trade.BinanceOrderFlags.LIMIT_MAKER)) {
type = OrderType.LIMIT_MAKER;
@@ -82,7 +80,8 @@ public String placeLimitOrder(LimitOrder limitOrder) throws IOException {
} else {
type = OrderType.LIMIT;
}
- return placeOrderAllProducts(type, limitOrder, limitOrder.getLimitPrice(), null, null, null,null, tif);
+ return placeOrderAllProducts(
+ type, limitOrder, limitOrder.getLimitPrice(), null, null, null, null, tif);
}
@Override
@@ -93,18 +92,26 @@ public String placeStopOrder(StopOrder order) throws IOException {
// allow
// it at some point.
TimeInForce tif =
- timeInForceFromOrder(order).orElse(order.getLimitPrice() != null ? TimeInForce.GTC : null);
-
+ getOrderFlag(order, TimeInForce.class)
+ .orElse(order.getLimitPrice() != null ? TimeInForce.GTC : null);
+ Long trailingDelta =
+ getOrderFlag(order, TrailingFlag.class).map(TrailingFlag::getTrailingBip).orElse(null);
OrderType orderType = BinanceAdapters.adaptOrderType(order);
return placeOrderAllProducts(
- orderType, order, order.getLimitPrice(), order.getStopPrice(), null, null, order.getTrailValue(), tif);
+ orderType,
+ order,
+ order.getLimitPrice(),
+ order.getStopPrice(),
+ null,
+ trailingDelta,
+ order.getTrailValue(),
+ tif);
}
- private Optional timeInForceFromOrder(Order order) {
- return order.getOrderFlags().stream()
- .filter(flag -> flag instanceof TimeInForce)
- .map(flag -> (TimeInForce) flag)
+ private Optional getOrderFlag(Order order, Class clazz) {
+ return (Optional) order.getOrderFlags().stream()
+ .filter(flag -> clazz.isAssignableFrom(flag.getClass()))
.findFirst();
}
@@ -121,36 +128,41 @@ private String placeOrderAllProducts(
try {
String orderId;
- if(order.getInstrument() instanceof FuturesContract){
- orderId = newFutureOrder(
- order.getInstrument(),
- BinanceAdapters.convert(order.getType()),
- type,
- tif,
- order.getOriginalAmount(),
- order.hasFlag(org.knowm.xchange.binance.dto.trade.BinanceOrderFlags.REDUCE_ONLY),
- limitPrice,
- getClientOrderId(order),
- stopPrice,
- false,
- null,
- callBackRate,
- null
- ).getOrderId();
+ if (order.getInstrument() instanceof FuturesContract) {
+ orderId =
+ newFutureOrder(
+ order.getInstrument(),
+ BinanceAdapters.convert(order.getType()),
+ type,
+ tif,
+ order.getOriginalAmount(),
+ order.hasFlag(
+ org.knowm.xchange.binance.dto.trade.BinanceOrderFlags.REDUCE_ONLY),
+ limitPrice,
+ order.getUserReference(),
+ stopPrice,
+ false,
+ null,
+ callBackRate,
+ null)
+ .getOrderId();
} else {
- orderId = Long.toString(newOrder(
- order.getInstrument(),
- BinanceAdapters.convert(order.getType()),
- type,
- tif,
- order.getOriginalAmount(),
- quoteOrderQty, // TODO (BigDecimal)order.getExtraValue("quoteOrderQty")
- limitPrice,
- getClientOrderId(order),
- stopPrice,
- trailingDelta, // TODO (Long)order.getExtraValue("trailingDelta")
- null,
- null).orderId);
+ orderId =
+ Long.toString(
+ newOrder(
+ order.getInstrument(),
+ BinanceAdapters.convert(order.getType()),
+ type,
+ tif,
+ order.getOriginalAmount(),
+ quoteOrderQty,
+ limitPrice,
+ order.getUserReference(),
+ stopPrice,
+ trailingDelta,
+ null,
+ null)
+ .orderId);
}
return orderId;
} catch (BinanceException e) {
@@ -172,7 +184,7 @@ public void placeTestOrder(
Long trailingDelta)
throws IOException {
try {
- TimeInForce tif = timeInForceFromOrder(order).orElse(null);
+ TimeInForce tif = getOrderFlag(order, TimeInForce.class).orElse(null);
testNewOrder(
order.getInstrument(),
BinanceAdapters.convert(order.getType()),
@@ -181,7 +193,7 @@ public void placeTestOrder(
order.getOriginalAmount(),
quoteOrderQty,
limitPrice,
- getClientOrderId(order),
+ order.getUserReference(),
stopPrice,
trailingDelta,
null);
@@ -190,20 +202,6 @@ public void placeTestOrder(
}
}
- private String getClientOrderId(Order order) {
-
- String clientOrderId = null;
- for (IOrderFlags flags : order.getOrderFlags()) {
- if (flags instanceof BinanceOrderFlags) {
- BinanceOrderFlags bof = (BinanceOrderFlags) flags;
- if (clientOrderId == null) {
- clientOrderId = bof.getClientId();
- }
- }
- }
- return clientOrderId;
- }
-
@Override
public boolean cancelOrder(CancelOrderParams params) throws IOException {
try {
@@ -216,10 +214,7 @@ public boolean cancelOrder(CancelOrderParams params) throws IOException {
CancelOrderByInstrument paramInstrument = (CancelOrderByInstrument) params;
CancelOrderByIdParams paramId = (CancelOrderByIdParams) params;
cancelOrderAllProducts(
- paramInstrument.getInstrument(),
- BinanceAdapters.id(paramId.getOrderId()),
- null,
- null);
+ paramInstrument.getInstrument(), BinanceAdapters.id(paramId.getOrderId()), null, null);
return true;
} catch (BinanceException e) {
@@ -246,8 +241,7 @@ public UserTrades getTradeHistory(TradeHistoryParams params) throws IOException
TradeHistoryParamInstrument pairParams = (TradeHistoryParamInstrument) params;
Instrument pair = pairParams.getInstrument();
if (pair == null) {
- throw new ExchangeException(
- "You need to provide the instrument to get the user trades.");
+ throw new ExchangeException("You need to provide the instrument to get the user trades.");
}
Long orderId = null;
Long startTime = null;
@@ -279,7 +273,8 @@ public UserTrades getTradeHistory(TradeHistoryParams params) throws IOException
limit = limitParams.getLimit();
}
- List binanceTrades = myTradesAllProducts(pair, orderId, startTime, endTime, fromId, limit);
+ List binanceTrades =
+ myTradesAllProducts(pair, orderId, startTime, endTime, fromId, limit);
return BinanceAdapters.adaptUserTrades(binanceTrades, pair instanceof FuturesContract);
} catch (BinanceException e) {
@@ -294,22 +289,22 @@ public Collection getOrder(OrderQueryParams... params) throws IOException
for (OrderQueryParams param : params) {
if (!(param instanceof OrderQueryParamInstrument)) {
throw new ExchangeException(
- "Parameters must be an instance of OrderQueryParamInstrument");
+ "Parameters must be an instance of OrderQueryParamInstrument");
}
- OrderQueryParamInstrument orderQueryParamInstrument =
- (OrderQueryParamInstrument) param;
+ OrderQueryParamInstrument orderQueryParamInstrument = (OrderQueryParamInstrument) param;
if (orderQueryParamInstrument.getInstrument() == null
- || orderQueryParamInstrument.getOrderId() == null) {
+ || orderQueryParamInstrument.getOrderId() == null) {
throw new ExchangeException(
- "You need to provide the currency pair and the order id to query an order.");
+ "You need to provide the currency pair and the order id to query an order.");
}
orders.add(
- BinanceAdapters.adaptOrder(
- orderStatusAllProducts(
- orderQueryParamInstrument.getInstrument(),
- BinanceAdapters.id(orderQueryParamInstrument.getOrderId()),
- null), orderQueryParamInstrument.getInstrument() instanceof FuturesContract));
+ BinanceAdapters.adaptOrder(
+ orderStatusAllProducts(
+ orderQueryParamInstrument.getInstrument(),
+ BinanceAdapters.id(orderQueryParamInstrument.getOrderId()),
+ null),
+ orderQueryParamInstrument.getInstrument() instanceof FuturesContract));
}
return orders;
} catch (BinanceException e) {
@@ -325,16 +320,16 @@ public OpenPositions getOpenPositions() throws IOException {
@Override
public Collection cancelAllOrders(CancelAllOrders orderParams) throws IOException {
- if(!(orderParams instanceof CancelOrderByInstrument)){
- throw new NotAvailableFromExchangeException("Parameters must be an instance of "+CancelOrderByInstrument.class.getSimpleName());
+ if (!(orderParams instanceof CancelOrderByInstrument)) {
+ throw new NotAvailableFromExchangeException(
+ "Parameters must be an instance of " + CancelOrderByInstrument.class.getSimpleName());
}
Instrument instrument = ((CancelOrderByInstrument) orderParams).getInstrument();
- return cancelAllOpenOrdersAllProducts(instrument)
- .stream()
- .map(binanceCancelledOrder -> Long.toString(binanceCancelledOrder.orderId))
- .collect(Collectors.toList());
+ return cancelAllOpenOrdersAllProducts(instrument).stream()
+ .map(binanceCancelledOrder -> Long.toString(binanceCancelledOrder.orderId))
+ .collect(Collectors.toList());
}
@Override
diff --git a/xchange-binance/src/test/java/org/knowm/xchange/binance/dto/trade/TrailingFlagTest.java b/xchange-binance/src/test/java/org/knowm/xchange/binance/dto/trade/TrailingFlagTest.java
new file mode 100644
index 00000000000..f8cc18f15b8
--- /dev/null
+++ b/xchange-binance/src/test/java/org/knowm/xchange/binance/dto/trade/TrailingFlagTest.java
@@ -0,0 +1,37 @@
+package org.knowm.xchange.binance.dto.trade;
+
+import java.util.Arrays;
+import java.util.List;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.catchIllegalArgumentException;
+import org.junit.Test;
+
+/** @author mrmx */
+public class TrailingFlagTest {
+
+ /** Test of method, of class BinanceOrderTrailingFlag. */
+ @Test
+ public void testOfValue() {
+ System.out.println("testOfValue");
+ List values = Arrays.asList(0.01, 0.1, 1, 10);
+ for (Number value : values) {
+ assertThat(TrailingFlag.of(value).getTrailingBip()).isBetween(1L, 1000L);
+ }
+ }
+
+ /** Test of method, of class BinanceOrderTrailingFlag. */
+ @Test
+ public void testOfValueWithInvalidNumbers() {
+ System.out.println("testOfValueWithInvalidNumbers");
+ List values = Arrays.asList(0.011, 0.11, 2, 11);
+ for (Number value : values) {
+ assertThat(
+ catchIllegalArgumentException(
+ () -> {
+ TrailingFlag.of(value);
+ }))
+ .as("Invalid value " + value)
+ .isNotNull();
+ }
+ }
+}
\ No newline at end of file
diff --git a/xchange-binance/src/test/resources/logback.xml b/xchange-binance/src/test/resources/logback.xml
index 5809b573500..8c86d2fa1c3 100644
--- a/xchange-binance/src/test/resources/logback.xml
+++ b/xchange-binance/src/test/resources/logback.xml
@@ -11,7 +11,7 @@
-
+
diff --git a/xchange-bitstamp/pom.xml b/xchange-bitstamp/pom.xml
index 8e3004aa9cf..1998f2321c5 100644
--- a/xchange-bitstamp/pom.xml
+++ b/xchange-bitstamp/pom.xml
@@ -24,6 +24,12 @@
+
+ org.projectlombok
+ lombok
+ provided
+
+
org.knowm.xchange
xchange-core
diff --git a/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/BitstampV2.java b/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/BitstampV2.java
index 235bcd892a7..ff6644b1f62 100644
--- a/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/BitstampV2.java
+++ b/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/BitstampV2.java
@@ -1,6 +1,7 @@
package org.knowm.xchange.bitstamp;
import java.io.IOException;
+import java.util.List;
import java.util.Objects;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@@ -32,6 +33,11 @@ BitstampOrderBook getOrderBook(@PathParam("pair") Pair pair)
BitstampTicker getTicker(@PathParam("pair") BitstampV2.Pair pair)
throws IOException, BitstampException;
+ @GET
+ @Path("ticker/")
+ List getTickers()
+ throws IOException, BitstampException;
+
@GET
@Path("ticker_hour/{pair}/")
BitstampTicker getTickerHour(@PathParam("pair") BitstampV2.Pair pair)
diff --git a/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/dto/marketdata/BitstampPairInfo.java b/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/dto/marketdata/BitstampPairInfo.java
index 654684a4dea..63550380393 100644
--- a/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/dto/marketdata/BitstampPairInfo.java
+++ b/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/dto/marketdata/BitstampPairInfo.java
@@ -1,91 +1,34 @@
package org.knowm.xchange.bitstamp.dto.marketdata;
import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Builder;
+import lombok.Value;
+import lombok.extern.jackson.Jacksonized;
-/** @author Matej Spiller Muys */
-public final class BitstampPairInfo {
+@Builder
+@Jacksonized
+@Value
+public class BitstampPairInfo {
- private final String name;
- private final String urlSymbol;
- private final Integer baseDecimals;
- private final Integer counterDecimals;
- private final String minimumOrder;
- private final String trading;
- private final String description;
+ @JsonProperty("name")
+ String name;
- /**
- * Constructor
- *
- * @param name
- * @param urlSymbol
- * @param baseDecimals
- * @param counterDecimals
- * @param minimumOrder
- * @param trading
- * @param description
- */
- public BitstampPairInfo(
- @JsonProperty("name") String name,
- @JsonProperty("url_symbol") String urlSymbol,
- @JsonProperty("base_decimals") Integer baseDecimals,
- @JsonProperty("counter_decimals") Integer counterDecimals,
- @JsonProperty("minimum_order") String minimumOrder,
- @JsonProperty("trading") String trading,
- @JsonProperty("description") String description) {
- this.name = name;
- this.urlSymbol = urlSymbol;
- this.baseDecimals = baseDecimals;
- this.counterDecimals = counterDecimals;
- this.minimumOrder = minimumOrder;
- this.trading = trading;
- this.description = description;
- }
+ @JsonProperty("url_symbol")
+ String urlSymbol;
- public String getName() {
- return name;
- }
+ @JsonProperty("base_decimals")
+ Integer baseDecimals;
- public String getUrlSymbol() {
- return urlSymbol;
- }
+ @JsonProperty("counter_decimals")
+ Integer counterDecimals;
- public Integer getBaseDecimals() {
- return baseDecimals;
- }
+ @JsonProperty("minimum_order")
+ String minimumOrder;
- public Integer getCounterDecimals() {
- return counterDecimals;
- }
+ @JsonProperty("trading")
+ String trading;
- public String getMinimumOrder() {
- return minimumOrder;
- }
+ @JsonProperty("description")
+ String description;
- public String getTrading() {
- return trading;
- }
-
- public String getDescription() {
- return description;
- }
-
- @Override
- public String toString() {
-
- return "BitstampTicker [name="
- + name
- + ", urlSymbol="
- + urlSymbol
- + ", baseDecimals="
- + baseDecimals
- + ", counterDecimals="
- + counterDecimals
- + ", minimumOrder="
- + minimumOrder
- + ", trading="
- + trading
- + ", description="
- + description
- + "]";
- }
}
diff --git a/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/dto/marketdata/BitstampTicker.java b/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/dto/marketdata/BitstampTicker.java
index e0713ba1d41..58a3fa9f675 100644
--- a/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/dto/marketdata/BitstampTicker.java
+++ b/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/dto/marketdata/BitstampTicker.java
@@ -2,119 +2,43 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
+import lombok.Builder;
+import lombok.Value;
+import lombok.extern.jackson.Jacksonized;
-/** @author Matija Mazi */
-public final class BitstampTicker {
+@Builder
+@Jacksonized
+@Value
+public class BitstampTicker {
- private final BigDecimal open;
- private final BigDecimal last;
- private final BigDecimal high;
- private final BigDecimal low;
- private final BigDecimal vwap;
- private final BigDecimal volume;
- private final BigDecimal bid;
- private final BigDecimal ask;
- private final long timestamp;
+ @JsonProperty("pair")
+ String pair;
- /**
- * Constructor
- *
- * @param open
- * @param last
- * @param high
- * @param low
- * @param vwap
- * @param volume
- * @param bid
- * @param ask
- */
- public BitstampTicker(
- @JsonProperty("open") BigDecimal open,
- @JsonProperty("last") BigDecimal last,
- @JsonProperty("high") BigDecimal high,
- @JsonProperty("low") BigDecimal low,
- @JsonProperty("vwap") BigDecimal vwap,
- @JsonProperty("volume") BigDecimal volume,
- @JsonProperty("bid") BigDecimal bid,
- @JsonProperty("ask") BigDecimal ask,
- @JsonProperty("timestamp") long timestamp) {
+ @JsonProperty("open")
+ BigDecimal open;
- this.open = open;
- this.last = last;
- this.high = high;
- this.low = low;
- this.vwap = vwap;
- this.volume = volume;
- this.bid = bid;
- this.ask = ask;
- this.timestamp = timestamp;
- }
+ @JsonProperty("last")
+ BigDecimal last;
- public BigDecimal getOpen() {
- return open;
- }
+ @JsonProperty("high")
+ BigDecimal high;
- public BigDecimal getLast() {
+ @JsonProperty("low")
+ BigDecimal low;
- return last;
- }
+ @JsonProperty("vwap")
+ BigDecimal vwap;
- public BigDecimal getHigh() {
+ @JsonProperty("volume")
+ BigDecimal volume;
- return high;
- }
+ @JsonProperty("bid")
+ BigDecimal bid;
- public BigDecimal getLow() {
+ @JsonProperty("ask")
+ BigDecimal ask;
- return low;
- }
+ @JsonProperty("timestamp")
+ long timestamp;
- public BigDecimal getVwap() {
-
- return vwap;
- }
-
- public BigDecimal getVolume() {
-
- return volume;
- }
-
- public BigDecimal getBid() {
-
- return bid;
- }
-
- public BigDecimal getAsk() {
-
- return ask;
- }
-
- public long getTimestamp() {
-
- return timestamp;
- }
-
- @Override
- public String toString() {
-
- return "BitstampTicker [open="
- + open
- + ", last="
- + last
- + ", high="
- + high
- + ", low="
- + low
- + ", vwap="
- + vwap
- + ", volume="
- + volume
- + ", bid="
- + bid
- + ", ask="
- + ask
- + ", timestamp="
- + timestamp
- + "]";
- }
}
diff --git a/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/service/BitstampMarketDataServiceRaw.java b/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/service/BitstampMarketDataServiceRaw.java
index f80e469fe61..6999ef7e529 100644
--- a/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/service/BitstampMarketDataServiceRaw.java
+++ b/xchange-bitstamp/src/main/java/org/knowm/xchange/bitstamp/service/BitstampMarketDataServiceRaw.java
@@ -1,6 +1,7 @@
package org.knowm.xchange.bitstamp.service;
import java.io.IOException;
+import java.util.List;
import javax.annotation.Nullable;
import org.knowm.xchange.Exchange;
import org.knowm.xchange.bitstamp.BitstampV2;
@@ -33,6 +34,14 @@ public BitstampTicker getBitstampTicker(CurrencyPair pair) throws IOException {
}
}
+ public List getBitstampTickers() throws IOException {
+ try {
+ return bitstampV2.getTickers();
+ } catch (BitstampException e) {
+ throw handleError(e);
+ }
+ }
+
public BitstampTicker getBitstampTickerHourly(CurrencyPair pair) throws IOException {
try {
return bitstampV2.getTickerHour(new BitstampV2.Pair(pair));
diff --git a/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/KucoinAdapters.java b/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/KucoinAdapters.java
index 65b8e8f9f5e..22bfd285fc6 100644
--- a/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/KucoinAdapters.java
+++ b/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/KucoinAdapters.java
@@ -229,7 +229,7 @@ public static OrderBook adaptOrderBook(CurrencyPair currencyPair, OrderBookRespo
.sorted(Ordering.natural().onResultOf((PriceAndSize s) -> s.price).reversed())
.map(s -> adaptLimitOrder(currencyPair, BID, s, timestamp))
.collect(toCollection(LinkedList::new));
- return new OrderBook(timestamp, asks, bids);
+ return new OrderBook(timestamp, asks, bids, true);
}
private static LimitOrder adaptLimitOrder(
diff --git a/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/KucoinMarketDataServiceRaw.java b/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/KucoinMarketDataServiceRaw.java
index 07831ffe86c..94be7c89b2f 100644
--- a/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/KucoinMarketDataServiceRaw.java
+++ b/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/KucoinMarketDataServiceRaw.java
@@ -10,10 +10,12 @@
import java.util.Map;
import java.util.stream.Collectors;
import org.knowm.xchange.client.ResilienceRegistries;
+import org.knowm.xchange.currency.Currency;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.kucoin.dto.KlineIntervalType;
import org.knowm.xchange.kucoin.dto.response.AllTickersResponse;
import org.knowm.xchange.kucoin.dto.response.CurrenciesResponse;
+import org.knowm.xchange.kucoin.dto.response.CurrencyResponseV2;
import org.knowm.xchange.kucoin.dto.response.KucoinKline;
import org.knowm.xchange.kucoin.dto.response.OrderBookResponse;
import org.knowm.xchange.kucoin.dto.response.SymbolResponse;
@@ -70,7 +72,7 @@ public TradeFeeResponse getKucoinBaseFee() throws IOException {
return classifyingExceptions(
() ->
decorateApiCall(
- () -> tradingFeeAPI.getBaseFee(apiKey, digest, nonceFactory, passphrase))
+ () -> tradingFeeAPI.getBaseFee(apiKey, digest, nonceFactory, passphrase))
.withRetry(retry("baseFee"))
.withRateLimiter(rateLimiter(PUBLIC_REST_ENDPOINT_RATE_LIMITER))
.call());
@@ -81,14 +83,18 @@ public List getKucoinTradeFee(String symbols) throws IOExcepti
return classifyingExceptions(
() ->
decorateApiCall(
- () ->
- tradingFeeAPI.getTradeFee(
- apiKey, digest, nonceFactory, passphrase, symbols))
+ () ->
+ tradingFeeAPI.getTradeFee(
+ apiKey, digest, nonceFactory, passphrase, symbols))
.withRetry(retry("tradeFee"))
.withRateLimiter(rateLimiter(PRIVATE_REST_ENDPOINT_RATE_LIMITER))
.call());
}
+ /**
+ * @deprecated use {@link #getKucoinSymbolsV2()}
+ */
+ @Deprecated
public List getKucoinSymbols() throws IOException {
return classifyingExceptions(
() ->
@@ -98,6 +104,15 @@ public List getKucoinSymbols() throws IOException {
.call());
}
+ public List getKucoinSymbolsV2() throws IOException {
+ return classifyingExceptions(
+ () ->
+ decorateApiCall(symbolApi::getSymbolsV2)
+ .withRetry(retry("symbols"))
+ .withRateLimiter(rateLimiter(PUBLIC_REST_ENDPOINT_RATE_LIMITER))
+ .call());
+ }
+
public List getKucoinCurrencies() throws IOException {
return classifyingExceptions(
() ->
@@ -107,13 +122,22 @@ public List getKucoinCurrencies() throws IOException {
.call());
}
+ public CurrencyResponseV2 getKucoinCurrencies(Currency currency) throws IOException {
+ return classifyingExceptions(
+ () ->
+ decorateApiCall(() -> symbolApi.getCurrencies(currency.getCurrencyCode()))
+ .withRetry(retry("currencies"))
+ .withRateLimiter(rateLimiter(PUBLIC_REST_ENDPOINT_RATE_LIMITER))
+ .call());
+ }
+
public OrderBookResponse getKucoinOrderBookPartial(CurrencyPair pair) throws IOException {
return classifyingExceptions(
() ->
decorateApiCall(
- () ->
- orderBookApi.getPartOrderBookAggregated(
- KucoinAdapters.adaptCurrencyPair(pair)))
+ () ->
+ orderBookApi.getPartOrderBookAggregated(
+ KucoinAdapters.adaptCurrencyPair(pair)))
.withRetry(retry("partialOrderBook"))
.withRateLimiter(rateLimiter(PUBLIC_REST_ENDPOINT_RATE_LIMITER))
.call());
@@ -123,9 +147,9 @@ public OrderBookResponse getKucoinOrderBookPartialShallow(CurrencyPair pair) thr
return classifyingExceptions(
() ->
decorateApiCall(
- () ->
- orderBookApi.getPartOrderBookShallowAggregated(
- KucoinAdapters.adaptCurrencyPair(pair)))
+ () ->
+ orderBookApi.getPartOrderBookShallowAggregated(
+ KucoinAdapters.adaptCurrencyPair(pair)))
.withRetry(retry("partialShallowOrderBook"))
.withRateLimiter(rateLimiter(PUBLIC_REST_ENDPOINT_RATE_LIMITER))
.call());
@@ -135,13 +159,13 @@ public OrderBookResponse getKucoinOrderBookFull(CurrencyPair pair) throws IOExce
return classifyingExceptions(
() ->
decorateApiCall(
- () ->
- orderBookApi.getFullOrderBookAggregated(
- KucoinAdapters.adaptCurrencyPair(pair),
- apiKey,
- digest,
- nonceFactory,
- passphrase))
+ () ->
+ orderBookApi.getFullOrderBookAggregated(
+ KucoinAdapters.adaptCurrencyPair(pair),
+ apiKey,
+ digest,
+ nonceFactory,
+ passphrase))
.withRetry(retry("fullOrderBook"))
.withRateLimiter(rateLimiter(PRIVATE_REST_ENDPOINT_RATE_LIMITER))
.call());
@@ -151,7 +175,7 @@ public List getKucoinTrades(CurrencyPair pair) throws IOEx
return classifyingExceptions(
() ->
decorateApiCall(
- () -> historyApi.getTradeHistories(KucoinAdapters.adaptCurrencyPair(pair)))
+ () -> historyApi.getTradeHistories(KucoinAdapters.adaptCurrencyPair(pair)))
.withRetry(retry("tradeHistories"))
.withRateLimiter(rateLimiter(PUBLIC_REST_ENDPOINT_RATE_LIMITER))
.call());
@@ -163,12 +187,12 @@ public List getKucoinKlines(
classifyingExceptions(
() ->
decorateApiCall(
- () ->
- historyApi.getKlines(
- KucoinAdapters.adaptCurrencyPair(pair),
- startTime,
- endTime,
- type.code()))
+ () ->
+ historyApi.getKlines(
+ KucoinAdapters.adaptCurrencyPair(pair),
+ startTime,
+ endTime,
+ type.code()))
.withRetry(retry("klines"))
.withRateLimiter(rateLimiter(PUBLIC_REST_ENDPOINT_RATE_LIMITER))
.call());
diff --git a/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/dto/response/CurrencyResponseV2.java b/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/dto/response/CurrencyResponseV2.java
new file mode 100644
index 00000000000..77f2259d45f
--- /dev/null
+++ b/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/dto/response/CurrencyResponseV2.java
@@ -0,0 +1,70 @@
+package org.knowm.xchange.kucoin.dto.response;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.math.BigDecimal;
+import java.util.List;
+import lombok.Data;
+import lombok.extern.jackson.Jacksonized;
+
+@Data
+@Jacksonized
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CurrencyResponseV2 {
+
+ @JsonProperty("currency")
+ private String currency;
+
+ @JsonProperty("name")
+ private String name;
+
+ @JsonProperty("fullName")
+ private String fullName;
+
+ @JsonProperty("precision")
+ private BigDecimal precision;
+
+ @JsonProperty("chains")
+ private List chains;
+
+ @JsonProperty("withdrawalMinSize")
+ private String withdrawalMinSize;
+
+ @JsonProperty("withdrawalMinFee")
+ private String withdrawalMinFee;
+
+ @JsonProperty("isMarginEnabled")
+ private Boolean isMarginEnabled;
+
+ @JsonProperty("isDebitEnabled")
+ private Boolean isDebitEnabled;
+
+ @Data
+ public static class Chain {
+
+ @JsonProperty("chainName")
+ private String chainName;
+
+ @JsonProperty("chain")
+ private String chain;
+
+ @JsonProperty("withdrawalMinSize")
+ private BigDecimal withdrawalMinSize;
+
+ @JsonProperty("withdrawalMinFee")
+ private BigDecimal withdrawalMinFee;
+
+ @JsonProperty("isWithdrawEnabled")
+ private Boolean isWithdrawEnabled;
+
+ @JsonProperty("isDepositEnabled")
+ private Boolean isDepositEnabled;
+
+ @JsonProperty("confirms")
+ private Long confirms;
+
+ @JsonProperty("contractAddress")
+ private String contractAddress;
+
+ }
+}
diff --git a/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/service/SymbolAPI.java b/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/service/SymbolAPI.java
index 8343991b5bb..1cfa56f1166 100644
--- a/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/service/SymbolAPI.java
+++ b/xchange-kucoin/src/main/java/org/knowm/xchange/kucoin/service/SymbolAPI.java
@@ -7,18 +7,20 @@
import java.util.Map;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.knowm.xchange.kucoin.dto.response.AllTickersResponse;
import org.knowm.xchange.kucoin.dto.response.CurrenciesResponse;
+import org.knowm.xchange.kucoin.dto.response.CurrencyResponseV2;
import org.knowm.xchange.kucoin.dto.response.KucoinResponse;
import org.knowm.xchange.kucoin.dto.response.SymbolResponse;
import org.knowm.xchange.kucoin.dto.response.SymbolTickResponse;
import org.knowm.xchange.kucoin.dto.response.TickerResponse;
/** Based on code by chenshiwei on 2019/1/11. */
-@Path("api/v1")
+@Path("api")
@Produces(MediaType.APPLICATION_JSON)
public interface SymbolAPI {
@@ -26,27 +28,47 @@ public interface SymbolAPI {
* Get a list of available currency pairs for trading.
*
* @return The available symbols.
+ * @deprecated use {@link #getSymbolsV2()}
*/
@GET
- @Path("/symbols")
+ @Path("/v1/symbols")
+ @Deprecated
KucoinResponse> getSymbols() throws IOException;
+ /**
+ * Get a list of available currency pairs for trading.
+ *
+ * @return The available symbols.
+ */
+ @GET
+ @Path("/v2/symbols")
+ KucoinResponse> getSymbolsV2() throws IOException;
+
/**
* Get a list of available currencies for trading.
*
* @return The available currencies.
*/
@GET
- @Path("/currencies")
+ @Path("/v1/currencies")
KucoinResponse> getCurrencies() throws IOException;
+ /**
+ * Get currency detail.
+ *
+ * @return The available currencies.
+ */
+ @GET
+ @Path("/v2/currencies/{currency}")
+ KucoinResponse getCurrencies(@PathParam("currency") String currency) throws IOException;
+
/**
* Get the fiat price of the currencies for the available trading pairs.
*
* @return USD fiat price of the currencies.
*/
@GET
- @Path("/prices")
+ @Path("/v1/prices")
KucoinResponse