From 79ecc3b75fbe739315d3d50edd79a6b7ae5b2e36 Mon Sep 17 00:00:00 2001 From: Victor Lee Date: Wed, 15 Sep 2021 20:28:27 -0700 Subject: [PATCH 1/2] Added ability to GetOrderDetailsAsync() by ClientOrderId - many, but not all, exchanges support this --- .../Exchanges/Aquanow/ExchangeAquanowAPI.cs | 3 ++- .../API/Exchanges/BL3P/ExchangeBL3PAPI.cs | 5 ++-- .../BinanceGroup/BinanceGroupCommon.cs | 9 +++++-- .../Exchanges/BitBank/ExchangeBitBankAPI.cs | 3 ++- .../API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs | 4 +-- .../Exchanges/Bitfinex/ExchangeBitfinexAPI.cs | 3 ++- .../Exchanges/Bitstamp/ExchangeBitstampAPI.cs | 11 +++++--- .../Exchanges/Bittrex/ExchangeBittrexAPI.cs | 3 ++- .../API/Exchanges/Bybit/ExchangeBybitAPI.cs | 13 ++++++---- .../Exchanges/Coinbase/ExchangeCoinbaseAPI.cs | 7 ++--- .../Digifinex/ExchangeDigifinexAPI.cs | 3 ++- .../API/Exchanges/GateIo/ExchangeGateIoAPI.cs | 3 ++- .../API/Exchanges/Gemini/ExchangeGeminiAPI.cs | 6 +++-- .../API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs | 7 ++--- .../API/Exchanges/Huobi/ExchangeHuobiAPI.cs | 20 +++++++++----- .../API/Exchanges/Kraken/ExchangeKrakenAPI.cs | 4 +-- .../API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs | 26 ++++++++++++------- .../API/Exchanges/LBank/ExchangeLBankAPI.cs | 3 ++- .../Exchanges/Livecoin/ExchangeLivecoinAPI.cs | 5 ++-- .../API/Exchanges/NDAX/ExchangeNDAXAPI.cs | 7 ++--- .../API/Exchanges/OKGroup/OKGroupCommon.cs | 13 +++++++--- .../Exchanges/Poloniex/ExchangePoloniexAPI.cs | 7 ++--- .../API/Exchanges/Yobit/ExchangeYobitAPI.cs | 7 ++--- .../API/Exchanges/_Base/ExchangeAPI.cs | 7 ++--- .../Exchanges/_Base/ExchangeAPIExtensions.cs | 2 +- .../API/Exchanges/_Base/IExchangeAPI.cs | 3 ++- src/ExchangeSharpConsole/Options/BuyOption.cs | 2 +- .../Options/OrderDetailsOption.cs | 2 +- .../ExchangeBitBankTests.cs | 2 +- 29 files changed, 119 insertions(+), 71 deletions(-) diff --git a/src/ExchangeSharp/API/Exchanges/Aquanow/ExchangeAquanowAPI.cs b/src/ExchangeSharp/API/Exchanges/Aquanow/ExchangeAquanowAPI.cs index 792cf002d..5375016cf 100644 --- a/src/ExchangeSharp/API/Exchanges/Aquanow/ExchangeAquanowAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Aquanow/ExchangeAquanowAPI.cs @@ -194,12 +194,13 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return orderDetails; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) { if (string.IsNullOrWhiteSpace(orderId)) { return null; } + if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); var payload = await GetNoncePayloadAsync(); JToken result = await MakeJsonRequestAsync($"/trades/v1/order?orderId={orderId}", null, payload, "GET"); bool isBuy = result["tradeSide"].ToStringInvariant() == "buy" ? true : false; diff --git a/src/ExchangeSharp/API/Exchanges/BL3P/ExchangeBL3PAPI.cs b/src/ExchangeSharp/API/Exchanges/BL3P/ExchangeBL3PAPI.cs index d5ab5bdde..824f021dd 100644 --- a/src/ExchangeSharp/API/Exchanges/BL3P/ExchangeBL3PAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/BL3P/ExchangeBL3PAPI.cs @@ -271,7 +271,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd var result = JsonConvert.DeserializeObject(resultBody) .Except(); - var orderDetails = await GetOrderDetailsAsync(result.OrderId, order.MarketSymbol); + var orderDetails = await GetOrderDetailsAsync(result.OrderId, marketSymbol: order.MarketSymbol); return orderDetails; } @@ -308,10 +308,11 @@ protected override async Task OnCancelOrderAsync(string orderId, string marketSy .Except(); } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) { if (string.IsNullOrWhiteSpace(marketSymbol)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(marketSymbol)); + if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); var data = new Dictionary { diff --git a/src/ExchangeSharp/API/Exchanges/BinanceGroup/BinanceGroupCommon.cs b/src/ExchangeSharp/API/Exchanges/BinanceGroup/BinanceGroupCommon.cs index 843a96eea..f676d57ae 100644 --- a/src/ExchangeSharp/API/Exchanges/BinanceGroup/BinanceGroupCommon.cs +++ b/src/ExchangeSharp/API/Exchanges/BinanceGroup/BinanceGroupCommon.cs @@ -580,7 +580,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return ParseOrder(token); } - protected override async Task OnGetOrderDetailsAsync(string orderId, string? marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string? marketSymbol = null) { Dictionary payload = await GetNoncePayloadAsync(); if (string.IsNullOrWhiteSpace(marketSymbol)) @@ -588,7 +588,12 @@ protected override async Task OnGetOrderDetailsAsync(string throw new InvalidOperationException("Binance single order details request requires symbol"); } payload["symbol"] = marketSymbol!; - payload["orderId"] = orderId; + + if (isClientOrderId) // Either orderId or origClientOrderId must be sent. + payload["origClientOrderId"] = orderId; + else + payload["orderId"] = orderId; + JToken token = await MakeJsonRequestAsync("/order", BaseUrlPrivate, payload); ExchangeOrderResult result = ParseOrder(token); diff --git a/src/ExchangeSharp/API/Exchanges/BitBank/ExchangeBitBankAPI.cs b/src/ExchangeSharp/API/Exchanges/BitBank/ExchangeBitBankAPI.cs index b36cf62e5..5bd6efb4c 100644 --- a/src/ExchangeSharp/API/Exchanges/BitBank/ExchangeBitBankAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/BitBank/ExchangeBitBankAPI.cs @@ -148,8 +148,9 @@ protected override async Task OnCancelOrderAsync(string orderId, string marketSy await MakeJsonRequestAsync("/user/spot/cancel_order", baseUrl: BaseUrlPrivate, payload: payload, requestMethod: "POST"); } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) { + if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); var payload = await GetNoncePayloadAsync(); payload.Add("order_id", orderId); if (marketSymbol == null) diff --git a/src/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs b/src/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs index 8a549532b..5591240b4 100644 --- a/src/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs @@ -600,11 +600,11 @@ protected override async Task> OnGetOpenOrderDe return orders; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) { List orders = new List(); Dictionary payload = await GetNoncePayloadAsync(); - string query = $"/order?filter={{\"orderID\": \"{orderId}\"}}"; + string query = $"/order?filter={{\"{(isClientOrderId ? "clOrdID" : "orderID")}\": \"{orderId}\"}}"; JToken token = await MakeJsonRequestAsync(query, BaseUrl, payload, "GET"); foreach (JToken order in token) { diff --git a/src/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs b/src/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs index f74c8c126..b972cec61 100644 --- a/src/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs @@ -493,8 +493,9 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return ParseOrder(obj); } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) { + if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); if (string.IsNullOrWhiteSpace(orderId)) { return null; diff --git a/src/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs b/src/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs index e88b8674f..20f72709b 100644 --- a/src/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs @@ -219,8 +219,8 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd }; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) - { + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + { //{ // "status": "Finished", // "id": 1022694747, @@ -241,8 +241,11 @@ protected override async Task OnGetOrderDetailsAsync(string } string url = "/order_status/"; Dictionary payload = await GetNoncePayloadAsync(); - payload["id"] = orderId; - JObject result = await MakeJsonRequestAsync(url, null, payload, "POST"); + if (isClientOrderId) // Order can be fetched by using either id or client_order_id parameter. + payload["client_order_id"] = orderId; + else + payload["id"] = orderId; + JObject result = await MakeJsonRequestAsync(url, null, payload, "POST"); var transactions = result["transactions"] as JArray; var anyTransaction = transactions.Any(); diff --git a/src/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs b/src/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs index ef268f4be..bfd6de023 100644 --- a/src/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs @@ -412,8 +412,9 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) { + if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); if (string.IsNullOrWhiteSpace(orderId)) { return null; diff --git a/src/ExchangeSharp/API/Exchanges/Bybit/ExchangeBybitAPI.cs b/src/ExchangeSharp/API/Exchanges/Bybit/ExchangeBybitAPI.cs index 108131e32..bfa1b7a75 100644 --- a/src/ExchangeSharp/API/Exchanges/Bybit/ExchangeBybitAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Bybit/ExchangeBybitAPI.cs @@ -718,13 +718,16 @@ public async Task GetPredictedFundingRateAsync(string marketSym return funding; } - private async Task> DoGetOrderDetailsAsync(string orderId, string marketSymbol = null) + private async Task> DoGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) { var extraParams = new Dictionary(); if (orderId != null) { - extraParams["order_id"] = orderId; + if (isClientOrderId) + extraParams["order_link_id"] = orderId; + else + extraParams["order_id"] = orderId; } if (!string.IsNullOrWhiteSpace(marketSymbol)) @@ -758,13 +761,13 @@ private async Task> DoGetOrderDetailsAsync(stri //Note, Bybit is not recommending the use of "/v2/private/order/list" now that "/v2/private/order" is capable of returning multiple results protected override async Task> OnGetOpenOrderDetailsAsync(string marketSymbol = null) { - var orders = await DoGetOrderDetailsAsync(null, marketSymbol); + var orders = await DoGetOrderDetailsAsync(null, isClientOrderId: false, marketSymbol: marketSymbol); return orders; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) { - var orders = await DoGetOrderDetailsAsync(orderId, marketSymbol); + var orders = await DoGetOrderDetailsAsync(orderId, isClientOrderId: isClientOrderId, marketSymbol: marketSymbol); if (orders.Count() > 0) { return orders.First(); diff --git a/src/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs b/src/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs index aa4082657..460a82ea4 100644 --- a/src/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs @@ -594,9 +594,10 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return ParseOrder(result); } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) - { - JToken obj = await MakeJsonRequestAsync("/orders/" + orderId, null, await GetNoncePayloadAsync(), "GET"); + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + { // Orders may be queried using either the exchange assigned id or the client assigned client_oid. When using client_oid it must be preceded by the client: namespace. + JToken obj = await MakeJsonRequestAsync("/orders/" + (isClientOrderId ? "client:" : "") + orderId, + null, await GetNoncePayloadAsync(), "GET"); return ParseOrder(obj); } diff --git a/src/ExchangeSharp/API/Exchanges/Digifinex/ExchangeDigifinexAPI.cs b/src/ExchangeSharp/API/Exchanges/Digifinex/ExchangeDigifinexAPI.cs index 6206ab1d7..71c87a385 100644 --- a/src/ExchangeSharp/API/Exchanges/Digifinex/ExchangeDigifinexAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Digifinex/ExchangeDigifinexAPI.cs @@ -361,8 +361,9 @@ protected override async Task> OnGetCompletedOr }); } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) { + if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); Dictionary payload = await GetNoncePayloadAsync(); JToken token = await MakeJsonRequestAsync($"/spot/order?order_id={orderId}", payload: payload); var x = token["data"]; diff --git a/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs b/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs index 73051df0b..7b7ef1d13 100644 --- a/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs @@ -376,12 +376,13 @@ private static ExchangeAPIOrderResult ParseExchangeAPIOrderResult(string status, } } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string symbol = null) { if (string.IsNullOrEmpty(symbol)) { throw new InvalidOperationException("MarketSymbol is required for querying order details with Gate.io API"); } + if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); var payload = await GetNoncePayloadAsync(); var responseToken = await MakeJsonRequestAsync($"/spot/orders/{orderId}?currency_pair={symbol}", payload: payload); diff --git a/src/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs b/src/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs index b814caa84..ad995ab9c 100644 --- a/src/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs @@ -320,7 +320,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return ParseOrder(obj); } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) { if (string.IsNullOrWhiteSpace(orderId)) { @@ -328,7 +328,9 @@ protected override async Task OnGetOrderDetailsAsync(string } object nonce = await GenerateNonceAsync(); - JToken result = await MakeJsonRequestAsync("/order/status", null, new Dictionary { { "nonce", nonce }, { "order_id", orderId } }); + var payload = new Dictionary { { "nonce", nonce }, + { isClientOrderId ? "client_order_id" : "order_id", orderId } }; // client_order_id cannot be used in combination with order_id + JToken result = await MakeJsonRequestAsync("/order/status", null, payload: payload); return ParseOrder(result); } diff --git a/src/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs b/src/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs index 43e69284a..c186f3031 100644 --- a/src/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs @@ -257,9 +257,10 @@ protected override async Task> OnGetAmountsAvailable /// /// /// - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) - { - JToken obj = await MakeJsonRequestAsync("/history/order/" + orderId + "/trades", null, await GetNoncePayloadAsync()); + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + { + if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); + JToken obj = await MakeJsonRequestAsync("/history/order/" + orderId + "/trades", null, await GetNoncePayloadAsync()); if (obj != null && obj.HasValues) return ParseCompletedOrder(obj); return null; } diff --git a/src/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs b/src/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs index 8063429a4..75399ab19 100644 --- a/src/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs @@ -607,8 +607,8 @@ protected override async Task> OnGetAmountsAvailable return amounts; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) - { + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + { /* {{ "status": "ok", @@ -631,8 +631,14 @@ protected override async Task OnGetOrderDetailsAsync(string }} */ var payload = await GetNoncePayloadAsync(); - JToken data = await MakeJsonRequestAsync($"/order/orders/{orderId}", PrivateUrlV1, payload); - return ParseOrder(data); + JToken data; + if (isClientOrderId) + { + payload.Add("clientOrderId", orderId); + data = await MakeJsonRequestAsync($"/order/orders/getClientOrder", PrivateUrlV1, payload); + } + else data = await MakeJsonRequestAsync($"/order/orders/{orderId}", PrivateUrlV1, payload); + return ParseOrder(data); } protected override async Task> OnGetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null) @@ -644,8 +650,10 @@ protected override async Task> OnGetCompletedOr payload.Add("symbol", marketSymbol); payload.Add("states", "partial-canceled,filled,canceled"); if (afterDate != null) - { - payload.Add("start-date", afterDate.Value.ToString("yyyy-MM-dd")); + { // This endpoint returns the detail of one order by specified client order id (within 8 hours). + // The order created via API will no longer be queryable after being cancelled for more than 2 hours. + // It is suggested to cancel orders via GET /v1/order/orders/{order-id}, which is faster and more stable. + payload.Add("start-date", afterDate.Value.ToString("yyyy-MM-dd")); } JToken data = await MakeJsonRequestAsync("/order/orders", PrivateUrlV1, payload); foreach (var prop in data) diff --git a/src/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs b/src/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs index 022c53b29..65cb1e110 100644 --- a/src/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs @@ -790,13 +790,13 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return result; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) { if (string.IsNullOrWhiteSpace(orderId)) { return null; } - + if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); object nonce = await GenerateNonceAsync(); Dictionary payload = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "txid", orderId }, { "nonce", nonce } diff --git a/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs b/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs index df74c8bb4..cf38f82b5 100644 --- a/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs @@ -374,18 +374,24 @@ protected override async Task> OnGetOpenOrderDe } /// - /// Kucoin does not support retrieving Orders by ID. This uses the GetCompletedOrderDetails and GetOpenOrderDetails filtered by orderId + /// Get Order by ID or ClientOrderId /// /// /// - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) - { - var orders = await GetCompletedOrderDetailsAsync(marketSymbol); - orders = orders.Concat(await GetOpenOrderDetailsAsync(marketSymbol)).ToList(); - - var ordertmp = orders?.Where(o => o.OrderId == orderId).FirstOrDefault(); - return ordertmp; - } + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + { + var payload = await GetNoncePayloadAsync(); + if (isClientOrderId) + payload["clientOid"] = Guid.NewGuid(); + else + payload["clientOid"] = Guid.NewGuid(); + + JToken token = await MakeJsonRequestAsync("/orders?&" + CryptoUtility.GetFormForPayload(payload, false), null, payload); + var isActive = token["id"].ToObject(); + if (isActive) + return ParseOpenOrder(token); + else return ParseCompletedOrder(token); + } protected override async Task OnPlaceOrderAsync(ExchangeOrderRequest order) { @@ -418,7 +424,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd protected override async Task OnCancelOrderAsync(string orderId, string marketSymbol = null) { // Find order detail - ExchangeOrderResult order = await GetOrderDetailsAsync(orderId, marketSymbol); + ExchangeOrderResult order = await GetOrderDetailsAsync(orderId, marketSymbol: marketSymbol); // There is no order to be cancelled if (order == null) diff --git a/src/ExchangeSharp/API/Exchanges/LBank/ExchangeLBankAPI.cs b/src/ExchangeSharp/API/Exchanges/LBank/ExchangeLBankAPI.cs index c0f3b70fc..14393d9a2 100644 --- a/src/ExchangeSharp/API/Exchanges/LBank/ExchangeLBankAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/LBank/ExchangeLBankAPI.cs @@ -356,8 +356,9 @@ protected override async Task OnCancelOrderAsync(string orderId, string symbol = } //GetOrderDetails 13 - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string symbol = null) { + if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); Dictionary payload = new Dictionary { { "api_key", PublicApiKey.ToUnsecureString() }, diff --git a/src/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs b/src/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs index b8d349b47..eb57999c9 100644 --- a/src/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs @@ -219,8 +219,9 @@ protected override async Task> OnGetAmountsAvailable return amounts; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) - { + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + { + if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); JToken token = await MakeJsonRequestAsync("/exchange/order?orderId=" + orderId, null, await GetNoncePayloadAsync()); return ParseOrder(token); } diff --git a/src/ExchangeSharp/API/Exchanges/NDAX/ExchangeNDAXAPI.cs b/src/ExchangeSharp/API/Exchanges/NDAX/ExchangeNDAXAPI.cs index 37afaa424..b8fa4e226 100644 --- a/src/ExchangeSharp/API/Exchanges/NDAX/ExchangeNDAXAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/NDAX/ExchangeNDAXAPI.cs @@ -197,9 +197,10 @@ protected override async Task OnPlaceOrdersAsync(params E return resp.ToArray(); } - protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null) - { - await EnsureInstrumentIdsAvailable(); + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string symbol = null) + { + if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); + await EnsureInstrumentIdsAvailable(); var result = await MakeJsonRequestAsync("GetOrderStatus", null, new Dictionary() { diff --git a/src/ExchangeSharp/API/Exchanges/OKGroup/OKGroupCommon.cs b/src/ExchangeSharp/API/Exchanges/OKGroup/OKGroupCommon.cs index af900f423..dac3819a9 100644 --- a/src/ExchangeSharp/API/Exchanges/OKGroup/OKGroupCommon.cs +++ b/src/ExchangeSharp/API/Exchanges/OKGroup/OKGroupCommon.cs @@ -461,8 +461,8 @@ protected override async Task OnCancelOrderAsync(string orderId, string marketSy await MakeJsonRequestAsync("/cancel_order.do", BaseUrl, payload, "POST"); } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) - { + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + { List orders = new List(); Dictionary payload = await GetNoncePayloadAsync(); if (marketSymbol.Length == 0) @@ -470,8 +470,13 @@ protected override async Task OnGetOrderDetailsAsync(string throw new InvalidOperationException("Okex single order details request requires symbol"); } payload["symbol"] = marketSymbol; - payload["order_id"] = orderId; - JToken token = await MakeJsonRequestAsync("/order_info.do", BaseUrl, payload, "POST"); + + if (isClientOrderId) // Either client_oid or order_id must be present. + payload["client_oid"] = orderId; + else + payload["order_id"] = orderId; + + JToken token = await MakeJsonRequestAsync("/order_info.do", BaseUrl, payload, "POST"); foreach (JToken order in token["orders"]) { orders.Add(ParseOrder(order)); diff --git a/src/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs b/src/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs index a7e1178be..c0f4fb4ed 100644 --- a/src/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs @@ -840,9 +840,10 @@ protected override async Task> OnGetOpenOrderDe return orders; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) - { - JToken resultArray = await MakePrivateAPIRequestAsync("returnOrderTrades", new object[] { "orderNumber", orderId }); + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + { + if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); + JToken resultArray = await MakePrivateAPIRequestAsync("returnOrderTrades", new object[] { "orderNumber", orderId }); string tickerSymbol = resultArray[0]["currencyPair"].ToStringInvariant(); List orders = new List(); ParseCompletedOrderDetails(orders, resultArray, tickerSymbol); diff --git a/src/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs b/src/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs index 1c7c87b0a..6f7106f05 100644 --- a/src/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs @@ -202,9 +202,10 @@ protected override async Task> OnGetAmountsAvailable return amounts; } - protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null) - { - var payload = await GetNoncePayloadAsync(); + protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + { + if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); + var payload = await GetNoncePayloadAsync(); payload.Add("method", "getInfo"); payload.Add("order_id", orderId); JToken token = await MakeJsonRequestAsync("/", PrivateURL, payload, "POST"); diff --git a/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs b/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs index 0ef9d84ba..92a8975dc 100644 --- a/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs @@ -203,7 +203,7 @@ protected virtual Task OnPlaceOrderAsync(ExchangeOrderReque throw new NotImplementedException(); protected virtual Task OnPlaceOrdersAsync(params ExchangeOrderRequest[] order) => throw new NotImplementedException(); - protected virtual Task OnGetOrderDetailsAsync(string orderId, string? marketSymbol = null) => + protected virtual Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string? marketSymbol = null) => throw new NotImplementedException(); protected virtual Task> OnGetOpenOrderDetailsAsync(string? marketSymbol = null) => throw new NotImplementedException(); @@ -935,12 +935,13 @@ public virtual async Task PlaceOrdersAsync(params Exchang /// Get order details /// /// Order id to get details for + /// /// Symbol of order (most exchanges do not require this) /// Order details - public virtual async Task GetOrderDetailsAsync(string orderId, string? marketSymbol = null) + public virtual async Task GetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string? marketSymbol = null) { marketSymbol = NormalizeMarketSymbol(marketSymbol); - return await Cache.CacheMethod(MethodCachePolicy, async() => await OnGetOrderDetailsAsync(orderId, marketSymbol), nameof(GetOrderDetailsAsync), nameof(orderId), orderId, nameof(marketSymbol), marketSymbol); + return await Cache.CacheMethod(MethodCachePolicy, async() => await OnGetOrderDetailsAsync(orderId, isClientOrderId: isClientOrderId, marketSymbol: marketSymbol), nameof(GetOrderDetailsAsync), nameof(orderId), orderId, nameof(isClientOrderId), isClientOrderId, nameof(marketSymbol), marketSymbol); } /// diff --git a/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs b/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs index e9f37155a..07b9fd808 100644 --- a/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs +++ b/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs @@ -327,7 +327,7 @@ public static async Task PlaceSafeMarketOrderAsync(this Exc for (; i < maxTries; i++) { await System.Threading.Tasks.Task.Delay(500); - result = await api.GetOrderDetailsAsync(result.OrderId, symbol); + result = await api.GetOrderDetailsAsync(result.OrderId, marketSymbol: symbol); switch (result.Result) { case ExchangeAPIOrderResult.Filled: diff --git a/src/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs b/src/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs index 58cb7f5f0..3e6ad1877 100644 --- a/src/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs @@ -206,9 +206,10 @@ public interface IExchangeAPI : IDisposable, IBaseAPI, IOrderBookProvider /// Get details of an order /// /// order id + /// /// Market Symbol /// Order details - Task GetOrderDetailsAsync(string orderId, string? marketSymbol = null); + Task GetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string? marketSymbol = null); /// /// Get the details of all open orders diff --git a/src/ExchangeSharpConsole/Options/BuyOption.cs b/src/ExchangeSharpConsole/Options/BuyOption.cs index 7de49919b..08f54a04d 100644 --- a/src/ExchangeSharpConsole/Options/BuyOption.cs +++ b/src/ExchangeSharpConsole/Options/BuyOption.cs @@ -54,7 +54,7 @@ private async Task WaitForOrder(ExchangeOrderResult order, IExchangeAPI api) await Task.Delay(IntervalMs) .ConfigureAwait(false); - order = await api.GetOrderDetailsAsync(order.OrderId, order.MarketSymbol); + order = await api.GetOrderDetailsAsync(order.OrderId, marketSymbol: order.MarketSymbol); } Console.Clear(); diff --git a/src/ExchangeSharpConsole/Options/OrderDetailsOption.cs b/src/ExchangeSharpConsole/Options/OrderDetailsOption.cs index 86963f697..e4ffb6111 100644 --- a/src/ExchangeSharpConsole/Options/OrderDetailsOption.cs +++ b/src/ExchangeSharpConsole/Options/OrderDetailsOption.cs @@ -14,7 +14,7 @@ public override async Task RunCommand() Authenticate(api); - var orderDetails = await api.GetOrderDetailsAsync(OrderId, MarketSymbol); + var orderDetails = await api.GetOrderDetailsAsync(OrderId, marketSymbol: MarketSymbol); Console.WriteLine(orderDetails); WaitInteractively(); diff --git a/tests/ExchangeSharpTests/ExchangeBitBankTests.cs b/tests/ExchangeSharpTests/ExchangeBitBankTests.cs index 49798f870..2b51ae7d4 100644 --- a/tests/ExchangeSharpTests/ExchangeBitBankTests.cs +++ b/tests/ExchangeSharpTests/ExchangeBitBankTests.cs @@ -189,7 +189,7 @@ public async Task ShouldGetOrderDetail() "; var api = MakeMockRequestMaker(data); // Throws error when no Market Symbol - var resp = await api.GetOrderDetailsAsync("558167000", "BTC-JPY"); + var resp = await api.GetOrderDetailsAsync("558167000", marketSymbol: "BTC-JPY"); ExchangeOrderResult resp2 = await api.GetOrderDetailsAsync("58037954"); resp.Should().BeEquivalentTo(resp2); } From bcecd9e6612a68a593aee4f2f56467cbcc96288a Mon Sep 17 00:00:00 2001 From: Victor Lee Date: Sat, 18 Sep 2021 11:01:20 -0700 Subject: [PATCH 2/2] address PR feedback --- .../API/Exchanges/Aquanow/ExchangeAquanowAPI.cs | 2 +- src/ExchangeSharp/API/Exchanges/BL3P/ExchangeBL3PAPI.cs | 2 +- .../API/Exchanges/BinanceGroup/BinanceGroupCommon.cs | 2 +- .../API/Exchanges/BitBank/ExchangeBitBankAPI.cs | 2 +- .../API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs | 2 +- .../API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs | 2 +- .../API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs | 2 +- .../API/Exchanges/Bittrex/ExchangeBittrexAPI.cs | 2 +- src/ExchangeSharp/API/Exchanges/Bybit/ExchangeBybitAPI.cs | 2 +- .../API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs | 2 +- .../API/Exchanges/Digifinex/ExchangeDigifinexAPI.cs | 2 +- .../API/Exchanges/GateIo/ExchangeGateIoAPI.cs | 2 +- .../API/Exchanges/Gemini/ExchangeGeminiAPI.cs | 2 +- .../API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs | 2 +- src/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs | 2 +- .../API/Exchanges/Kraken/ExchangeKrakenAPI.cs | 2 +- .../API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs | 2 +- src/ExchangeSharp/API/Exchanges/LBank/ExchangeLBankAPI.cs | 2 +- .../API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs | 2 +- src/ExchangeSharp/API/Exchanges/NDAX/ExchangeNDAXAPI.cs | 2 +- src/ExchangeSharp/API/Exchanges/OKGroup/OKGroupCommon.cs | 2 +- .../API/Exchanges/Poloniex/ExchangePoloniexAPI.cs | 2 +- src/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs | 2 +- src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs | 8 ++++---- src/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs | 4 ++-- 25 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/ExchangeSharp/API/Exchanges/Aquanow/ExchangeAquanowAPI.cs b/src/ExchangeSharp/API/Exchanges/Aquanow/ExchangeAquanowAPI.cs index 5375016cf..517b7097d 100644 --- a/src/ExchangeSharp/API/Exchanges/Aquanow/ExchangeAquanowAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Aquanow/ExchangeAquanowAPI.cs @@ -194,7 +194,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return orderDetails; } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { if (string.IsNullOrWhiteSpace(orderId)) { diff --git a/src/ExchangeSharp/API/Exchanges/BL3P/ExchangeBL3PAPI.cs b/src/ExchangeSharp/API/Exchanges/BL3P/ExchangeBL3PAPI.cs index 824f021dd..ddef36e2e 100644 --- a/src/ExchangeSharp/API/Exchanges/BL3P/ExchangeBL3PAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/BL3P/ExchangeBL3PAPI.cs @@ -308,7 +308,7 @@ protected override async Task OnCancelOrderAsync(string orderId, string marketSy .Except(); } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { if (string.IsNullOrWhiteSpace(marketSymbol)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(marketSymbol)); diff --git a/src/ExchangeSharp/API/Exchanges/BinanceGroup/BinanceGroupCommon.cs b/src/ExchangeSharp/API/Exchanges/BinanceGroup/BinanceGroupCommon.cs index f676d57ae..21024b50f 100644 --- a/src/ExchangeSharp/API/Exchanges/BinanceGroup/BinanceGroupCommon.cs +++ b/src/ExchangeSharp/API/Exchanges/BinanceGroup/BinanceGroupCommon.cs @@ -580,7 +580,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return ParseOrder(token); } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string? marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string? marketSymbol = null, bool isClientOrderId = false) { Dictionary payload = await GetNoncePayloadAsync(); if (string.IsNullOrWhiteSpace(marketSymbol)) diff --git a/src/ExchangeSharp/API/Exchanges/BitBank/ExchangeBitBankAPI.cs b/src/ExchangeSharp/API/Exchanges/BitBank/ExchangeBitBankAPI.cs index 5bd6efb4c..e6b15bb9d 100644 --- a/src/ExchangeSharp/API/Exchanges/BitBank/ExchangeBitBankAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/BitBank/ExchangeBitBankAPI.cs @@ -148,7 +148,7 @@ protected override async Task OnCancelOrderAsync(string orderId, string marketSy await MakeJsonRequestAsync("/user/spot/cancel_order", baseUrl: BaseUrlPrivate, payload: payload, requestMethod: "POST"); } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); var payload = await GetNoncePayloadAsync(); diff --git a/src/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs b/src/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs index 5591240b4..17e473d56 100644 --- a/src/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs @@ -600,7 +600,7 @@ protected override async Task> OnGetOpenOrderDe return orders; } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { List orders = new List(); Dictionary payload = await GetNoncePayloadAsync(); diff --git a/src/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs b/src/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs index b972cec61..fab3250bc 100644 --- a/src/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs @@ -493,7 +493,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return ParseOrder(obj); } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); if (string.IsNullOrWhiteSpace(orderId)) diff --git a/src/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs b/src/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs index 20f72709b..9bb89a1e5 100644 --- a/src/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs @@ -219,7 +219,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd }; } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { //{ // "status": "Finished", diff --git a/src/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs b/src/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs index bfd6de023..781c5a6d3 100644 --- a/src/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs @@ -412,7 +412,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); if (string.IsNullOrWhiteSpace(orderId)) diff --git a/src/ExchangeSharp/API/Exchanges/Bybit/ExchangeBybitAPI.cs b/src/ExchangeSharp/API/Exchanges/Bybit/ExchangeBybitAPI.cs index bfa1b7a75..0d93d1223 100644 --- a/src/ExchangeSharp/API/Exchanges/Bybit/ExchangeBybitAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Bybit/ExchangeBybitAPI.cs @@ -765,7 +765,7 @@ protected override async Task> OnGetOpenOrderDe return orders; } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { var orders = await DoGetOrderDetailsAsync(orderId, isClientOrderId: isClientOrderId, marketSymbol: marketSymbol); if (orders.Count() > 0) diff --git a/src/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs b/src/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs index 460a82ea4..d0ce1a9c8 100644 --- a/src/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs @@ -594,7 +594,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return ParseOrder(result); } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { // Orders may be queried using either the exchange assigned id or the client assigned client_oid. When using client_oid it must be preceded by the client: namespace. JToken obj = await MakeJsonRequestAsync("/orders/" + (isClientOrderId ? "client:" : "") + orderId, null, await GetNoncePayloadAsync(), "GET"); diff --git a/src/ExchangeSharp/API/Exchanges/Digifinex/ExchangeDigifinexAPI.cs b/src/ExchangeSharp/API/Exchanges/Digifinex/ExchangeDigifinexAPI.cs index 71c87a385..6efa71ecd 100644 --- a/src/ExchangeSharp/API/Exchanges/Digifinex/ExchangeDigifinexAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Digifinex/ExchangeDigifinexAPI.cs @@ -361,7 +361,7 @@ protected override async Task> OnGetCompletedOr }); } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); Dictionary payload = await GetNoncePayloadAsync(); diff --git a/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs b/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs index 7b7ef1d13..c1c7c4c31 100644 --- a/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs @@ -376,7 +376,7 @@ private static ExchangeAPIOrderResult ParseExchangeAPIOrderResult(string status, } } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null, bool isClientOrderId = false) { if (string.IsNullOrEmpty(symbol)) { diff --git a/src/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs b/src/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs index ad995ab9c..fc6812705 100644 --- a/src/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs @@ -320,7 +320,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return ParseOrder(obj); } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { if (string.IsNullOrWhiteSpace(orderId)) { diff --git a/src/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs b/src/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs index c186f3031..2887ddc6d 100644 --- a/src/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Hitbtc/ExchangeHitbtcAPI.cs @@ -257,7 +257,7 @@ protected override async Task> OnGetAmountsAvailable /// /// /// - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); JToken obj = await MakeJsonRequestAsync("/history/order/" + orderId + "/trades", null, await GetNoncePayloadAsync()); diff --git a/src/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs b/src/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs index 75399ab19..74a10dc1e 100644 --- a/src/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Huobi/ExchangeHuobiAPI.cs @@ -607,7 +607,7 @@ protected override async Task> OnGetAmountsAvailable return amounts; } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { /* {{ diff --git a/src/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs b/src/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs index 65cb1e110..d3c45ca6c 100644 --- a/src/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs @@ -790,7 +790,7 @@ protected override async Task OnPlaceOrderAsync(ExchangeOrd return result; } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { if (string.IsNullOrWhiteSpace(orderId)) { diff --git a/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs b/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs index cf38f82b5..ff6877c88 100644 --- a/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/KuCoin/ExchangeKuCoinAPI.cs @@ -378,7 +378,7 @@ protected override async Task> OnGetOpenOrderDe /// /// /// - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { var payload = await GetNoncePayloadAsync(); if (isClientOrderId) diff --git a/src/ExchangeSharp/API/Exchanges/LBank/ExchangeLBankAPI.cs b/src/ExchangeSharp/API/Exchanges/LBank/ExchangeLBankAPI.cs index 14393d9a2..361a46f31 100644 --- a/src/ExchangeSharp/API/Exchanges/LBank/ExchangeLBankAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/LBank/ExchangeLBankAPI.cs @@ -356,7 +356,7 @@ protected override async Task OnCancelOrderAsync(string orderId, string symbol = } //GetOrderDetails 13 - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null, bool isClientOrderId = false) { if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); Dictionary payload = new Dictionary diff --git a/src/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs b/src/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs index eb57999c9..e8709eb26 100644 --- a/src/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Livecoin/ExchangeLivecoinAPI.cs @@ -219,7 +219,7 @@ protected override async Task> OnGetAmountsAvailable return amounts; } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); JToken token = await MakeJsonRequestAsync("/exchange/order?orderId=" + orderId, null, await GetNoncePayloadAsync()); diff --git a/src/ExchangeSharp/API/Exchanges/NDAX/ExchangeNDAXAPI.cs b/src/ExchangeSharp/API/Exchanges/NDAX/ExchangeNDAXAPI.cs index b8fa4e226..c0fc332da 100644 --- a/src/ExchangeSharp/API/Exchanges/NDAX/ExchangeNDAXAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/NDAX/ExchangeNDAXAPI.cs @@ -197,7 +197,7 @@ protected override async Task OnPlaceOrdersAsync(params E return resp.ToArray(); } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string symbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string symbol = null, bool isClientOrderId = false) { if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); await EnsureInstrumentIdsAvailable(); diff --git a/src/ExchangeSharp/API/Exchanges/OKGroup/OKGroupCommon.cs b/src/ExchangeSharp/API/Exchanges/OKGroup/OKGroupCommon.cs index dac3819a9..7046586f5 100644 --- a/src/ExchangeSharp/API/Exchanges/OKGroup/OKGroupCommon.cs +++ b/src/ExchangeSharp/API/Exchanges/OKGroup/OKGroupCommon.cs @@ -461,7 +461,7 @@ protected override async Task OnCancelOrderAsync(string orderId, string marketSy await MakeJsonRequestAsync("/cancel_order.do", BaseUrl, payload, "POST"); } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { List orders = new List(); Dictionary payload = await GetNoncePayloadAsync(); diff --git a/src/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs b/src/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs index c0f4fb4ed..14fbfbf6a 100644 --- a/src/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs @@ -840,7 +840,7 @@ protected override async Task> OnGetOpenOrderDe return orders; } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); JToken resultArray = await MakePrivateAPIRequestAsync("returnOrderTrades", new object[] { "orderNumber", orderId }); diff --git a/src/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs b/src/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs index 6f7106f05..fe467e038 100644 --- a/src/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/Yobit/ExchangeYobitAPI.cs @@ -202,7 +202,7 @@ protected override async Task> OnGetAmountsAvailable return amounts; } - protected override async Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null) + protected override async Task OnGetOrderDetailsAsync(string orderId, string marketSymbol = null, bool isClientOrderId = false) { if (isClientOrderId) throw new NotImplementedException("Querying by client order ID is not implemented in ExchangeSharp. Please submit a PR if you are interested in this feature"); var payload = await GetNoncePayloadAsync(); diff --git a/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs b/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs index 92a8975dc..c58d11d35 100644 --- a/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs @@ -203,7 +203,7 @@ protected virtual Task OnPlaceOrderAsync(ExchangeOrderReque throw new NotImplementedException(); protected virtual Task OnPlaceOrdersAsync(params ExchangeOrderRequest[] order) => throw new NotImplementedException(); - protected virtual Task OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string? marketSymbol = null) => + protected virtual Task OnGetOrderDetailsAsync(string orderId, string? marketSymbol = null, bool isClientOrderId = false) => throw new NotImplementedException(); protected virtual Task> OnGetOpenOrderDetailsAsync(string? marketSymbol = null) => throw new NotImplementedException(); @@ -935,13 +935,13 @@ public virtual async Task PlaceOrdersAsync(params Exchang /// Get order details /// /// Order id to get details for - /// /// Symbol of order (most exchanges do not require this) + /// /// Order details - public virtual async Task GetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string? marketSymbol = null) + public virtual async Task GetOrderDetailsAsync(string orderId, string? marketSymbol = null, bool isClientOrderId = false) { marketSymbol = NormalizeMarketSymbol(marketSymbol); - return await Cache.CacheMethod(MethodCachePolicy, async() => await OnGetOrderDetailsAsync(orderId, isClientOrderId: isClientOrderId, marketSymbol: marketSymbol), nameof(GetOrderDetailsAsync), nameof(orderId), orderId, nameof(isClientOrderId), isClientOrderId, nameof(marketSymbol), marketSymbol); + return await Cache.CacheMethod(MethodCachePolicy, async() => await OnGetOrderDetailsAsync(orderId, marketSymbol: marketSymbol, isClientOrderId: isClientOrderId), nameof(GetOrderDetailsAsync), nameof(orderId), orderId, nameof(isClientOrderId), isClientOrderId, nameof(marketSymbol), marketSymbol); } /// diff --git a/src/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs b/src/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs index 3e6ad1877..3931cddf6 100644 --- a/src/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs @@ -206,10 +206,10 @@ public interface IExchangeAPI : IDisposable, IBaseAPI, IOrderBookProvider /// Get details of an order /// /// order id - /// /// Market Symbol + /// /// Order details - Task GetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string? marketSymbol = null); + Task GetOrderDetailsAsync(string orderId, string? marketSymbol = null, bool isClientOrderId = false); /// /// Get the details of all open orders