From b9e07c4044f6b841369efbc911627b36316d2390 Mon Sep 17 00:00:00 2001 From: JKorf Date: Mon, 19 Aug 2024 15:15:43 +0200 Subject: [PATCH] Added FuturesApi.Trading.PlaceMultipleOrdersAsync, PlaceMultipleStopOrdersAsync, CancelOrdersAsync and CancelStopOrdersAsync batch endpoints --- .../CoinExRestClientFuturesApiTrading.cs | 56 +++++- CoinEx.Net/CoinEx.Net.xml | 160 ++++++++++++++++++ .../ICoinExRestClientFuturesApiTrading.cs | 42 +++++ .../V2/CoinExFuturesPlaceOrderRequest.cs | 61 +++++++ .../V2/CoinExFuturesPlaceStopOrderRequest.cs | 71 ++++++++ 5 files changed, 389 insertions(+), 1 deletion(-) create mode 100644 CoinEx.Net/Objects/Models/V2/CoinExFuturesPlaceOrderRequest.cs create mode 100644 CoinEx.Net/Objects/Models/V2/CoinExFuturesPlaceStopOrderRequest.cs diff --git a/CoinEx.Net/Clients/FuturesApi/CoinExRestClientFuturesApiTrading.cs b/CoinEx.Net/Clients/FuturesApi/CoinExRestClientFuturesApiTrading.cs index 7d4caca..9a0a2c6 100644 --- a/CoinEx.Net/Clients/FuturesApi/CoinExRestClientFuturesApiTrading.cs +++ b/CoinEx.Net/Clients/FuturesApi/CoinExRestClientFuturesApiTrading.cs @@ -7,6 +7,7 @@ using System; using CryptoExchange.Net; using CoinEx.Net.Interfaces.Clients.FuturesApi; +using System.Collections.Generic; namespace CoinEx.Net.Clients.FuturesApi { @@ -82,6 +83,36 @@ public async Task> PlaceStopOrderAsync( return await _baseClient.ExecuteAsync(_baseClient.GetUri("v2/futures/stop-order"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); } + /// + public async Task>>> PlaceMultipleOrdersAsync( + IEnumerable requests, + CancellationToken ct = default) + { + foreach (var order in requests) + order.ClientOrderId ??= ExchangeHelpers.AppendRandomString("x-" + _baseClient._brokerId + "-", 32); + + var parameters = new ParameterCollection() + { + { "orders", requests } + }; + return await _baseClient.ExecuteAsync>>(_baseClient.GetUri("v2/futures/batch-order"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); + } + + /// + public async Task>>> PlaceMultipleStopOrdersAsync( + IEnumerable requests, + CancellationToken ct = default) + { + foreach (var order in requests) + order.ClientOrderId ??= ExchangeHelpers.AppendRandomString("x-" + _baseClient._brokerId + "-", 32); + + var parameters = new ParameterCollection() + { + { "orders", requests } + }; + return await _baseClient.ExecuteAsync>>(_baseClient.GetUri("v2/futures/batch-stop-order"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); + } + /// public async Task> GetOrderAsync(string symbol, long orderId, CancellationToken ct = default) { @@ -245,7 +276,30 @@ public async Task> CancelStopOrderByClientOrderId }; parameters.AddEnum("market_type", AccountType.Futures); return await _baseClient.ExecuteAsync(_baseClient.GetUri("v2/futures/cancel-stop-order-by-client-id"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - + } + + /// + public async Task>>> CancelOrdersAsync(string symbol, IEnumerable orderIds, CancellationToken ct = default) + { + var parameters = new ParameterCollection() + { + { "market", symbol }, + { "order_ids", orderIds } + }; + parameters.AddEnum("market_type", AccountType.Futures); + return await _baseClient.ExecuteAsync>>(_baseClient.GetUri("v2/futures/cancel-batch-order"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); + } + + /// + public async Task>>> CancelStopOrdersAsync(string symbol, IEnumerable orderIds, CancellationToken ct = default) + { + var parameters = new ParameterCollection() + { + { "market", symbol }, + { "stop_ids", orderIds } + }; + parameters.AddEnum("market_type", AccountType.Futures); + return await _baseClient.ExecuteAsync>>(_baseClient.GetUri("v2/futures/cancel-batch-stop-order"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); } /// diff --git a/CoinEx.Net/CoinEx.Net.xml b/CoinEx.Net/CoinEx.Net.xml index fcd0efb..5de1f6e 100644 --- a/CoinEx.Net/CoinEx.Net.xml +++ b/CoinEx.Net/CoinEx.Net.xml @@ -184,6 +184,12 @@ + + + + + + @@ -220,6 +226,12 @@ + + + + + + @@ -1832,6 +1844,24 @@ Cancelation Token + + + Place multiple orders in a single call + + + Orders to place + Cancelation Token + + + + + Place multiple stop orders in a single call + + + Stop orders to place + Cancelation Token + + Get an order by id @@ -1969,6 +1999,26 @@ Cancelation Token + + + Cancel multiple orders + + + Symbol, for example `ETHUSDT` + Ids of orders to cancel + Cancelation Token + + + + + Cancel multiple stop orders + + + Symbol, for example `ETHUSDT` + Ids of stop orders to cancel + Cancelation Token + + Get trade list @@ -5440,6 +5490,116 @@ Order data + + + Place order request + + + + + The symbol, for example `ETHUSDT` + + + + + The account type + + + + + The side + + + + + The order type + + + + + The quantity + + + + + The limit price + + + + + The client order id + + + + + Whether to hide the order + + + + + Self trade prevention mode + + + + + Place stop order request + + + + + The symbol, for example `ETHUSDT` + + + + + The account type + + + + + The side + + + + + The order type + + + + + The quantity + + + + + The limit price + + + + + The trigger price + + + + + The trigger price type + + + + + The client order id + + + + + Whether to hide the order + + + + + Self trade prevention mode + + Futures symbol info diff --git a/CoinEx.Net/Interfaces/Clients/FuturesApi/ICoinExRestClientFuturesApiTrading.cs b/CoinEx.Net/Interfaces/Clients/FuturesApi/ICoinExRestClientFuturesApiTrading.cs index fcb772c..b02217f 100644 --- a/CoinEx.Net/Interfaces/Clients/FuturesApi/ICoinExRestClientFuturesApiTrading.cs +++ b/CoinEx.Net/Interfaces/Clients/FuturesApi/ICoinExRestClientFuturesApiTrading.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using CoinEx.Net.Objects.Models.V2; using System; +using System.Collections.Generic; namespace CoinEx.Net.Interfaces.Clients.FuturesApi { @@ -66,6 +67,28 @@ Task> PlaceStopOrderAsync( SelfTradePreventionMode? stpMode = null, CancellationToken ct = default); + /// + /// Place multiple orders in a single call + /// + /// + /// Orders to place + /// Cancelation Token + /// + Task>>> PlaceMultipleOrdersAsync( + IEnumerable requests, + CancellationToken ct = default); + + /// + /// Place multiple stop orders in a single call + /// + /// + /// Stop orders to place + /// Cancelation Token + /// + Task>>> PlaceMultipleStopOrdersAsync( + IEnumerable requests, + CancellationToken ct = default); + /// /// Get an order by id /// @@ -215,6 +238,25 @@ Task> EditStopOrderAsync( /// Task> CancelStopOrderByClientOrderIdAsync(string symbol, string clientStopOrderId, CancellationToken ct = default); + /// + /// Cancel multiple orders + /// + /// + /// Symbol, for example `ETHUSDT` + /// Ids of orders to cancel + /// Cancelation Token + /// + Task>>> CancelOrdersAsync(string symbol, IEnumerable orderIds, CancellationToken ct = default); + + /// + /// Cancel multiple stop orders + /// + /// + /// Symbol, for example `ETHUSDT` + /// Ids of stop orders to cancel + /// Cancelation Token + /// + Task>>> CancelStopOrdersAsync(string symbol, IEnumerable orderIds, CancellationToken ct = default); /// /// Get trade list diff --git a/CoinEx.Net/Objects/Models/V2/CoinExFuturesPlaceOrderRequest.cs b/CoinEx.Net/Objects/Models/V2/CoinExFuturesPlaceOrderRequest.cs new file mode 100644 index 0000000..53c6dd3 --- /dev/null +++ b/CoinEx.Net/Objects/Models/V2/CoinExFuturesPlaceOrderRequest.cs @@ -0,0 +1,61 @@ +using CoinEx.Net.Enums; +using CryptoExchange.Net.Converters.SystemTextJson; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json.Serialization; + +namespace CoinEx.Net.Objects.Models.V2 +{ + /// + /// Place order request + /// + public record CoinExFuturesPlaceOrderRequest + { + /// + /// The symbol, for example `ETHUSDT` + /// + [JsonPropertyName("market")] + public string Symbol { get; set; } = string.Empty; + /// + /// The account type + /// + [JsonPropertyName("market_type")] + public AccountType AccountType { get; set; } + /// + /// The side + /// + [JsonPropertyName("side")] + public OrderSide Side { get; set; } + /// + /// The order type + /// + [JsonPropertyName("type")] + public OrderTypeV2 OrderType { get; set; } + /// + /// The quantity + /// + [JsonPropertyName("amount"), JsonConverter(typeof(CryptoExchange.Net.Converters.SystemTextJson.DecimalStringWriterConverter))] + public decimal Quantity { get; set; } + /// + /// The limit price + /// + [JsonPropertyName("price"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault), JsonConverter(typeof(CryptoExchange.Net.Converters.SystemTextJson.DecimalStringWriterConverter))] + public decimal? Price { get; set; } + /// + /// The client order id + /// + [JsonPropertyName("client_id"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public string? ClientOrderId { get; set; } + /// + /// Whether to hide the order + /// + [JsonPropertyName("is_hide"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public bool? Hide { get; set; } + /// + /// Self trade prevention mode + /// + [JsonPropertyName("stp_mode"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public SelfTradePreventionMode? StpMode { get; set; } + } +} diff --git a/CoinEx.Net/Objects/Models/V2/CoinExFuturesPlaceStopOrderRequest.cs b/CoinEx.Net/Objects/Models/V2/CoinExFuturesPlaceStopOrderRequest.cs new file mode 100644 index 0000000..941adaa --- /dev/null +++ b/CoinEx.Net/Objects/Models/V2/CoinExFuturesPlaceStopOrderRequest.cs @@ -0,0 +1,71 @@ +using CoinEx.Net.Enums; +using CryptoExchange.Net.Converters.SystemTextJson; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json.Serialization; + +namespace CoinEx.Net.Objects.Models.V2 +{ + /// + /// Place stop order request + /// + public record CoinExFuturesPlaceStopOrderRequest + { + /// + /// The symbol, for example `ETHUSDT` + /// + [JsonPropertyName("market")] + public string Symbol { get; set; } = string.Empty; + /// + /// The account type + /// + [JsonPropertyName("market_type")] + public AccountType AccountType { get; set; } + /// + /// The side + /// + [JsonPropertyName("side")] + public OrderSide Side { get; set; } + /// + /// The order type + /// + [JsonPropertyName("type")] + public OrderTypeV2 OrderType { get; set; } + /// + /// The quantity + /// + [JsonPropertyName("amount"), JsonConverter(typeof(CryptoExchange.Net.Converters.SystemTextJson.DecimalStringWriterConverter))] + public decimal Quantity { get; set; } + /// + /// The limit price + /// + [JsonPropertyName("price"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault), JsonConverter(typeof(CryptoExchange.Net.Converters.SystemTextJson.DecimalStringWriterConverter))] + public decimal? Price { get; set; } + /// + /// The trigger price + /// + [JsonPropertyName("trigger_price"), JsonConverter(typeof(CryptoExchange.Net.Converters.SystemTextJson.DecimalStringWriterConverter))] + public decimal TriggerPrice { get; set; } + /// + /// The trigger price type + /// + [JsonPropertyName("trigger_price_type")] + public TriggerPriceType TriggerPriceType { get; set; } + /// + /// The client order id + /// + [JsonPropertyName("client_id"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public string? ClientOrderId { get; set; } + /// + /// Whether to hide the order + /// + [JsonPropertyName("is_hide"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public bool? Hide { get; set; } + /// + /// Self trade prevention mode + /// + [JsonPropertyName("stp_mode"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public SelfTradePreventionMode? StpMode { get; set; } + } +}