diff --git a/xchange-core/src/main/java/org/knowm/xchange/service/trade/params/orders/PlaceOrderKnownParams.java b/xchange-core/src/main/java/org/knowm/xchange/service/trade/params/orders/PlaceOrderKnownParams.java new file mode 100644 index 00000000000..c5fa336bdf1 --- /dev/null +++ b/xchange-core/src/main/java/org/knowm/xchange/service/trade/params/orders/PlaceOrderKnownParams.java @@ -0,0 +1,5 @@ +package org.knowm.xchange.service.trade.params.orders; + +public class PlaceOrderKnownParams { + public static final String CLIENT_ORDER_ID = "clientOrderId"; +} diff --git a/xchange-core/src/main/java/org/knowm/xchange/service/trade/params/orders/PlaceOrderParams.java b/xchange-core/src/main/java/org/knowm/xchange/service/trade/params/orders/PlaceOrderParams.java new file mode 100644 index 00000000000..3e6d8a2d398 --- /dev/null +++ b/xchange-core/src/main/java/org/knowm/xchange/service/trade/params/orders/PlaceOrderParams.java @@ -0,0 +1,5 @@ +package org.knowm.xchange.service.trade.params.orders; + +public interface PlaceOrderParams { + T getOrderParam(String param, Class type); +} diff --git a/xchange-kraken/src/main/java/org/knowm/xchange/kraken/KrakenAuthenticated.java b/xchange-kraken/src/main/java/org/knowm/xchange/kraken/KrakenAuthenticated.java index d11c0c1b445..f2337b0adf4 100644 --- a/xchange-kraken/src/main/java/org/knowm/xchange/kraken/KrakenAuthenticated.java +++ b/xchange-kraken/src/main/java/org/knowm/xchange/kraken/KrakenAuthenticated.java @@ -111,6 +111,7 @@ KrakenOrderResult addOrder( @FormParam("userref") String userRefId, @FormParam("close") Map closeOrder, @FormParam("timeinforce") String timeInForce, + @FormParam("cl_ord_id") String clientOrderId, @HeaderParam("API-Key") String apiKey, @HeaderParam("API-Sign") ParamsDigest signer, @FormParam("nonce") SynchronizedValueFactory nonce) @@ -135,6 +136,7 @@ KrakenOrderResult addOrderValidateOnly( @FormParam("validate") boolean validateOnly, @FormParam("close") Map closeOrder, @FormParam("timeinforce") String timeInForce, + @FormParam("cl_ord_id") String clientOrderId, @HeaderParam("API-Key") String apiKey, @HeaderParam("API-Sign") ParamsDigest signer, @FormParam("nonce") SynchronizedValueFactory nonce) diff --git a/xchange-kraken/src/main/java/org/knowm/xchange/kraken/dto/trade/KrakenStandardOrder.java b/xchange-kraken/src/main/java/org/knowm/xchange/kraken/dto/trade/KrakenStandardOrder.java index 2ab827292f3..8fcc6c96c42 100644 --- a/xchange-kraken/src/main/java/org/knowm/xchange/kraken/dto/trade/KrakenStandardOrder.java +++ b/xchange-kraken/src/main/java/org/knowm/xchange/kraken/dto/trade/KrakenStandardOrder.java @@ -1,9 +1,12 @@ package org.knowm.xchange.kraken.dto.trade; -import java.math.*; -import java.util.*; -import org.knowm.xchange.currency.*; -import org.knowm.xchange.dto.Order.*; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.knowm.xchange.currency.CurrencyPair; +import org.knowm.xchange.dto.Order.IOrderFlags; public class KrakenStandardOrder { @@ -22,6 +25,7 @@ public class KrakenStandardOrder { private final boolean validateOnly; private final Map closeOrder; private final TimeInForce timeInForce; + private final String clientOrderId; private KrakenStandardOrder( CurrencyPair currencyPair, @@ -38,7 +42,8 @@ private KrakenStandardOrder( String userRefId, boolean validateOnly, Map closeOrder, - TimeInForce timeInForce) { + TimeInForce timeInForce, + String clientOrderId) { this.currencyPair = currencyPair; this.type = type; @@ -55,6 +60,7 @@ private KrakenStandardOrder( this.validateOnly = validateOnly; this.closeOrder = closeOrder; this.timeInForce = timeInForce; + this.clientOrderId = clientOrderId; } public static KrakenOrderBuilder getMarketOrderBuilder( @@ -232,6 +238,10 @@ public String getUserRefId() { return userRefId; } + public String getClientOrderId() { + return clientOrderId; + } + public boolean isValidateOnly() { return validateOnly; @@ -274,6 +284,8 @@ public String toString() { + expireTime + ", userRefId=" + userRefId + + ", clientOrderId=" + + clientOrderId + ", validateOnly=" + validateOnly + ", closeOrder=" @@ -297,6 +309,7 @@ public static class KrakenOrderBuilder { private String startTime; private String expireTime; private String userRefId; + private String clientOrderId; private boolean validateOnly; private Map closeOrder; private TimeInForce timeInForce; @@ -366,6 +379,12 @@ public KrakenOrderBuilder withUserRefId(String userRefId) { return this; } + public KrakenOrderBuilder withClientOrderId(String clientOrderId) { + + this.clientOrderId = clientOrderId; + return this; + } + public KrakenOrderBuilder withValidateOnly(boolean validateOnly) { this.validateOnly = validateOnly; @@ -404,7 +423,8 @@ public KrakenStandardOrder buildOrder() { userRefId, validateOnly, closeOrder == null ? new HashMap<>() : closeOrder, - timeInForce); + timeInForce, + clientOrderId); } @Override diff --git a/xchange-kraken/src/main/java/org/knowm/xchange/kraken/service/KrakenTradeServiceRaw.java b/xchange-kraken/src/main/java/org/knowm/xchange/kraken/service/KrakenTradeServiceRaw.java index b6cf8ca3610..def129ee696 100644 --- a/xchange-kraken/src/main/java/org/knowm/xchange/kraken/service/KrakenTradeServiceRaw.java +++ b/xchange-kraken/src/main/java/org/knowm/xchange/kraken/service/KrakenTradeServiceRaw.java @@ -1,17 +1,26 @@ package org.knowm.xchange.kraken.service; +import static org.knowm.xchange.service.trade.params.orders.PlaceOrderKnownParams.CLIENT_ORDER_ID; + import java.io.IOException; -import java.util.*; +import java.util.Map; +import java.util.Optional; import org.knowm.xchange.Exchange; import org.knowm.xchange.currency.CurrencyPair; -import org.knowm.xchange.dto.*; +import org.knowm.xchange.dto.Order; import org.knowm.xchange.dto.trade.LimitOrder; import org.knowm.xchange.dto.trade.MarketOrder; import org.knowm.xchange.kraken.KrakenUtils; import org.knowm.xchange.kraken.dto.account.KrakenTradeVolume; import org.knowm.xchange.kraken.dto.account.results.KrakenTradeVolumeResult; -import org.knowm.xchange.kraken.dto.trade.*; +import org.knowm.xchange.kraken.dto.trade.KrakenOpenPosition; +import org.knowm.xchange.kraken.dto.trade.KrakenOrder; +import org.knowm.xchange.kraken.dto.trade.KrakenOrderResponse; +import org.knowm.xchange.kraken.dto.trade.KrakenStandardOrder; import org.knowm.xchange.kraken.dto.trade.KrakenStandardOrder.KrakenOrderBuilder; +import org.knowm.xchange.kraken.dto.trade.KrakenTrade; +import org.knowm.xchange.kraken.dto.trade.KrakenType; +import org.knowm.xchange.kraken.dto.trade.TimeInForce; import org.knowm.xchange.kraken.dto.trade.results.KrakenCancelOrderResult; import org.knowm.xchange.kraken.dto.trade.results.KrakenCancelOrderResult.KrakenCancelOrderResponse; import org.knowm.xchange.kraken.dto.trade.results.KrakenClosedOrdersResult; @@ -22,6 +31,7 @@ import org.knowm.xchange.kraken.dto.trade.results.KrakenQueryTradeResult; import org.knowm.xchange.kraken.dto.trade.results.KrakenTradeHistoryResult; import org.knowm.xchange.kraken.dto.trade.results.KrakenTradeHistoryResult.KrakenTradeHistory; +import org.knowm.xchange.service.trade.params.orders.PlaceOrderParams; public class KrakenTradeServiceRaw extends KrakenBaseService { @@ -188,6 +198,8 @@ public KrakenOrderResponse placeKrakenMarketOrder(MarketOrder marketOrder) throw .withOrderFlags(marketOrder.getOrderFlags()) .withLeverage(marketOrder.getLeverage()); + getClientOrderId(marketOrder).ifPresent(orderBuilder::withClientOrderId); + return placeKrakenOrder(orderBuilder.buildOrder()); } @@ -200,6 +212,8 @@ public KrakenOrderResponse placeKrakenSettlePositionOrder(MarketOrder marketOrde marketOrder.getCurrencyPair(), type, marketOrder.getOriginalAmount()) .withUserRefId(marketOrder.getUserReference()); + getClientOrderId(marketOrder).ifPresent(orderBuilder::withClientOrderId); + return placeKrakenOrder(orderBuilder.buildOrder()); } @@ -216,9 +230,19 @@ public KrakenOrderResponse placeKrakenLimitOrder(LimitOrder limitOrder) throws I .withLeverage(limitOrder.getLeverage()) .withTimeInForce(timeInForceFromOrder(limitOrder).orElse(null)); + getClientOrderId(limitOrder).ifPresent(krakenOrderBuilder::withClientOrderId); + return placeKrakenOrder(krakenOrderBuilder.buildOrder()); } + private Optional getClientOrderId(Order order) { + if (order instanceof PlaceOrderParams) { + return Optional.ofNullable( + ((PlaceOrderParams) order).getOrderParam(CLIENT_ORDER_ID, String.class)); + } + return Optional.empty(); + } + private Optional timeInForceFromOrder(Order order) { return order.getOrderFlags().stream() .filter(flag -> flag instanceof TimeInForce) @@ -247,6 +271,7 @@ public KrakenOrderResponse placeKrakenOrder(KrakenStandardOrder krakenStandardOr krakenStandardOrder.getUserRefId(), krakenStandardOrder.getCloseOrder(), nullSafeToString(krakenStandardOrder.getTimeInForce()), + krakenStandardOrder.getClientOrderId(), exchange.getExchangeSpecification().getApiKey(), signatureCreator, exchange.getNonceFactory()); @@ -268,6 +293,7 @@ public KrakenOrderResponse placeKrakenOrder(KrakenStandardOrder krakenStandardOr true, krakenStandardOrder.getCloseOrder(), nullSafeToString(krakenStandardOrder.getTimeInForce()), + krakenStandardOrder.getClientOrderId(), exchange.getExchangeSpecification().getApiKey(), signatureCreator, exchange.getNonceFactory());