Skip to content

Commit 3fcfea6

Browse files
committed
Updated client order id logic for spot API, added AllowAppendingClientOrderId option
1 parent b5c987d commit 3fcfea6

20 files changed

+100
-44
lines changed

HTX.Net/Clients/SpotApi/HTXRestClientSpotApi.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ internal partial class HTXRestClientSpotApi : RestApiClient, IHTXRestClientSpotA
3030
/// <inheritdoc />
3131
public string ExchangeName => "HTX";
3232

33-
internal readonly string _brokerId;
34-
3533
#region Api clients
3634

3735
/// <inheritdoc />
@@ -57,7 +55,6 @@ internal HTXRestClientSpotApi(ILogger logger, HttpClient? httpClient, HTXRestOpt
5755
Margin = new HTXRestClientSpotApiMargin(this);
5856
Trading = new HTXRestClientSpotApiTrading(this);
5957

60-
_brokerId = !string.IsNullOrEmpty(options.BrokerId) ? options.BrokerId! : "AA1ef14811";
6158
}
6259
#endregion
6360

HTX.Net/Clients/SpotApi/HTXRestClientSpotApiTrading.cs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public async Task<WebCallResult<long>> PlaceOrderAsync(
4747
};
4848
parameters.AddString("amount", quantity);
4949

50-
clientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 64);
50+
clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, HTXExchange.ClientOrderId, 64, _baseClient.ClientOptions.AllowAppendingClientOrderId);
5151

5252
parameters.AddOptionalParameter("client-order-id", clientOrderId);
5353
parameters.AddOptionalString("stop-price", stopPrice);
@@ -84,8 +84,8 @@ public async Task<WebCallResult<IEnumerable<HTXBatchPlaceResult>>> PlaceMultiple
8484
{ "type", orderType }
8585
};
8686
parameters.AddString("amount", order.Quantity);
87-
order.ClientOrderId ??= ExchangeHelpers.AppendRandomString(_baseClient._brokerId, 64);
88-
87+
order.ClientOrderId = LibraryHelpers.ApplyBrokerId(order.ClientOrderId, HTXExchange.ClientOrderId, 64, _baseClient.ClientOptions.AllowAppendingClientOrderId);
88+
8989
parameters.AddOptionalParameter("client-order-id", order.ClientOrderId);
9090
parameters.AddOptionalString("stop-price", order.StopPrice);
9191
parameters.AddOptionalEnum("source", order.Source);
@@ -180,6 +180,8 @@ public async Task<WebCallResult<long>> CancelOrderAsync(long orderId, Cancellati
180180
/// <inheritdoc />
181181
public async Task<WebCallResult<long>> CancelOrderByClientOrderIdAsync(string clientOrderId, CancellationToken ct = default)
182182
{
183+
clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, HTXExchange.ClientOrderId, 64, _baseClient.ClientOptions.AllowAppendingClientOrderId);
184+
183185
var parameters = new ParameterCollection()
184186
{
185187
{ "client-order-id", clientOrderId }
@@ -239,8 +241,8 @@ public async Task<WebCallResult<HTXBatchCancelResult>> CancelOrdersAsync(IEnumer
239241
throw new ArgumentException("Either orderIds or clientOrderIds should be provided");
240242

241243
var parameters = new ParameterCollection();
242-
parameters.AddOptionalParameter("order-ids", orderIds?.Select(s => s.ToString(CultureInfo.InvariantCulture)));
243-
parameters.AddOptionalParameter("client-order-ids", clientOrderIds?.Select(s => s.ToString(CultureInfo.InvariantCulture)));
244+
parameters.AddOptionalParameter("order-ids", orderIds?.Select(s => s.ToString(CultureInfo.InvariantCulture)).ToArray());
245+
parameters.AddOptionalParameter("client-order-ids", clientOrderIds?.Select(s => LibraryHelpers.ApplyBrokerId(s, HTXExchange.ClientOrderId, 64, _baseClient.ClientOptions.AllowAppendingClientOrderId).ToString(CultureInfo.InvariantCulture)).ToArray());
244246

245247
var request = _definitions.GetOrCreate(HttpMethod.Post, "v1/order/orders/batchcancel", HTXExchange.RateLimiter.EndpointLimit, 1, true,
246248
new SingleLimitGuard(50, TimeSpan.FromSeconds(2), RateLimitWindowType.Sliding, keySelector: SingleLimitGuard.PerApiKey));
@@ -268,6 +270,8 @@ public async Task<WebCallResult<HTXOrder>> GetOrderAsync(long orderId, Cancellat
268270
/// <inheritdoc />
269271
public async Task<WebCallResult<HTXOrder>> GetOrderByClientOrderIdAsync(string clientOrderId, CancellationToken ct = default)
270272
{
273+
clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, HTXExchange.ClientOrderId, 64, _baseClient.ClientOptions.AllowAppendingClientOrderId);
274+
271275
var parameters = new ParameterCollection()
272276
{
273277
{ "clientOrderId", clientOrderId }
@@ -381,13 +385,14 @@ public async Task<WebCallResult<HTXPlacedConditionalOrder>> PlaceConditionalOrde
381385
{
382386
symbol = symbol.ToLowerInvariant();
383387

388+
clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, HTXExchange.ClientOrderId, 64, _baseClient.ClientOptions.AllowAppendingClientOrderId);
384389
var parameters = new ParameterCollection()
385390
{
386391
{ "accountId", accountId },
387392
{ "symbol", symbol },
388393
{ "orderSide", EnumConverter.GetString(side) },
389394
{ "orderType", EnumConverter.GetString(type) },
390-
{ "clientOrderId", clientOrderId ?? Guid.NewGuid().ToString() }
395+
{ "clientOrderId", clientOrderId }
391396
};
392397
parameters.AddString("stopPrice", stopPrice);
393398

@@ -411,7 +416,7 @@ public async Task<WebCallResult<HTXConditionalOrderCancelResult>> CancelConditio
411416
{
412417
var parameters = new ParameterCollection()
413418
{
414-
{ "clientOrderIds", clientOrderIds }
419+
{ "clientOrderIds", clientOrderIds.Select(x => LibraryHelpers.ApplyBrokerId(x, HTXExchange.ClientOrderId, 64, _baseClient.ClientOptions.AllowAppendingClientOrderId)).ToArray() }
415420
};
416421

417422
var request = _definitions.GetOrCreate(HttpMethod.Post, $"v2/algo-orders/cancellation", HTXExchange.RateLimiter.EndpointLimit, 1, true,
@@ -488,6 +493,8 @@ public async Task<WebCallResult<IEnumerable<HTXConditionalOrder>>> GetClosedCond
488493
/// <inheritdoc />
489494
public async Task<WebCallResult<HTXConditionalOrder>> GetConditionalOrderAsync(string clientOrderId, CancellationToken ct = default)
490495
{
496+
clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, HTXExchange.ClientOrderId, 64, _baseClient.ClientOptions.AllowAppendingClientOrderId);
497+
491498
var parameters = new ParameterCollection()
492499
{
493500
{ "clientOrderId", clientOrderId }

HTX.Net/Clients/SpotApi/HTXSocketClientSpotApi.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ internal partial class HTXSocketClientSpotApi : SocketApiClient, IHTXSocketClien
2828
private static readonly MessagePath _channelPath = MessagePath.Get().Property("ch");
2929
private static readonly MessagePath _pingPath = MessagePath.Get().Property("ping");
3030

31-
#region fields
32-
internal readonly string _brokerId;
33-
#endregion
31+
/// <inheritdoc />
32+
public new HTXSocketOptions ClientOptions => (HTXSocketOptions)base.ClientOptions;
3433

3534
#region ctor
3635
internal HTXSocketClientSpotApi(ILogger logger, HTXSocketOptions options)
@@ -43,8 +42,6 @@ internal HTXSocketClientSpotApi(ILogger logger, HTXSocketOptions options)
4342

4443
RateLimiter = HTXExchange.RateLimiter.SpotConnection;
4544

46-
_brokerId = !string.IsNullOrEmpty(options.BrokerId) ? options.BrokerId! : "AA1ef14811";
47-
4845
SetDedicatedConnection(options.Environment.SocketBaseAddress.AppendPath("ws/trade"), true);
4946
}
5047

@@ -299,7 +296,7 @@ public async Task<CallResult<string>> PlaceOrderAsync(
299296
var request = new HTXSocketPlaceOrderRequest()
300297
{
301298
AccountId = accountId,
302-
ClientOrderId = clientOrderId ?? ExchangeHelpers.AppendRandomString(_brokerId, 64),
299+
ClientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, HTXExchange.ClientOrderId, 64, ClientOptions.AllowAppendingClientOrderId),
303300
Price = price,
304301
Type = orderType,
305302
Quantity = quantity,
@@ -333,7 +330,7 @@ public async Task<CallResult<IEnumerable<HTXBatchPlaceResult>>> PlaceMultipleOrd
333330
var parameters = new HTXSocketPlaceOrderRequest()
334331
{
335332
AccountId = long.Parse(order.AccountId),
336-
ClientOrderId = order.ClientOrderId ?? ExchangeHelpers.AppendRandomString(_brokerId, 64),
333+
ClientOrderId = LibraryHelpers.ApplyBrokerId(order.ClientOrderId, HTXExchange.ClientOrderId, 64, ClientOptions.AllowAppendingClientOrderId),
337334
Price = order.Price,
338335
Type = orderType,
339336
Quantity = order.Quantity,
@@ -429,6 +426,9 @@ public async Task<CallResult> CancelOrdersAsync(
429426
string? clientOrderId = null,
430427
CancellationToken ct = default)
431428
{
429+
if (clientOrderId != null)
430+
clientOrderId = LibraryHelpers.ApplyBrokerId(clientOrderId, HTXExchange.ClientOrderId, 64, ClientOptions.AllowAppendingClientOrderId);
431+
432432
var result = await CancelOrdersAsync(orderId == null ? null : [orderId], clientOrderId == null ? null : [clientOrderId], ct).ConfigureAwait(false);
433433
if (!result)
434434
return result.AsDataless();
@@ -445,9 +445,10 @@ public async Task<CallResult<HTXBatchCancelResult>> CancelOrdersAsync(
445445
IEnumerable<string>? clientOrderIds = null,
446446
CancellationToken ct = default)
447447
{
448+
448449
var parameters = new ParameterCollection();
449-
parameters.AddOptional("order-ids", orderIds);
450-
parameters.AddOptional("client-order-ids", clientOrderIds);
450+
parameters.AddOptional("order-ids", orderIds?.ToArray());
451+
parameters.AddOptional("client-order-ids", clientOrderIds?.Select(x => LibraryHelpers.ApplyBrokerId(x, HTXExchange.ClientOrderId, 64, ClientOptions.AllowAppendingClientOrderId)).ToArray());
451452

452453
var query = new HTXOrderQuery<ParameterCollection, HTXBatchCancelResult>(new HTXSocketOrderRequest<ParameterCollection>
453454
{

HTX.Net/Clients/UsdtFutures/HTXRestClientUsdtFuturesApi.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ internal partial class HTXRestClientUsdtFuturesApi : RestApiClient, IHTXRestClie
1919
/// <inheritdoc />
2020
public string ExchangeName => "HTX";
2121

22-
internal readonly string _brokerId;
23-
2422
#region Api clients
2523

2624
/// <inheritdoc />
@@ -43,7 +41,6 @@ internal HTXRestClientUsdtFuturesApi(ILogger log, HttpClient? httpClient, HTXRes
4341
SubAccount = new HTXRestClientUsdtFuturesApiSubAccount(this);
4442
Trading = new HTXRestClientUsdtFuturesApiTrading(this);
4543

46-
_brokerId = !string.IsNullOrEmpty(options.BrokerId) ? options.BrokerId! : "AA1ef14811";
4744
}
4845
#endregion
4946

HTX.Net/Clients/UsdtFutures/HTXRestClientUsdtFuturesApiTrading.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public async Task<WebCallResult<HTXOrderIds>> PlaceIsolatedMarginOrderAsync(
5757
{ "volume", quantity },
5858
{ "direction", EnumConverter.GetString(side) },
5959
{ "lever_rate", leverageRate },
60-
{ "channel_code", _baseClient._brokerId },
60+
{ "channel_code", HTXExchange.ClientOrderId },
6161
{ "order_price_type", EnumConverter.GetString(orderPriceType) }
6262
};
6363
parameters.AddOptionalParameter("price", price?.ToString(CultureInfo.InvariantCulture));
@@ -105,7 +105,7 @@ public async Task<WebCallResult<HTXOrderIds>> PlaceCrossMarginOrderAsync(
105105
{ "volume", quantity },
106106
{ "direction", EnumConverter.GetString(side) },
107107
{ "lever_rate", leverageRate },
108-
{ "channel_code", _baseClient._brokerId },
108+
{ "channel_code", HTXExchange.ClientOrderId },
109109
{ "order_price_type", EnumConverter.GetString(orderPriceType) }
110110
};
111111
parameters.AddOptionalParameter("contract_code", contractCode);
@@ -554,7 +554,7 @@ public async Task<WebCallResult<HTXOrderIds>> PlaceIsolatedMarginTriggerOrderAsy
554554
{
555555
var parameters = new ParameterCollection()
556556
{
557-
{ "channel_code", _baseClient._brokerId }
557+
{ "channel_code", HTXExchange.ClientOrderId }
558558
};
559559
parameters.Add("contract_code", contractCode);
560560
parameters.AddEnum("trigger_type", triggerType);
@@ -580,7 +580,7 @@ public async Task<WebCallResult<HTXOrderIds>> PlaceCrossMarginTriggerOrderAsync(
580580
{
581581
var parameters = new ParameterCollection()
582582
{
583-
{ "channel_code", _baseClient._brokerId }
583+
{ "channel_code", HTXExchange.ClientOrderId }
584584
};
585585
parameters.AddOptional("contract_code", contractCode);
586586
parameters.AddEnum("trigger_type", triggerType);
@@ -966,7 +966,7 @@ public async Task<WebCallResult<HTXOrderIds>> PlaceIsolatedMarginTrailingOrderAs
966966
{
967967
var parameters = new ParameterCollection()
968968
{
969-
{ "channel_code", _baseClient._brokerId }
969+
{ "channel_code", HTXExchange.ClientOrderId }
970970
};
971971
parameters.Add("contract_code", contractCode);
972972
parameters.Add("reduce_only", reduceOnly ? 1 : 0);
@@ -991,7 +991,7 @@ public async Task<WebCallResult<HTXOrderIds>> PlaceCrossMarginTrailingOrderAsync
991991
{
992992
var parameters = new ParameterCollection()
993993
{
994-
{ "channel_code", _baseClient._brokerId }
994+
{ "channel_code", HTXExchange.ClientOrderId }
995995
};
996996
parameters.AddOptional("contract_code", contractCode);
997997
parameters.AddOptional("pair", pair);

HTX.Net/HTX.Net.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
<PrivateAssets>all</PrivateAssets>
4949
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
5050
</PackageReference>
51-
<PackageReference Include="CryptoExchange.Net" Version="8.4.0" />
51+
<PackageReference Include="CryptoExchange.Net" Version="8.4.2" />
5252
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0">
5353
<PrivateAssets>all</PrivateAssets>
5454
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

HTX.Net/HTX.Net.xml

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,9 @@
419419
<member name="T:HTX.Net.Clients.SpotApi.HTXSocketClientSpotApi">
420420
<inheritdoc />
421421
</member>
422+
<member name="P:HTX.Net.Clients.SpotApi.HTXSocketClientSpotApi.ClientOptions">
423+
<inheritdoc />
424+
</member>
422425
<member name="M:HTX.Net.Clients.SpotApi.HTXSocketClientSpotApi.FormatSymbol(System.String,System.String,CryptoExchange.Net.SharedApis.TradingMode,System.Nullable{System.DateTime})">
423426
<inheritdoc />
424427
</member>
@@ -17387,6 +17390,16 @@
1738717390
HTX options
1738817391
</summary>
1738917392
</member>
17393+
<member name="P:HTX.Net.Objects.Options.HTXOptions.AllowAppendingClientOrderId">
17394+
<summary>
17395+
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.<br />
17396+
Note that:<br />
17397+
* It does not impact the amount of fees a user pays in any way<br />
17398+
* It does not impact functionality. The reference is added just before sending the request and removed again during data deserialization<br />
17399+
* 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<br />
17400+
* 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
17401+
</summary>
17402+
</member>
1739017403
<member name="T:HTX.Net.Objects.Options.HTXOrderBookOptions">
1739117404
<summary>
1739217405
Options for the HTX SymbolOrderBook
@@ -17427,14 +17440,19 @@
1742717440
ctor
1742817441
</summary>
1742917442
</member>
17430-
<member name="P:HTX.Net.Objects.Options.HTXRestOptions.SignPublicRequests">
17443+
<member name="P:HTX.Net.Objects.Options.HTXRestOptions.AllowAppendingClientOrderId">
1743117444
<summary>
17432-
Whether public requests should be signed if ApiCredentials are provided. Needed for accurate rate limiting.
17445+
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.<br />
17446+
Note that:<br />
17447+
* It does not impact the amount of fees a user pays in any way<br />
17448+
* It does not impact functionality. The reference is added just before sending the request and removed again during data deserialization<br />
17449+
* 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<br />
17450+
* 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
1743317451
</summary>
1743417452
</member>
17435-
<member name="P:HTX.Net.Objects.Options.HTXRestOptions.BrokerId">
17453+
<member name="P:HTX.Net.Objects.Options.HTXRestOptions.SignPublicRequests">
1743617454
<summary>
17437-
Broker id
17455+
Whether public requests should be signed if ApiCredentials are provided. Needed for accurate rate limiting.
1743817456
</summary>
1743917457
</member>
1744017458
<member name="P:HTX.Net.Objects.Options.HTXRestOptions.SpotOptions">
@@ -17462,9 +17480,14 @@
1746217480
ctor
1746317481
</summary>
1746417482
</member>
17465-
<member name="P:HTX.Net.Objects.Options.HTXSocketOptions.BrokerId">
17483+
<member name="P:HTX.Net.Objects.Options.HTXSocketOptions.AllowAppendingClientOrderId">
1746617484
<summary>
17467-
Broker id
17485+
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.<br />
17486+
Note that:<br />
17487+
* It does not impact the amount of fees a user pays in any way<br />
17488+
* It does not impact functionality. The reference is added just before sending the request and removed again during data deserialization<br />
17489+
* 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<br />
17490+
* 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
1746817491
</summary>
1746917492
</member>
1747017493
<member name="P:HTX.Net.Objects.Options.HTXSocketOptions.SpotOptions">

HTX.Net/HTXExchange.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ public static class HTXExchange
3838
"https://www.htx.com/en-us/opend/newApiPages/"
3939
};
4040

41+
internal const string ClientOrderId = "AA1ef14811";
42+
internal const string ClientOrderIdPrefix = ClientOrderId + LibraryHelpers.ClientOrderIdSeperator;
43+
4144
/// <summary>
4245
/// Format a base and quote asset to an HTX recognized symbol
4346
/// </summary>

HTX.Net/Objects/Models/HTXBatchCancelResult.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public record HTXFailedCancelResult
4646
/// The id of the failed order
4747
/// </summary>
4848
[JsonPropertyName("client-order-id")]
49+
[JsonConverterCtor<ReplaceConverter>($"{HTXExchange.ClientOrderIdPrefix}->")]
4950
public string? ClientOrderId { get; set; }
5051
}
5152
}

HTX.Net/Objects/Models/HTXBatchPlaceResult.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public record HTXBatchPlaceResult
1414
/// Client order id
1515
/// </summary>
1616
[JsonPropertyName("client-order-id")]
17+
[JsonConverterCtor<ReplaceConverter>($"{HTXExchange.ClientOrderIdPrefix}->")]
1718
public string? ClientOrderId { get; set; }
1819
/// <summary>
1920
/// Whether the placement was successful

0 commit comments

Comments
 (0)