From b69e65d1ac38068ac552cf0275df9036cf652655 Mon Sep 17 00:00:00 2001 From: "Isaac.Tang" Date: Thu, 17 Oct 2024 11:35:44 +0800 Subject: [PATCH 1/3] Update The API for August --- pom.xml | 2 +- .../core/rest/adapter/OrderAPIAdapter.java | 6 +++ .../core/rest/adapter/PositionAPIAdapter.java | 13 +++--- .../core/rest/adapter/TickerAPIAdaptor.java | 6 +++ .../core/rest/interfaces/OrderAPI.java | 13 ++++++ .../core/rest/interfaces/PositionAPI.java | 12 +++-- .../core/rest/interfaces/TickerAPI.java | 9 ++++ .../interfaces/retrofit/OrderAPIRetrofit.java | 37 ++++++++-------- .../retrofit/PositionAPIRetrofit.java | 6 +++ .../retrofit/TickerAPIRetrofit.java | 5 +++ .../rest/request/OrderCreateApiRequest.java | 2 +- .../rest/request/StOrderCreateRequest.java | 44 +++++++++++++++++++ .../rest/response/MaxOpenSizeRequest.java | 30 +++++++++++++ .../rest/response/MaxOpenSizeResponse.java | 30 +++++++++++++ .../rest/response/OrderCreateResponse.java | 2 + .../rest/response/StOrderCreateResponse.java | 21 +++++++++ .../com/kucoin/futures/core/BaseTest.java | 2 +- .../core/KucoinFuturesRestClientTest.java | 30 ++++++++++++- 18 files changed, 238 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/kucoin/futures/core/rest/request/StOrderCreateRequest.java create mode 100644 src/main/java/com/kucoin/futures/core/rest/response/MaxOpenSizeRequest.java create mode 100644 src/main/java/com/kucoin/futures/core/rest/response/MaxOpenSizeResponse.java create mode 100644 src/main/java/com/kucoin/futures/core/rest/response/StOrderCreateResponse.java diff --git a/pom.xml b/pom.xml index 3fffb85..c9e50db 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,7 @@ org.projectlombok lombok - 1.16.18 + 1.18.34 compile diff --git a/src/main/java/com/kucoin/futures/core/rest/adapter/OrderAPIAdapter.java b/src/main/java/com/kucoin/futures/core/rest/adapter/OrderAPIAdapter.java index c90f99f..f1072ec 100644 --- a/src/main/java/com/kucoin/futures/core/rest/adapter/OrderAPIAdapter.java +++ b/src/main/java/com/kucoin/futures/core/rest/adapter/OrderAPIAdapter.java @@ -9,6 +9,7 @@ import com.kucoin.futures.core.rest.request.OrderCreateApiRequest; import com.kucoin.futures.core.rest.impl.retrofit.AuthRetrofitAPIImpl; import com.kucoin.futures.core.rest.request.DuringPageRequest; +import com.kucoin.futures.core.rest.request.StOrderCreateRequest; import com.kucoin.futures.core.rest.response.*; import retrofit2.http.Query; @@ -40,6 +41,11 @@ public OrderCreateResponse createOrderTest(OrderCreateApiRequest opsRequest) thr return executeSync(getAPIImpl().createOrderTest(opsRequest)); } + @Override + public StOrderCreateResponse createStOrders(StOrderCreateRequest request) throws IOException { + return executeSync(getAPIImpl().createStOrders(request)); + } + @Override public OrderCancelResponse cancelOrder(String orderId) throws IOException { return executeSync(getAPIImpl().cancelOrder(orderId)); diff --git a/src/main/java/com/kucoin/futures/core/rest/adapter/PositionAPIAdapter.java b/src/main/java/com/kucoin/futures/core/rest/adapter/PositionAPIAdapter.java index a567bdc..3eda10a 100644 --- a/src/main/java/com/kucoin/futures/core/rest/adapter/PositionAPIAdapter.java +++ b/src/main/java/com/kucoin/futures/core/rest/adapter/PositionAPIAdapter.java @@ -3,17 +3,15 @@ */ package com.kucoin.futures.core.rest.adapter; +import com.kucoin.futures.core.rest.impl.retrofit.AuthRetrofitAPIImpl; import com.kucoin.futures.core.rest.interceptor.FuturesApiKey; import com.kucoin.futures.core.rest.interfaces.PositionAPI; +import com.kucoin.futures.core.rest.interfaces.retrofit.PositionAPIRetrofit; import com.kucoin.futures.core.rest.request.AddMarginManuallyRequest; import com.kucoin.futures.core.rest.request.HistoryPositionsRequest; import com.kucoin.futures.core.rest.request.UpdateAutoDepositMarginRequest; -import com.kucoin.futures.core.rest.impl.retrofit.AuthRetrofitAPIImpl; -import com.kucoin.futures.core.rest.interfaces.retrofit.PositionAPIRetrofit; import com.kucoin.futures.core.rest.request.WithdrawMarginRequest; -import com.kucoin.futures.core.rest.response.HistoryPositionResponse; -import com.kucoin.futures.core.rest.response.Pagination; -import com.kucoin.futures.core.rest.response.PositionResponse; +import com.kucoin.futures.core.rest.response.*; import java.io.IOException; import java.math.BigDecimal; @@ -40,6 +38,11 @@ public List getPositions() throws IOException { return super.executeSync(getAPIImpl().getPositions()); } + @Override + public MaxOpenSizeResponse getMaxOpenSize(MaxOpenSizeRequest request) throws IOException { + return super.executeSync(getAPIImpl().getMaxOpenSize(request.getSymbol(), request.getPrice(), request.getLeverage())); + } + @Override public Pagination getHistoryPositions(HistoryPositionsRequest request) throws IOException { return super.executeSync(getAPIImpl().getHistoryPositions(request.getSymbol(), diff --git a/src/main/java/com/kucoin/futures/core/rest/adapter/TickerAPIAdaptor.java b/src/main/java/com/kucoin/futures/core/rest/adapter/TickerAPIAdaptor.java index ce6ef21..4adfc34 100644 --- a/src/main/java/com/kucoin/futures/core/rest/adapter/TickerAPIAdaptor.java +++ b/src/main/java/com/kucoin/futures/core/rest/adapter/TickerAPIAdaptor.java @@ -9,6 +9,7 @@ import com.kucoin.futures.core.rest.response.TickerResponse; import java.io.IOException; +import java.util.List; /** * @author chenshiwei @@ -24,4 +25,9 @@ public TickerAPIAdaptor(String baseUrl) { public TickerResponse getTicker(String symbol) throws IOException { return super.executeSync(getAPIImpl().getTicker(symbol)); } + + @Override + public List getAllTickers() throws IOException { + return super.executeSync(getAPIImpl().getAllTickers()); + } } diff --git a/src/main/java/com/kucoin/futures/core/rest/interfaces/OrderAPI.java b/src/main/java/com/kucoin/futures/core/rest/interfaces/OrderAPI.java index a8cf62c..b54ac9f 100644 --- a/src/main/java/com/kucoin/futures/core/rest/interfaces/OrderAPI.java +++ b/src/main/java/com/kucoin/futures/core/rest/interfaces/OrderAPI.java @@ -5,6 +5,7 @@ import com.kucoin.futures.core.rest.request.DuringPageRequest; import com.kucoin.futures.core.rest.request.OrderCreateApiRequest; +import com.kucoin.futures.core.rest.request.StOrderCreateRequest; import com.kucoin.futures.core.rest.response.*; import java.io.IOException; @@ -53,6 +54,18 @@ public interface OrderAPI { */ OrderCreateResponse createOrderTest(OrderCreateApiRequest opsRequest) throws IOException; + + /** + * This interface supports both take-profit and stop-loss functions, and other functions are exactly the same as the place order interface. + * You can place two types of orders: limit and market. Orders can only be placed if your account has sufficient funds. Once an order is placed, + * your funds will be put on hold for the duration of the order. The amount of funds on hold depends on the order type and parameters specified. + * Please be noted that the system would hold the fees from the orders entered the orderbook in advance. Read Get Fills to learn more. + * @param request + * @return + * @throws IOException + */ + StOrderCreateResponse createStOrders(StOrderCreateRequest request) throws IOException; + /** * Cancel an order *

diff --git a/src/main/java/com/kucoin/futures/core/rest/interfaces/PositionAPI.java b/src/main/java/com/kucoin/futures/core/rest/interfaces/PositionAPI.java index 9ea1c31..6210a6b 100644 --- a/src/main/java/com/kucoin/futures/core/rest/interfaces/PositionAPI.java +++ b/src/main/java/com/kucoin/futures/core/rest/interfaces/PositionAPI.java @@ -5,9 +5,7 @@ import com.kucoin.futures.core.rest.request.HistoryPositionsRequest; import com.kucoin.futures.core.rest.request.WithdrawMarginRequest; -import com.kucoin.futures.core.rest.response.HistoryPositionResponse; -import com.kucoin.futures.core.rest.response.Pagination; -import com.kucoin.futures.core.rest.response.PositionResponse; +import com.kucoin.futures.core.rest.response.*; import java.io.IOException; import java.math.BigDecimal; @@ -37,6 +35,14 @@ public interface PositionAPI { */ List getPositions() throws IOException; + + /** + * Get Maximum Open Position Size + * @return + * @throws IOException + */ + MaxOpenSizeResponse getMaxOpenSize(MaxOpenSizeRequest request) throws IOException; + /** * This interface can query position history information records * diff --git a/src/main/java/com/kucoin/futures/core/rest/interfaces/TickerAPI.java b/src/main/java/com/kucoin/futures/core/rest/interfaces/TickerAPI.java index 6c4ec92..a9ead0e 100644 --- a/src/main/java/com/kucoin/futures/core/rest/interfaces/TickerAPI.java +++ b/src/main/java/com/kucoin/futures/core/rest/interfaces/TickerAPI.java @@ -6,6 +6,7 @@ import com.kucoin.futures.core.rest.response.TickerResponse; import java.io.IOException; +import java.util.List; /** * @author chenshiwei @@ -25,4 +26,12 @@ public interface TickerAPI { */ TickerResponse getTicker(String symbol) throws IOException; + + /** + * Get Latest Ticker for All Contracts + * @return + * @throws IOException + */ + List getAllTickers() throws IOException; + } diff --git a/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/OrderAPIRetrofit.java b/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/OrderAPIRetrofit.java index 445634c..4477019 100644 --- a/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/OrderAPIRetrofit.java +++ b/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/OrderAPIRetrofit.java @@ -4,14 +4,10 @@ package com.kucoin.futures.core.rest.interfaces.retrofit; import com.kucoin.futures.core.rest.request.OrderCreateApiRequest; +import com.kucoin.futures.core.rest.request.StOrderCreateRequest; import com.kucoin.futures.core.rest.response.*; import retrofit2.Call; -import retrofit2.http.Body; -import retrofit2.http.DELETE; -import retrofit2.http.GET; -import retrofit2.http.POST; -import retrofit2.http.Path; -import retrofit2.http.Query; +import retrofit2.http.*; import java.util.List; @@ -29,6 +25,9 @@ public interface OrderAPIRetrofit { @POST("api/v1/orders/test") Call> createOrderTest(@Body OrderCreateApiRequest opsRequest); + @POST("api/v1/st-orders") + Call> createStOrders(@Body StOrderCreateRequest opsRequest); + @DELETE("api/v1/orders/{orderId}") Call> cancelOrder(@Path("orderId") String orderId); @@ -46,22 +45,22 @@ public interface OrderAPIRetrofit { @GET("api/v1/orders") Call>> queryOrders(@Query("symbol") String symbol, - @Query("side") String side, - @Query("type") String type, - @Query("status") String status, - @Query("startAt") Long startAt, - @Query("endAt") Long endAt, - @Query("pageSize") int pageSize, - @Query("currentPage") int currentPage); + @Query("side") String side, + @Query("type") String type, + @Query("status") String status, + @Query("startAt") Long startAt, + @Query("endAt") Long endAt, + @Query("pageSize") int pageSize, + @Query("currentPage") int currentPage); @GET("api/v1/stopOrders") Call>> queryStopOrders(@Query("symbol") String symbol, - @Query("side") String side, - @Query("type") String type, - @Query("startAt") Long startAt, - @Query("endAt") Long endAt, - @Query("pageSize") int pageSize, - @Query("currentPage") int currentPage); + @Query("side") String side, + @Query("type") String type, + @Query("startAt") Long startAt, + @Query("endAt") Long endAt, + @Query("pageSize") int pageSize, + @Query("currentPage") int currentPage); @GET("api/v1/recentDoneOrders") Call>> queryRecentDoneOrders(); diff --git a/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/PositionAPIRetrofit.java b/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/PositionAPIRetrofit.java index 515409f..a57644f 100644 --- a/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/PositionAPIRetrofit.java +++ b/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/PositionAPIRetrofit.java @@ -28,6 +28,12 @@ public interface PositionAPIRetrofit { @GET("api/v1/positions") Call>> getPositions(); + @GET("api/v2/getMaxOpenSize") + Call> getMaxOpenSize(@Query("symbol") String symbol, + @Query("price") BigDecimal price, + @Query("leverage") BigDecimal leverage); + + @GET("api/v1/history-positions") Call>> getHistoryPositions(@Query("symbol") String symbol, @Query("from") Long from, diff --git a/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/TickerAPIRetrofit.java b/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/TickerAPIRetrofit.java index 8ae48bf..deb36a1 100644 --- a/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/TickerAPIRetrofit.java +++ b/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/TickerAPIRetrofit.java @@ -9,6 +9,8 @@ import retrofit2.http.GET; import retrofit2.http.Query; +import java.util.List; + /** * @author chenshiwei * @since 2019/10/15 @@ -18,4 +20,7 @@ public interface TickerAPIRetrofit { @GET("api/v1/ticker") Call> getTicker(@Query("symbol") String symbol); + @GET("api/v1/allTickers") + Call>> getAllTickers(); + } diff --git a/src/main/java/com/kucoin/futures/core/rest/request/OrderCreateApiRequest.java b/src/main/java/com/kucoin/futures/core/rest/request/OrderCreateApiRequest.java index 51c2eed..6ecbc39 100644 --- a/src/main/java/com/kucoin/futures/core/rest/request/OrderCreateApiRequest.java +++ b/src/main/java/com/kucoin/futures/core/rest/request/OrderCreateApiRequest.java @@ -29,7 +29,7 @@ public class OrderCreateApiRequest { private String side; /** - * a valid trading symbol code. e.g. XBTUSDM + * a valid trading symbol code. e.g. XBTUSDTM */ private String symbol; diff --git a/src/main/java/com/kucoin/futures/core/rest/request/StOrderCreateRequest.java b/src/main/java/com/kucoin/futures/core/rest/request/StOrderCreateRequest.java new file mode 100644 index 0000000..fba4b49 --- /dev/null +++ b/src/main/java/com/kucoin/futures/core/rest/request/StOrderCreateRequest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2019 Mek Global Limited + */ +package com.kucoin.futures.core.rest.request; + +import lombok.Builder; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +@Builder +public class StOrderCreateRequest { + + // Required parameters + private String clientOid; // Unique order id created by users + private String side; // buy or sell + private String symbol; // contract code e.g. XBTUSDM + private BigDecimal leverage; // Used to calculate the margin to be frozen for the order + + // Optional parameters + private String type; // limit or market, default is limit + private String remark; // remark for the order + private BigDecimal triggerStopUpPrice; // Take profit price + private String stopPriceType; // TP, IP or MP + private BigDecimal triggerStopDownPrice; // Stop loss price + private boolean reduceOnly = false; // default to false + private boolean closeOrder = false; // default to false + private boolean forceHold = false; // default to false + private String stp; // self trade prevention: CN, CO, CB + private String marginMode; // ISOLATED , CROSS + + // Additional request parameters required by limit orders + private BigDecimal price; // Limit price + private Integer size; // Order size (positive number) + private String timeInForce; // GTC, IOC (default GTC) + private boolean postOnly = false; // default to false + private boolean hidden = false; // default to false + private boolean iceberg = false; // default to false + private Integer visibleSize; // Max visible size for iceberg order + + // Additional request parameters required by market orders + private Integer marketOrderSize; // contract amount to buy or sell +} \ No newline at end of file diff --git a/src/main/java/com/kucoin/futures/core/rest/response/MaxOpenSizeRequest.java b/src/main/java/com/kucoin/futures/core/rest/response/MaxOpenSizeRequest.java new file mode 100644 index 0000000..922d509 --- /dev/null +++ b/src/main/java/com/kucoin/futures/core/rest/response/MaxOpenSizeRequest.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019 Mek Global Limited + */ + +package com.kucoin.futures.core.rest.response; + +import lombok.Builder; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +@Builder +public class MaxOpenSizeRequest { + + /** + * Contract symbol + */ + private String symbol; + + /** + * Order price + */ + private BigDecimal price; + + /** + * Leverage + */ + private BigDecimal leverage; +} diff --git a/src/main/java/com/kucoin/futures/core/rest/response/MaxOpenSizeResponse.java b/src/main/java/com/kucoin/futures/core/rest/response/MaxOpenSizeResponse.java new file mode 100644 index 0000000..fbe39e3 --- /dev/null +++ b/src/main/java/com/kucoin/futures/core/rest/response/MaxOpenSizeResponse.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019 Mek Global Limited + */ + +package com.kucoin.futures.core.rest.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class MaxOpenSizeResponse { + + /** + * Contract symbol + */ + private String symbol; + + /** + * Maximum buy size + */ + private BigDecimal maxBuyOpenSize; + + /** + * Maximum sell size + */ + private BigDecimal maxSellOpenSize; +} diff --git a/src/main/java/com/kucoin/futures/core/rest/response/OrderCreateResponse.java b/src/main/java/com/kucoin/futures/core/rest/response/OrderCreateResponse.java index 9d7f906..fa8b383 100644 --- a/src/main/java/com/kucoin/futures/core/rest/response/OrderCreateResponse.java +++ b/src/main/java/com/kucoin/futures/core/rest/response/OrderCreateResponse.java @@ -12,4 +12,6 @@ public class OrderCreateResponse { private String orderId; + + private String clientOid; } diff --git a/src/main/java/com/kucoin/futures/core/rest/response/StOrderCreateResponse.java b/src/main/java/com/kucoin/futures/core/rest/response/StOrderCreateResponse.java new file mode 100644 index 0000000..cc12888 --- /dev/null +++ b/src/main/java/com/kucoin/futures/core/rest/response/StOrderCreateResponse.java @@ -0,0 +1,21 @@ +/* + * Copyright 2019 Mek Global Limited + */ +package com.kucoin.futures.core.rest.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Builder; +import lombok.Data; + +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class StOrderCreateResponse { + /** + * Order ID + */ + private String orderId; + /** + * Client order ID + */ + private String clientOid; +} \ No newline at end of file diff --git a/src/test/java/com/kucoin/futures/core/BaseTest.java b/src/test/java/com/kucoin/futures/core/BaseTest.java index 609ddc9..0d86fad 100644 --- a/src/test/java/com/kucoin/futures/core/BaseTest.java +++ b/src/test/java/com/kucoin/futures/core/BaseTest.java @@ -43,7 +43,7 @@ public class BaseTest { @BeforeClass public static void setUpClass() throws IOException { KucoinFuturesClientBuilder builder = new KucoinFuturesClientBuilder().withBaseUrl("https://api-futures.kucoin.com") - .withApiKey("", "", "", APIConstants.DEFAULT_API_KEY_VERSION); + .withApiKey(System.getenv("API_KEY"), System.getenv("API_SECRET"), System.getenv("API_PASSPHRASE"), APIConstants.DEFAULT_API_KEY_VERSION); futuresRestClient = builder.buildRestClient(); kucoinFuturesPrivateWSClient = builder.buildPrivateWSClient(); diff --git a/src/test/java/com/kucoin/futures/core/KucoinFuturesRestClientTest.java b/src/test/java/com/kucoin/futures/core/KucoinFuturesRestClientTest.java index 2f4b076..17c6d13 100644 --- a/src/test/java/com/kucoin/futures/core/KucoinFuturesRestClientTest.java +++ b/src/test/java/com/kucoin/futures/core/KucoinFuturesRestClientTest.java @@ -176,14 +176,17 @@ public void fillAPI() throws Exception { List fillResponses = futuresRestClient.fillAPI().recentFills(); assertThat(fillResponses, notNullValue()); - ActiveOrderResponse xbtusdm = futuresRestClient.fillAPI().calActiveOrderValue(SYMBOL); - assertThat(xbtusdm, notNullValue()); + ActiveOrderResponse xbtusdtm = futuresRestClient.fillAPI().calActiveOrderValue(SYMBOL); + assertThat(xbtusdtm, notNullValue()); } @Test public void positionAPI() throws Exception { PositionResponse position = futuresRestClient.positionAPI().getPosition(SYMBOL); assertThat(position, notNullValue()); + MaxOpenSizeResponse maxOpenSize = futuresRestClient.positionAPI().getMaxOpenSize(MaxOpenSizeRequest.builder(). + symbol("PEPEUSDTM").price(BigDecimal.valueOf(0.0000000001)).leverage(BigDecimal.valueOf(10)).build()); + assertThat(maxOpenSize, notNullValue()); List positions = futuresRestClient.positionAPI().getPositions(); assertThat(positions, notNullValue()); @@ -228,6 +231,12 @@ public void symbolAPI() throws Exception { public void tickerAPI() throws Exception { TickerResponse ticker = futuresRestClient.tickerAPI().getTicker(SYMBOL); assertThat(ticker, notNullValue()); + + List tickers = futuresRestClient.tickerAPI().getAllTickers(); + tickers.forEach(t -> { + assertThat(t, notNullValue()); + }); + assertThat(tickers.size(), greaterThan(0)); } @Test @@ -293,6 +302,23 @@ public void placeOrderTest() throws IOException { assertThat(orderTest, notNullValue()); } + @Test + public void stOrderTest() throws IOException { + StOrderCreateRequest request = StOrderCreateRequest.builder(). + clientOid(UUID.randomUUID().toString()). + side("buy").symbol("XBTUSDTM"). + leverage(BigDecimal.valueOf(2)). + type("limit"). + price(BigDecimal.valueOf(800)). + size(1).stopPriceType("TP").marginMode("CROSS"). + triggerStopUpPrice(BigDecimal.valueOf(9000)). + triggerStopDownPrice(BigDecimal.valueOf(100)). + timeInForce("GTC"). + build(); + StOrderCreateResponse orderTest = futuresRestClient.orderAPI().createStOrders(request); + assertThat(orderTest, notNullValue()); + } + @Test public void placeOrderMultiTest() throws IOException { OrderCreateApiRequest pageRequest = OrderCreateApiRequest.builder() From 1f7e25b2bf3bd4046ad7e73b1476c8e7584a8210 Mon Sep 17 00:00:00 2001 From: "Isaac.Tang" Date: Fri, 18 Oct 2024 10:04:56 +0800 Subject: [PATCH 2/3] Update the API for September --- .../core/KucoinFuturesPrivateWSClient.java | 16 ++++++ .../futures/core/constants/APIConstants.java | 2 + .../KucoinFuturesPrivateWSClientImpl.java | 22 ++++++++ .../core/model/enums/PrivateChannelEnum.java | 3 ++ .../core/rest/adapter/OrderAPIAdapter.java | 5 ++ .../core/rest/adapter/PositionAPIAdapter.java | 25 ++++++++-- .../core/rest/interfaces/OrderAPI.java | 9 ++++ .../core/rest/interfaces/PositionAPI.java | 28 +++++++++++ .../interfaces/retrofit/OrderAPIRetrofit.java | 3 ++ .../retrofit/PositionAPIRetrofit.java | 17 +++++-- .../ChangeCrossUserLeverageRequest.java | 22 ++++++++ .../rest/request/ChangeMarginRequest.java | 23 +++++++++ .../rest/request/OrderCreateApiRequest.java | 5 ++ .../core/rest/response/FillResponse.java | 2 + .../GetCrossUserLeverageResponse.java | 21 ++++++++ .../rest/response/MarginModeResponse.java | 22 ++++++++ .../core/rest/response/OrderResponse.java | 5 ++ .../core/rest/response/PositionResponse.java | 7 +++ .../websocket/event/AccountChangeEvent.java | 25 ++++++---- .../event/CrossLeverageChangeEvent.java | 25 ++++++++++ .../event/MarginModeChangeEvent.java | 21 ++++++++ .../websocket/event/OrderChangeEvent.java | 1 + .../websocket/event/PositionChangeEvent.java | 8 +++ .../event/StopOrderLifecycleEvent.java | 2 + .../KucoinFuturesWebsocketListener.java | 22 +++++--- .../core/KucoinFuturesRestClientTest.java | 22 ++++++++ .../core/KucoinFuturesWSClientTest.java | 50 ++++++++++++++++++- 27 files changed, 387 insertions(+), 26 deletions(-) create mode 100644 src/main/java/com/kucoin/futures/core/rest/request/ChangeCrossUserLeverageRequest.java create mode 100644 src/main/java/com/kucoin/futures/core/rest/request/ChangeMarginRequest.java create mode 100644 src/main/java/com/kucoin/futures/core/rest/response/GetCrossUserLeverageResponse.java create mode 100644 src/main/java/com/kucoin/futures/core/rest/response/MarginModeResponse.java create mode 100644 src/main/java/com/kucoin/futures/core/websocket/event/CrossLeverageChangeEvent.java create mode 100644 src/main/java/com/kucoin/futures/core/websocket/event/MarginModeChangeEvent.java diff --git a/src/main/java/com/kucoin/futures/core/KucoinFuturesPrivateWSClient.java b/src/main/java/com/kucoin/futures/core/KucoinFuturesPrivateWSClient.java index 9e2305a..d47b156 100644 --- a/src/main/java/com/kucoin/futures/core/KucoinFuturesPrivateWSClient.java +++ b/src/main/java/com/kucoin/futures/core/KucoinFuturesPrivateWSClient.java @@ -54,6 +54,22 @@ public interface KucoinFuturesPrivateWSClient extends KucoinFuturesPublicWSClien */ String onPositionAllChange(KucoinFuturesAPICallback> callback); + + /** + * Margin Mode Change Events + * @param callback + * @return + */ + String onMarginModeChange(KucoinFuturesAPICallback> callback); + + + /** + * Cross Leverage Change Events + * @param callback + * @return + */ + String onCrossLeverageChange(KucoinFuturesAPICallback> callback); + /** * You will receive a message when the specified symbol order changes * diff --git a/src/main/java/com/kucoin/futures/core/constants/APIConstants.java b/src/main/java/com/kucoin/futures/core/constants/APIConstants.java index dceacde..dbe86ec 100644 --- a/src/main/java/com/kucoin/futures/core/constants/APIConstants.java +++ b/src/main/java/com/kucoin/futures/core/constants/APIConstants.java @@ -42,5 +42,7 @@ private APIConstants() {} public static final String API_POSITION_TOPIC_PREFIX = "/contract/position:"; public static final String API_POSITION_ALL_TOPIC_PREFIX = "/contract/positionAll"; + public static final String API_CONTRACT_MARGIN_MODE_PREFIX = "/contract/marginMode"; + public static final String API_CONTRACT_CROSS_LEVERAGE_PREFIX = "/contract/crossLeverage"; public static final String API_K_LINE_TOPIC_PREFIX = "/contractMarket/limitCandle:"; } diff --git a/src/main/java/com/kucoin/futures/core/impl/KucoinFuturesPrivateWSClientImpl.java b/src/main/java/com/kucoin/futures/core/impl/KucoinFuturesPrivateWSClientImpl.java index 9dfc72e..1c0e9b2 100644 --- a/src/main/java/com/kucoin/futures/core/impl/KucoinFuturesPrivateWSClientImpl.java +++ b/src/main/java/com/kucoin/futures/core/impl/KucoinFuturesPrivateWSClientImpl.java @@ -90,6 +90,28 @@ public String onPositionAllChange(KucoinFuturesAPICallback> callback) { + if (callback != null) { + this.getListener().getCallbackMap().put(APIConstants.API_CONTRACT_MARGIN_MODE_PREFIX, callback); + this.getListener().getTypeReferenceMap().put(APIConstants.API_CONTRACT_MARGIN_MODE_PREFIX, + new TypeReference>() {}); + } + String topic = APIConstants.API_CONTRACT_MARGIN_MODE_PREFIX; + return subscribe(topic, true, true); + } + + @Override + public String onCrossLeverageChange(KucoinFuturesAPICallback> callback) { + if (callback != null) { + this.getListener().getCallbackMap().put(APIConstants.API_CONTRACT_CROSS_LEVERAGE_PREFIX, callback); + this.getListener().getTypeReferenceMap().put(APIConstants.API_CONTRACT_CROSS_LEVERAGE_PREFIX, + new TypeReference>() {}); + } + String topic = APIConstants.API_CONTRACT_CROSS_LEVERAGE_PREFIX; + return subscribe(topic, true, true); + } + @Override public String onOrderChange(KucoinFuturesAPICallback> callback, String symbol) { if (callback != null) { diff --git a/src/main/java/com/kucoin/futures/core/model/enums/PrivateChannelEnum.java b/src/main/java/com/kucoin/futures/core/model/enums/PrivateChannelEnum.java index 319d0a7..cfe2979 100644 --- a/src/main/java/com/kucoin/futures/core/model/enums/PrivateChannelEnum.java +++ b/src/main/java/com/kucoin/futures/core/model/enums/PrivateChannelEnum.java @@ -19,6 +19,9 @@ public enum PrivateChannelEnum { POSITION(APIConstants.API_POSITION_TOPIC_PREFIX), POSITION_ALL(APIConstants.API_POSITION_ALL_TOPIC_PREFIX), + MARGIN_MODE_CHANGE(APIConstants.API_CONTRACT_MARGIN_MODE_PREFIX), + CROSS_LEVERAGE_CHANGE(APIConstants.API_CONTRACT_CROSS_LEVERAGE_PREFIX), + SYMBOL_ORDER_CHANGE(APIConstants.API_SYMBOL_ORDER_CHANGE_TOPIC_PREFIX), ORDER_CHANGE(APIConstants.API_ORDER_CHANGE_TOPIC_PREFIX); diff --git a/src/main/java/com/kucoin/futures/core/rest/adapter/OrderAPIAdapter.java b/src/main/java/com/kucoin/futures/core/rest/adapter/OrderAPIAdapter.java index f1072ec..8276f27 100644 --- a/src/main/java/com/kucoin/futures/core/rest/adapter/OrderAPIAdapter.java +++ b/src/main/java/com/kucoin/futures/core/rest/adapter/OrderAPIAdapter.java @@ -71,6 +71,11 @@ public OrderResponse getOrderDetail(String orderId) throws IOException { return executeSync(getAPIImpl().getOrder(orderId)); } + @Override + public OrderResponse getOrderDetailByClientOid(String clientOid) throws IOException { + return executeSync(getAPIImpl().getOrderByClientOid(clientOid)); + } + @Override public Pagination getOrderList(String symbol, String side, String type, String status, DuringPageRequest request) throws IOException { diff --git a/src/main/java/com/kucoin/futures/core/rest/adapter/PositionAPIAdapter.java b/src/main/java/com/kucoin/futures/core/rest/adapter/PositionAPIAdapter.java index 3eda10a..787d164 100644 --- a/src/main/java/com/kucoin/futures/core/rest/adapter/PositionAPIAdapter.java +++ b/src/main/java/com/kucoin/futures/core/rest/adapter/PositionAPIAdapter.java @@ -7,10 +7,7 @@ import com.kucoin.futures.core.rest.interceptor.FuturesApiKey; import com.kucoin.futures.core.rest.interfaces.PositionAPI; import com.kucoin.futures.core.rest.interfaces.retrofit.PositionAPIRetrofit; -import com.kucoin.futures.core.rest.request.AddMarginManuallyRequest; -import com.kucoin.futures.core.rest.request.HistoryPositionsRequest; -import com.kucoin.futures.core.rest.request.UpdateAutoDepositMarginRequest; -import com.kucoin.futures.core.rest.request.WithdrawMarginRequest; +import com.kucoin.futures.core.rest.request.*; import com.kucoin.futures.core.rest.response.*; import java.io.IOException; @@ -53,6 +50,26 @@ public Pagination getHistoryPositions(HistoryPositionsR ); } + @Override + public MarginModeResponse getMarginMode(String symbol) throws IOException { + return super.executeSync(getAPIImpl().getMarginMode(symbol)); + } + + @Override + public MarginModeResponse changeMarginMode(ChangeMarginRequest request) throws IOException { + return super.executeSync(getAPIImpl().changeMarginMode(request)); + } + + @Override + public GetCrossUserLeverageResponse getCrossUserLeverage(String symbol) throws IOException { + return super.executeSync(getAPIImpl().getCrossUserLeverage(symbol)); + } + + @Override + public boolean changeCrossUserLeverage(ChangeCrossUserLeverageRequest req) throws IOException { + return super.executeSync(getAPIImpl().changeCrossUserLeverage(req)); + } + @Override public void setAutoDepositMargin(String symbol, boolean status) throws IOException { UpdateAutoDepositMarginRequest request = UpdateAutoDepositMarginRequest.builder().status(status).symbol(symbol).build(); diff --git a/src/main/java/com/kucoin/futures/core/rest/interfaces/OrderAPI.java b/src/main/java/com/kucoin/futures/core/rest/interfaces/OrderAPI.java index b54ac9f..1bddcca 100644 --- a/src/main/java/com/kucoin/futures/core/rest/interfaces/OrderAPI.java +++ b/src/main/java/com/kucoin/futures/core/rest/interfaces/OrderAPI.java @@ -146,6 +146,15 @@ Pagination getOrderList(String symbol, String side, String type, */ OrderResponse getOrderDetail(String orderId) throws IOException; + + /** + * Get a single order by clientOid + * + * @param clientOid + * @return The requested order. + */ + OrderResponse getOrderDetailByClientOid(String clientOid) throws IOException; + /** * This interface is for the actual fee rate of the trading pair. * The fee rate of your sub-account is the same as that of the master account. diff --git a/src/main/java/com/kucoin/futures/core/rest/interfaces/PositionAPI.java b/src/main/java/com/kucoin/futures/core/rest/interfaces/PositionAPI.java index 6210a6b..5ed1c10 100644 --- a/src/main/java/com/kucoin/futures/core/rest/interfaces/PositionAPI.java +++ b/src/main/java/com/kucoin/futures/core/rest/interfaces/PositionAPI.java @@ -3,6 +3,8 @@ */ package com.kucoin.futures.core.rest.interfaces; +import com.kucoin.futures.core.rest.request.ChangeCrossUserLeverageRequest; +import com.kucoin.futures.core.rest.request.ChangeMarginRequest; import com.kucoin.futures.core.rest.request.HistoryPositionsRequest; import com.kucoin.futures.core.rest.request.WithdrawMarginRequest; import com.kucoin.futures.core.rest.response.*; @@ -52,6 +54,32 @@ public interface PositionAPI { */ Pagination getHistoryPositions(HistoryPositionsRequest request) throws IOException; + + /** + * This interface can query the margin mode of the current symbol. + * @param symbol symbol + * @return + * @throws IOException + */ + MarginModeResponse getMarginMode(String symbol) throws IOException; + + + /** + * This interface can modify the margin mode of the current symbol + */ + MarginModeResponse changeMarginMode(ChangeMarginRequest request) throws IOException; + + + /** + * This interface can query the current symbol’s cross-margin leverage multiple + */ + GetCrossUserLeverageResponse getCrossUserLeverage(String symbol) throws IOException; + + /** + * This interface can modify the current symbol’s cross-margin leverage multiple + */ + boolean changeCrossUserLeverage(ChangeCrossUserLeverageRequest req) throws IOException; + /** * Enable/Disable of Auto-Deposit Margin * diff --git a/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/OrderAPIRetrofit.java b/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/OrderAPIRetrofit.java index 4477019..56df8e3 100644 --- a/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/OrderAPIRetrofit.java +++ b/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/OrderAPIRetrofit.java @@ -43,6 +43,9 @@ public interface OrderAPIRetrofit { @GET("api/v1/orders/{orderId}") Call> getOrder(@Path("orderId") String orderId); + @GET("api/v1/orders/byClientOid") + Call> getOrderByClientOid(@Query("clientOid") String clientOid); + @GET("api/v1/orders") Call>> queryOrders(@Query("symbol") String symbol, @Query("side") String side, diff --git a/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/PositionAPIRetrofit.java b/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/PositionAPIRetrofit.java index a57644f..cbf2377 100644 --- a/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/PositionAPIRetrofit.java +++ b/src/main/java/com/kucoin/futures/core/rest/interfaces/retrofit/PositionAPIRetrofit.java @@ -3,9 +3,7 @@ */ package com.kucoin.futures.core.rest.interfaces.retrofit; -import com.kucoin.futures.core.rest.request.AddMarginManuallyRequest; -import com.kucoin.futures.core.rest.request.UpdateAutoDepositMarginRequest; -import com.kucoin.futures.core.rest.request.WithdrawMarginRequest; +import com.kucoin.futures.core.rest.request.*; import com.kucoin.futures.core.rest.response.*; import retrofit2.Call; import retrofit2.http.Body; @@ -41,6 +39,19 @@ Call>> getHistoryPosit @Query("limit") Integer limit, @Query("pageId") Integer pageId); + @GET("api/v2/position/getMarginMode") + Call> getMarginMode(@Query("symbol") String symbol); + + @POST("api/v2/position/changeMarginMode") + Call> changeMarginMode(@Body ChangeMarginRequest request); + + @GET("api/v2/getCrossUserLeverage") + Call> getCrossUserLeverage(@Query("symbol") String symbol); + + @POST("api/v2/changeCrossUserLeverage") + Call> changeCrossUserLeverage(@Body ChangeCrossUserLeverageRequest request); + + @POST("api/v1/position/margin/auto-deposit-status") Call> setAutoDepositMargin(@Body UpdateAutoDepositMarginRequest request); diff --git a/src/main/java/com/kucoin/futures/core/rest/request/ChangeCrossUserLeverageRequest.java b/src/main/java/com/kucoin/futures/core/rest/request/ChangeCrossUserLeverageRequest.java new file mode 100644 index 0000000..540f4c1 --- /dev/null +++ b/src/main/java/com/kucoin/futures/core/rest/request/ChangeCrossUserLeverageRequest.java @@ -0,0 +1,22 @@ +package com.kucoin.futures.core.rest.request; + +import lombok.Builder; +import lombok.Data; + +/** + * @author isaac.tang + */ +@Data +@Builder +public class ChangeCrossUserLeverageRequest { + + /** + * Symbol of the contract + */ + private String symbol; + + /** + * Leverage multiple + */ + private String leverage; +} diff --git a/src/main/java/com/kucoin/futures/core/rest/request/ChangeMarginRequest.java b/src/main/java/com/kucoin/futures/core/rest/request/ChangeMarginRequest.java new file mode 100644 index 0000000..d4e76bd --- /dev/null +++ b/src/main/java/com/kucoin/futures/core/rest/request/ChangeMarginRequest.java @@ -0,0 +1,23 @@ +package com.kucoin.futures.core.rest.request; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Builder; +import lombok.Data; + +/** + * @author blazetan + */ +@Data +@Builder +public class ChangeMarginRequest { + + /** + * Symbol of the contract + */ + private String symbol; + + /** + * Margin mode: ISOLATED (isolated), CROSS (cross margin). + */ + private String marginMode; +} diff --git a/src/main/java/com/kucoin/futures/core/rest/request/OrderCreateApiRequest.java b/src/main/java/com/kucoin/futures/core/rest/request/OrderCreateApiRequest.java index 6ecbc39..ee1cb1b 100644 --- a/src/main/java/com/kucoin/futures/core/rest/request/OrderCreateApiRequest.java +++ b/src/main/java/com/kucoin/futures/core/rest/request/OrderCreateApiRequest.java @@ -125,4 +125,9 @@ public class OrderCreateApiRequest { */ private BigDecimal visibleSize; + /** + * Margin mode: ISOLATED, CROSS, default: ISOLATED + */ + private String marginMode; + } \ No newline at end of file diff --git a/src/main/java/com/kucoin/futures/core/rest/response/FillResponse.java b/src/main/java/com/kucoin/futures/core/rest/response/FillResponse.java index 78b2c11..2b08e2a 100644 --- a/src/main/java/com/kucoin/futures/core/rest/response/FillResponse.java +++ b/src/main/java/com/kucoin/futures/core/rest/response/FillResponse.java @@ -51,6 +51,8 @@ public class FillResponse { private Long tradeTime; + private String marginMode; + public String getSide() { return this.side == null ? null : this.side.toLowerCase(); } diff --git a/src/main/java/com/kucoin/futures/core/rest/response/GetCrossUserLeverageResponse.java b/src/main/java/com/kucoin/futures/core/rest/response/GetCrossUserLeverageResponse.java new file mode 100644 index 0000000..c357100 --- /dev/null +++ b/src/main/java/com/kucoin/futures/core/rest/response/GetCrossUserLeverageResponse.java @@ -0,0 +1,21 @@ +package com.kucoin.futures.core.rest.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +/** + * @author isaac.tang + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class GetCrossUserLeverageResponse { + /** + * Symbol of the contract + */ + private String symbol; + + /** + * Leverage multiple + */ + private String leverage; +} diff --git a/src/main/java/com/kucoin/futures/core/rest/response/MarginModeResponse.java b/src/main/java/com/kucoin/futures/core/rest/response/MarginModeResponse.java new file mode 100644 index 0000000..7cc7a16 --- /dev/null +++ b/src/main/java/com/kucoin/futures/core/rest/response/MarginModeResponse.java @@ -0,0 +1,22 @@ +package com.kucoin.futures.core.rest.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +/** + * @author blazetan + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class MarginModeResponse { + + /** + * Symbol of the contract + */ + private String symbol; + + /** + * Margin mode: ISOLATED (isolated), CROSS (cross margin). + */ + private String marginMode; +} diff --git a/src/main/java/com/kucoin/futures/core/rest/response/OrderResponse.java b/src/main/java/com/kucoin/futures/core/rest/response/OrderResponse.java index 36663b3..7da0650 100644 --- a/src/main/java/com/kucoin/futures/core/rest/response/OrderResponse.java +++ b/src/main/java/com/kucoin/futures/core/rest/response/OrderResponse.java @@ -87,6 +87,11 @@ public class OrderResponse { private boolean reduceOnly; + /** + * Margin mode: ISOLATED, CROSS + */ + private String marginMode; + public String getStop() { return this.stop == null ? null : this.stop.toLowerCase(); } diff --git a/src/main/java/com/kucoin/futures/core/rest/response/PositionResponse.java b/src/main/java/com/kucoin/futures/core/rest/response/PositionResponse.java index e06c655..0863c33 100644 --- a/src/main/java/com/kucoin/futures/core/rest/response/PositionResponse.java +++ b/src/main/java/com/kucoin/futures/core/rest/response/PositionResponse.java @@ -89,4 +89,11 @@ public class PositionResponse { private String settleCurrency; + private String marginMode; + + private String positionSide; + + private String leverage; + + private String posFunding; } diff --git a/src/main/java/com/kucoin/futures/core/websocket/event/AccountChangeEvent.java b/src/main/java/com/kucoin/futures/core/websocket/event/AccountChangeEvent.java index 77f77fd..0f98435 100644 --- a/src/main/java/com/kucoin/futures/core/websocket/event/AccountChangeEvent.java +++ b/src/main/java/com/kucoin/futures/core/websocket/event/AccountChangeEvent.java @@ -15,14 +15,19 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class AccountChangeEvent { - private BigDecimal orderMargin; - - private BigDecimal availableBalance; - - private BigDecimal withdrawHold; - - private String currency; - - private long timestamp; - + private String currency; // Currency Symbol + private String walletBalance; // Wallet Balance + private String availableBalance; // Available Balance + private String holdBalance; // Frozen Balance + private String isolatedOrderMargin; // Margin of the isolated margin order + private String isolatedPosMargin; // Margin of the isolated margin position + private String isolatedUnPnl; // Unrealized P&L in isolated margin mode + private String isolatedFundingFeeMargin; // Isolated margin funding fee + private String crossOrderMargin; // Margin of the cross margin order + private String crossPosMargin; // Margin of the cross margin position + private String crossUnPnl; // Unrealized P&L in cross margin mode + private String equity; // Equity + private String totalCrossMargin; // Total margin under cross margin mode + private String version; // Version + private String timestamp; // Last modified time } diff --git a/src/main/java/com/kucoin/futures/core/websocket/event/CrossLeverageChangeEvent.java b/src/main/java/com/kucoin/futures/core/websocket/event/CrossLeverageChangeEvent.java new file mode 100644 index 0000000..5858b3c --- /dev/null +++ b/src/main/java/com/kucoin/futures/core/websocket/event/CrossLeverageChangeEvent.java @@ -0,0 +1,25 @@ +/* + * Copyright 2019 Mek Global Limited + */ + +package com.kucoin.futures.core.websocket.event; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +import java.util.HashMap; + +/** + * @author chenshiwei + * @since 2019/10/18 + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class CrossLeverageChangeEvent extends HashMap { + + @Data + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Leverage { + private String leverage; + } +} diff --git a/src/main/java/com/kucoin/futures/core/websocket/event/MarginModeChangeEvent.java b/src/main/java/com/kucoin/futures/core/websocket/event/MarginModeChangeEvent.java new file mode 100644 index 0000000..ae297f7 --- /dev/null +++ b/src/main/java/com/kucoin/futures/core/websocket/event/MarginModeChangeEvent.java @@ -0,0 +1,21 @@ +/* + * Copyright 2019 Mek Global Limited + */ + +package com.kucoin.futures.core.websocket.event; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +import java.util.HashMap; + +/** + * @author chenshiwei + * @since 2019/10/18 + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class MarginModeChangeEvent extends HashMap { + + +} diff --git a/src/main/java/com/kucoin/futures/core/websocket/event/OrderChangeEvent.java b/src/main/java/com/kucoin/futures/core/websocket/event/OrderChangeEvent.java index 6d77bb2..8d48e87 100644 --- a/src/main/java/com/kucoin/futures/core/websocket/event/OrderChangeEvent.java +++ b/src/main/java/com/kucoin/futures/core/websocket/event/OrderChangeEvent.java @@ -29,5 +29,6 @@ public class OrderChangeEvent { private BigDecimal oldSize; private String liquidity; private long ts; + private String marginMode; } diff --git a/src/main/java/com/kucoin/futures/core/websocket/event/PositionChangeEvent.java b/src/main/java/com/kucoin/futures/core/websocket/event/PositionChangeEvent.java index d8a14d7..366f639 100644 --- a/src/main/java/com/kucoin/futures/core/websocket/event/PositionChangeEvent.java +++ b/src/main/java/com/kucoin/futures/core/websocket/event/PositionChangeEvent.java @@ -97,4 +97,12 @@ public class PositionChangeEvent { /** Adjustment Result of Risk Limit Level **/ private Integer riskLimitLevel; + private String marginMode; + + private String positionSide; + + private String leverage; + + private String posFunding; + } diff --git a/src/main/java/com/kucoin/futures/core/websocket/event/StopOrderLifecycleEvent.java b/src/main/java/com/kucoin/futures/core/websocket/event/StopOrderLifecycleEvent.java index cf8fc32..3568afd 100644 --- a/src/main/java/com/kucoin/futures/core/websocket/event/StopOrderLifecycleEvent.java +++ b/src/main/java/com/kucoin/futures/core/websocket/event/StopOrderLifecycleEvent.java @@ -45,4 +45,6 @@ public class StopOrderLifecycleEvent { private Long ts; + private String marginMode; + } diff --git a/src/main/java/com/kucoin/futures/core/websocket/listener/KucoinFuturesWebsocketListener.java b/src/main/java/com/kucoin/futures/core/websocket/listener/KucoinFuturesWebsocketListener.java index 724943d..42ac406 100644 --- a/src/main/java/com/kucoin/futures/core/websocket/listener/KucoinFuturesWebsocketListener.java +++ b/src/main/java/com/kucoin/futures/core/websocket/listener/KucoinFuturesWebsocketListener.java @@ -38,17 +38,22 @@ public class KucoinFuturesWebsocketListener extends WebSocketListener { private Map typeReferenceMap = new HashMap<>(); @Override - public void onOpen(WebSocket webSocket, Response response) { - LOGGER.debug("web socket open"); - } + public void onOpen(WebSocket webSocket, Response response) { + LOGGER.debug("web socket open"); + } - @Override - public void onMessage(WebSocket webSocket, String text) { - LOGGER.debug("Got message: {}", text); - JsonNode jsonObject = tree(text); + @Override + public void onMessage(WebSocket webSocket, String text) { + LOGGER.debug("Got message: {}", text); + JsonNode jsonObject = tree(text); LOGGER.debug("Parsed message OK"); String type = jsonObject.get("type").asText(); + + if (type.equals("error")) { + LOGGER.error("get error from server: {}", text); + } + if (!type.equals("message")) { LOGGER.debug("Ignoring message type ({})", type); return; @@ -58,7 +63,8 @@ public void onMessage(WebSocket webSocket, String text) { Optional first = callbackMap.keySet().stream().filter(topic::contains).findFirst(); - KucoinEvent kucoinEvent = (KucoinEvent) deserialize(text, typeReferenceMap.getOrDefault(first.get(), new TypeReference() {})); + KucoinEvent kucoinEvent = (KucoinEvent) deserialize(text, typeReferenceMap.getOrDefault(first.get(), new TypeReference() { + })); if (first.isPresent()) { callbackMap.get(first.get()).onResponse(kucoinEvent); diff --git a/src/test/java/com/kucoin/futures/core/KucoinFuturesRestClientTest.java b/src/test/java/com/kucoin/futures/core/KucoinFuturesRestClientTest.java index 17c6d13..4728b0c 100644 --- a/src/test/java/com/kucoin/futures/core/KucoinFuturesRestClientTest.java +++ b/src/test/java/com/kucoin/futures/core/KucoinFuturesRestClientTest.java @@ -131,6 +131,9 @@ public void orderAPI() throws Exception { OrderResponse orderDetail = futuresRestClient.orderAPI().getOrderDetail(order.getOrderId()); assertThat(orderDetail, notNullValue()); + OrderResponse orderDetail2 = futuresRestClient.orderAPI().getOrderDetailByClientOid(order.getClientOid()); + assertThat(orderDetail2, notNullValue()); + OrderCancelResponse orderCancelResponse = futuresRestClient.orderAPI().cancelOrder(order.getOrderId()); assertThat(orderCancelResponse.getCancelledOrderIds().size(), is(1)); @@ -207,6 +210,24 @@ public void positionAPI() throws Exception { } + @Test + public void positionAPI1() throws Exception { + MarginModeResponse marginMode = futuresRestClient.positionAPI().getMarginMode(SYMBOL); + assertThat(marginMode, notNullValue()); + + marginMode = futuresRestClient.positionAPI().changeMarginMode(ChangeMarginRequest.builder().marginMode("CROSS").symbol(SYMBOL).build()); + assertThat(marginMode, notNullValue()); + + + boolean success = futuresRestClient.positionAPI().changeCrossUserLeverage(ChangeCrossUserLeverageRequest.builder().symbol(SYMBOL).leverage("10").build()); + assertThat(success, is(true)); + + GetCrossUserLeverageResponse response = futuresRestClient.positionAPI().getCrossUserLeverage(SYMBOL); + assertThat(response, notNullValue()); + + + } + @Test public void fundingFeeAPI() throws Exception { HasMoreResponse fundingHistory = futuresRestClient.fundingFeeAPI() @@ -331,6 +352,7 @@ public void placeOrderMultiTest() throws IOException { private OrderCreateResponse placeCannotDealLimitOrder() throws IOException { OrderCreateApiRequest pageRequest = OrderCreateApiRequest.builder() .price(BigDecimal.valueOf(5)).size(BigDecimal.ONE).side("buy").leverage("5") + .marginMode("CROSS") .symbol(SYMBOL).type("limit").clientOid(UUID.randomUUID().toString()).build(); return futuresRestClient.orderAPI().createOrder(pageRequest); } diff --git a/src/test/java/com/kucoin/futures/core/KucoinFuturesWSClientTest.java b/src/test/java/com/kucoin/futures/core/KucoinFuturesWSClientTest.java index 55e5927..d02310b 100644 --- a/src/test/java/com/kucoin/futures/core/KucoinFuturesWSClientTest.java +++ b/src/test/java/com/kucoin/futures/core/KucoinFuturesWSClientTest.java @@ -7,6 +7,8 @@ import com.kucoin.futures.core.enums.KLineTypeEnum; import com.kucoin.futures.core.model.enums.PrivateChannelEnum; import com.kucoin.futures.core.model.enums.PublicChannelEnum; +import com.kucoin.futures.core.rest.request.ChangeCrossUserLeverageRequest; +import com.kucoin.futures.core.rest.request.ChangeMarginRequest; import com.kucoin.futures.core.rest.request.OrderCreateApiRequest; import com.kucoin.futures.core.rest.response.MarkPriceResponse; import com.kucoin.futures.core.rest.response.OrderCreateResponse; @@ -24,7 +26,7 @@ import java.util.concurrent.atomic.AtomicReference; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.assertTrue; /** @@ -114,6 +116,50 @@ public void onPositionAllChange() throws Exception { assertThat(event.get(), notNullValue()); } + @Test + public void onMarginModeAndCrossLeverageChange() throws Exception { + CountDownLatch gotEvent = new CountDownLatch(2); + + kucoinFuturesPrivateWSClient.onMarginModeChange(response -> { + + try { + response.getData().forEach((k, v) -> { + assertThat(k, equalTo(SYMBOL)); + assertThat(v, equalTo("CROSS")); + }); + kucoinFuturesPrivateWSClient.unsubscribe(PrivateChannelEnum.MARGIN_MODE_CHANGE); + } catch (Exception e) { + assertThat(e, nullValue()); + } finally { + gotEvent.countDown(); + } + + }); + + String subId = kucoinFuturesPrivateWSClient.onCrossLeverageChange(response -> { + try { + response.getData().forEach((k, v) -> { + assertThat(k, equalTo(SYMBOL)); + assertThat(v.getLeverage(), equalTo("10")); + }); + kucoinFuturesPrivateWSClient.unsubscribe(PrivateChannelEnum.CROSS_LEVERAGE_CHANGE); + } catch (Exception e) { + assertThat(e, nullValue()); + } finally { + gotEvent.countDown(); + } + }); + + + Thread.sleep(1000); + futuresRestClient.positionAPI().changeMarginMode(ChangeMarginRequest.builder().marginMode("CROSS").symbol(SYMBOL).build()); + Thread.sleep(1000); + futuresRestClient.positionAPI().changeCrossUserLeverage(ChangeCrossUserLeverageRequest.builder(). + symbol(SYMBOL).leverage("10").build()); + Thread.sleep(1000); + assertTrue(gotEvent.await(20000, TimeUnit.SECONDS)); + } + @Test public void onSymbolOrderChange() throws Exception { AtomicReference event = new AtomicReference<>(); @@ -318,6 +364,7 @@ private void buyAndSell() throws InterruptedException, IOException { .size(BigDecimal.ONE) .side("buy") .symbol(SYMBOL) + .marginMode("CROSS") .type("market") .leverage("5") .clientOid(UUID.randomUUID().toString()) @@ -326,6 +373,7 @@ private void buyAndSell() throws InterruptedException, IOException { OrderCreateApiRequest request2 = OrderCreateApiRequest.builder() .size(BigDecimal.ONE) .side("sell") + .marginMode("CROSS") .symbol(SYMBOL) .type("market") .leverage("5") From 8206cff832f69bad0c6ad7fda0b183e466fe4690 Mon Sep 17 00:00:00 2001 From: "Isaac.Tang" Date: Fri, 18 Oct 2024 15:01:59 +0800 Subject: [PATCH 3/3] upgrade version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c9e50db..6bb442f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.kucoin.futures kucoin-futures-java-sdk - 1.2.8 + 1.2.9 kucoin-futures-java-sdk kucoin-futures-java-sdk