Skip to content

Commit 79ecc3b

Browse files
committed
Added ability to GetOrderDetailsAsync() by ClientOrderId
- many, but not all, exchanges support this
1 parent 7fcff44 commit 79ecc3b

29 files changed

+119
-71
lines changed

src/ExchangeSharp/API/Exchanges/Aquanow/ExchangeAquanowAPI.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,13 @@ protected override async Task<ExchangeOrderResult> OnPlaceOrderAsync(ExchangeOrd
194194
return orderDetails;
195195
}
196196

197-
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, string marketSymbol = null)
197+
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null)
198198
{
199199
if (string.IsNullOrWhiteSpace(orderId))
200200
{
201201
return null;
202202
}
203+
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");
203204
var payload = await GetNoncePayloadAsync();
204205
JToken result = await MakeJsonRequestAsync<JToken>($"/trades/v1/order?orderId={orderId}", null, payload, "GET");
205206
bool isBuy = result["tradeSide"].ToStringInvariant() == "buy" ? true : false;

src/ExchangeSharp/API/Exchanges/BL3P/ExchangeBL3PAPI.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ protected override async Task<ExchangeOrderResult> OnPlaceOrderAsync(ExchangeOrd
271271
var result = JsonConvert.DeserializeObject<BL3POrderAddResponse>(resultBody)
272272
.Except();
273273

274-
var orderDetails = await GetOrderDetailsAsync(result.OrderId, order.MarketSymbol);
274+
var orderDetails = await GetOrderDetailsAsync(result.OrderId, marketSymbol: order.MarketSymbol);
275275

276276
return orderDetails;
277277
}
@@ -308,10 +308,11 @@ protected override async Task OnCancelOrderAsync(string orderId, string marketSy
308308
.Except();
309309
}
310310

311-
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, string marketSymbol = null)
311+
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null)
312312
{
313313
if (string.IsNullOrWhiteSpace(marketSymbol))
314314
throw new ArgumentException("Value cannot be null or whitespace.", nameof(marketSymbol));
315+
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");
315316

316317
var data = new Dictionary<string, object>
317318
{

src/ExchangeSharp/API/Exchanges/BinanceGroup/BinanceGroupCommon.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -580,15 +580,20 @@ protected override async Task<ExchangeOrderResult> OnPlaceOrderAsync(ExchangeOrd
580580
return ParseOrder(token);
581581
}
582582

583-
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, string? marketSymbol = null)
583+
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string? marketSymbol = null)
584584
{
585585
Dictionary<string, object> payload = await GetNoncePayloadAsync();
586586
if (string.IsNullOrWhiteSpace(marketSymbol))
587587
{
588588
throw new InvalidOperationException("Binance single order details request requires symbol");
589589
}
590590
payload["symbol"] = marketSymbol!;
591-
payload["orderId"] = orderId;
591+
592+
if (isClientOrderId) // Either orderId or origClientOrderId must be sent.
593+
payload["origClientOrderId"] = orderId;
594+
else
595+
payload["orderId"] = orderId;
596+
592597
JToken token = await MakeJsonRequestAsync<JToken>("/order", BaseUrlPrivate, payload);
593598
ExchangeOrderResult result = ParseOrder(token);
594599

src/ExchangeSharp/API/Exchanges/BitBank/ExchangeBitBankAPI.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,9 @@ protected override async Task OnCancelOrderAsync(string orderId, string marketSy
148148
await MakeJsonRequestAsync<JToken>("/user/spot/cancel_order", baseUrl: BaseUrlPrivate, payload: payload, requestMethod: "POST");
149149
}
150150

151-
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, string marketSymbol = null)
151+
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null)
152152
{
153+
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");
153154
var payload = await GetNoncePayloadAsync();
154155
payload.Add("order_id", orderId);
155156
if (marketSymbol == null)

src/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,11 +600,11 @@ protected override async Task<IEnumerable<ExchangeOrderResult>> OnGetOpenOrderDe
600600
return orders;
601601
}
602602

603-
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, string marketSymbol = null)
603+
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null)
604604
{
605605
List<ExchangeOrderResult> orders = new List<ExchangeOrderResult>();
606606
Dictionary<string, object> payload = await GetNoncePayloadAsync();
607-
string query = $"/order?filter={{\"orderID\": \"{orderId}\"}}";
607+
string query = $"/order?filter={{\"{(isClientOrderId ? "clOrdID" : "orderID")}\": \"{orderId}\"}}";
608608
JToken token = await MakeJsonRequestAsync<JToken>(query, BaseUrl, payload, "GET");
609609
foreach (JToken order in token)
610610
{

src/ExchangeSharp/API/Exchanges/Bitfinex/ExchangeBitfinexAPI.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,8 +493,9 @@ protected override async Task<ExchangeOrderResult> OnPlaceOrderAsync(ExchangeOrd
493493
return ParseOrder(obj);
494494
}
495495

496-
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, string marketSymbol = null)
496+
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null)
497497
{
498+
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");
498499
if (string.IsNullOrWhiteSpace(orderId))
499500
{
500501
return null;

src/ExchangeSharp/API/Exchanges/Bitstamp/ExchangeBitstampAPI.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,8 @@ protected override async Task<ExchangeOrderResult> OnPlaceOrderAsync(ExchangeOrd
219219
};
220220
}
221221

222-
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, string marketSymbol = null)
223-
{
222+
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null)
223+
{
224224
//{
225225
// "status": "Finished",
226226
// "id": 1022694747,
@@ -241,8 +241,11 @@ protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string
241241
}
242242
string url = "/order_status/";
243243
Dictionary<string, object> payload = await GetNoncePayloadAsync();
244-
payload["id"] = orderId;
245-
JObject result = await MakeJsonRequestAsync<JObject>(url, null, payload, "POST");
244+
if (isClientOrderId) // Order can be fetched by using either id or client_order_id parameter.
245+
payload["client_order_id"] = orderId;
246+
else
247+
payload["id"] = orderId;
248+
JObject result = await MakeJsonRequestAsync<JObject>(url, null, payload, "POST");
246249

247250
var transactions = result["transactions"] as JArray;
248251
var anyTransaction = transactions.Any();

src/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,9 @@ protected override async Task<ExchangeOrderResult> OnPlaceOrderAsync(ExchangeOrd
412412
}
413413

414414

415-
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, string marketSymbol = null)
415+
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null)
416416
{
417+
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");
417418
if (string.IsNullOrWhiteSpace(orderId))
418419
{
419420
return null;

src/ExchangeSharp/API/Exchanges/Bybit/ExchangeBybitAPI.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -718,13 +718,16 @@ public async Task<ExchangeFunding> GetPredictedFundingRateAsync(string marketSym
718718
return funding;
719719
}
720720

721-
private async Task<IEnumerable<ExchangeOrderResult>> DoGetOrderDetailsAsync(string orderId, string marketSymbol = null)
721+
private async Task<IEnumerable<ExchangeOrderResult>> DoGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null)
722722
{
723723
var extraParams = new Dictionary<string, object>();
724724

725725
if (orderId != null)
726726
{
727-
extraParams["order_id"] = orderId;
727+
if (isClientOrderId)
728+
extraParams["order_link_id"] = orderId;
729+
else
730+
extraParams["order_id"] = orderId;
728731
}
729732

730733
if (!string.IsNullOrWhiteSpace(marketSymbol))
@@ -758,13 +761,13 @@ private async Task<IEnumerable<ExchangeOrderResult>> DoGetOrderDetailsAsync(stri
758761
//Note, Bybit is not recommending the use of "/v2/private/order/list" now that "/v2/private/order" is capable of returning multiple results
759762
protected override async Task<IEnumerable<ExchangeOrderResult>> OnGetOpenOrderDetailsAsync(string marketSymbol = null)
760763
{
761-
var orders = await DoGetOrderDetailsAsync(null, marketSymbol);
764+
var orders = await DoGetOrderDetailsAsync(null, isClientOrderId: false, marketSymbol: marketSymbol);
762765
return orders;
763766
}
764767

765-
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, string marketSymbol = null)
768+
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null)
766769
{
767-
var orders = await DoGetOrderDetailsAsync(orderId, marketSymbol);
770+
var orders = await DoGetOrderDetailsAsync(orderId, isClientOrderId: isClientOrderId, marketSymbol: marketSymbol);
768771
if (orders.Count() > 0)
769772
{
770773
return orders.First();

src/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -594,9 +594,10 @@ protected override async Task<ExchangeOrderResult> OnPlaceOrderAsync(ExchangeOrd
594594
return ParseOrder(result);
595595
}
596596

597-
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, string marketSymbol = null)
598-
{
599-
JToken obj = await MakeJsonRequestAsync<JToken>("/orders/" + orderId, null, await GetNoncePayloadAsync(), "GET");
597+
protected override async Task<ExchangeOrderResult> OnGetOrderDetailsAsync(string orderId, bool isClientOrderId = false, string marketSymbol = null)
598+
{ // 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.
599+
JToken obj = await MakeJsonRequestAsync<JToken>("/orders/" + (isClientOrderId ? "client:" : "") + orderId,
600+
null, await GetNoncePayloadAsync(), "GET");
600601
return ParseOrder(obj);
601602
}
602603

0 commit comments

Comments
 (0)