diff --git a/HTX.Net/Clients/HTXUserClientProvider.cs b/HTX.Net/Clients/HTXUserClientProvider.cs
index ce108844..372cc7ab 100644
--- a/HTX.Net/Clients/HTXUserClientProvider.cs
+++ b/HTX.Net/Clients/HTXUserClientProvider.cs
@@ -60,7 +60,7 @@ public void ClearUserClients(string userIdentifier)
///
public IHTXRestClient GetRestClient(string userIdentifier, ApiCredentials? credentials = null, HTXEnvironment? environment = null)
{
- if (!_restClients.TryGetValue(userIdentifier, out var client))
+ if (!_restClients.TryGetValue(userIdentifier, out var client) || client.Disposed)
client = CreateRestClient(userIdentifier, credentials, environment);
return client;
@@ -69,7 +69,7 @@ public IHTXRestClient GetRestClient(string userIdentifier, ApiCredentials? crede
///
public IHTXSocketClient GetSocketClient(string userIdentifier, ApiCredentials? credentials = null, HTXEnvironment? environment = null)
{
- if (!_socketClients.TryGetValue(userIdentifier, out var client))
+ if (!_socketClients.TryGetValue(userIdentifier, out var client) || client.Disposed)
client = CreateSocketClient(userIdentifier, credentials, environment);
return client;
diff --git a/HTX.Net/Clients/MessageHandlers/HTXSocketUsdtFuturesMessageHandler.cs b/HTX.Net/Clients/MessageHandlers/HTXSocketUsdtFuturesMessageHandler.cs
index 2e829f4c..040be771 100644
--- a/HTX.Net/Clients/MessageHandlers/HTXSocketUsdtFuturesMessageHandler.cs
+++ b/HTX.Net/Clients/MessageHandlers/HTXSocketUsdtFuturesMessageHandler.cs
@@ -26,7 +26,8 @@ internal class HTXSocketUsdtFuturesMessageHandler : JsonSocketMessageHandler
{ "accounts_cross.", "accounts_cross" },
{ "orders_cross.", "orders_cross" },
{ "positions_cross.", "positions_cross" },
- { "matchOrders.", "matchOrders" }
+ { "matchOrders.", "matchOrders" },
+ { "matchOrders_cross.", "matchOrders_cross" }
};
public override JsonSerializerOptions Options { get; } = SerializerOptions.WithConverters(HTXExchange._serializerContext);
diff --git a/HTX.Net/Clients/SpotApi/HTXRestClientSpotApiShared.cs b/HTX.Net/Clients/SpotApi/HTXRestClientSpotApiShared.cs
index be3f29a0..3f1d1a2f 100644
--- a/HTX.Net/Clients/SpotApi/HTXRestClientSpotApiShared.cs
+++ b/HTX.Net/Clients/SpotApi/HTXRestClientSpotApiShared.cs
@@ -109,6 +109,44 @@ async Task> ISpotSymbolRestClient.GetSpotS
return response;
}
+ async Task> ISpotSymbolRestClient.GetSpotSymbolsForBaseAssetAsync(string baseAsset)
+ {
+ if (!ExchangeSymbolCache.HasCached(_topicId))
+ {
+ var symbols = await ((ISpotSymbolRestClient)this).GetSpotSymbolsAsync(new GetSymbolsRequest()).ConfigureAwait(false);
+ if (!symbols)
+ return new ExchangeResult(Exchange, symbols.Error!);
+ }
+
+ return new ExchangeResult(Exchange, ExchangeSymbolCache.GetSymbolsForBaseAsset(_topicId, baseAsset));
+ }
+
+ async Task> ISpotSymbolRestClient.SupportsSpotSymbolAsync(SharedSymbol symbol)
+ {
+ if (symbol.TradingMode != TradingMode.Spot)
+ throw new ArgumentException(nameof(symbol), "Only Spot symbols allowed");
+
+ if (!ExchangeSymbolCache.HasCached(_topicId))
+ {
+ var symbols = await ((ISpotSymbolRestClient)this).GetSpotSymbolsAsync(new GetSymbolsRequest()).ConfigureAwait(false);
+ if (!symbols)
+ return new ExchangeResult(Exchange, symbols.Error!);
+ }
+
+ return new ExchangeResult(Exchange, ExchangeSymbolCache.SupportsSymbol(_topicId, symbol));
+ }
+
+ async Task> ISpotSymbolRestClient.SupportsSpotSymbolAsync(string symbolName)
+ {
+ if (!ExchangeSymbolCache.HasCached(_topicId))
+ {
+ var symbols = await ((ISpotSymbolRestClient)this).GetSpotSymbolsAsync(new GetSymbolsRequest()).ConfigureAwait(false);
+ if (!symbols)
+ return new ExchangeResult(Exchange, symbols.Error!);
+ }
+
+ return new ExchangeResult(Exchange, ExchangeSymbolCache.SupportsSymbol(_topicId, symbolName));
+ }
#endregion
#region Ticker client
@@ -706,7 +744,15 @@ async Task> IDepositRestClient.GetDepositsAsy
if (deposits.Data.Count() == (request.Limit ?? 100))
nextToken = new FromIdToken(deposits.Data.Min(x => x.Id - 1).ToString());
- return deposits.AsExchangeResult(Exchange, TradingMode.Spot, deposits.Data.Select(x => new SharedDeposit(x.Asset!.ToUpperInvariant(), x.Quantity, x.Status == WithdrawDepositStatus.Safe, x.CreateTime)
+ return deposits.AsExchangeResult(Exchange, TradingMode.Spot, deposits.Data.Select(x =>
+ new SharedDeposit(
+ x.Asset!.ToUpperInvariant(),
+ x.Quantity,
+ x.Status == WithdrawDepositStatus.Safe,
+ x.CreateTime,
+ x.Status == WithdrawDepositStatus.Safe ? SharedTransferStatus.Completed
+ : x.Status == WithdrawDepositStatus.Repealed || x.Status == WithdrawDepositStatus.ConfirmError || x.Status == WithdrawDepositStatus.WalletReject || x.Status == WithdrawDepositStatus.Reject || x.Status == WithdrawDepositStatus.Canceled || x.Status == WithdrawDepositStatus.Failed ? SharedTransferStatus.Failed
+ : SharedTransferStatus.Failed)
{
Id = x.Id.ToString(),
Network = x.Network,
diff --git a/HTX.Net/Clients/UsdtFutures/HTXRestClientUsdtFuturesApiShared.cs b/HTX.Net/Clients/UsdtFutures/HTXRestClientUsdtFuturesApiShared.cs
index 6b938db9..e4f535ee 100644
--- a/HTX.Net/Clients/UsdtFutures/HTXRestClientUsdtFuturesApiShared.cs
+++ b/HTX.Net/Clients/UsdtFutures/HTXRestClientUsdtFuturesApiShared.cs
@@ -37,7 +37,7 @@ async Task> IBalanceRestClient.GetBalancesAsy
if (!result)
return result.AsExchangeResult(Exchange, null, default);
- return result.AsExchangeResult(Exchange, SupportedTradingModes, result.Data.Select(x => new SharedBalance(x.MarginAsset, x.MarginBalance, x.MarginFrozen + x.MarginBalance)).ToArray());
+ return result.AsExchangeResult(Exchange, SupportedTradingModes, result.Data.Select(x => new SharedBalance(x.MarginAsset, x.WithdrawAvailable, x.MarginBalance)).ToArray());
}
else
{
@@ -45,7 +45,7 @@ async Task> IBalanceRestClient.GetBalancesAsy
if (!result)
return result.AsExchangeResult(Exchange, null, default);
- return result.AsExchangeResult(Exchange, SupportedTradingModes, result.Data.Select(x => new SharedBalance(x.MarginAsset, x.MarginBalance, x.MarginFrozen + x.MarginBalance)
+ return result.AsExchangeResult(Exchange, SupportedTradingModes, result.Data.Select(x => new SharedBalance("USDT", x.WithdrawAvailable, x.MarginBalance)
{
IsolatedMarginSymbol = x.ContractCode
}).ToArray());
@@ -177,7 +177,44 @@ async Task> IFuturesSymbolRestClient.Ge
ExchangeSymbolCache.UpdateSymbolInfo(_topicId, response.Data);
return response;
}
+ async Task> IFuturesSymbolRestClient.GetFuturesSymbolsForBaseAssetAsync(string baseAsset)
+ {
+ if (!ExchangeSymbolCache.HasCached(_topicId))
+ {
+ var symbols = await ((IFuturesSymbolRestClient)this).GetFuturesSymbolsAsync(new GetSymbolsRequest()).ConfigureAwait(false);
+ if (!symbols)
+ return new ExchangeResult(Exchange, symbols.Error!);
+ }
+
+ return new ExchangeResult(Exchange, ExchangeSymbolCache.GetSymbolsForBaseAsset(_topicId, baseAsset));
+ }
+ async Task> IFuturesSymbolRestClient.SupportsFuturesSymbolAsync(SharedSymbol symbol)
+ {
+ if (symbol.TradingMode == TradingMode.Spot)
+ throw new ArgumentException(nameof(symbol), "Spot symbols not allowed");
+
+ if (!ExchangeSymbolCache.HasCached(_topicId))
+ {
+ var symbols = await ((IFuturesSymbolRestClient)this).GetFuturesSymbolsAsync(new GetSymbolsRequest()).ConfigureAwait(false);
+ if (!symbols)
+ return new ExchangeResult(Exchange, symbols.Error!);
+ }
+
+ return new ExchangeResult(Exchange, ExchangeSymbolCache.SupportsSymbol(_topicId, symbol));
+ }
+
+ async Task> IFuturesSymbolRestClient.SupportsFuturesSymbolAsync(string symbolName)
+ {
+ if (!ExchangeSymbolCache.HasCached(_topicId))
+ {
+ var symbols = await ((IFuturesSymbolRestClient)this).GetFuturesSymbolsAsync(new GetSymbolsRequest()).ConfigureAwait(false);
+ if (!symbols)
+ return new ExchangeResult(Exchange, symbols.Error!);
+ }
+
+ return new ExchangeResult(Exchange, ExchangeSymbolCache.SupportsSymbol(_topicId, symbolName));
+ }
#endregion
#region Futures Order Client
@@ -743,6 +780,7 @@ async Task> IFuturesOrderRestClient.GetPosit
UnrealizedPnl = x.UnrealizedPnl,
AverageOpenPrice = x.CostOpen,
Leverage = x.LeverageRate,
+ PositionMode = x.PositionMode == PositionMode.SingleSide ? SharedPositionMode.OneWay : SharedPositionMode.HedgeMode,
PositionSide = x.Side == OrderSide.Sell ? SharedPositionSide.Short : SharedPositionSide.Long
}).ToArray());
}
@@ -757,6 +795,7 @@ async Task> IFuturesOrderRestClient.GetPosit
UnrealizedPnl = x.UnrealizedPnl,
AverageOpenPrice = x.CostOpen,
Leverage = x.LeverageRate,
+ PositionMode = x.PositionMode == PositionMode.SingleSide ? SharedPositionMode.OneWay : SharedPositionMode.HedgeMode,
PositionSide = x.Side == OrderSide.Sell ? SharedPositionSide.Short : SharedPositionSide.Long
}).ToArray());
}
diff --git a/HTX.Net/Clients/UsdtFutures/HTXSocketClientUsdtFuturesApiShared.cs b/HTX.Net/Clients/UsdtFutures/HTXSocketClientUsdtFuturesApiShared.cs
index 2b079fe7..45324130 100644
--- a/HTX.Net/Clients/UsdtFutures/HTXSocketClientUsdtFuturesApiShared.cs
+++ b/HTX.Net/Clients/UsdtFutures/HTXSocketClientUsdtFuturesApiShared.cs
@@ -131,7 +131,7 @@ async Task> IBalanceSocketClient.SubscribeToB
if (marginMode == SharedMarginMode.Cross)
{
var result = await SubscribeToCrossMarginBalanceUpdatesAsync(
- update => handler(update.ToType(update.Data.Data.Select(x => new SharedBalance(x.MarginAsset, x.MarginBalance - x.MarginFrozen, x.MarginBalance) ).ToArray())),
+ update => handler(update.ToType(update.Data.Data.Select(x => new SharedBalance(x.MarginAsset, x.WithdrawAvailable, x.MarginBalance) ).ToArray())),
ct: ct).ConfigureAwait(false);
return new ExchangeResult(Exchange, result);
@@ -139,7 +139,7 @@ async Task> IBalanceSocketClient.SubscribeToB
else
{
var result = await SubscribeToIsolatedMarginBalanceUpdatesAsync(
- update => handler(update.ToType(update.Data.Data.Select(x => new SharedBalance(x.Asset, x.MarginBalance - x.MarginFrozen, x.MarginBalance) { IsolatedMarginSymbol = x.MarginAccount }).ToArray())),
+ update => handler(update.ToType(update.Data.Data.Select(x => new SharedBalance("USDT", x.WithdrawAvailable, x.MarginBalance) { IsolatedMarginSymbol = x.MarginAccount }).ToArray())),
ct: ct).ConfigureAwait(false);
return new ExchangeResult(Exchange, result);
@@ -326,6 +326,7 @@ async Task> IPositionSocketClient.SubscribeTo
ExchangeSymbolCache.ParseSymbol(_topicId, x.ContractCode), x.ContractCode, x.Quantity, update.Data.Timestamp)
{
AverageOpenPrice = x.PositionPrice,
+ PositionMode = x.PositionMode == PositionMode.SingleSide ? SharedPositionMode.OneWay : SharedPositionMode.HedgeMode,
PositionSide = x.OrderSide == Enums.OrderSide.Sell ? SharedPositionSide.Short : SharedPositionSide.Long,
Leverage = x.LeverageRate,
UnrealizedPnl = x.UnrealizedPnl
@@ -339,6 +340,7 @@ async Task> IPositionSocketClient.SubscribeTo
update => handler(update.ToType(update.Data.Data.Select(x => new SharedPosition(ExchangeSymbolCache.ParseSymbol(_topicId, x.ContractCode), x.ContractCode, x.Quantity, update.Data.Timestamp)
{
AverageOpenPrice = x.PositionPrice,
+ PositionMode = x.PositionMode == PositionMode.SingleSide ? SharedPositionMode.OneWay : SharedPositionMode.HedgeMode,
PositionSide = x.OrderSide == Enums.OrderSide.Sell ? SharedPositionSide.Short : SharedPositionSide.Long,
Leverage = x.LeverageRate,
UnrealizedPnl = x.UnrealizedPnl
diff --git a/HTX.Net/Enums/EventTrigger.cs b/HTX.Net/Enums/EventTrigger.cs
index 25de077b..d328b63e 100644
--- a/HTX.Net/Enums/EventTrigger.cs
+++ b/HTX.Net/Enums/EventTrigger.cs
@@ -62,6 +62,11 @@ public enum EventTrigger
/// Snapshot
///
[Map("snapshot")]
- Snapshot
+ Snapshot,
+ ///
+ /// Close order
+ ///
+ [Map("order.close")]
+ Close
}
}
diff --git a/HTX.Net/HTX.Net.csproj b/HTX.Net/HTX.Net.csproj
index 25a06fc6..66d562d2 100644
--- a/HTX.Net/HTX.Net.csproj
+++ b/HTX.Net/HTX.Net.csproj
@@ -1,4 +1,4 @@
-
+
net8.0;net9.0;net10.0;netstandard2.0;netstandard2.1
enable
@@ -52,7 +52,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/HTX.Net/HTX.Net.xml b/HTX.Net/HTX.Net.xml
index 51221be0..099dd2fa 100644
--- a/HTX.Net/HTX.Net.xml
+++ b/HTX.Net/HTX.Net.xml
@@ -6107,6 +6107,11 @@
Snapshot
+
+
+ Close order
+
+
Fee deduction status.
@@ -8019,6 +8024,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ctor
+
+
+
+
+
+
+
+
+
+
+ ctor
+
+
Client for accessing the HTX API.
@@ -11258,6 +11294,38 @@
Tracker factory
+
+
+ Create a new Spot user data tracker
+
+ User identifier
+ Configuration
+ Credentials
+ Environment
+
+
+
+ Create a new spot user data tracker
+
+ Configuration
+
+
+
+ Create a new futures user data tracker
+
+ User identifier
+ Configuration
+ Credentials
+ Margin mode
+ Environment
+
+
+
+ Create a new futures user data tracker
+
+ Configuration
+ Margin mode
+
Api addresses usable for the HTX clients
diff --git a/HTX.Net/HTXTrackerFactory.cs b/HTX.Net/HTXTrackerFactory.cs
index f1c6c96e..2d8741fb 100644
--- a/HTX.Net/HTXTrackerFactory.cs
+++ b/HTX.Net/HTXTrackerFactory.cs
@@ -1,10 +1,13 @@
using CryptoExchange.Net.SharedApis;
using CryptoExchange.Net.Trackers.Klines;
using CryptoExchange.Net.Trackers.Trades;
+using CryptoExchange.Net.Trackers.UserData.Interfaces;
+using CryptoExchange.Net.Trackers.UserData.Objects;
using HTX.Net.Clients;
using HTX.Net.Interfaces;
using HTX.Net.Interfaces.Clients;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging.Abstractions;
namespace HTX.Net
{
@@ -98,5 +101,68 @@ public ITradeTracker CreateTradeTracker(SharedSymbol symbol, int? limit = null,
period
);
}
+ ///
+ public IUserSpotDataTracker CreateUserSpotDataTracker(SpotUserDataTrackerConfig? config = null)
+ {
+ var restClient = _serviceProvider?.GetRequiredService() ?? new HTXRestClient();
+ var socketClient = _serviceProvider?.GetRequiredService() ?? new HTXSocketClient();
+ return new HTXUserSpotDataTracker(
+ _serviceProvider?.GetRequiredService>() ?? new NullLogger(),
+ restClient,
+ socketClient,
+ null,
+ config
+ );
+ }
+
+ ///
+ public IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, ApiCredentials credentials, SpotUserDataTrackerConfig? config = null, HTXEnvironment? environment = null)
+ {
+ var clientProvider = _serviceProvider?.GetRequiredService() ?? new HTXUserClientProvider();
+ var restClient = clientProvider.GetRestClient(userIdentifier, credentials, environment);
+ var socketClient = clientProvider.GetSocketClient(userIdentifier, credentials, environment);
+ return new HTXUserSpotDataTracker(
+ _serviceProvider?.GetRequiredService>() ?? new NullLogger(),
+ restClient,
+ socketClient,
+ userIdentifier,
+ config
+ );
+ }
+
+ ///
+ public IUserFuturesDataTracker CreateUserFuturesDataTracker(SharedMarginMode marginMode, FuturesUserDataTrackerConfig? config = null)
+ {
+ var exchangeParams = new ExchangeParameters(new ExchangeParameter("HTX", "MarginMode", marginMode));
+
+ var restClient = _serviceProvider?.GetRequiredService() ?? new HTXRestClient();
+ var socketClient = _serviceProvider?.GetRequiredService() ?? new HTXSocketClient();
+ return new HTXUserFuturesDataTracker(
+ _serviceProvider?.GetRequiredService>() ?? new NullLogger(),
+ restClient,
+ socketClient,
+ null,
+ config,
+ exchangeParams
+ );
+ }
+
+ ///
+ public IUserFuturesDataTracker CreateUserFuturesDataTracker(string userIdentifier, ApiCredentials credentials, SharedMarginMode marginMode, FuturesUserDataTrackerConfig? config = null, HTXEnvironment? environment = null)
+ {
+ var exchangeParams = new ExchangeParameters(new ExchangeParameter("HTX", "MarginMode", marginMode));
+
+ var clientProvider = _serviceProvider?.GetRequiredService() ?? new HTXUserClientProvider();
+ var restClient = clientProvider.GetRestClient(userIdentifier, credentials, environment);
+ var socketClient = clientProvider.GetSocketClient(userIdentifier, credentials, environment);
+ return new HTXUserFuturesDataTracker(
+ _serviceProvider?.GetRequiredService>() ?? new NullLogger(),
+ restClient,
+ socketClient,
+ userIdentifier,
+ config,
+ exchangeParams
+ );
+ }
}
}
diff --git a/HTX.Net/HTXUserDataTracker.cs b/HTX.Net/HTXUserDataTracker.cs
new file mode 100644
index 00000000..7c1384f6
--- /dev/null
+++ b/HTX.Net/HTXUserDataTracker.cs
@@ -0,0 +1,65 @@
+using HTX.Net.Interfaces.Clients;
+using CryptoExchange.Net.SharedApis;
+using CryptoExchange.Net.Trackers.UserData;
+using CryptoExchange.Net.Trackers.UserData.Objects;
+using Microsoft.Extensions.Logging;
+
+namespace HTX.Net
+{
+ ///
+ public class HTXUserSpotDataTracker : UserSpotDataTracker
+ {
+ ///
+ /// ctor
+ ///
+ public HTXUserSpotDataTracker(
+ ILogger logger,
+ IHTXRestClient restClient,
+ IHTXSocketClient socketClient,
+ string? userIdentifier,
+ SpotUserDataTrackerConfig? config) : base(
+ logger,
+ restClient.SpotApi.SharedClient,
+ null,
+ restClient.SpotApi.SharedClient,
+ socketClient.SpotApi.SharedClient,
+ restClient.SpotApi.SharedClient,
+ socketClient.SpotApi.SharedClient,
+ socketClient.SpotApi.SharedClient,
+ userIdentifier,
+ config ?? new SpotUserDataTrackerConfig())
+ {
+ }
+ }
+
+ ///
+ public class HTXUserFuturesDataTracker : UserFuturesDataTracker
+ {
+ ///
+ protected override bool WebsocketPositionUpdatesAreFullSnapshots => true;
+
+ ///
+ /// ctor
+ ///
+ public HTXUserFuturesDataTracker(
+ ILogger logger,
+ IHTXRestClient restClient,
+ IHTXSocketClient socketClient,
+ string? userIdentifier,
+ FuturesUserDataTrackerConfig? config,
+ ExchangeParameters? exchangeParameters) : base(logger,
+ restClient.UsdtFuturesApi.SharedClient,
+ null,
+ restClient.UsdtFuturesApi.SharedClient,
+ socketClient.UsdtFuturesApi.SharedClient,
+ restClient.UsdtFuturesApi.SharedClient,
+ socketClient.UsdtFuturesApi.SharedClient,
+ socketClient.UsdtFuturesApi.SharedClient,
+ socketClient.UsdtFuturesApi.SharedClient,
+ userIdentifier,
+ config ?? new FuturesUserDataTrackerConfig(),
+ exchangeParameters: exchangeParameters)
+ {
+ }
+ }
+}
diff --git a/HTX.Net/Interfaces/IHTXTrackerFactory.cs b/HTX.Net/Interfaces/IHTXTrackerFactory.cs
index 091bfbd8..4c230173 100644
--- a/HTX.Net/Interfaces/IHTXTrackerFactory.cs
+++ b/HTX.Net/Interfaces/IHTXTrackerFactory.cs
@@ -1,9 +1,42 @@
-namespace HTX.Net.Interfaces
+using CryptoExchange.Net.SharedApis;
+using CryptoExchange.Net.Trackers.UserData.Interfaces;
+using CryptoExchange.Net.Trackers.UserData.Objects;
+
+namespace HTX.Net.Interfaces
{
///
/// Tracker factory
///
public interface IHTXTrackerFactory : ITrackerFactory
{
+ ///
+ /// Create a new Spot user data tracker
+ ///
+ /// User identifier
+ /// Configuration
+ /// Credentials
+ /// Environment
+ IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, ApiCredentials credentials, SpotUserDataTrackerConfig? config = null, HTXEnvironment? environment = null);
+ ///
+ /// Create a new spot user data tracker
+ ///
+ /// Configuration
+ IUserSpotDataTracker CreateUserSpotDataTracker(SpotUserDataTrackerConfig? config = null);
+
+ ///
+ /// Create a new futures user data tracker
+ ///
+ /// User identifier
+ /// Configuration
+ /// Credentials
+ /// Margin mode
+ /// Environment
+ IUserFuturesDataTracker CreateUserFuturesDataTracker(string userIdentifier, ApiCredentials credentials, SharedMarginMode marginMode, FuturesUserDataTrackerConfig? config = null, HTXEnvironment? environment = null);
+ ///
+ /// Create a new futures user data tracker
+ ///
+ /// Configuration
+ /// Margin mode
+ IUserFuturesDataTracker CreateUserFuturesDataTracker(SharedMarginMode marginMode, FuturesUserDataTrackerConfig? config = null);
}
}