Skip to content

Commit

Permalink
Merge pull request #12 from knowm/develop
Browse files Browse the repository at this point in the history
Pull request
  • Loading branch information
trixprod authored Mar 22, 2019
2 parents 84ab7c1 + e0da42b commit 12bcfde
Show file tree
Hide file tree
Showing 70 changed files with 4,256 additions and 109 deletions.
3 changes: 2 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<version.qos.logback>1.2.3</version.qos.logback>
<version.reflections>0.9.11</version.reflections>
<version.slf4j>1.8.0-beta4</version.slf4j>
<version.crypto>4.1.1</version.crypto>
<version.crypto>4.2.0</version.crypto>
<version.java-jwt>3.8.0</version.java-jwt>

<skipIntegrationTests>true</skipIntegrationTests>
Expand Down Expand Up @@ -180,6 +180,7 @@
<module>xchange-quadrigacx</module>
<module>xchange-quoine</module>
<module>xchange-ripple</module>
<module>xchange-simulated</module>
<module>xchange-therock</module>
<module>xchange-truefx</module>
<module>xchange-upbit</module>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.knowm.xchange.exceptions.ExchangeException;
import org.knowm.xchange.exceptions.ExchangeSecurityException;
import org.knowm.xchange.exceptions.ExchangeUnavailableException;
import org.knowm.xchange.exceptions.FundsExceededException;
import org.knowm.xchange.exceptions.NonceException;
import org.knowm.xchange.exceptions.RateLimitExceededException;

Expand All @@ -24,6 +25,14 @@ public static ExchangeException adapt(BinanceException e) {
return new ExchangeSecurityException(message, e);
case -1003:
return new RateLimitExceededException(message, e);
case -1010:
case -2010:
case -2011:
if (e.getMessage().contains("insufficient balance")) {
return new FundsExceededException(e.getMessage(), e);
} else {
return new ExchangeException(message, e);
}
case -1016:
return new ExchangeUnavailableException(message, e);
case -1021:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,7 @@ public static LimitOrder adaptLimitOrder(BitmexOrder bitmexOrder, String id) {
}

public static OrderType adaptOrderType(BitmexSide bitmexType) {

return bitmexType.equals(BitmexSide.BUY) ? OrderType.BID : OrderType.ASK;
return bitmexType == null ? null : bitmexType.equals(BitmexSide.BUY) ? OrderType.BID : OrderType.ASK;
}

public static String adaptOrderId(BitmexOrderResponse orderResponse) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package org.knowm.xchange.examples.kucoin.account;

import com.kucoin.sdk.rest.response.AccountBalancesResponse;
import java.io.IOException;
import java.util.List;

import org.knowm.xchange.Exchange;
import org.knowm.xchange.dto.account.AccountInfo;
import org.knowm.xchange.examples.kucoin.KucoinExamplesUtils;
import org.knowm.xchange.kucoin.KucoinAccountServiceRaw;
import org.knowm.xchange.kucoin.dto.response.AccountBalancesResponse;
import org.knowm.xchange.service.account.AccountService;

public class KucoinAccountDemo {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
package org.knowm.xchange.examples.kucoin.marketdata;

import com.kucoin.sdk.rest.response.OrderBookResponse;
import com.kucoin.sdk.rest.response.SymbolResponse;
import com.kucoin.sdk.rest.response.SymbolTickResponse;
import com.kucoin.sdk.rest.response.TickerResponse;
import com.kucoin.sdk.rest.response.TradeHistoryResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
Expand All @@ -16,6 +11,11 @@
import org.knowm.xchange.dto.marketdata.Trades;
import org.knowm.xchange.kucoin.KucoinExchange;
import org.knowm.xchange.kucoin.KucoinMarketDataService;
import org.knowm.xchange.kucoin.dto.response.OrderBookResponse;
import org.knowm.xchange.kucoin.dto.response.SymbolResponse;
import org.knowm.xchange.kucoin.dto.response.SymbolTickResponse;
import org.knowm.xchange.kucoin.dto.response.TickerResponse;
import org.knowm.xchange.kucoin.dto.response.TradeHistoryResponse;
import org.knowm.xchange.service.marketdata.MarketDataService;

public class KucoinMarketDataDemo {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package org.knowm.xchange.examples.kucoin.trade;

import com.kucoin.sdk.exception.KucoinApiException;
import com.kucoin.sdk.rest.request.OrderCreateApiRequest;
import com.kucoin.sdk.rest.response.OrderCancelResponse;
import com.kucoin.sdk.rest.response.OrderCreateResponse;
import java.math.BigDecimal;
import java.util.Optional;
import java.util.UUID;
Expand All @@ -15,7 +11,11 @@
import org.knowm.xchange.dto.trade.OpenOrders;
import org.knowm.xchange.dto.trade.StopOrder;
import org.knowm.xchange.examples.kucoin.KucoinExamplesUtils;
import org.knowm.xchange.exceptions.ExchangeException;
import org.knowm.xchange.kucoin.KucoinTradeServiceRaw;
import org.knowm.xchange.kucoin.dto.request.OrderCreateApiRequest;
import org.knowm.xchange.kucoin.dto.response.OrderCancelResponse;
import org.knowm.xchange.kucoin.dto.response.OrderCreateResponse;
import org.knowm.xchange.service.trade.TradeService;
import org.knowm.xchange.service.trade.params.TradeHistoryParamCurrencyPair;
import org.knowm.xchange.service.trade.params.orders.OpenOrdersParamCurrencyPair;
Expand Down Expand Up @@ -96,7 +96,7 @@ private static void genericLimitOrder(TradeService tradeService) throws Exceptio
if (tradeService.cancelOrder("NONEXISTENT")) {
throw new AssertionError("Shouldn't be able to cancel a non-existent order");
}
} catch (KucoinApiException e) {
} catch (ExchangeException e) {
// Fine
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.knowm.xchange.examples.simulated;

import java.io.IOException;

public class SimulatedExchangeDemo {

public static void main(String[] args) throws IOException {

System.out.println("See SimulatedExchangeExample in the xchange-simulated module's test tree.");

}

}
10 changes: 0 additions & 10 deletions xchange-kraken/src/main/resources/kraken.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,6 @@
"min_amount": 0.030,
"trading_fee": 0.0026
},
"ICN/BTC": {
"price_scale": 6,
"min_amount": 2.000,
"trading_fee": 0.0026
},
"ICN/ETH": {
"price_scale": 6,
"min_amount": 2.000,
"trading_fee": 0.0026
},
"LTC/EUR": {
"price_scale": 2,
"min_amount": 0.100,
Expand Down
13 changes: 8 additions & 5 deletions xchange-kucoin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@
<artifactId>xchange-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.gruelbox</groupId>
<artifactId>kucoin-java-sdk</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import static java.util.stream.Collectors.toList;

import com.kucoin.sdk.rest.response.AccountBalancesResponse;
import java.io.IOException;
import java.util.List;
import org.knowm.xchange.dto.account.AccountInfo;
import org.knowm.xchange.dto.account.Wallet;
import org.knowm.xchange.kucoin.dto.response.AccountBalancesResponse;
import org.knowm.xchange.service.account.AccountService;

public class KucoinAccountService extends KucoinAccountServiceRaw implements AccountService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import static org.knowm.xchange.kucoin.KucoinExceptionClassifier.classifyingExceptions;

import com.kucoin.sdk.rest.response.AccountBalancesResponse;
import java.io.IOException;
import java.util.List;
import org.knowm.xchange.kucoin.dto.response.AccountBalancesResponse;

public class KucoinAccountServiceRaw extends KucoinBaseService {

Expand All @@ -13,6 +13,8 @@ protected KucoinAccountServiceRaw(KucoinExchange exchange) {
}

public List<AccountBalancesResponse> getKucoinAccounts() throws IOException {
return classifyingExceptions(() -> kucoinRestClient.accountAPI().listAccounts(null, null));
checkAuthenticated();
return classifyingExceptions(
() -> accountApi.getAccountList(apiKey, digest, nonceFactory, passphrase, null, null));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@

import com.google.common.base.MoreObjects;
import com.google.common.collect.Ordering;
import com.kucoin.sdk.rest.request.OrderCreateApiRequest;
import com.kucoin.sdk.rest.response.AccountBalancesResponse;
import com.kucoin.sdk.rest.response.OrderBookResponse;
import com.kucoin.sdk.rest.response.OrderResponse;
import com.kucoin.sdk.rest.response.SymbolResponse;
import com.kucoin.sdk.rest.response.SymbolTickResponse;
import com.kucoin.sdk.rest.response.TradeHistoryResponse;
import com.kucoin.sdk.rest.response.TradeResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
Expand Down Expand Up @@ -48,6 +40,14 @@
import org.knowm.xchange.dto.trade.UserTrade;
import org.knowm.xchange.exceptions.ExchangeException;
import org.knowm.xchange.kucoin.KucoinTradeService.KucoinOrderFlags;
import org.knowm.xchange.kucoin.dto.request.OrderCreateApiRequest;
import org.knowm.xchange.kucoin.dto.response.AccountBalancesResponse;
import org.knowm.xchange.kucoin.dto.response.OrderBookResponse;
import org.knowm.xchange.kucoin.dto.response.OrderResponse;
import org.knowm.xchange.kucoin.dto.response.SymbolResponse;
import org.knowm.xchange.kucoin.dto.response.SymbolTickResponse;
import org.knowm.xchange.kucoin.dto.response.TradeHistoryResponse;
import org.knowm.xchange.kucoin.dto.response.TradeResponse;

public class KucoinAdapters {

Expand Down Expand Up @@ -244,11 +244,12 @@ public static UserTrade adaptUserTrade(TradeResponse trade) {
}

public static OrderCreateApiRequest adaptLimitOrder(LimitOrder limitOrder) {
return adaptOrder(limitOrder).type("limit").price(limitOrder.getLimitPrice()).build();
return ((OrderCreateApiRequest.OrderCreateApiRequestBuilder)adaptOrder(limitOrder))
.type("limit").price(limitOrder.getLimitPrice()).build();
}

public static OrderCreateApiRequest adaptStopOrder(StopOrder stopOrder) {
return adaptOrder(stopOrder)
return ((OrderCreateApiRequest.OrderCreateApiRequestBuilder)adaptOrder(stopOrder))
.type(stopOrder.getLimitPrice() == null ? "market" : "limit")
.price(stopOrder.getLimitPrice())
.stop(stopOrder.getType().equals(ASK) ? "loss" : "entry")
Expand All @@ -257,10 +258,15 @@ public static OrderCreateApiRequest adaptStopOrder(StopOrder stopOrder) {
}

public static OrderCreateApiRequest adaptMarketOrder(MarketOrder marketOrder) {
return adaptOrder(marketOrder).type("market").build();
return ((OrderCreateApiRequest.OrderCreateApiRequestBuilder)adaptOrder(marketOrder))
.type("market").build();
}

public static OrderCreateApiRequest.OrderCreateApiRequestBuilder adaptOrder(Order order) {
/**
* Returns {@code Object} instead of the Lombok builder in order to avoid
* a Lombok limitation with Javadoc.
*/
private static Object adaptOrder(Order order) {
OrderCreateApiRequest.OrderCreateApiRequestBuilder request = OrderCreateApiRequest.builder();
boolean hasClientId = false;
for (IOrderFlags flag : order.getOrderFlags()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,58 @@
package org.knowm.xchange.kucoin;

import com.kucoin.sdk.KucoinClientBuilder;
import com.kucoin.sdk.KucoinRestClient;
import org.apache.commons.lang3.StringUtils;
import org.knowm.xchange.ExchangeSpecification;
import com.google.common.base.Strings;
import org.knowm.xchange.kucoin.service.AccountAPI;
import org.knowm.xchange.kucoin.service.FillAPI;
import org.knowm.xchange.kucoin.service.HistoryAPI;
import org.knowm.xchange.kucoin.service.KucoinApiException;
import org.knowm.xchange.kucoin.service.KucoinDigest;
import org.knowm.xchange.kucoin.service.OrderAPI;
import org.knowm.xchange.kucoin.service.OrderBookAPI;
import org.knowm.xchange.kucoin.service.SymbolAPI;
import org.knowm.xchange.service.BaseExchangeService;
import org.knowm.xchange.service.BaseService;
import si.mazi.rescu.RestProxyFactory;
import si.mazi.rescu.SynchronizedValueFactory;

public class KucoinBaseService extends BaseExchangeService<KucoinExchange> implements BaseService {

protected final KucoinRestClient kucoinRestClient;
protected final SymbolAPI symbolApi;
protected final OrderBookAPI orderBookApi;
protected final HistoryAPI historyApi;
protected final AccountAPI accountApi;
protected final OrderAPI orderApi;
protected final FillAPI fillApi;

protected KucoinDigest digest;
protected String apiKey;
protected String passphrase;
protected SynchronizedValueFactory<Long> nonceFactory;

protected KucoinBaseService(KucoinExchange exchange) {
super(exchange);
ExchangeSpecification spec = exchange.getExchangeSpecification();
KucoinClientBuilder builder = new KucoinClientBuilder().withBaseUrl(spec.getSslUri());
if (StringUtils.isNotEmpty(spec.getApiKey())) {
builder.withApiKey(
spec.getApiKey(),
spec.getSecretKey(),
(String)
exchange.getExchangeSpecification().getExchangeSpecificParametersItem("passphrase"));
}
kucoinRestClient = builder.buildRestClient();
this.symbolApi = service(exchange, SymbolAPI.class);
this.orderBookApi = service(exchange, OrderBookAPI.class);
this.historyApi = service(exchange, HistoryAPI.class);
this.accountApi = service(exchange, AccountAPI.class);
this.orderApi = service(exchange, OrderAPI.class);
this.fillApi = service(exchange, FillAPI.class);

this.digest = KucoinDigest.createInstance(exchange.getExchangeSpecification().getSecretKey());
this.apiKey = exchange.getExchangeSpecification().getApiKey();
this.passphrase =
(String)
exchange.getExchangeSpecification().getExchangeSpecificParametersItem("passphrase");
this.nonceFactory = exchange.getNonceFactory();
}

private <T> T service(KucoinExchange exchange, Class<T> clazz) {
return RestProxyFactory.createProxy(
clazz, exchange.getExchangeSpecification().getSslUri(), getClientConfig());
}

protected void checkAuthenticated() {
if (Strings.isNullOrEmpty(this.apiKey)) throw new KucoinApiException("Missing API key");
if (this.digest == null) throw new KucoinApiException("Missing secret key");
if (Strings.isNullOrEmpty(this.passphrase)) throw new KucoinApiException("Missing passphrase");
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
package org.knowm.xchange.kucoin;

import com.kucoin.sdk.exception.KucoinApiException;
import java.io.IOException;
import org.knowm.xchange.exceptions.ExchangeException;
import org.knowm.xchange.exceptions.ExchangeSecurityException;
import org.knowm.xchange.exceptions.ExchangeUnavailableException;
import org.knowm.xchange.exceptions.NonceException;
import org.knowm.xchange.kucoin.dto.response.KucoinResponse;
import org.knowm.xchange.kucoin.service.KucoinApiException;

public final class KucoinExceptionClassifier {

KucoinExceptionClassifier() {}

public static <T> T classifyingExceptions(IOExceptionThrowingSupplier<T> apiCall)
public static <T> T classifyingExceptions(IOExceptionThrowingSupplier<KucoinResponse<T>> apiCall)
throws IOException {
try {
T result = apiCall.get();
if (result == null) {
throw new ExchangeException("Empty response from Kucoin. Check logs.");
}
return result;
} catch (KucoinApiException e) {
throw classify(e);
KucoinResponse<T> response = apiCall.get();
if (response.isSuccessful()) {
return response.getData();
} else {
throw classify(new KucoinApiException(response.getCode(), response.getMessage()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
import org.knowm.xchange.Exchange;
import org.knowm.xchange.ExchangeSpecification;
import org.knowm.xchange.exceptions.ExchangeException;
import org.knowm.xchange.utils.nonce.CurrentTimeNonceFactory;
import si.mazi.rescu.SynchronizedValueFactory;

public class KucoinExchange extends BaseExchange implements Exchange {

private final SynchronizedValueFactory<Long> nonceFactory = new CurrentTimeNonceFactory();

/**
* Use with {@link ExchangeSpecification#getExchangeSpecificParametersItem(String)} to specify
* that connection should be made to the Kucoin sandbox instead of the live API.
Expand Down Expand Up @@ -62,7 +65,7 @@ public ExchangeSpecification getDefaultExchangeSpecification() {

@Override
public SynchronizedValueFactory<Long> getNonceFactory() {
throw new UnsupportedOperationException("Kucoin does not use a nonce factory.");
return nonceFactory;
}

@Override
Expand Down
Loading

0 comments on commit 12bcfde

Please sign in to comment.