From 708896d83ba51a969cdfc9f70f8e8ecb8d266f1b Mon Sep 17 00:00:00 2001 From: JKorf Date: Sun, 1 Feb 2026 15:04:49 +0100 Subject: [PATCH 1/8] wip --- BitMEX.Net/BitMEX.Net.csproj | 4 +- .../BitMEXRestClientExchangeApiShared.cs | 76 +++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/BitMEX.Net/BitMEX.Net.csproj b/BitMEX.Net/BitMEX.Net.csproj index 799b32b..e192b32 100644 --- a/BitMEX.Net/BitMEX.Net.csproj +++ b/BitMEX.Net/BitMEX.Net.csproj @@ -52,10 +52,12 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - all runtime; build; native; contentfiles; analyzers; buildtransitive + + + \ No newline at end of file diff --git a/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs b/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs index fda846a..17b7ba1 100644 --- a/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs +++ b/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs @@ -522,6 +522,44 @@ async Task> ISpotSymbolRestClient.GetSpotS return response; } + public async Task> GetSpotSymbolsForBaseAssetAsync(string baseAsset) + { + if (!ExchangeSymbolCache.HasCached(_topicSpotId)) + { + var symbols = await ((ISpotSymbolRestClient)this).GetSpotSymbolsAsync(new GetSymbolsRequest()).ConfigureAwait(false); + if (!symbols) + return new ExchangeResult(Exchange, symbols.Error!); + } + + return new ExchangeResult(Exchange, ExchangeSymbolCache.GetSymbolsForBaseAsset(_topicSpotId, baseAsset)); + } + + public async Task> SupportsSpotSymbolAsync(SharedSymbol symbol) + { + if (symbol.TradingMode != TradingMode.Spot) + throw new ArgumentException(nameof(symbol), "Only Spot symbols allowed"); + + if (!ExchangeSymbolCache.HasCached(_topicSpotId)) + { + var symbols = await ((ISpotSymbolRestClient)this).GetSpotSymbolsAsync(new GetSymbolsRequest()).ConfigureAwait(false); + if (!symbols) + return new ExchangeResult(Exchange, symbols.Error!); + } + + return new ExchangeResult(Exchange, ExchangeSymbolCache.SupportsSymbol(_topicSpotId, symbol)); + } + + public async Task> SupportsSpotSymbolAsync(string symbolName) + { + if (!ExchangeSymbolCache.HasCached(_topicSpotId)) + { + var symbols = await ((ISpotSymbolRestClient)this).GetSpotSymbolsAsync(new GetSymbolsRequest()).ConfigureAwait(false); + if (!symbols) + return new ExchangeResult(Exchange, symbols.Error!); + } + + return new ExchangeResult(Exchange, ExchangeSymbolCache.SupportsSymbol(_topicSpotId, symbolName)); + } #endregion #region Spot Ticker client @@ -1064,6 +1102,44 @@ async Task> IFuturesSymbolRestClient.Ge return response; } + public async Task> GetFuturesSymbolsForBaseAssetAsync(string baseAsset) + { + if (!ExchangeSymbolCache.HasCached(_topicFuturesId)) + { + var symbols = await ((IFuturesSymbolRestClient)this).GetFuturesSymbolsAsync(new GetSymbolsRequest()).ConfigureAwait(false); + if (!symbols) + return new ExchangeResult(Exchange, symbols.Error!); + } + + return new ExchangeResult(Exchange, ExchangeSymbolCache.GetSymbolsForBaseAsset(_topicFuturesId, baseAsset)); + } + + public async Task> SupportsFuturesSymbolAsync(SharedSymbol symbol) + { + if (symbol.TradingMode == TradingMode.Spot) + throw new ArgumentException(nameof(symbol), "Spot symbols not allowed"); + + if (!ExchangeSymbolCache.HasCached(_topicFuturesId)) + { + var symbols = await ((IFuturesSymbolRestClient)this).GetFuturesSymbolsAsync(new GetSymbolsRequest()).ConfigureAwait(false); + if (!symbols) + return new ExchangeResult(Exchange, symbols.Error!); + } + + return new ExchangeResult(Exchange, ExchangeSymbolCache.SupportsSymbol(_topicFuturesId, symbol)); + } + + public async Task> SupportsFuturesSymbolAsync(string symbolName) + { + if (!ExchangeSymbolCache.HasCached(_topicFuturesId)) + { + var symbols = await ((IFuturesSymbolRestClient)this).GetFuturesSymbolsAsync(new GetSymbolsRequest()).ConfigureAwait(false); + if (!symbols) + return new ExchangeResult(Exchange, symbols.Error!); + } + + return new ExchangeResult(Exchange, ExchangeSymbolCache.SupportsSymbol(_topicFuturesId, symbolName)); + } #endregion #region Futures Ticker client From 4d84e9095fe1394f9298ce7c3263e13a0f0c240b Mon Sep 17 00:00:00 2001 From: Jkorf Date: Mon, 2 Feb 2026 09:36:24 +0100 Subject: [PATCH 2/8] Added check for disposed client in UserClientProvider --- BitMEX.Net/Clients/BitMEXUserClientProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BitMEX.Net/Clients/BitMEXUserClientProvider.cs b/BitMEX.Net/Clients/BitMEXUserClientProvider.cs index 781a23f..a53383c 100644 --- a/BitMEX.Net/Clients/BitMEXUserClientProvider.cs +++ b/BitMEX.Net/Clients/BitMEXUserClientProvider.cs @@ -64,7 +64,7 @@ public void ClearUserClients(string userIdentifier) /// public IBitMEXRestClient GetRestClient(string userIdentifier, ApiCredentials? credentials = null, BitMEXEnvironment? 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; @@ -73,7 +73,7 @@ public IBitMEXRestClient GetRestClient(string userIdentifier, ApiCredentials? cr /// public IBitMEXSocketClient GetSocketClient(string userIdentifier, ApiCredentials? credentials = null, BitMEXEnvironment? 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; From 58e90a4756e3c813f97af8e302f291e7635bb167 Mon Sep 17 00:00:00 2001 From: Jkorf Date: Mon, 2 Feb 2026 16:35:13 +0100 Subject: [PATCH 3/8] wip --- .../Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs | 1 + .../Clients/ExchangeApi/BitMEXSocketClientExchangeApiShared.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs b/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs index 17b7ba1..b1088eb 100644 --- a/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs +++ b/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs @@ -1600,6 +1600,7 @@ async Task> IFuturesOrderRestClient.GetPosit LiquidationPrice = x.LiquidationPrice == 0 ? null : x.LiquidationPrice, Leverage = x.Leverage, AverageOpenPrice = x.AverageEntryPrice, + PositionMode = SharedPositionMode.OneWay, PositionSide = x.CurrentQuantity < 0 ? SharedPositionSide.Short : SharedPositionSide.Long }).ToArray()); } diff --git a/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApiShared.cs b/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApiShared.cs index 48af957..80b5406 100644 --- a/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApiShared.cs +++ b/BitMEX.Net/Clients/ExchangeApi/BitMEXSocketClientExchangeApiShared.cs @@ -397,6 +397,7 @@ async Task> IPositionSocketClient.SubscribeTo update => handler(update.ToType(update.Data.Where(x => x.Currency != null).Select(x => new SharedPosition(ExchangeSymbolCache.ParseSymbol(_topicFuturesId, x.Symbol), x.Symbol, Math.Abs(x.CurrentQuantity ?? 0), x.Timestamp) { AverageOpenPrice = x.AverageEntryPrice, + PositionMode = SharedPositionMode.OneWay, PositionSide = x.CurrentQuantity < 0 ? SharedPositionSide.Short : SharedPositionSide.Long, UnrealizedPnl = x.UnrealizedPnl.ToSharedAssetQuantity(x.Currency!), Leverage = x.Leverage, From 428ff57ca3d6702ee398c266f5a7c86e8fa8cb6a Mon Sep 17 00:00:00 2001 From: Jkorf Date: Tue, 3 Feb 2026 16:40:11 +0100 Subject: [PATCH 4/8] wip --- BitMEX.Net/BitMEX.Net.xml | 61 ++++++++++++++++ BitMEX.Net/BitMEXTrackerFactory.cs | 69 ++++++++++++++++++- BitMEX.Net/BitMEXUserDataTracker.cs | 63 +++++++++++++++++ .../Interfaces/IBitMEXTrackerFactory.cs | 31 +++++++++ 4 files changed, 221 insertions(+), 3 deletions(-) create mode 100644 BitMEX.Net/BitMEXUserDataTracker.cs diff --git a/BitMEX.Net/BitMEX.Net.xml b/BitMEX.Net/BitMEX.Net.xml index a36e84c..5bdbf55 100644 --- a/BitMEX.Net/BitMEX.Net.xml +++ b/BitMEX.Net/BitMEX.Net.xml @@ -150,6 +150,37 @@ + + + + + + + + + + + + + + + + + + ctor + + + + + + + + + + + ctor + + Utility methods for BitMEX @@ -3440,6 +3471,36 @@ 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 + Environment + + + + Create a new futures user data tracker + + Configuration + Api addresses diff --git a/BitMEX.Net/BitMEXTrackerFactory.cs b/BitMEX.Net/BitMEXTrackerFactory.cs index 0e9702a..200ab0e 100644 --- a/BitMEX.Net/BitMEXTrackerFactory.cs +++ b/BitMEX.Net/BitMEXTrackerFactory.cs @@ -1,12 +1,17 @@ +using BitMEX.Net.Clients; +using BitMEX.Net.Interfaces; +using BitMEX.Net.Interfaces.Clients; +using CryptoExchange.Net.Authentication; using CryptoExchange.Net.SharedApis; using CryptoExchange.Net.Trackers.Klines; using CryptoExchange.Net.Trackers.Trades; -using BitMEX.Net.Interfaces; -using BitMEX.Net.Interfaces.Clients; +using CryptoExchange.Net.Trackers.UserData; +using CryptoExchange.Net.Trackers.UserData.Interfaces; +using CryptoExchange.Net.Trackers.UserData.Objects; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using System; -using BitMEX.Net.Clients; namespace BitMEX.Net { @@ -59,5 +64,63 @@ public ITradeTracker CreateTradeTracker(SharedSymbol symbol, int? limit = null, period ); } + + /// + public IUserSpotDataTracker CreateUserSpotDataTracker(SpotUserDataTrackerConfig config) + { + var restClient = _serviceProvider?.GetRequiredService() ?? new BitMEXRestClient(); + var socketClient = _serviceProvider?.GetRequiredService() ?? new BitMEXSocketClient(); + return new BitMEXUserSpotDataTracker( + _serviceProvider?.GetRequiredService>() ?? new NullLogger(), + restClient, + socketClient, + null, + config + ); + } + + /// + public IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, SpotUserDataTrackerConfig config, ApiCredentials credentials, BitMEXEnvironment? environment = null) + { + var clientProvider = _serviceProvider?.GetRequiredService() ?? new BitMEXUserClientProvider(); + var restClient = clientProvider.GetRestClient(userIdentifier, credentials, environment); + var socketClient = clientProvider.GetSocketClient(userIdentifier, credentials, environment); + return new BitMEXUserSpotDataTracker( + _serviceProvider?.GetRequiredService>() ?? new NullLogger(), + restClient, + socketClient, + userIdentifier, + config + ); + } + + /// + public IUserFuturesDataTracker CreateUserFuturesDataTracker(FuturesUserDataTrackerConfig config) + { + var restClient = _serviceProvider?.GetRequiredService() ?? new BitMEXRestClient(); + var socketClient = _serviceProvider?.GetRequiredService() ?? new BitMEXSocketClient(); + return new BitMEXUserFuturesDataTracker( + _serviceProvider?.GetRequiredService>() ?? new NullLogger(), + restClient, + socketClient, + null, + config + ); + } + + /// + public IUserFuturesDataTracker CreateUserFuturesDataTracker(string userIdentifier, FuturesUserDataTrackerConfig config, ApiCredentials credentials, BitMEXEnvironment? environment = null) + { + var clientProvider = _serviceProvider?.GetRequiredService() ?? new BitMEXUserClientProvider(); + var restClient = clientProvider.GetRestClient(userIdentifier, credentials, environment); + var socketClient = clientProvider.GetSocketClient(userIdentifier, credentials, environment); + return new BitMEXUserFuturesDataTracker( + _serviceProvider?.GetRequiredService>() ?? new NullLogger(), + restClient, + socketClient, + userIdentifier, + config + ); + } } } diff --git a/BitMEX.Net/BitMEXUserDataTracker.cs b/BitMEX.Net/BitMEXUserDataTracker.cs new file mode 100644 index 0000000..200e793 --- /dev/null +++ b/BitMEX.Net/BitMEXUserDataTracker.cs @@ -0,0 +1,63 @@ +using BitMEX.Net.Interfaces.Clients; +using CryptoExchange.Net.SharedApis; +using CryptoExchange.Net.Trackers.UserData; +using CryptoExchange.Net.Trackers.UserData.Objects; +using Microsoft.Extensions.Logging; + +namespace BitMEX.Net +{ + /// + public class BitMEXUserSpotDataTracker : UserSpotDataTracker + { + /// + /// ctor + /// + public BitMEXUserSpotDataTracker( + ILogger logger, + IBitMEXRestClient restClient, + IBitMEXSocketClient socketClient, + string? userIdentifier, + SpotUserDataTrackerConfig config) : base( + logger, + restClient.ExchangeApi.SharedClient, + null, + restClient.ExchangeApi.SharedClient, + socketClient.ExchangeApi.SharedClient, + restClient.ExchangeApi.SharedClient, + socketClient.ExchangeApi.SharedClient, + socketClient.ExchangeApi.SharedClient, + userIdentifier, + config) + { + } + } + + /// + public class BitMEXUserFuturesDataTracker : UserFuturesDataTracker + { + /// + protected override bool WebsocketPositionUpdatesAreFullSnapshots => false; + + /// + /// ctor + /// + public BitMEXUserFuturesDataTracker( + ILogger logger, + IBitMEXRestClient restClient, + IBitMEXSocketClient socketClient, + string? userIdentifier, + FuturesUserDataTrackerConfig config) : base(logger, + restClient.ExchangeApi.SharedClient, + null, + restClient.ExchangeApi.SharedClient, + socketClient.ExchangeApi.SharedClient, + restClient.ExchangeApi.SharedClient, + socketClient.ExchangeApi.SharedClient, + socketClient.ExchangeApi.SharedClient, + socketClient.ExchangeApi.SharedClient, + userIdentifier, + config) + { + } + } +} diff --git a/BitMEX.Net/Interfaces/IBitMEXTrackerFactory.cs b/BitMEX.Net/Interfaces/IBitMEXTrackerFactory.cs index 23891af..cc10427 100644 --- a/BitMEX.Net/Interfaces/IBitMEXTrackerFactory.cs +++ b/BitMEX.Net/Interfaces/IBitMEXTrackerFactory.cs @@ -1,4 +1,8 @@ +using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Interfaces; +using CryptoExchange.Net.Trackers.UserData; +using CryptoExchange.Net.Trackers.UserData.Interfaces; +using CryptoExchange.Net.Trackers.UserData.Objects; namespace BitMEX.Net.Interfaces { @@ -7,5 +11,32 @@ namespace BitMEX.Net.Interfaces /// public interface IBitMEXTrackerFactory : ITrackerFactory { + /// + /// Create a new Spot user data tracker + /// + /// User identifier + /// Configuration + /// Credentials + /// Environment + IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, SpotUserDataTrackerConfig config, ApiCredentials credentials, BitMEXEnvironment? environment = null); + /// + /// Create a new spot user data tracker + /// + /// Configuration + IUserSpotDataTracker CreateUserSpotDataTracker(SpotUserDataTrackerConfig config); + + /// + /// Create a new futures user data tracker + /// + /// User identifier + /// Configuration + /// Credentials + /// Environment + IUserFuturesDataTracker CreateUserFuturesDataTracker(string userIdentifier, FuturesUserDataTrackerConfig config, ApiCredentials credentials, BitMEXEnvironment? environment = null); + /// + /// Create a new futures user data tracker + /// + /// Configuration + IUserFuturesDataTracker CreateUserFuturesDataTracker(FuturesUserDataTrackerConfig config); } } From 34e0a8777b0664f96998ae88f0e9d91c02260ebd Mon Sep 17 00:00:00 2001 From: JKorf Date: Tue, 3 Feb 2026 20:35:33 +0100 Subject: [PATCH 5/8] wip --- .../ExchangeApi/BitMEXRestClientExchangeApiShared.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs b/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs index b1088eb..8f6bee2 100644 --- a/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs +++ b/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs @@ -522,7 +522,7 @@ async Task> ISpotSymbolRestClient.GetSpotS return response; } - public async Task> GetSpotSymbolsForBaseAssetAsync(string baseAsset) + async Task> ISpotSymbolRestClient.GetSpotSymbolsForBaseAssetAsync(string baseAsset) { if (!ExchangeSymbolCache.HasCached(_topicSpotId)) { @@ -534,7 +534,7 @@ public async Task> GetSpotSymbolsForBaseAssetAsyn return new ExchangeResult(Exchange, ExchangeSymbolCache.GetSymbolsForBaseAsset(_topicSpotId, baseAsset)); } - public async Task> SupportsSpotSymbolAsync(SharedSymbol symbol) + async Task> ISpotSymbolRestClient.SupportsSpotSymbolAsync(SharedSymbol symbol) { if (symbol.TradingMode != TradingMode.Spot) throw new ArgumentException(nameof(symbol), "Only Spot symbols allowed"); @@ -549,7 +549,7 @@ public async Task> SupportsSpotSymbolAsync(SharedSymbol sym return new ExchangeResult(Exchange, ExchangeSymbolCache.SupportsSymbol(_topicSpotId, symbol)); } - public async Task> SupportsSpotSymbolAsync(string symbolName) + async Task> ISpotSymbolRestClient.SupportsSpotSymbolAsync(string symbolName) { if (!ExchangeSymbolCache.HasCached(_topicSpotId)) { @@ -1102,7 +1102,7 @@ async Task> IFuturesSymbolRestClient.Ge return response; } - public async Task> GetFuturesSymbolsForBaseAssetAsync(string baseAsset) + async Task> IFuturesSymbolRestClient.GetFuturesSymbolsForBaseAssetAsync(string baseAsset) { if (!ExchangeSymbolCache.HasCached(_topicFuturesId)) { @@ -1114,7 +1114,7 @@ public async Task> GetFuturesSymbolsForBaseAssetA return new ExchangeResult(Exchange, ExchangeSymbolCache.GetSymbolsForBaseAsset(_topicFuturesId, baseAsset)); } - public async Task> SupportsFuturesSymbolAsync(SharedSymbol symbol) + async Task> IFuturesSymbolRestClient.SupportsFuturesSymbolAsync(SharedSymbol symbol) { if (symbol.TradingMode == TradingMode.Spot) throw new ArgumentException(nameof(symbol), "Spot symbols not allowed"); @@ -1129,7 +1129,7 @@ public async Task> SupportsFuturesSymbolAsync(SharedSymbol return new ExchangeResult(Exchange, ExchangeSymbolCache.SupportsSymbol(_topicFuturesId, symbol)); } - public async Task> SupportsFuturesSymbolAsync(string symbolName) + async Task> IFuturesSymbolRestClient.SupportsFuturesSymbolAsync(string symbolName) { if (!ExchangeSymbolCache.HasCached(_topicFuturesId)) { From 7df2678f6d2868ae68bdbcf3f21630e78fa086fb Mon Sep 17 00:00:00 2001 From: JKorf Date: Wed, 4 Feb 2026 21:45:33 +0100 Subject: [PATCH 6/8] Added shared deposit status --- .../ExchangeApi/BitMEXRestClientExchangeApiShared.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs b/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs index 8f6bee2..341aa38 100644 --- a/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs +++ b/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs @@ -181,7 +181,13 @@ async Task> IDepositRestClient.GetDepositsAsy nextToken = new OffsetToken((offset ?? 0) + deposits.Data.Count()); return deposits.AsExchangeResult(Exchange, TradingMode.Spot, - deposits.Data.Where(x => x.TransactionType == TransactionType.Deposit).Select(x => new SharedDeposit(BitMEXExchange.AssetAliases.ExchangeToCommonName(BitMEXUtils.GetAssetFromCurrency(x.Currency)), x.Quantity.ToSharedAssetQuantity(x.Currency), x.TransactionStatus == TransactionStatus.Completed, x.TransactionTime) + deposits.Data.Where(x => x.TransactionType == TransactionType.Deposit).Select(x => + new SharedDeposit( + BitMEXExchange.AssetAliases.ExchangeToCommonName(BitMEXUtils.GetAssetFromCurrency(x.Currency)), + x.Quantity.ToSharedAssetQuantity(x.Currency), + x.TransactionStatus == TransactionStatus.Completed, + x.TransactionTime, + x.TransactionStatus == TransactionStatus.Completed ? SharedTransferStatus.Completed : SharedTransferStatus.Failed) { Network = x.Network, TransactionId = x.Transaction, From db412d0c72d855f891ce235b29515f9d3a9697f8 Mon Sep 17 00:00:00 2001 From: Jkorf Date: Thu, 5 Feb 2026 16:27:21 +0100 Subject: [PATCH 7/8] wip --- BitMEX.Net/BitMEX.Net.xml | 8 +-- BitMEX.Net/BitMEXTrackerFactory.cs | 8 +-- BitMEX.Net/BitMEXUserDataTracker.cs | 8 +-- .../BitMEXRestClientExchangeApiShared.cs | 6 +- .../Interfaces/IBitMEXTrackerFactory.cs | 8 +-- BitMEX.Net/Objects/Models/BitMEXPosition.cs | 64 +++++++++---------- 6 files changed, 51 insertions(+), 51 deletions(-) diff --git a/BitMEX.Net/BitMEX.Net.xml b/BitMEX.Net/BitMEX.Net.xml index 5bdbf55..2586c4d 100644 --- a/BitMEX.Net/BitMEX.Net.xml +++ b/BitMEX.Net/BitMEX.Net.xml @@ -153,13 +153,13 @@ - + - + @@ -3471,7 +3471,7 @@ Tracker factory - + Create a new Spot user data tracker @@ -3486,7 +3486,7 @@ Configuration - + Create a new futures user data tracker diff --git a/BitMEX.Net/BitMEXTrackerFactory.cs b/BitMEX.Net/BitMEXTrackerFactory.cs index 200ab0e..8045b32 100644 --- a/BitMEX.Net/BitMEXTrackerFactory.cs +++ b/BitMEX.Net/BitMEXTrackerFactory.cs @@ -66,7 +66,7 @@ public ITradeTracker CreateTradeTracker(SharedSymbol symbol, int? limit = null, } /// - public IUserSpotDataTracker CreateUserSpotDataTracker(SpotUserDataTrackerConfig config) + public IUserSpotDataTracker CreateUserSpotDataTracker(SpotUserDataTrackerConfig? config = null) { var restClient = _serviceProvider?.GetRequiredService() ?? new BitMEXRestClient(); var socketClient = _serviceProvider?.GetRequiredService() ?? new BitMEXSocketClient(); @@ -80,7 +80,7 @@ public IUserSpotDataTracker CreateUserSpotDataTracker(SpotUserDataTrackerConfig } /// - public IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, SpotUserDataTrackerConfig config, ApiCredentials credentials, BitMEXEnvironment? environment = null) + public IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, ApiCredentials credentials, SpotUserDataTrackerConfig? config = null, BitMEXEnvironment? environment = null) { var clientProvider = _serviceProvider?.GetRequiredService() ?? new BitMEXUserClientProvider(); var restClient = clientProvider.GetRestClient(userIdentifier, credentials, environment); @@ -95,7 +95,7 @@ public IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, Spo } /// - public IUserFuturesDataTracker CreateUserFuturesDataTracker(FuturesUserDataTrackerConfig config) + public IUserFuturesDataTracker CreateUserFuturesDataTracker(FuturesUserDataTrackerConfig? config = null) { var restClient = _serviceProvider?.GetRequiredService() ?? new BitMEXRestClient(); var socketClient = _serviceProvider?.GetRequiredService() ?? new BitMEXSocketClient(); @@ -109,7 +109,7 @@ public IUserFuturesDataTracker CreateUserFuturesDataTracker(FuturesUserDataTrack } /// - public IUserFuturesDataTracker CreateUserFuturesDataTracker(string userIdentifier, FuturesUserDataTrackerConfig config, ApiCredentials credentials, BitMEXEnvironment? environment = null) + public IUserFuturesDataTracker CreateUserFuturesDataTracker(string userIdentifier, ApiCredentials credentials, FuturesUserDataTrackerConfig? config = null, BitMEXEnvironment? environment = null) { var clientProvider = _serviceProvider?.GetRequiredService() ?? new BitMEXUserClientProvider(); var restClient = clientProvider.GetRestClient(userIdentifier, credentials, environment); diff --git a/BitMEX.Net/BitMEXUserDataTracker.cs b/BitMEX.Net/BitMEXUserDataTracker.cs index 200e793..527bba8 100644 --- a/BitMEX.Net/BitMEXUserDataTracker.cs +++ b/BitMEX.Net/BitMEXUserDataTracker.cs @@ -17,7 +17,7 @@ public BitMEXUserSpotDataTracker( IBitMEXRestClient restClient, IBitMEXSocketClient socketClient, string? userIdentifier, - SpotUserDataTrackerConfig config) : base( + SpotUserDataTrackerConfig? config) : base( logger, restClient.ExchangeApi.SharedClient, null, @@ -27,7 +27,7 @@ public BitMEXUserSpotDataTracker( socketClient.ExchangeApi.SharedClient, socketClient.ExchangeApi.SharedClient, userIdentifier, - config) + config ?? new SpotUserDataTrackerConfig()) { } } @@ -46,7 +46,7 @@ public BitMEXUserFuturesDataTracker( IBitMEXRestClient restClient, IBitMEXSocketClient socketClient, string? userIdentifier, - FuturesUserDataTrackerConfig config) : base(logger, + FuturesUserDataTrackerConfig? config) : base(logger, restClient.ExchangeApi.SharedClient, null, restClient.ExchangeApi.SharedClient, @@ -56,7 +56,7 @@ public BitMEXUserFuturesDataTracker( socketClient.ExchangeApi.SharedClient, socketClient.ExchangeApi.SharedClient, userIdentifier, - config) + config ?? new FuturesUserDataTrackerConfig()) { } } diff --git a/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs b/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs index 341aa38..5626012 100644 --- a/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs +++ b/BitMEX.Net/Clients/ExchangeApi/BitMEXRestClientExchangeApiShared.cs @@ -1228,7 +1228,7 @@ async Task> ILeverageRestClient.GetLeverageAsy return result.AsExchangeError(Exchange, new ServerError(new ErrorInfo(ErrorType.NoPosition, "Position not found"))); var position = result.Data.First(); - return result.AsExchangeResult(Exchange, request.Symbol!.TradingMode, new SharedLeverage(position.Leverage) + return result.AsExchangeResult(Exchange, request.Symbol!.TradingMode, new SharedLeverage(position.Leverage ?? 0) { MarginMode = position.CrossMargin ? SharedMarginMode.Cross : SharedMarginMode.Isolated }); @@ -1253,7 +1253,7 @@ async Task> ILeverageRestClient.SetLeverageAsy if (!result) return result.AsExchangeResult(Exchange, null, default); - return result.AsExchangeResult(Exchange, request.Symbol!.TradingMode, new SharedLeverage(result.Data.Leverage) { MarginMode = request.MarginMode }); + return result.AsExchangeResult(Exchange, request.Symbol!.TradingMode, new SharedLeverage(result.Data.Leverage ?? 0) { MarginMode = request.MarginMode }); } else { @@ -1261,7 +1261,7 @@ async Task> ILeverageRestClient.SetLeverageAsy if (!result) return result.AsExchangeResult(Exchange, null, default); - return result.AsExchangeResult(Exchange, request.Symbol!.TradingMode, new SharedLeverage(result.Data.Leverage) { MarginMode = request.MarginMode }); + return result.AsExchangeResult(Exchange, request.Symbol!.TradingMode, new SharedLeverage(result.Data.Leverage ?? 0) { MarginMode = request.MarginMode }); } } diff --git a/BitMEX.Net/Interfaces/IBitMEXTrackerFactory.cs b/BitMEX.Net/Interfaces/IBitMEXTrackerFactory.cs index cc10427..0a15911 100644 --- a/BitMEX.Net/Interfaces/IBitMEXTrackerFactory.cs +++ b/BitMEX.Net/Interfaces/IBitMEXTrackerFactory.cs @@ -18,12 +18,12 @@ public interface IBitMEXTrackerFactory : ITrackerFactory /// Configuration /// Credentials /// Environment - IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, SpotUserDataTrackerConfig config, ApiCredentials credentials, BitMEXEnvironment? environment = null); + IUserSpotDataTracker CreateUserSpotDataTracker(string userIdentifier, ApiCredentials credentials, SpotUserDataTrackerConfig? config = null, BitMEXEnvironment? environment = null); /// /// Create a new spot user data tracker /// /// Configuration - IUserSpotDataTracker CreateUserSpotDataTracker(SpotUserDataTrackerConfig config); + IUserSpotDataTracker CreateUserSpotDataTracker(SpotUserDataTrackerConfig? config = null); /// /// Create a new futures user data tracker @@ -32,11 +32,11 @@ public interface IBitMEXTrackerFactory : ITrackerFactory /// Configuration /// Credentials /// Environment - IUserFuturesDataTracker CreateUserFuturesDataTracker(string userIdentifier, FuturesUserDataTrackerConfig config, ApiCredentials credentials, BitMEXEnvironment? environment = null); + IUserFuturesDataTracker CreateUserFuturesDataTracker(string userIdentifier, ApiCredentials credentials, FuturesUserDataTrackerConfig? config = null, BitMEXEnvironment? environment = null); /// /// Create a new futures user data tracker /// /// Configuration - IUserFuturesDataTracker CreateUserFuturesDataTracker(FuturesUserDataTrackerConfig config); + IUserFuturesDataTracker CreateUserFuturesDataTracker(FuturesUserDataTrackerConfig? config = null); } } diff --git a/BitMEX.Net/Objects/Models/BitMEXPosition.cs b/BitMEX.Net/Objects/Models/BitMEXPosition.cs index 5325943..cbad60c 100644 --- a/BitMEX.Net/Objects/Models/BitMEXPosition.cs +++ b/BitMEX.Net/Objects/Models/BitMEXPosition.cs @@ -39,27 +39,27 @@ public record BitMEXPosition /// The maximum of the maker, taker, and settlement fee. /// [JsonPropertyName("commission")] - public decimal FeeRate { get; set; } + public decimal? FeeRate { get; set; } /// /// Initial margin requirement /// [JsonPropertyName("initMarginReq")] - public decimal InitialMarginRequirement { get; set; } + public decimal? InitialMarginRequirement { get; set; } /// /// Maintenance margin requirement /// [JsonPropertyName("maintMarginReq")] - public decimal MaintenanceMarginRequirement { get; set; } + public decimal? MaintenanceMarginRequirement { get; set; } /// /// Risk limit /// [JsonPropertyName("riskLimit")] - public decimal RiskLimit { get; set; } + public decimal? RiskLimit { get; set; } /// /// Leverage /// [JsonPropertyName("leverage")] - public decimal Leverage { get; set; } + public decimal? Leverage { get; set; } /// /// Cross margin /// @@ -74,22 +74,22 @@ public record BitMEXPosition /// Rebalanced profit and loss /// [JsonPropertyName("rebalancedPnl")] - public long RebalancedPnl { get; set; } + public long? RebalancedPnl { get; set; } /// /// Previous realised profit and loss /// [JsonPropertyName("prevRealisedPnl")] - public long PreviousRealisedPnl { get; set; } + public long? PreviousRealisedPnl { get; set; } /// /// Previous unrealised profit and loss /// [JsonPropertyName("prevUnrealisedPnl")] - public long PreviousUnrealisedPnl { get; set; } + public long? PreviousUnrealisedPnl { get; set; } /// /// Opening quantity /// [JsonPropertyName("openingQty")] - public long OpeningQuantity { get; set; } + public long? OpeningQuantity { get; set; } /// /// Open order buy quantity /// @@ -104,7 +104,7 @@ public record BitMEXPosition /// Open order buy premium /// [JsonPropertyName("openOrderBuyPremium")] - public decimal OpenOrderBuyPremium { get; set; } + public decimal? OpenOrderBuyPremium { get; set; } /// /// Open order sell quantity /// @@ -119,7 +119,7 @@ public record BitMEXPosition /// Open order sell premium /// [JsonPropertyName("openOrderSellPremium")] - public decimal OpenOrderSellPremium { get; set; } + public decimal? OpenOrderSellPremium { get; set; } /// /// Current quantity /// @@ -129,27 +129,27 @@ public record BitMEXPosition /// Current cost /// [JsonPropertyName("currentCost")] - public decimal CurrentCost { get; set; } + public decimal? CurrentCost { get; set; } /// /// Current commissions /// [JsonPropertyName("currentComm")] - public long CurrentCommissions { get; set; } + public long? CurrentCommissions { get; set; } /// /// Realised cost /// [JsonPropertyName("realisedCost")] - public decimal RealisedCost { get; set; } + public decimal? RealisedCost { get; set; } /// /// Unrealised cost /// [JsonPropertyName("unrealisedCost")] - public decimal UnrealisedCost { get; set; } + public decimal? UnrealisedCost { get; set; } /// /// Gross open premium /// [JsonPropertyName("grossOpenPremium")] - public decimal GrossOpenPremium { get; set; } + public decimal? GrossOpenPremium { get; set; } /// /// Is open /// @@ -164,22 +164,22 @@ public record BitMEXPosition /// Mark value /// [JsonPropertyName("markValue")] - public decimal MarkValue { get; set; } + public decimal? MarkValue { get; set; } /// /// Risk value /// [JsonPropertyName("riskValue")] - public decimal RiskValue { get; set; } + public decimal? RiskValue { get; set; } /// /// Home notional /// [JsonPropertyName("homeNotional")] - public decimal HomeNotional { get; set; } + public decimal? HomeNotional { get; set; } /// /// Foreign notional /// [JsonPropertyName("foreignNotional")] - public decimal ForeignNotional { get; set; } + public decimal? ForeignNotional { get; set; } /// /// Position status /// @@ -189,62 +189,62 @@ public record BitMEXPosition /// Position cost /// [JsonPropertyName("posCost")] - public decimal PositionCost { get; set; } + public decimal? PositionCost { get; set; } /// /// Position cross /// [JsonPropertyName("posCross")] - public decimal PositionCross { get; set; } + public decimal? PositionCross { get; set; } /// /// Position commissions /// [JsonPropertyName("posComm")] - public long PositionCommissions { get; set; } + public long? PositionCommissions { get; set; } /// /// Position loss /// [JsonPropertyName("posLoss")] - public decimal PositionLoss { get; set; } + public decimal? PositionLoss { get; set; } /// /// Position margin /// [JsonPropertyName("posMargin")] - public long PositionMargin { get; set; } + public long? PositionMargin { get; set; } /// /// Position maintenance /// [JsonPropertyName("posMaint")] - public long PositionMaintenance { get; set; } + public long? PositionMaintenance { get; set; } /// /// Initial margin /// [JsonPropertyName("initMargin")] - public decimal InitialMargin { get; set; } + public decimal? InitialMargin { get; set; } /// /// Maintenance margin /// [JsonPropertyName("maintMargin")] - public decimal MaintenanceMargin { get; set; } + public decimal? MaintenanceMargin { get; set; } /// /// Realised profit and loss /// [JsonPropertyName("realisedPnl")] - public long RealisedPnl { get; set; } + public long? RealisedPnl { get; set; } /// /// Unrealised profit and loss /// [JsonPropertyName("unrealisedPnl")] - public long UnrealizedPnl { get; set; } + public long? UnrealizedPnl { get; set; } /// /// Unrealised profit and loss percentage /// [JsonPropertyName("unrealisedPnlPcnt")] - public decimal UnrealisedPnlPcnt { get; set; } + public decimal? UnrealisedPnlPcnt { get; set; } /// /// Unrealised roe percentage /// [JsonPropertyName("unrealisedRoePcnt")] - public decimal UnrealisedRoePercentage { get; set; } + public decimal? UnrealisedRoePercentage { get; set; } /// /// Average cost price /// From c66e7cfbad9fbe7e609bb077ce7875622203af7f Mon Sep 17 00:00:00 2001 From: Jkorf Date: Fri, 6 Feb 2026 13:10:09 +0100 Subject: [PATCH 8/8] CryptoExchange.Net update --- BitMEX.Net/BitMEX.Net.csproj | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/BitMEX.Net/BitMEX.Net.csproj b/BitMEX.Net/BitMEX.Net.csproj index e192b32..aafd51a 100644 --- a/BitMEX.Net/BitMEX.Net.csproj +++ b/BitMEX.Net/BitMEX.Net.csproj @@ -52,12 +52,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - \ No newline at end of file