diff --git a/Binance.Net.UnitTests/BinanceClientTests.cs b/Binance.Net.UnitTests/BinanceClientTests.cs index 1bb6100a9..ae4689c0a 100644 --- a/Binance.Net.UnitTests/BinanceClientTests.cs +++ b/Binance.Net.UnitTests/BinanceClientTests.cs @@ -20,6 +20,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Binance.Net.Interfaces.Clients; +using System.Diagnostics; namespace Binance.Net.UnitTests { diff --git a/Binance.Net/Binance.Net.csproj b/Binance.Net/Binance.Net.csproj index 5673f1781..eb8b44f68 100644 --- a/Binance.Net/Binance.Net.csproj +++ b/Binance.Net/Binance.Net.csproj @@ -1,7 +1,7 @@ - + netstandard2.0;netstandard2.1 - 10.0 + 12.0 enable @@ -48,7 +48,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Binance.Net/Binance.Net.xml b/Binance.Net/Binance.Net.xml index 9c113eee6..c5550a847 100644 --- a/Binance.Net/Binance.Net.xml +++ b/Binance.Net/Binance.Net.xml @@ -1895,7 +1895,7 @@ - + @@ -11256,7 +11256,7 @@ Cancellation token Order list info - + Place a new OCO order. An OCO has 2 legs called the above leg and below leg. One of the legs must be a LimitMaker order and the other leg must be StopLoss or StopLossLimit order. @@ -11283,6 +11283,7 @@ Strategy id for the below leg Strategy type for the below leg Self trade prevention mode + List client order id Cancellation token @@ -29332,6 +29333,16 @@ Binance options + + + Whether to allow the client to adjust the clientOrderId parameter send by the user when placing orders to include a client reference. This reference is used by the exchange to allocate a small percentage of the paid trading fees to developer of this library. Defaults to false.
+ Note that:
+ * It does not impact the amount of fees a user pays in any way
+ * It does not impact functionality. The reference is added just before sending the request and removed again during data deserialization
+ * It does respect client order id field limitations. For example if the user provided client order id parameter is too long to fit the reference it will not be added
+ * Toggling this option might fail operations using a clientOrderId parameter for pre-existing orders which were placed before the toggle. Operations on orders placed after the toggle will work as expected. It's adviced to toggle when there are no open orders +
+
Options for the Binance SymbolOrderBook @@ -29377,11 +29388,6 @@ How often the trade rules should be updated. Only used when TradeRulesBehaviour is not None - - - The broker reference id to use - - Options for the BinanceRestClient @@ -29402,6 +29408,16 @@ The default receive window for requests + + + Whether to allow the client to adjust the clientOrderId parameter send by the user when placing orders to include a client reference. This reference is used by the exchange to allocate a small percentage of the paid trading fees to developer of this library. Defaults to false.
+ Note that:
+ * It does not impact the amount of fees a user pays in any way
+ * It does not impact functionality. The reference is added just before sending the request and removed again during data deserialization
+ * It does respect client order id field limitations. For example if the user provided client order id parameter is too long to fit the reference it will not be added
+ * Toggling this option might fail operations using a clientOrderId parameter for pre-existing orders which were placed before the toggle. Operations on orders placed after the toggle will work as expected. It's adviced to toggle when there are no open orders +
+
Spot API options @@ -29432,11 +29448,6 @@ How often the trade rules should be updated. Only used when TradeRulesBehaviour is not None - - - The broker reference id to use - - Options for the BinanceSocketClient @@ -29452,6 +29463,16 @@ ctor + + + Whether to allow the client to adjust the clientOrderId parameter send by the user when placing orders to include a client reference. This reference is used by the exchange to allocate a small percentage of the paid trading fees to developer of this library. Defaults to false.
+ Note that:
+ * It does not impact the amount of fees a user pays in any way
+ * It does not impact functionality. The reference is added just before sending the request and removed again during data deserialization
+ * It does respect client order id field limitations. For example if the user provided client order id parameter is too long to fit the reference it will not be added
+ * Toggling this option might fail operations using a clientOrderId parameter for pre-existing orders which were placed before the toggle. Operations on orders placed after the toggle will work as expected. It's adviced to toggle when there are no open orders +
+
Options for the Spot API diff --git a/Binance.Net/BinanceExchange.cs b/Binance.Net/BinanceExchange.cs index 833942490..36fb8b314 100644 --- a/Binance.Net/BinanceExchange.cs +++ b/Binance.Net/BinanceExchange.cs @@ -38,6 +38,11 @@ public static class BinanceExchange "https://binance-docs.github.io/apidocs/spot/en/#change-log" }; + internal const string ClientOrderIdSpot = "x-VICEW9VV"; + internal const string ClientOrderIdFutures = "x-d63tKbx3"; + internal const string ClientOrderIdPrefixSpot = ClientOrderIdSpot + LibraryHelpers.ClientOrderIdSeperator; + internal const string ClientOrderIdPrefixFutures = ClientOrderIdFutures + LibraryHelpers.ClientOrderIdSeperator; + /// /// Format a base and quote asset to a Binance recognized symbol /// diff --git a/Binance.Net/Clients/CoinFuturesApi/BinanceRestClientCoinFuturesApi.cs b/Binance.Net/Clients/CoinFuturesApi/BinanceRestClientCoinFuturesApi.cs index 72b37abe4..44886938f 100644 --- a/Binance.Net/Clients/CoinFuturesApi/BinanceRestClientCoinFuturesApi.cs +++ b/Binance.Net/Clients/CoinFuturesApi/BinanceRestClientCoinFuturesApi.cs @@ -27,8 +27,6 @@ internal partial class BinanceRestClientCoinFuturesApi : RestApiClient, IBinance internal static TimeSyncState _timeSyncState = new TimeSyncState("Coin Futures Api"); - internal readonly string _brokerId; - #endregion #region Api clients @@ -62,8 +60,6 @@ internal BinanceRestClientCoinFuturesApi(ILogger logger, HttpClient? httpClient, RequestBodyEmptyContent = ""; RequestBodyFormat = RequestBodyFormat.FormData; ArraySerialization = ArrayParametersSerialization.MultipleValues; - - _brokerId = !string.IsNullOrEmpty(options.CoinFuturesOptions.BrokerId) ? options.CoinFuturesOptions.BrokerId! : "x-d63tKbx3"; } #endregion diff --git a/Binance.Net/Clients/CoinFuturesApi/BinanceRestClientCoinFuturesApiTrading.cs b/Binance.Net/Clients/CoinFuturesApi/BinanceRestClientCoinFuturesApiTrading.cs index f94ef8d48..3c3d6efaa 100644 --- a/Binance.Net/Clients/CoinFuturesApi/BinanceRestClientCoinFuturesApiTrading.cs +++ b/Binance.Net/Clients/CoinFuturesApi/BinanceRestClientCoinFuturesApiTrading.cs @@ -69,7 +69,7 @@ public async Task> PlaceOrderAsync( price = rulesCheck.Price; stopPrice = rulesCheck.StopPrice; - string clientOrderId = newClientOrderId ?? ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); + var clientOrderId = LibraryHelpers.ApplyBrokerId(newClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection() { @@ -147,7 +147,7 @@ public async Task>>> P orderParameters.AddEnum("side", order.Side); orderParameters.AddEnum("type", order.Type); - var clientOrderId = order.NewClientOrderId ?? ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); + var clientOrderId = LibraryHelpers.ApplyBrokerId(order.NewClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); orderParameters.AddOptionalParameter("quantity", order.Quantity?.ToString(CultureInfo.InvariantCulture)); orderParameters.AddOptionalParameter("newClientOrderId", clientOrderId); orderParameters.AddOptionalParameter("price", order.Price?.ToString(CultureInfo.InvariantCulture)); @@ -194,6 +194,9 @@ public async Task> GetOrderAsync(string symbo if (orderId == null && origClientOrderId == null) throw new ArgumentException("Either orderId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol } @@ -217,6 +220,9 @@ public async Task> CancelOrderAsync(string sy if (!orderId.HasValue && string.IsNullOrEmpty(origClientOrderId)) throw new ArgumentException("Either orderId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol } @@ -283,6 +289,8 @@ public async Task>>> C if (origClientOrderIdList?.Count() > 10) throw new ArgumentException("origClientOrderIdList cannot contain more than 10 items"); + var convertClientOrderIdList = origClientOrderIdList?.Select(x => LibraryHelpers.ApplyBrokerId(x, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId)); + var parameters = new ParameterCollection { { "symbol", symbol } @@ -323,6 +331,9 @@ public async Task> GetOpenOrderAsync(string s if (orderId == null && origClientOrderId == null) throw new ArgumentException("Either orderId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol } diff --git a/Binance.Net/Clients/SpotApi/BinanceRestClientSpotApi.cs b/Binance.Net/Clients/SpotApi/BinanceRestClientSpotApi.cs index 11ed3f389..2bd95b529 100644 --- a/Binance.Net/Clients/SpotApi/BinanceRestClientSpotApi.cs +++ b/Binance.Net/Clients/SpotApi/BinanceRestClientSpotApi.cs @@ -27,8 +27,6 @@ internal partial class BinanceRestClientSpotApi : RestApiClient, IBinanceRestCli internal BinanceExchangeInfo? _exchangeInfo; internal DateTime? _lastExchangeInfoUpdate; - internal readonly string _brokerId; - internal static TimeSyncState _timeSyncState = new TimeSyncState("Spot Api"); #endregion @@ -63,8 +61,6 @@ internal BinanceRestClientSpotApi(ILogger logger, HttpClient? httpClient, Binanc RequestBodyEmptyContent = ""; RequestBodyFormat = RequestBodyFormat.FormData; ArraySerialization = ArrayParametersSerialization.MultipleValues; - - _brokerId = !string.IsNullOrEmpty(options.SpotOptions.BrokerId) ? options.SpotOptions.BrokerId! : "x-VICEW9VV"; } #endregion @@ -124,7 +120,7 @@ internal async Task> PlaceOrderInternal(Uri ur stopPrice = rulesCheck.StopPrice; quoteQuantity = rulesCheck.QuoteQuantity; - string clientOrderId = newClientOrderId ?? ExchangeHelpers.AppendRandomString(_brokerId, 32); + var clientOrderId = LibraryHelpers.ApplyBrokerId(newClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection() { diff --git a/Binance.Net/Clients/SpotApi/BinanceRestClientSpotApiTrading.cs b/Binance.Net/Clients/SpotApi/BinanceRestClientSpotApiTrading.cs index 953ce0d23..e6a9845d7 100644 --- a/Binance.Net/Clients/SpotApi/BinanceRestClientSpotApiTrading.cs +++ b/Binance.Net/Clients/SpotApi/BinanceRestClientSpotApiTrading.cs @@ -141,6 +141,7 @@ public async Task> PlaceOrderAsync(string symb ct).ConfigureAwait(false); if (result) _baseClient.InvokeOrderPlaced(new OrderId() { SourceObject = result.Data, Id = result.Data.Id.ToString(CultureInfo.InvariantCulture) }); + return result; } @@ -154,6 +155,11 @@ public async Task> CancelOrderAsync(string symbo if (!orderId.HasValue && string.IsNullOrEmpty(origClientOrderId)) throw new ArgumentException("Either orderId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + if (newClientOrderId != null) + newClientOrderId = LibraryHelpers.ApplyBrokerId(newClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection() { { "symbol", symbol } @@ -168,6 +174,7 @@ public async Task> CancelOrderAsync(string symbo var result = await _baseClient.SendAsync(request, parameters, ct).ConfigureAwait(false); if (result) _baseClient.InvokeOrderCanceled(new OrderId() { SourceObject = result.Data, Id = result.Data.Id.ToString(CultureInfo.InvariantCulture) }); + return result; } @@ -235,7 +242,7 @@ public async Task> ReplaceOrderAsync(st stopPrice = rulesCheck.StopPrice; quoteQuantity = rulesCheck.QuoteQuantity; - string clientOrderId = newClientOrderId ?? ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); + var clientOrderId = LibraryHelpers.ApplyBrokerId(newClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection { @@ -278,6 +285,9 @@ public async Task> GetOrderAsync(string symbol, long if (orderId == null && origClientOrderId == null) throw new ArgumentException("Either orderId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection() { { "symbol", symbol } @@ -364,8 +374,8 @@ public async Task> PlaceOcoOrderAsync(string price = rulesCheck.Price!.Value; stopPrice = rulesCheck.StopPrice!.Value; - limitClientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); - stopClientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); + limitClientOrderId = LibraryHelpers.ApplyBrokerId(limitClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + stopClientOrderId = LibraryHelpers.ApplyBrokerId(stopClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection { @@ -429,8 +439,8 @@ public async Task> PlaceOcoOrderListAsync( int? receiveWindow = null, CancellationToken ct = default) { - aboveClientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); - belowClientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); + aboveClientOrderId = LibraryHelpers.ApplyBrokerId(aboveClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + belowClientOrderId = LibraryHelpers.ApplyBrokerId(belowClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection { @@ -475,6 +485,9 @@ public async Task> CancelOcoOrderAsync(string if (!orderListId.HasValue && string.IsNullOrEmpty(listClientOrderId)) throw new ArgumentException("Either orderListId or listClientOrderId must be sent"); + if (listClientOrderId != null) + listClientOrderId = LibraryHelpers.ApplyBrokerId(listClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol } @@ -498,6 +511,9 @@ public async Task> GetOcoOrderAsync(long? ord if (orderListId == null && origClientOrderId == null) throw new ArgumentException("Either orderListId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection(); parameters.AddOptionalParameter("orderListId", orderListId?.ToString(CultureInfo.InvariantCulture)); parameters.AddOptionalParameter("origClientOrderId", origClientOrderId); @@ -582,8 +598,8 @@ public async Task> PlaceOtoOrderListAsync( int? receiveWindow = null, CancellationToken ct = default) { - workingClientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); - pendingClientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); + workingClientOrderId = LibraryHelpers.ApplyBrokerId(workingClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + pendingClientOrderId = LibraryHelpers.ApplyBrokerId(pendingClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection(); parameters.Add("symbol", symbol); @@ -665,9 +681,10 @@ public async Task> PlaceOtocoOrderListAsync( int? receiveWindow = null, CancellationToken ct = default) { - workingClientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); - pendingAboveClientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); - pendingBelowClientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); + + workingClientOrderId = LibraryHelpers.ApplyBrokerId(workingClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + pendingAboveClientOrderId = LibraryHelpers.ApplyBrokerId(pendingAboveClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + pendingBelowClientOrderId = LibraryHelpers.ApplyBrokerId(pendingBelowClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection(); parameters.Add("symbol", symbol); @@ -796,6 +813,12 @@ public async Task> CancelMarginOrderAsync(string if (!orderId.HasValue && string.IsNullOrEmpty(origClientOrderId)) throw new ArgumentException("Either orderId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + + if (newClientOrderId != null) + newClientOrderId = LibraryHelpers.ApplyBrokerId(newClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol } @@ -841,6 +864,9 @@ public async Task> GetMarginOrderAsync(string symbol if (orderId == null && origClientOrderId == null) throw new ArgumentException("Either orderId or origClientOrderId should be provided"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol } @@ -956,8 +982,8 @@ public async Task> PlaceMarginOCOOrderA price = rulesCheck.Price!.Value; stopPrice = rulesCheck.StopPrice!.Value; - limitClientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); - stopClientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); + limitClientOrderId = LibraryHelpers.ApplyBrokerId(limitClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + stopClientOrderId = LibraryHelpers.ApplyBrokerId(stopClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId);; var parameters = new ParameterCollection { @@ -995,6 +1021,12 @@ public async Task> CancelMarginOcoOrder if (!orderListId.HasValue && string.IsNullOrEmpty(listClientOrderId)) throw new ArgumentException("Either orderListId or listClientOrderId must be sent"); + if (listClientOrderId != null) + listClientOrderId = LibraryHelpers.ApplyBrokerId(listClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + + if (newClientOrderId != null) + newClientOrderId = LibraryHelpers.ApplyBrokerId(newClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol } @@ -1019,6 +1051,9 @@ public async Task> GetMarginOcoOrderAsy if (orderListId == null && origClientOrderId == null) throw new ArgumentException("Either orderListId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection(); parameters.AddOptionalParameter("symbol", symbol); parameters.AddOptionalParameter("isIsolated", isIsolated.ToString()); @@ -1317,7 +1352,7 @@ public async Task> PlaceTimeWeightedAverag long? receiveWindow = null, CancellationToken ct = default) { - clientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); + clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection() { diff --git a/Binance.Net/Clients/SpotApi/BinanceSocketClientSpotApi.cs b/Binance.Net/Clients/SpotApi/BinanceSocketClientSpotApi.cs index 18aac6a09..f4e0677c2 100644 --- a/Binance.Net/Clients/SpotApi/BinanceSocketClientSpotApi.cs +++ b/Binance.Net/Clients/SpotApi/BinanceSocketClientSpotApi.cs @@ -25,7 +25,6 @@ internal partial class BinanceSocketClientSpotApi : SocketApiClient, IBinanceSoc internal BinanceExchangeInfo? _exchangeInfo; internal DateTime? _lastExchangeInfoUpdate; - internal readonly string _brokerId; private static readonly MessagePath _idPath = MessagePath.Get().Property("id"); private static readonly MessagePath _streamPath = MessagePath.Get().Property("stream"); @@ -47,8 +46,6 @@ internal BinanceSocketClientSpotApi(ILogger logger, BinanceSocketOptions options ExchangeData = new BinanceSocketClientSpotApiExchangeData(logger, this); Trading = new BinanceSocketClientSpotApiTrading(logger, this); - _brokerId = !string.IsNullOrEmpty(options.SpotOptions.BrokerId) ? options.SpotOptions.BrokerId! : "x-VICEW9VV"; - // When sending more than 4000 bytes the server responds very delayed (somehow connected to the websocket keep alive interval) // See https://dev.binance.vision/t/socket-live-subscribing-server-delay/9645/2 // To prevent issues we keep below this diff --git a/Binance.Net/Clients/SpotApi/BinanceSocketClientSpotApiTrading.cs b/Binance.Net/Clients/SpotApi/BinanceSocketClientSpotApiTrading.cs index 20434f7e9..d48a114c6 100644 --- a/Binance.Net/Clients/SpotApi/BinanceSocketClientSpotApiTrading.cs +++ b/Binance.Net/Clients/SpotApi/BinanceSocketClientSpotApiTrading.cs @@ -51,7 +51,7 @@ public async Task>> PlaceOrderAsy return new CallResult>(new ArgumentError(rulesCheck.ErrorMessage!)); } - string clientOrderId = newClientOrderId ?? ExchangeHelpers.AppendRandomString(_client._brokerId, 32); + string clientOrderId = LibraryHelpers.ApplyBrokerId(newClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); var parameters = new Dictionary(); parameters.AddParameter("symbol", symbol); @@ -117,6 +117,9 @@ public async Task>> PlaceTestOrde /// public async Task>> GetOrderAsync(string symbol, long? orderId = null, string? clientOrderId = null, CancellationToken ct = default) { + if (clientOrderId != null) + clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); + var parameters = new Dictionary(); parameters.AddParameter("symbol", symbol); parameters.AddOptionalParameter("orderId", orderId); @@ -131,6 +134,12 @@ public async Task>> GetOrderAsync(strin /// public async Task>> CancelOrderAsync(string symbol, long? orderId = null, string? clientOrderId = null, string? newClientOrderId = null, CancellationToken ct = default) { + if (clientOrderId != null) + clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); + + if (newClientOrderId != null) + newClientOrderId = LibraryHelpers.ApplyBrokerId(newClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); + var parameters = new Dictionary(); parameters.AddParameter("symbol", symbol); parameters.AddOptionalParameter("orderId", orderId); @@ -164,7 +173,13 @@ public async Task>> Replac int? strategyType = null, CancellationToken ct = default) { - string clientOrderId = newClientOrderId ?? ExchangeHelpers.AppendRandomString(_client._brokerId, 32); + string clientOrderId = LibraryHelpers.ApplyBrokerId(newClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); + + if (newCancelClientOrderId != null) + newCancelClientOrderId = LibraryHelpers.ApplyBrokerId(newCancelClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); + + if (cancelClientOrderId != null) + cancelClientOrderId = LibraryHelpers.ApplyBrokerId(cancelClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection { @@ -242,8 +257,9 @@ public async Task>> PlaceOcoOrde SelfTradePreventionMode? selfTradePreventionMode = null, CancellationToken ct = default) { - limitClientOrderId ??= ExchangeHelpers.AppendRandomString(_client._brokerId, 32); - stopClientOrderId ??= ExchangeHelpers.AppendRandomString(_client._brokerId, 32); + limitClientOrderId = LibraryHelpers.ApplyBrokerId(limitClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); + stopClientOrderId = LibraryHelpers.ApplyBrokerId(stopClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); + listClientOrderId = LibraryHelpers.ApplyBrokerId(listClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection { @@ -306,10 +322,12 @@ public async Task>> PlaceOcoOrde int? belowStrategyType = null, SelfTradePreventionMode? selfTradePreventionMode = null, + string? listClientOrderId = null, CancellationToken ct = default) { - aboveClientOrderId ??= ExchangeHelpers.AppendRandomString(_client._brokerId, 32); - belowClientOrderId ??= ExchangeHelpers.AppendRandomString(_client._brokerId, 32); + aboveClientOrderId = LibraryHelpers.ApplyBrokerId(aboveClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); + belowClientOrderId = LibraryHelpers.ApplyBrokerId(belowClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); + listClientOrderId = LibraryHelpers.ApplyBrokerId(listClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection { @@ -319,6 +337,7 @@ public async Task>> PlaceOcoOrde { "belowType", EnumConverter.GetString(belowOrderType) }, }; parameters.AddEnum("side", side); + parameters.AddOptional("listClientOrderId", listClientOrderId); parameters.AddOptional("aboveClientOrderId", aboveClientOrderId); parameters.AddOptional("aboveIcebergQty", aboveIcebergQuantity); @@ -349,6 +368,9 @@ public async Task>> PlaceOcoOrde /// public async Task>> GetOcoOrderAsync(long? orderId = null, string? clientOrderId = null, CancellationToken ct = default) { + if (clientOrderId != null) + clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); + var parameters = new Dictionary(); parameters.AddOptionalParameter("orderListId", orderId); parameters.AddOptionalParameter("origClientOrderId", clientOrderId); @@ -362,11 +384,17 @@ public async Task>> GetOcoOrderA /// public async Task>> CancelOcoOrderAsync(string symbol, long? orderId = null, string? clientOrderId = null, string? newClientOrderId = null, CancellationToken ct = default) { + if (clientOrderId != null) + clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); + + if (newClientOrderId != null) + newClientOrderId = LibraryHelpers.ApplyBrokerId(newClientOrderId, BinanceExchange.ClientOrderIdSpot, 36, _client.ClientOptions.AllowAppendingClientOrderId); + var parameters = new Dictionary(); parameters.AddParameter("symbol", symbol); parameters.AddOptionalParameter("orderListId", orderId); parameters.AddOptionalParameter("origClientOrderId", clientOrderId); - parameters.AddOptionalParameter("newClientOrderId", clientOrderId); + parameters.AddOptionalParameter("newClientOrderId", newClientOrderId); return await _client.QueryAsync(_client.ClientOptions.Environment.SpotSocketApiAddress.AppendPath("ws-api/v3"), $"orderList.cancel", parameters, true, true, ct: ct).ConfigureAwait(false); } diff --git a/Binance.Net/Clients/UsdFuturesApi/BinanceRestClientUsdFuturesApi.cs b/Binance.Net/Clients/UsdFuturesApi/BinanceRestClientUsdFuturesApi.cs index 06bf4e999..20268bdd7 100644 --- a/Binance.Net/Clients/UsdFuturesApi/BinanceRestClientUsdFuturesApi.cs +++ b/Binance.Net/Clients/UsdFuturesApi/BinanceRestClientUsdFuturesApi.cs @@ -24,7 +24,6 @@ internal partial class BinanceRestClientUsdFuturesApi : RestApiClient, IBinanceR internal BinanceFuturesUsdtExchangeInfo? _exchangeInfo; internal DateTime? _lastExchangeInfoUpdate; - internal readonly string _brokerId; internal static TimeSyncState _timeSyncState = new TimeSyncState("USD Futures Api"); #endregion @@ -64,7 +63,6 @@ internal BinanceRestClientUsdFuturesApi(ILogger logger, HttpClient? httpClient, RequestBodyEmptyContent = ""; RequestBodyFormat = RequestBodyFormat.FormData; ArraySerialization = ArrayParametersSerialization.MultipleValues; - _brokerId = !string.IsNullOrEmpty(options.UsdFuturesOptions.BrokerId) ? options.UsdFuturesOptions.BrokerId! : "x-d63tKbx3"; } event Action IBaseRestClient.OnOrderPlaced diff --git a/Binance.Net/Clients/UsdFuturesApi/BinanceRestClientUsdFuturesApiTrading.cs b/Binance.Net/Clients/UsdFuturesApi/BinanceRestClientUsdFuturesApiTrading.cs index 7bd83191f..d805e00d7 100644 --- a/Binance.Net/Clients/UsdFuturesApi/BinanceRestClientUsdFuturesApiTrading.cs +++ b/Binance.Net/Clients/UsdFuturesApi/BinanceRestClientUsdFuturesApiTrading.cs @@ -73,7 +73,7 @@ public async Task> PlaceOrderAsync( price = rulesCheck.Price; stopPrice = rulesCheck.StopPrice; - string clientOrderId = newClientOrderId ?? ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); + var clientOrderId = LibraryHelpers.ApplyBrokerId(newClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection() { @@ -142,7 +142,7 @@ public async Task>> int i = 0; foreach (var order in orders) { - string clientOrderId = order.NewClientOrderId ?? ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); + var clientOrderId = LibraryHelpers.ApplyBrokerId(order.NewClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); var orderParameters = new ParameterCollection() { @@ -197,6 +197,9 @@ public async Task> GetOrderAsync(string sy if (orderId == null && origClientOrderId == null) throw new ArgumentException("Either orderId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol } @@ -216,6 +219,9 @@ public async Task> GetOrderAsync(string sy /// public async Task>> GetOrderEditHistoryAsync(string symbol, long? orderId = null, string? clientOrderId = null, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default) { + if (clientOrderId != null) + clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol } @@ -241,6 +247,9 @@ public async Task> CancelOrderAsync(string if (!orderId.HasValue && string.IsNullOrEmpty(origClientOrderId)) throw new ArgumentException("Either orderId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol } @@ -289,6 +298,9 @@ public async Task> EditOrderAsync(string s if (!orderId.HasValue && string.IsNullOrEmpty(origClientOrderId)) throw new ArgumentException("Either orderId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol }, @@ -319,6 +331,10 @@ public async Task>> int i = 0; foreach (var order in orders) { + var clientOrderId = order.ClientOrderId; + if (clientOrderId != null) + clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var orderParameters = new ParameterCollection() { { "symbol", order.Symbol }, @@ -327,7 +343,7 @@ public async Task>> }; orderParameters.AddEnum("side", order.Side); orderParameters.AddOptionalParameter("orderId", order.OrderId?.ToString(CultureInfo.InvariantCulture)); - orderParameters.AddOptionalParameter("origClientOrderId", order.ClientOrderId); + orderParameters.AddOptionalParameter("origClientOrderId", clientOrderId); parameterOrders.Add(orderParameters); i++; } @@ -385,6 +401,8 @@ public async Task>> if (origClientOrderIdList?.Count > 10) throw new ArgumentException("origClientOrderIdList cannot contain more than 10 items"); + var convertClientOrderIdList = origClientOrderIdList?.Select(x => LibraryHelpers.ApplyBrokerId(x, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId)); + var parameters = new ParameterCollection { { "symbol", symbol } @@ -394,7 +412,7 @@ public async Task>> parameters.AddOptionalParameter("orderIdList", $"[{string.Join(",", orderIdList)}]"); if (origClientOrderIdList != null) - parameters.AddOptionalParameter("origClientOrderIdList", $"[{string.Join(",", origClientOrderIdList.Select(id => $"\"{id}\""))}]"); + parameters.AddOptionalParameter("origClientOrderIdList", $"[{string.Join(",", convertClientOrderIdList.Select(id => $"\"{id}\""))}]"); parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); @@ -425,6 +443,9 @@ public async Task> GetOpenOrderAsync(strin if (orderId == null && origClientOrderId == null) throw new ArgumentException("Either orderId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol } @@ -537,7 +558,7 @@ public async Task> PlaceVolumeParticipatio long? receiveWindow = null, CancellationToken ct = default) { - clientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); + clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection() { @@ -571,7 +592,7 @@ public async Task> PlaceTimeWeightedAverag long? receiveWindow = null, CancellationToken ct = default) { - clientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 32); + clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _baseClient.ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection() { diff --git a/Binance.Net/Clients/UsdFuturesApi/BinanceSocketClientUsdFuturesApi.cs b/Binance.Net/Clients/UsdFuturesApi/BinanceSocketClientUsdFuturesApi.cs index 2f9e41930..ef43337fa 100644 --- a/Binance.Net/Clients/UsdFuturesApi/BinanceSocketClientUsdFuturesApi.cs +++ b/Binance.Net/Clients/UsdFuturesApi/BinanceSocketClientUsdFuturesApi.cs @@ -36,7 +36,6 @@ internal partial class BinanceSocketClientUsdFuturesApi : SocketApiClient, IBina internal BinanceFuturesUsdtExchangeInfo? _exchangeInfo; internal DateTime? _lastExchangeInfoUpdate; - internal readonly string _brokerId; #endregion /// @@ -58,8 +57,6 @@ internal BinanceSocketClientUsdFuturesApi(ILogger logger, BinanceSocketOptions o ExchangeData = new BinanceSocketClientUsdFuturesApiExchangeData(logger, this); Trading = new BinanceSocketClientUsdFuturesApiTrading(logger, this); - _brokerId = !string.IsNullOrEmpty(options.UsdFuturesOptions.BrokerId) ? options.UsdFuturesOptions.BrokerId! : "x-d63tKbx3"; - // When sending more than 4000 bytes the server responds very delayed (somehow connected to the websocket keep alive interval on framework level) // See https://dev.binance.vision/t/socket-live-subscribing-server-delay/9645/2 // To prevent issues we keep below this diff --git a/Binance.Net/Clients/UsdFuturesApi/BinanceSocketClientUsdFuturesApiTrading.cs b/Binance.Net/Clients/UsdFuturesApi/BinanceSocketClientUsdFuturesApiTrading.cs index a71f507ea..8a85650f3 100644 --- a/Binance.Net/Clients/UsdFuturesApi/BinanceSocketClientUsdFuturesApiTrading.cs +++ b/Binance.Net/Clients/UsdFuturesApi/BinanceSocketClientUsdFuturesApiTrading.cs @@ -57,7 +57,7 @@ public async Task>> PlaceOrde if (orderResponseType == OrderResponseType.Full) throw new ArgumentException("OrderResponseType.Full is not supported in Futures"); - string clientOrderId = newClientOrderId ?? ExchangeHelpers.AppendRandomString(_client._brokerId, 32); + string clientOrderId = LibraryHelpers.ApplyBrokerId(newClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _client.ClientOptions.AllowAppendingClientOrderId); var parameters = new ParameterCollection(); parameters.AddParameter("symbol", symbol); @@ -94,6 +94,9 @@ public async Task>> EditOrder if (!orderId.HasValue && string.IsNullOrEmpty(origClientOrderId)) throw new ArgumentException("Either orderId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _client.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol }, @@ -119,6 +122,9 @@ public async Task>> CancelOrd if (!orderId.HasValue && string.IsNullOrEmpty(origClientOrderId)) throw new ArgumentException("Either orderId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _client.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol } @@ -140,6 +146,9 @@ public async Task>> GetOrderA if (orderId == null && origClientOrderId == null) throw new ArgumentException("Either orderId or origClientOrderId must be sent"); + if (origClientOrderId != null) + origClientOrderId = LibraryHelpers.ApplyBrokerId(origClientOrderId, BinanceExchange.ClientOrderIdFutures, 36, _client.ClientOptions.AllowAppendingClientOrderId); + var parameters = new ParameterCollection { { "symbol", symbol } diff --git a/Binance.Net/ExtensionMethods/ServiceCollectionExtensions.cs b/Binance.Net/ExtensionMethods/ServiceCollectionExtensions.cs index 6d095c2ec..1586192e3 100644 --- a/Binance.Net/ExtensionMethods/ServiceCollectionExtensions.cs +++ b/Binance.Net/ExtensionMethods/ServiceCollectionExtensions.cs @@ -39,8 +39,10 @@ public static IServiceCollection AddBinance( var restEnvName = options.Rest.Environment?.Name ?? options.Environment?.Name ?? BinanceEnvironment.Live.Name; var socketEnvName = options.Socket.Environment?.Name ?? options.Environment?.Name ?? BinanceEnvironment.Live.Name; + options.Rest.AllowAppendingClientOrderId = options.Rest.AllowAppendingClientOrderId || options.AllowAppendingClientOrderId; options.Rest.Environment = BinanceEnvironment.GetEnvironmentByName(restEnvName) ?? options.Rest.Environment!; options.Rest.ApiCredentials = options.Rest.ApiCredentials ?? options.ApiCredentials; + options.Socket.AllowAppendingClientOrderId = options.Socket.AllowAppendingClientOrderId || options.AllowAppendingClientOrderId; options.Socket.Environment = BinanceEnvironment.GetEnvironmentByName(socketEnvName) ?? options.Socket.Environment!; options.Socket.ApiCredentials = options.Socket.ApiCredentials ?? options.ApiCredentials; @@ -71,8 +73,10 @@ public static IServiceCollection AddBinance( options.Rest.Environment = options.Rest.Environment ?? options.Environment ?? BinanceEnvironment.Live; options.Rest.ApiCredentials = options.Rest.ApiCredentials ?? options.ApiCredentials; + options.Rest.AllowAppendingClientOrderId = options.Rest.AllowAppendingClientOrderId || options.AllowAppendingClientOrderId; options.Socket.Environment = options.Socket.Environment ?? options.Environment ?? BinanceEnvironment.Live; options.Socket.ApiCredentials = options.Socket.ApiCredentials ?? options.ApiCredentials; + options.Socket.AllowAppendingClientOrderId = options.Socket.AllowAppendingClientOrderId || options.AllowAppendingClientOrderId; services.AddSingleton(x => Options.Options.Create(options.Rest)); services.AddSingleton(x => Options.Options.Create(options.Socket)); diff --git a/Binance.Net/Interfaces/Clients/SpotApi/IBinanceSocketClientSpotApiTrading.cs b/Binance.Net/Interfaces/Clients/SpotApi/IBinanceSocketClientSpotApiTrading.cs index 4f44899fd..09d6a653f 100644 --- a/Binance.Net/Interfaces/Clients/SpotApi/IBinanceSocketClientSpotApiTrading.cs +++ b/Binance.Net/Interfaces/Clients/SpotApi/IBinanceSocketClientSpotApiTrading.cs @@ -176,6 +176,7 @@ public interface IBinanceSocketClientSpotApiTrading /// Strategy id for the below leg /// Strategy type for the below leg /// Self trade prevention mode + /// List client order id /// Cancellation token /// Task>> PlaceOcoOrderListAsync( @@ -204,6 +205,7 @@ Task>> PlaceOcoOrderListAsync( int? belowStrategyType = null, SelfTradePreventionMode? selfTradePreventionMode = null, + string? listClientOrderId = null, CancellationToken ct = default); /// diff --git a/Binance.Net/Objects/Models/BinanceOrderBase.cs b/Binance.Net/Objects/Models/BinanceOrderBase.cs index 44ab7fdb2..fc1d89a36 100644 --- a/Binance.Net/Objects/Models/BinanceOrderBase.cs +++ b/Binance.Net/Objects/Models/BinanceOrderBase.cs @@ -29,12 +29,18 @@ public record BinanceOrderBase /// Original order id /// [JsonPropertyName("origClientOrderId")] + [JsonConverterCtor( + $"{BinanceExchange.ClientOrderIdPrefixSpot}->", + $"{BinanceExchange.ClientOrderIdPrefixFutures}->")] public string OriginalClientOrderId { get; set; } = string.Empty; /// /// The order id as assigned by the client /// [JsonPropertyName("clientOrderId")] + [JsonConverterCtor( + $"{BinanceExchange.ClientOrderIdPrefixSpot}->", + $"{BinanceExchange.ClientOrderIdPrefixFutures}->")] public string ClientOrderId { get; set; } = string.Empty; private decimal _price; diff --git a/Binance.Net/Objects/Models/Futures/AlgoOrders/BinanceAlgoOrder.cs b/Binance.Net/Objects/Models/Futures/AlgoOrders/BinanceAlgoOrder.cs index 1a56a8ec0..65882ffba 100644 --- a/Binance.Net/Objects/Models/Futures/AlgoOrders/BinanceAlgoOrder.cs +++ b/Binance.Net/Objects/Models/Futures/AlgoOrders/BinanceAlgoOrder.cs @@ -70,6 +70,9 @@ public record BinanceAlgoOrder /// Client algo id /// [JsonPropertyName("clientAlgoId")] + [JsonConverterCtor( + $"{BinanceExchange.ClientOrderIdPrefixSpot}->", + $"{BinanceExchange.ClientOrderIdPrefixFutures}->")] public string ClientAlgoId { get; set; } = string.Empty; /// /// Book time diff --git a/Binance.Net/Objects/Models/Futures/AlgoOrders/BinanceAlgoOrderResult.cs b/Binance.Net/Objects/Models/Futures/AlgoOrders/BinanceAlgoOrderResult.cs index 939a45a4f..17a7efb91 100644 --- a/Binance.Net/Objects/Models/Futures/AlgoOrders/BinanceAlgoOrderResult.cs +++ b/Binance.Net/Objects/Models/Futures/AlgoOrders/BinanceAlgoOrderResult.cs @@ -9,6 +9,9 @@ public record BinanceAlgoOrderResult: BinanceResult /// Order id /// [JsonPropertyName("clientAlgoId")] + [JsonConverterCtor( + $"{BinanceExchange.ClientOrderIdPrefixSpot}->", + $"{BinanceExchange.ClientOrderIdPrefixFutures}->")] public string ClientAlgoId { get; set; } = string.Empty; /// /// Successful diff --git a/Binance.Net/Objects/Models/Futures/BinanceFuturesOrder.cs b/Binance.Net/Objects/Models/Futures/BinanceFuturesOrder.cs index cace3c317..45af62b46 100644 --- a/Binance.Net/Objects/Models/Futures/BinanceFuturesOrder.cs +++ b/Binance.Net/Objects/Models/Futures/BinanceFuturesOrder.cs @@ -29,6 +29,9 @@ public record BinanceFuturesOrder /// The order id as assigned by the client /// [JsonPropertyName("clientOrderId")] + [JsonConverterCtor( + $"{BinanceExchange.ClientOrderIdPrefixSpot}->", + $"{BinanceExchange.ClientOrderIdPrefixFutures}->")] public string ClientOrderId { get; set; } = string.Empty; /// /// The price of the order diff --git a/Binance.Net/Objects/Models/Futures/BinanceFuturesOrderEditHistory.cs b/Binance.Net/Objects/Models/Futures/BinanceFuturesOrderEditHistory.cs index 2dbbc7fa8..1c27ab922 100644 --- a/Binance.Net/Objects/Models/Futures/BinanceFuturesOrderEditHistory.cs +++ b/Binance.Net/Objects/Models/Futures/BinanceFuturesOrderEditHistory.cs @@ -33,6 +33,9 @@ public record BinanceFuturesOrderEditHistory /// The order id as assigned by the client /// [JsonPropertyName("clientOrderId")] + [JsonConverterCtor( + $"{BinanceExchange.ClientOrderIdPrefixSpot}->", + $"{BinanceExchange.ClientOrderIdPrefixFutures}->")] public string? ClientOrderId { get; set; } /// /// Edit time diff --git a/Binance.Net/Objects/Models/Futures/Socket/BinanceFuturesStreamOrderUpdate.cs b/Binance.Net/Objects/Models/Futures/Socket/BinanceFuturesStreamOrderUpdate.cs index 1d7cfe4cf..fffdd79a0 100644 --- a/Binance.Net/Objects/Models/Futures/Socket/BinanceFuturesStreamOrderUpdate.cs +++ b/Binance.Net/Objects/Models/Futures/Socket/BinanceFuturesStreamOrderUpdate.cs @@ -39,6 +39,9 @@ public record BinanceFuturesStreamOrderUpdateData /// The new client order id /// [JsonPropertyName("c")] + [JsonConverterCtor( + $"{BinanceExchange.ClientOrderIdPrefixSpot}->", + $"{BinanceExchange.ClientOrderIdPrefixFutures}->")] public string ClientOrderId { get; set; } = string.Empty; /// /// The side of the order diff --git a/Binance.Net/Objects/Models/Futures/Socket/BinanceFuturesStreamTradeUpdate.cs b/Binance.Net/Objects/Models/Futures/Socket/BinanceFuturesStreamTradeUpdate.cs index 86b474f5c..1218287c4 100644 --- a/Binance.Net/Objects/Models/Futures/Socket/BinanceFuturesStreamTradeUpdate.cs +++ b/Binance.Net/Objects/Models/Futures/Socket/BinanceFuturesStreamTradeUpdate.cs @@ -42,6 +42,9 @@ public record BinanceFuturesStreamTradeUpdate : BinanceStreamEvent /// "settlement_autoclose-": settlement order for delisting or delivery /// [JsonPropertyName("c")] + [JsonConverterCtor( + $"{BinanceExchange.ClientOrderIdPrefixSpot}->", + $"{BinanceExchange.ClientOrderIdPrefixFutures}->")] public string ClientOrderId { get; set; } = string.Empty; /// /// The side of the order diff --git a/Binance.Net/Objects/Models/Spot/BinanceOrderOcoList.cs b/Binance.Net/Objects/Models/Spot/BinanceOrderOcoList.cs index c7f055972..11c6f3d99 100644 --- a/Binance.Net/Objects/Models/Spot/BinanceOrderOcoList.cs +++ b/Binance.Net/Objects/Models/Spot/BinanceOrderOcoList.cs @@ -32,6 +32,9 @@ public record BinanceOrderOcoList /// The client id of the order list /// [JsonPropertyName("listClientOrderId")] + [JsonConverterCtor( + $"{BinanceExchange.ClientOrderIdPrefixSpot}->", + $"{BinanceExchange.ClientOrderIdPrefixFutures}->")] public string ListClientOrderId { get; set; } = string.Empty; /// /// The transaction time @@ -75,6 +78,9 @@ public record BinanceOrderId /// The client order id /// [JsonPropertyName("clientOrderId")] + [JsonConverterCtor( + $"{BinanceExchange.ClientOrderIdPrefixSpot}->", + $"{BinanceExchange.ClientOrderIdPrefixFutures}->")] public string ClientOrderId { get; set; } = string.Empty; } diff --git a/Binance.Net/Objects/Models/Spot/Socket/BinanceStreamOrderList.cs b/Binance.Net/Objects/Models/Spot/Socket/BinanceStreamOrderList.cs index c0a0972d1..100143a2b 100644 --- a/Binance.Net/Objects/Models/Spot/Socket/BinanceStreamOrderList.cs +++ b/Binance.Net/Objects/Models/Spot/Socket/BinanceStreamOrderList.cs @@ -37,6 +37,9 @@ public record BinanceStreamOrderList: BinanceStreamEvent /// The client id of the order list /// [JsonPropertyName("C")] + [JsonConverterCtor( + $"{BinanceExchange.ClientOrderIdPrefixSpot}->", + $"{BinanceExchange.ClientOrderIdPrefixFutures}->")] public string ListClientOrderId { get; set; } = string.Empty; /// /// The transaction time @@ -79,6 +82,9 @@ public record BinanceStreamOrderId /// The client order id /// [JsonPropertyName("c")] + [JsonConverterCtor( + $"{BinanceExchange.ClientOrderIdPrefixSpot}->", + $"{BinanceExchange.ClientOrderIdPrefixFutures}->")] public string ClientOrderId { get; set; } = string.Empty; } } diff --git a/Binance.Net/Objects/Models/Spot/Socket/BinanceStreamOrderUpdate.cs b/Binance.Net/Objects/Models/Spot/Socket/BinanceStreamOrderUpdate.cs index 8c8b51a36..536026795 100644 --- a/Binance.Net/Objects/Models/Spot/Socket/BinanceStreamOrderUpdate.cs +++ b/Binance.Net/Objects/Models/Spot/Socket/BinanceStreamOrderUpdate.cs @@ -22,6 +22,9 @@ public record BinanceStreamOrderUpdate: BinanceStreamEvent /// The new client order id /// [JsonPropertyName("c")] + [JsonConverterCtor( + $"{BinanceExchange.ClientOrderIdPrefixSpot}->", + $"{BinanceExchange.ClientOrderIdPrefixFutures}->")] public string ClientOrderId { get; set; } = string.Empty; /// /// The side of the order @@ -72,6 +75,9 @@ public record BinanceStreamOrderUpdate: BinanceStreamEvent /// The original client order id /// [JsonPropertyName("C")] + [JsonConverterCtor( + $"{BinanceExchange.ClientOrderIdPrefixSpot}->", + $"{BinanceExchange.ClientOrderIdPrefixFutures}->")] public string? OriginalClientOrderId { get; set; } = string.Empty; /// /// The execution type diff --git a/Binance.Net/Objects/Options/BinanceOptions.cs b/Binance.Net/Objects/Options/BinanceOptions.cs index 9e2105fac..d598194f1 100644 --- a/Binance.Net/Objects/Options/BinanceOptions.cs +++ b/Binance.Net/Objects/Options/BinanceOptions.cs @@ -11,5 +11,14 @@ namespace Binance.Net.Objects.Options /// public class BinanceOptions : LibraryOptions { + /// + /// Whether to allow the client to adjust the clientOrderId parameter send by the user when placing orders to include a client reference. This reference is used by the exchange to allocate a small percentage of the paid trading fees to developer of this library. Defaults to false.
+ /// Note that:
+ /// * It does not impact the amount of fees a user pays in any way
+ /// * It does not impact functionality. The reference is added just before sending the request and removed again during data deserialization
+ /// * It does respect client order id field limitations. For example if the user provided client order id parameter is too long to fit the reference it will not be added
+ /// * Toggling this option might fail operations using a clientOrderId parameter for pre-existing orders which were placed before the toggle. Operations on orders placed after the toggle will work as expected. It's adviced to toggle when there are no open orders + ///
+ public bool AllowAppendingClientOrderId { get; set; } = false; } } diff --git a/Binance.Net/Objects/Options/BinanceRestApiOptions.cs b/Binance.Net/Objects/Options/BinanceRestApiOptions.cs index bdafee740..9a3be3312 100644 --- a/Binance.Net/Objects/Options/BinanceRestApiOptions.cs +++ b/Binance.Net/Objects/Options/BinanceRestApiOptions.cs @@ -22,11 +22,6 @@ public class BinanceRestApiOptions : RestApiOptions /// public TimeSpan TradeRulesUpdateInterval { get; set; } = TimeSpan.FromMinutes(60); - /// - /// The broker reference id to use - /// - public string? BrokerId { get; set; } - internal BinanceRestApiOptions Set(BinanceRestApiOptions targetOptions) { targetOptions = base.Set(targetOptions); diff --git a/Binance.Net/Objects/Options/BinanceRestOptions.cs b/Binance.Net/Objects/Options/BinanceRestOptions.cs index eb622832d..c9665a106 100644 --- a/Binance.Net/Objects/Options/BinanceRestOptions.cs +++ b/Binance.Net/Objects/Options/BinanceRestOptions.cs @@ -30,6 +30,16 @@ public BinanceRestOptions() /// public TimeSpan ReceiveWindow { get; set; } = TimeSpan.FromSeconds(5); + /// + /// Whether to allow the client to adjust the clientOrderId parameter send by the user when placing orders to include a client reference. This reference is used by the exchange to allocate a small percentage of the paid trading fees to developer of this library. Defaults to false.
+ /// Note that:
+ /// * It does not impact the amount of fees a user pays in any way
+ /// * It does not impact functionality. The reference is added just before sending the request and removed again during data deserialization
+ /// * It does respect client order id field limitations. For example if the user provided client order id parameter is too long to fit the reference it will not be added
+ /// * Toggling this option might fail operations using a clientOrderId parameter for pre-existing orders which were placed before the toggle. Operations on orders placed after the toggle will work as expected. It's adviced to toggle when there are no open orders + ///
+ public bool AllowAppendingClientOrderId { get; set; } = false; + /// /// Spot API options /// @@ -48,6 +58,7 @@ public BinanceRestOptions() internal BinanceRestOptions Set(BinanceRestOptions targetOptions) { targetOptions = base.Set(targetOptions); + targetOptions.AllowAppendingClientOrderId = AllowAppendingClientOrderId; targetOptions.ReceiveWindow = ReceiveWindow; targetOptions.SpotOptions = SpotOptions.Set(targetOptions.SpotOptions); targetOptions.UsdFuturesOptions = UsdFuturesOptions.Set(targetOptions.UsdFuturesOptions); diff --git a/Binance.Net/Objects/Options/BinanceSocketApiOptions.cs b/Binance.Net/Objects/Options/BinanceSocketApiOptions.cs index 92472a3de..424db04b2 100644 --- a/Binance.Net/Objects/Options/BinanceSocketApiOptions.cs +++ b/Binance.Net/Objects/Options/BinanceSocketApiOptions.cs @@ -18,11 +18,6 @@ public class BinanceSocketApiOptions : SocketApiOptions /// public TimeSpan TradeRulesUpdateInterval { get; set; } = TimeSpan.FromMinutes(60); - /// - /// The broker reference id to use - /// - public string? BrokerId { get; set; } - internal BinanceSocketApiOptions Set(BinanceSocketApiOptions targetOptions) { targetOptions = base.Set(targetOptions); diff --git a/Binance.Net/Objects/Options/BinanceSocketOptions.cs b/Binance.Net/Objects/Options/BinanceSocketOptions.cs index 567eb87a2..0ae254eae 100644 --- a/Binance.Net/Objects/Options/BinanceSocketOptions.cs +++ b/Binance.Net/Objects/Options/BinanceSocketOptions.cs @@ -24,6 +24,16 @@ public BinanceSocketOptions() Default?.Set(this); } + /// + /// Whether to allow the client to adjust the clientOrderId parameter send by the user when placing orders to include a client reference. This reference is used by the exchange to allocate a small percentage of the paid trading fees to developer of this library. Defaults to false.
+ /// Note that:
+ /// * It does not impact the amount of fees a user pays in any way
+ /// * It does not impact functionality. The reference is added just before sending the request and removed again during data deserialization
+ /// * It does respect client order id field limitations. For example if the user provided client order id parameter is too long to fit the reference it will not be added
+ /// * Toggling this option might fail operations using a clientOrderId parameter for pre-existing orders which were placed before the toggle. Operations on orders placed after the toggle will work as expected. It's adviced to toggle when there are no open orders + ///
+ public bool AllowAppendingClientOrderId { get; set; } = true; + /// /// Options for the Spot API /// @@ -42,6 +52,7 @@ public BinanceSocketOptions() internal BinanceSocketOptions Set(BinanceSocketOptions targetOptions) { targetOptions = base.Set(targetOptions); + targetOptions.AllowAppendingClientOrderId = AllowAppendingClientOrderId; targetOptions.SpotOptions = SpotOptions.Set(targetOptions.SpotOptions); targetOptions.UsdFuturesOptions = UsdFuturesOptions.Set(targetOptions.UsdFuturesOptions); targetOptions.CoinFuturesOptions = CoinFuturesOptions.Set(targetOptions.CoinFuturesOptions);