From 58c510599643a6f9a2ce966ee95fedcb65380e2a Mon Sep 17 00:00:00 2001 From: Jan Korf Date: Sat, 24 Feb 2024 22:39:44 +0100 Subject: [PATCH 01/17] Beta (#195) Websocket refactoring --- ByBit.Net/Bybit.Net.csproj | 18 +- ByBit.Net/Clients/BybitRestClient.cs | 9 +- ByBit.Net/Clients/BybitSocketClient.cs | 41 +- .../BybitSocketClientCopyTradingApi.cs | 298 ---------- .../BybitRestClientDerivativesApi.cs | 1 - .../BybitSocketClientDerivativesPublicApi.cs | 303 ++-------- .../BybitSocketClientContractApi.cs | 270 ++------- .../BybitSocketClientUnifiedMarginApi.cs | 302 ++-------- .../GeneralApi/BybitRestClientGeneralApi.cs | 1 - .../BybitRestClientInverseFuturesApi.cs | 1 - .../BybitRestClientInversePerpetualApi.cs | 1 - .../BybitSocketClientInversePerpetualApi.cs | 547 ------------------ .../SpotApi/BybitRestClientBaseSpotApi.cs | 1 - .../SpotApi/BybitSocketClientBaseSpotApi.cs | 214 ------- .../SpotApi/v1/BybitRestClientSpotApiV1.cs | 1 - .../SpotApi/v1/BybitSocketClientSpotApiV1.cs | 288 --------- .../SpotApi/v2/BybitSocketClientSpotApiV2.cs | 270 --------- .../SpotApi/v3/BybitRestClientSpotApiV3.cs | 1 - .../SpotApi/v3/BybitSocketClientSpotApiV3.cs | 340 ++--------- .../BybitRestClientUsdPerpetualApi.cs | 2 - .../BybitSocketClientUsdPerpetualApi.cs | 496 ---------------- ByBit.Net/Clients/V5/BybitRestClientApi.cs | 3 +- .../Clients/V5/BybitSocketClientBaseApi.cs | 107 +--- .../Clients/V5/BybitSocketClientInverseApi.cs | 175 +----- .../Clients/V5/BybitSocketClientLinearApi.cs | 213 +------ .../Clients/V5/BybitSocketClientOptionApi.cs | 224 +------ .../Clients/V5/BybitSocketClientPrivateApi.cs | 314 ++-------- .../Clients/V5/BybitSocketClientSpotApi.cs | 283 +-------- ByBit.Net/Enums/CancelType.cs | 6 +- ByBit.Net/Enums/SubAccountStatus.cs | 3 - ByBit.Net/Enums/V5/PositionIdx.cs | 3 - .../CryptoClientExtensions.cs | 25 + .../ServiceCollectionExtensions.cs} | 21 +- .../IBybitSocketClientCopyTradingApi.cs | 53 -- .../IBybitRestClientContractApi.cs | 4 +- .../IBybitSocketClientContractApi.cs | 2 +- .../IBybitSocketClientDerivativesPublicApi.cs | 22 +- .../IBybitRestClientUnifiedMarginApi.cs | 4 +- .../IBybitSocketClientUnifiedMarginApi.cs | 2 +- .../Interfaces/Clients/IBybitSocketClient.cs | 23 - .../IBybitSocketClientInversePerpetualApi.cs | 258 --------- .../v1/IBybitRestClientSpotApiAccountV1.cs | 1 - .../SpotApi/v1/IBybitSocketClientSpotApiV1.cs | 89 --- .../SpotApi/v2/IBybitSocketClientSpotApiV2.cs | 86 --- .../v3/IBybitRestClientSpotApiAccountV3.cs | 1 - .../SpotApi/v3/IBybitSocketClientSpotApiV3.cs | 2 +- .../IBybitSocketClientUsdPerpetualApi.cs | 209 ------- .../Clients/V5/IBybitSocketClientBaseApi.cs | 12 +- .../V5/IBybitSocketClientInverseApi.cs | 2 +- .../Clients/V5/IBybitSocketClientLinearApi.cs | 2 +- .../Clients/V5/IBybitSocketClientOptionApi.cs | 2 +- .../V5/IBybitSocketClientPrivateApi.cs | 2 +- .../Clients/V5/IBybitSocketClientSpotApi.cs | 2 +- .../Objects/Internal/BybitBalanceWrapper.cs | 3 +- ByBit.Net/Objects/Internal/BybitSpotPing.cs | 10 - .../Internal/Socket/BybitRequestMessage.cs | 186 ------ .../Internal/Socket/BybitResponseMessage.cs | 14 - .../Internal/Socket/BybitV5RequestMessage.cs | 21 - .../UnifiedMargin/BybitUnifiedMarginOrder.cs | 4 +- .../BybitDerivativesTickerUpdate.cs | 77 --- .../Objects/Models/V5/BybitAccountTypeInfo.cs | 1 - .../Objects/Models/V5/BybitApiKeyInfo.cs | 3 +- ByBit.Net/Objects/Models/V5/BybitFeeRate.cs | 3 - .../Models/V5/BybitHistoricalVolatility.cs | 2 - ByBit.Net/Objects/Models/V5/BybitKline.cs | 1 - .../Objects/Models/V5/BybitLeverageToken.cs | 1 - .../Models/V5/BybitLinearInverseSymbol.cs | 3 +- .../Models/V5/BybitLinearInverseTicker.cs | 4 +- .../Objects/Models/V5/BybitOperationResult.cs | 3 +- .../Objects/Models/V5/BybitOptionSymbol.cs | 3 +- .../Models/V5/BybitOptionTickerUpdate.cs | 3 - ByBit.Net/Objects/Models/V5/BybitOrder.cs | 3 +- ByBit.Net/Objects/Models/V5/BybitOrderbook.cs | 1 - ByBit.Net/Objects/Models/V5/BybitResponse.cs | 1 - ByBit.Net/Objects/Models/V5/BybitRiskLimit.cs | 3 +- .../Models/V5/BybitSetMarginModeResult.cs | 1 - .../Objects/Models/V5/BybitSetRiskLimit.cs | 3 - .../V5/BybitSpotMarginLeverageStatus.cs | 3 +- .../Models/V5/BybitSpotMarginStatus.cs | 3 +- .../Objects/Models/V5/BybitSpotSymbol.cs | 3 +- .../Objects/Models/V5/BybitTransactionLog.cs | 2 - .../Objects/Models/V5/BybitUserAssetInfo.cs | 3 +- .../Objects/Options/BybitOrdeBookOptions.cs | 2 - .../Sockets/BybitOptionsQueryResponse.cs | 30 + ByBit.Net/Objects/Sockets/BybitPong.cs | 10 + .../Objects/Sockets/BybitQueryResponse.cs | 18 + .../Objects/Sockets/BybitRequestMessage.cs | 15 + .../Objects/Sockets/BybitSpotSocketEvent.cs | 19 + .../Sockets/Queries/BybitOptionsQuery.cs | 28 + .../Objects/Sockets/Queries/BybitPingQuery.cs | 16 + .../Objects/Sockets/Queries/BybitQuery.cs | 28 + .../Sockets/Queries/BybitUnifiedQuery.cs | 31 + .../Subscriptions/BybitOptionsSubscription.cs | 44 ++ .../Subscriptions/BybitSubscription.cs | 44 ++ .../Subscriptions/BybitUnifiedSubscription.cs | 44 ++ .../SymbolOrderBooks/BybitOrderBookFactory.cs | 2 - .../SymbolOrderBooks/BybitSymbolOrderBook.cs | 24 +- Bybit.UnitTests/InterfacesTests.cs | 2 +- README.md | 132 ++++- 99 files changed, 873 insertions(+), 5544 deletions(-) delete mode 100644 ByBit.Net/Clients/CopyTradingApi/BybitSocketClientCopyTradingApi.cs delete mode 100644 ByBit.Net/Clients/InversePerpetualApi/BybitSocketClientInversePerpetualApi.cs delete mode 100644 ByBit.Net/Clients/SpotApi/BybitSocketClientBaseSpotApi.cs delete mode 100644 ByBit.Net/Clients/SpotApi/v1/BybitSocketClientSpotApiV1.cs delete mode 100644 ByBit.Net/Clients/SpotApi/v2/BybitSocketClientSpotApiV2.cs delete mode 100644 ByBit.Net/Clients/UsdPerpetualApi/BybitSocketClientUsdPerpetualApi.cs create mode 100644 ByBit.Net/ExtensionMethods/CryptoClientExtensions.cs rename ByBit.Net/{BybitHelpers.cs => ExtensionMethods/ServiceCollectionExtensions.cs} (89%) delete mode 100644 ByBit.Net/Interfaces/Clients/CopyTradingApi/IBybitSocketClientCopyTradingApi.cs delete mode 100644 ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitSocketClientInversePerpetualApi.cs delete mode 100644 ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitSocketClientSpotApiV1.cs delete mode 100644 ByBit.Net/Interfaces/Clients/SpotApi/v2/IBybitSocketClientSpotApiV2.cs delete mode 100644 ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitSocketClientUsdPerpetualApi.cs delete mode 100644 ByBit.Net/Objects/Internal/BybitSpotPing.cs delete mode 100644 ByBit.Net/Objects/Internal/Socket/BybitRequestMessage.cs delete mode 100644 ByBit.Net/Objects/Internal/Socket/BybitResponseMessage.cs delete mode 100644 ByBit.Net/Objects/Internal/Socket/BybitV5RequestMessage.cs delete mode 100644 ByBit.Net/Objects/Models/Socket/Derivatives/BybitDerivativesTickerUpdate.cs create mode 100644 ByBit.Net/Objects/Sockets/BybitOptionsQueryResponse.cs create mode 100644 ByBit.Net/Objects/Sockets/BybitPong.cs create mode 100644 ByBit.Net/Objects/Sockets/BybitQueryResponse.cs create mode 100644 ByBit.Net/Objects/Sockets/BybitRequestMessage.cs create mode 100644 ByBit.Net/Objects/Sockets/BybitSpotSocketEvent.cs create mode 100644 ByBit.Net/Objects/Sockets/Queries/BybitOptionsQuery.cs create mode 100644 ByBit.Net/Objects/Sockets/Queries/BybitPingQuery.cs create mode 100644 ByBit.Net/Objects/Sockets/Queries/BybitQuery.cs create mode 100644 ByBit.Net/Objects/Sockets/Queries/BybitUnifiedQuery.cs create mode 100644 ByBit.Net/Objects/Sockets/Subscriptions/BybitOptionsSubscription.cs create mode 100644 ByBit.Net/Objects/Sockets/Subscriptions/BybitSubscription.cs create mode 100644 ByBit.Net/Objects/Sockets/Subscriptions/BybitUnifiedSubscription.cs diff --git a/ByBit.Net/Bybit.Net.csproj b/ByBit.Net/Bybit.Net.csproj index c934a63a..879e0bdb 100644 --- a/ByBit.Net/Bybit.Net.csproj +++ b/ByBit.Net/Bybit.Net.csproj @@ -1,15 +1,15 @@ - + netstandard2.0;netstandard2.1 enable - 9.0 + 10.0 Bybit.Net JKorf - 3.3.0 - 3.3.0 - 3.3.0 + 3.4.0-beta1 + 3.4.0 + 3.4.0 Bybit.Net is a .Net wrapper for the Bybit API. It includes all features the API provides, REST API and Websocket, using clear and readable objects including but not limited to Reading market info, Placing and managing orders and Reading balances and funds false Bybit Bybit.Net C# .Net CryptoCurrency Exchange API wrapper @@ -21,7 +21,7 @@ README.md en true - 3.3.0 - Added V5Api.Account.GetBrokerEarningsAsync endpoint, Added V5Api.Account.GetBrokerAccountInfoAsync endpoint, Added V5Api.Account.GetInternalDepositsAsync endpoint, Added V5Api.Account.SetMultipleCollateralAssetsAsync endpoint, Added PricePercentageFilter to V5Api.ExchangeData.GetSpotSymbolsAsync model, Updated various endpoint parameters and models + 3.4.0-beta1 - Updated CryptoExchange.Net and implemented reworked websocket message handling. For release notes for the CryptoExchange.Net base library see: https://github.com/JKorf/CryptoExchange.Net/tree/beta?tab=readme-ov-file#release-notes, Fixed issue in DI registration causing http client to not be correctly injected, Combined update and snapshot handlers for orderbook updates in favor of the UpdateType in the DataEvent wrapper, Removed excessive constructor overload for BybitRestClient, Removed deprecated socket APIs Bybit.Net.xml @@ -48,12 +48,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - \ No newline at end of file diff --git a/ByBit.Net/Clients/BybitRestClient.cs b/ByBit.Net/Clients/BybitRestClient.cs index 96c75c77..6ba6b447 100644 --- a/ByBit.Net/Clients/BybitRestClient.cs +++ b/ByBit.Net/Clients/BybitRestClient.cs @@ -51,14 +51,7 @@ public class BybitRestClient : BaseRestClient, IBybitRestClient /// Create a new instance of the BybitRestClient using provided options /// /// Option configuration delegate - public BybitRestClient(Action optionsDelegate) : this(null, null, optionsDelegate) - { - } - - /// - /// Create a new instance of the BybitRestClient using default options - /// - public BybitRestClient(ILoggerFactory? loggerFactory = null, HttpClient? httpClient = null) : this(httpClient, loggerFactory, null) + public BybitRestClient(Action? optionsDelegate = null) : this(null, null, optionsDelegate) { } diff --git a/ByBit.Net/Clients/BybitSocketClient.cs b/ByBit.Net/Clients/BybitSocketClient.cs index fd688169..c94bb105 100644 --- a/ByBit.Net/Clients/BybitSocketClient.cs +++ b/ByBit.Net/Clients/BybitSocketClient.cs @@ -1,48 +1,28 @@ -using Bybit.Net.Objects; -using CryptoExchange.Net; +using CryptoExchange.Net; using System; using Bybit.Net.Interfaces.Clients; using Bybit.Net.Interfaces.Clients.UsdPerpetualApi; -using Bybit.Net.Interfaces.Clients.InversePerpetualApi; -using Bybit.Net.Clients.InversePerpetualApi; -using Bybit.Net.Clients.UsdPerpetualApi; -using Bybit.Net.Clients.SpotApi.v1; -using Bybit.Net.Clients.SpotApi.v2; -using Bybit.Net.Clients.SpotApi.v3; -using Bybit.Net.Interfaces.Clients.SpotApi.v1; -using Bybit.Net.Interfaces.Clients.SpotApi.v2; using Bybit.Net.Interfaces.Clients.SpotApi.v3; using Bybit.Net.Interfaces.Clients.DerivativesApi.UnifiedMarginApi; using Bybit.Net.Interfaces.Clients.DerivativesApi.ContractApi; -using Bybit.Net.Clients.DerivativesApi.UnifiedMarginApi; -using Bybit.Net.Clients.DerivativesApi.ContractApi; -using Bybit.Net.Clients.DerivativesApi; using Bybit.Net.Interfaces.Clients.DerivativesApi; using CryptoExchange.Net.Authentication; using Bybit.Net.Clients.V5; using Bybit.Net.Interfaces.Clients.V5; using Microsoft.Extensions.Logging; using Bybit.Net.Objects.Options; +using Bybit.Net.Clients.DerivativesApi; +using Bybit.Net.Clients.DerivativesApi.ContractApi; +using Bybit.Net.Clients.DerivativesApi.UnifiedMarginApi; +using Bybit.Net.Clients.SpotApi.v3; namespace Bybit.Net.Clients { /// public class BybitSocketClient : BaseSocketClient, IBybitSocketClient { - /// - public IBybitSocketClientUsdPerpetualApi UsdPerpetualApi { get; } - /// - public IBybitSocketClientInversePerpetualApi InversePerpetualApi { get; } - /// - public IBybitSocketClientSpotApiV1 SpotV1Api { get; } - /// - public IBybitSocketClientSpotApiV2 SpotV2Api { get; } /// public IBybitSocketClientSpotApiV3 SpotV3Api { get; } - - /// - public IBybitSocketClientCopyTradingApi CopyTradingApi { get; } - /// public IBybitSocketClientDerivativesPublicApi DerivativesApi { get; } /// @@ -87,14 +67,8 @@ public BybitSocketClient(Action optionsDelegate, ILoggerFact optionsDelegate(options); Initialize(options); - UsdPerpetualApi = AddApiClient(new BybitSocketClientUsdPerpetualApi(_logger, options)); - InversePerpetualApi = AddApiClient(new BybitSocketClientInversePerpetualApi(_logger, options)); - SpotV1Api = AddApiClient(new BybitSocketClientSpotApiV1(_logger, options)); - SpotV2Api = AddApiClient(new BybitSocketClientSpotApiV2(_logger, options)); SpotV3Api = AddApiClient(new BybitSocketClientSpotApiV3(_logger, options)); - CopyTradingApi = AddApiClient(new BybitSocketClientCopyTradingApi(_logger, options)); - DerivativesApi = AddApiClient(new BybitSocketClientDerivativesPublicApi(_logger, options)); UnifiedMarginApi = AddApiClient(new BybitSocketClientUnifiedMarginApi(_logger, options)); ContractApi = AddApiClient(new BybitSocketClientContractApi(_logger, options)); @@ -120,12 +94,7 @@ public static void SetDefaultOptions(Action optionsDelegate) /// public void SetApiCredentials(ApiCredentials credentials) { - UsdPerpetualApi.SetApiCredentials(credentials); - InversePerpetualApi.SetApiCredentials(credentials); - SpotV1Api.SetApiCredentials(credentials); - SpotV2Api.SetApiCredentials(credentials); SpotV3Api.SetApiCredentials(credentials); - CopyTradingApi.SetApiCredentials(credentials); DerivativesApi.SetApiCredentials(credentials); UnifiedMarginApi.SetApiCredentials(credentials); ContractApi.SetApiCredentials(credentials); diff --git a/ByBit.Net/Clients/CopyTradingApi/BybitSocketClientCopyTradingApi.cs b/ByBit.Net/Clients/CopyTradingApi/BybitSocketClientCopyTradingApi.cs deleted file mode 100644 index 67826321..00000000 --- a/ByBit.Net/Clients/CopyTradingApi/BybitSocketClientCopyTradingApi.cs +++ /dev/null @@ -1,298 +0,0 @@ -using Bybit.Net.Objects.Internal.Socket; -using Bybit.Net.Objects; -using CryptoExchange.Net; -using CryptoExchange.Net.Authentication; -using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Bybit.Net.Interfaces.Clients.UsdPerpetualApi; -using Bybit.Net.Objects.Models.CopyTrading; -using CryptoExchange.Net.Converters; -using Bybit.Net.Objects.Options; - -namespace Bybit.Net.Clients.InversePerpetualApi -{ - /// - public class BybitSocketClientCopyTradingApi : SocketApiClient, IBybitSocketClientCopyTradingApi - { - internal BybitSocketClientCopyTradingApi(ILogger log, BybitSocketOptions options) - : base(log, options.Environment.SocketBaseAddress, options, options.CopyTradingOptions) - { - ContinueOnQueryResponse = true; - UnhandledMessageExpected = true; - KeepAliveInterval = TimeSpan.Zero; - - SendPeriodic("Ping", options.CopyTradingOptions.PingInterval, (connection) => - { - return new BybitRequestMessage() { Operation = "ping" }; - }); - AddGenericHandler("Heartbeat", (evnt) => { }); - } - - /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) - => new BybitAuthenticationProvider(credentials); - - /// - public async Task> SubscribeToPositionUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitCopyTradingPositionUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - return await SubscribeAsync(BaseAddress.AppendPath("realtime_private"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = new[] { "copyTradePosition" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToUserTradeUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitCopyTradingUserTradeUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - return await SubscribeAsync(BaseAddress.AppendPath("realtime_private"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = new[] { "copyTradeExecution" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToOrderUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitCopyTradingOrderUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - return await SubscribeAsync(BaseAddress.AppendPath("realtime_private"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = new[] { "copyTradeOrder" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToBalanceUpdatesAsync(Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitCopyTradingBalanceUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - return await SubscribeAsync(BaseAddress.AppendPath("realtime_private"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = new[] { "copyTradeWallet" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - - /// - protected override async Task> AuthenticateSocketAsync(SocketConnection socketConnection) - { - if (socketConnection.ApiClient.AuthenticationProvider == null) - return new CallResult(new NoApiCredentialsError()); - - var expireTime = DateTimeConverter.ConvertToMilliseconds(DateTime.UtcNow.AddSeconds(30))!; - var bybitAuthProvider = (BybitAuthenticationProvider)socketConnection.ApiClient.AuthenticationProvider; - var key = bybitAuthProvider.GetApiKey(); - var sign = bybitAuthProvider.Sign($"GET/realtime{expireTime}"); - - var authRequest = new BybitRequestMessage() - { - Operation = "auth", - Parameters = new object[] - { - key, - expireTime, - sign - } - }; - - var result = false; - var error = "unspecified error"; - await socketConnection.SendAndWaitAsync(authRequest, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["request"]?["op"]?.ToString(); - var args = data["request"]?["args"].Select(p => p.ToString()).ToList(); - if (operation != "auth") - return false; - - result = data["success"]?.Value() == true; - error = data["ret_msg"]?.ToString(); - return true; - - }).ConfigureAwait(false); - return result ? new CallResult(result) : new CallResult(new ServerError(error)); - } - - /// - protected override bool HandleQueryResponse(SocketConnection socketConnection, object request, JToken data, out CallResult callResult) - { - throw new NotImplementedException(); - } - - /// - protected override bool HandleSubscriptionResponse(SocketConnection socketConnection, SocketSubscription subscription, object request, JToken data, out CallResult? callResult) - { - callResult = null; - if (data.Type != JTokenType.Object) - return false; - - var requestParams = ((BybitRequestMessage)request).Parameters; - var operation = data["request"]?["op"]?.ToString(); - var args = data["request"]?["args"].Select(p => p.ToString()).ToList(); - if (operation != "subscribe") - return false; - - if (requestParams.Any(p => !args.Contains(p))) - return false; - - var success = data["success"]?.Value() == true; - if (success) - callResult = new CallResult(true); - else - callResult = new CallResult(new ServerError(data["ret_msg"]!.ToString())); - return true; - } - - /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, object request) - { - if (message.Type != JTokenType.Object) - return false; - - var topic = message["topic"]?.ToString(); - if (topic == null) - return false; - - var requestParams = ((BybitRequestMessage)request).Parameters; - if (requestParams.Any(p => topic == p.ToString())) - return true; - - if (topic.Contains('.')) - { - // Some subscriptions have topics like orderbook.ETHUSDT - // Split on `.` to get the topic and symbol - var split = topic.Split('.'); - var symbol = split.Last(); - if (symbol.Length == 0) - return false; - - var mainTopic = topic.Substring(0, topic.Length - symbol.Length - 1); - if (requestParams.Any(p => (string)p == (mainTopic + ".*"))) - return true; - } - - return false; - } - - /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, string identifier) - { - if (identifier == "Heartbeat") - { - if (message.Type != JTokenType.Object) - return false; - - var ret = message["ret_msg"]; - if (ret == null) - return false; - - var isPing = ret.ToString() == "pong"; - if (!isPing) - return false; - - return true; - } - - if (identifier == "AccountInfo") - { - if (message.Type != JTokenType.Array) - return false; - - var updateType = ((JArray)message)[0]["e"]?.ToString(); - if (updateType == null) - return false; - - return updateType == "outboundAccountInfo" || updateType == "stop_executionReport" || updateType == "executionReport" || updateType == "order" || updateType == "ticketInfo"; - } - - return false; - } - - /// - protected override async Task UnsubscribeAsync(SocketConnection connection, SocketSubscription subscriptionToUnsub) - { - var requestParams = ((BybitRequestMessage)subscriptionToUnsub.Request!).Parameters; - var message = new BybitRequestMessage { Operation = "unsubscribe", Parameters = requestParams }; - - var result = false; - await connection.SendAndWaitAsync(message, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["request"]?["op"]?.ToString(); - var args = data["request"]?["args"].Select(p => p.ToString()).ToList(); - if (operation != "unsubscribe") - return false; - - if (requestParams.Any(p => !args.Contains(p))) - return false; - - result = data["success"]?.Value() == true; - return true; - }).ConfigureAwait(false); - return result; - } - } -} diff --git a/ByBit.Net/Clients/DerivativesApi/BybitRestClientDerivativesApi.cs b/ByBit.Net/Clients/DerivativesApi/BybitRestClientDerivativesApi.cs index ae26026e..cffdac5f 100644 --- a/ByBit.Net/Clients/DerivativesApi/BybitRestClientDerivativesApi.cs +++ b/ByBit.Net/Clients/DerivativesApi/BybitRestClientDerivativesApi.cs @@ -3,7 +3,6 @@ using Bybit.Net.Interfaces.Clients.DerivativesApi; using Bybit.Net.Interfaces.Clients.DerivativesApi.ContractApi; using Bybit.Net.Interfaces.Clients.DerivativesApi.UnifiedMarginApi; -using Bybit.Net.Objects; using Bybit.Net.Objects.Internal; using Bybit.Net.Objects.Options; using CryptoExchange.Net; diff --git a/ByBit.Net/Clients/DerivativesApi/BybitSocketClientDerivativesPublicApi.cs b/ByBit.Net/Clients/DerivativesApi/BybitSocketClientDerivativesPublicApi.cs index e4c534e4..a6809b4c 100644 --- a/ByBit.Net/Clients/DerivativesApi/BybitSocketClientDerivativesPublicApi.cs +++ b/ByBit.Net/Clients/DerivativesApi/BybitSocketClientDerivativesPublicApi.cs @@ -1,22 +1,26 @@ using Bybit.Net.Converters; using Bybit.Net.Enums; using Bybit.Net.Interfaces.Clients.DerivativesApi; -using Bybit.Net.Objects.Internal.Socket; -using Bybit.Net.Objects.Models; using Bybit.Net.Objects.Models.Derivatives; using Bybit.Net.Objects.Models.Socket.Derivatives; using Bybit.Net.Objects.Options; +using Bybit.Net.Objects.Sockets.Queries; +using Bybit.Net.Objects.Sockets.Subscriptions; using CryptoExchange.Net; using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Converters; using CryptoExchange.Net.Objects; +using CryptoExchange.Net.Objects.Sockets; using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Sockets.MessageParsing; +using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -25,58 +29,40 @@ namespace Bybit.Net.Clients.DerivativesApi /// public class BybitSocketClientDerivativesPublicApi : SocketApiClient, IBybitSocketClientDerivativesPublicApi { + private static readonly MessagePath _reqIdPath = MessagePath.Get().Property("req_id"); + private static readonly MessagePath _topicPath = MessagePath.Get().Property("topic"); + internal BybitSocketClientDerivativesPublicApi(ILogger log, BybitSocketOptions options) : base(log, options.Environment.SocketBaseAddress, options, options.DerivativesPublicOptions) { - ContinueOnQueryResponse = true; UnhandledMessageExpected = true; KeepAliveInterval = TimeSpan.Zero; + HandleMessageBeforeConfirmation = true; - SendPeriodic("Ping", options.DerivativesPublicOptions.PingInterval, (connection) => - { - return new BybitRequestMessage() { Operation = "ping" }; - }); - AddGenericHandler("Heartbeat", (evnt) => { }); + RegisterPeriodicQuery("Heartbeat", TimeSpan.FromSeconds(20), x => new BybitQuery("ping", null), x => { }); } /// - public Task> SubscribeToOrderBookUpdatesAsync(StreamDerivativesCategory category, string symbol, int limit, Action> snapshotHandler, Action> deltaHandler, CancellationToken ct = default) - => SubscribeToOrderBooksUpdatesAsync(category, new string[] { symbol }, limit, snapshotHandler, deltaHandler, ct); - - /// - public async Task> SubscribeToOrderBooksUpdatesAsync(StreamDerivativesCategory category, IEnumerable symbols, int limit, Action> snapshotHandler, Action> deltaHandler, CancellationToken ct = default) + public override string? GetListenerIdentifier(IMessageAccessor message) { - limit.ValidateIntValues(nameof(limit), 1, 25, 50, 100, 200); + var reqId = message.GetValue(_reqIdPath); + if (reqId != null) + return reqId; - var internalHandler = new Action>(data => - { - var type = data.Data["type"]?.ToString(); - var internalData = data.Data["data"]; - if (internalData == null || type == null || string.IsNullOrWhiteSpace(type)) - return; + return message.GetValue(_topicPath); + } - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitOrderBookEntry)} object: " + desResult.Error); - return; - } + /// + public Task> SubscribeToOrderBookUpdatesAsync(StreamDerivativesCategory category, string symbol, int limit, Action> handler, CancellationToken ct = default) + => SubscribeToOrderBooksUpdatesAsync(category, new string[] { symbol }, limit, handler, ct); - if (type.Equals("snapshot", StringComparison.Ordinal)) - { - snapshotHandler(data.As(desResult.Data, desResult.Data.Symbol)); - } - else - { - deltaHandler(data.As(desResult.Data, desResult.Data.Symbol)); - } - }); + /// + public async Task> SubscribeToOrderBooksUpdatesAsync(StreamDerivativesCategory category, IEnumerable symbols, int limit, Action> handler, CancellationToken ct = default) + { + limit.ValidateIntValues(nameof(limit), 1, 25, 50, 100, 200); - var topic = $"orderbook.{limit}."; - return await SubscribeAsync( - BaseAddress.AppendPath($"/{EnumConverter.GetString(category)}/public/v3"), - new BybitDerivativesRequestMessage() { Operation = "subscribe", CustomisedId = Guid.NewGuid().ToString(), Parameters = symbols.Select(s => topic + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription(_logger, symbols.Select(x => $"orderbook.{limit}." + x).ToArray(), handler); + return await SubscribeAsync(BaseAddress + $"/{EnumConverter.GetString(category)}/public/v3", subscription, ct).ConfigureAwait(false); } /// @@ -86,69 +72,19 @@ public Task> SubscribeToTradeUpdatesAsync(StreamD /// public async Task> SubscribeToTradesUpdatesAsync(StreamDerivativesCategory category, IEnumerable symbols, Action>> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitDerivativesTradeUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, desResult.Data.First().Symbol)); - }); - - return await SubscribeAsync( - BaseAddress.AppendPath($"/{EnumConverter.GetString(category)}/public/v3"), - new BybitDerivativesRequestMessage() { Operation = "subscribe", CustomisedId = Guid.NewGuid().ToString(), Parameters = symbols.Select(s => "publicTrade." + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription>(_logger, symbols.Select(x => $"publicTrade." + x).ToArray(), handler); + return await SubscribeAsync(BaseAddress + $"/{EnumConverter.GetString(category)}/public/v3", subscription, ct).ConfigureAwait(false); } /// - public Task> SubscribeToTickerUpdatesAsync(StreamDerivativesCategory category, string symbol, Action> snapshotHandler, Action> updateHandler, CancellationToken ct = default) - => SubscribeToTickersUpdatesAsync(category, new string[] { symbol }, snapshotHandler, updateHandler, ct); + public Task> SubscribeToTickerUpdatesAsync(StreamDerivativesCategory category, string symbol, Action> handler, CancellationToken ct = default) + => SubscribeToTickersUpdatesAsync(category, new string[] { symbol }, handler, ct); /// - public async Task> SubscribeToTickersUpdatesAsync(StreamDerivativesCategory category, IEnumerable symbols, Action> snapshotHandler, Action> updateHandler, CancellationToken ct = default) + public async Task> SubscribeToTickersUpdatesAsync(StreamDerivativesCategory category, IEnumerable symbols, Action> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - if (data.Data["type"]?.ToString() == "delta") - { - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitDerivativesTickerUpdate)} object: " + desResult.Error); - return; - } - - updateHandler(data.As(desResult.Data, desResult.Data.Symbol)); - } - else - { - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitDerivativesTicker)} object: " + desResult.Error); - return; - } - - snapshotHandler(data.As(desResult.Data, desResult.Data.Symbol)); - } - }); - - return await SubscribeAsync( - BaseAddress.AppendPath($"/{EnumConverter.GetString(category)}/public/v3"), - new BybitDerivativesRequestMessage() { Operation = "subscribe", CustomisedId = Guid.NewGuid().ToString(), Parameters = symbols.Select(s => "tickers." + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription(_logger, symbols.Select(x => $"tickers." + x).ToArray(), handler); + return await SubscribeAsync(BaseAddress + $"/{EnumConverter.GetString(category)}/public/v3", subscription, ct).ConfigureAwait(false); } /// @@ -158,181 +94,12 @@ public Task> SubscribeToKlineUpdatesAsync(StreamD /// public async Task> SubscribeToKlinesUpdatesAsync(StreamDerivativesCategory category, IEnumerable symbols, KlineInterval interval, Action>> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitDerivativesKlineUpdate)} object: " + desResult.Error); - return; - } - - var topic = data.Data["topic"]!.ToString(); - handler(data.As(desResult.Data, topic.Split('.').Last())); - }); - - return await SubscribeAsync( - BaseAddress.AppendPath($"/{EnumConverter.GetString(category)}/public/v3"), - new BybitDerivativesRequestMessage() { Operation = "subscribe", CustomisedId = Guid.NewGuid().ToString(), Parameters = symbols.Select(s => "kline." + JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) + "." + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription>(_logger, symbols.Select(x => "kline." + JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) + "." + x).ToArray(), handler); + return await SubscribeAsync(BaseAddress + $"/{EnumConverter.GetString(category)}/public/v3", subscription, ct).ConfigureAwait(false); } /// protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => new BybitAuthenticationProvider(credentials); - - /// - protected override async Task> AuthenticateSocketAsync(SocketConnection socketConnection) - { - if (socketConnection.ApiClient.AuthenticationProvider == null) - return new CallResult(new NoApiCredentialsError()); - - var expireTime = DateTimeConverter.ConvertToMilliseconds(DateTime.UtcNow.AddSeconds(30))!; - var bybitAuthProvider = (BybitAuthenticationProvider)socketConnection.ApiClient.AuthenticationProvider; - var key = bybitAuthProvider.GetApiKey(); - var sign = bybitAuthProvider.Sign($"GET/realtime{expireTime}"); - - var authRequest = new BybitRequestMessage() - { - Operation = "auth", - Parameters = new object[] - { - key, - expireTime, - sign - } - }; - - var result = false; - var error = "unspecified error"; - await socketConnection.SendAndWaitAsync(authRequest, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["request"]?["op"]?.ToString(); - var args = data["request"]?["args"].Select(p => p.ToString()).ToList(); - if (operation != "auth") - return false; - - result = data["success"]?.Value() == true; - error = data["ret_msg"]?.ToString(); - return true; - - }).ConfigureAwait(false); - return result ? new CallResult(result) : new CallResult(new ServerError(error)); - } - - /// - protected override bool HandleQueryResponse(SocketConnection socketConnection, object request, JToken data, out CallResult callResult) - { - throw new NotImplementedException(); - } - - /// - protected override bool HandleSubscriptionResponse(SocketConnection socketConnection, SocketSubscription subscription, object request, JToken data, out CallResult? callResult) - { - callResult = null; - if (data.Type != JTokenType.Object) - return false; - - var operation = data["op"]?.ToString(); - if (operation != "subscribe") - return false; - - var id = ((BybitDerivativesRequestMessage)request).CustomisedId; - if (!id.Equals(data["req_id"]?.ToString())) - return false; - - var success = data["success"]?.Value() == true; - if (success) - callResult = new CallResult(true); - else - callResult = new CallResult(new ServerError(data["ret_msg"]!.ToString())); - return true; - } - - /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, object request) - { - if (message.Type != JTokenType.Object) - return false; - - var topic = message["topic"]?.ToString(); - if (topic == null) - return false; - - var requestParams = ((BybitRequestMessage)request).Parameters; - if (requestParams.Any(p => topic == p.ToString())) - return true; - - if (topic.Contains('.')) - { - // Some subscriptions have topics like orderbook.ETHUSDT - // Split on `.` to get the topic and symbol - var split = topic.Split('.'); - var symbol = split.Last(); - if (symbol.Length == 0) - return false; - - var mainTopic = topic.Substring(0, topic.Length - symbol.Length - 1); - if (requestParams.Any(p => (string)p == mainTopic + ".*")) - return true; - } - - return false; - } - - /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, string identifier) - { - if (identifier == "Heartbeat") - { - if (message.Type != JTokenType.Object) - return false; - - var ret = message["ret_msg"]; - if (ret == null) - return false; - - var isPing = ret.ToString() == "pong"; - if (!isPing) - return false; - - return true; - } - - return false; - } - - /// - protected override async Task UnsubscribeAsync(SocketConnection connection, SocketSubscription subscriptionToUnsub) - { - var requestParams = ((BybitRequestMessage)subscriptionToUnsub.Request!).Parameters; - var message = new BybitRequestMessage { Operation = "unsubscribe", Parameters = requestParams }; - - var result = false; - await connection.SendAndWaitAsync(message, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["request"]?["op"]?.ToString(); - var args = data["request"]?["args"].Select(p => p.ToString()).ToList(); - if (operation != "unsubscribe") - return false; - - if (requestParams.Any(p => !args.Contains(p))) - return false; - - result = data["success"]?.Value() == true; - return true; - }).ConfigureAwait(false); - return result; - } } } diff --git a/ByBit.Net/Clients/DerivativesApi/ContractApi/BybitSocketClientContractApi.cs b/ByBit.Net/Clients/DerivativesApi/ContractApi/BybitSocketClientContractApi.cs index 590ceaea..71dfeb6b 100644 --- a/ByBit.Net/Clients/DerivativesApi/ContractApi/BybitSocketClientContractApi.cs +++ b/ByBit.Net/Clients/DerivativesApi/ContractApi/BybitSocketClientContractApi.cs @@ -1,13 +1,17 @@ using Bybit.Net.Interfaces.Clients.DerivativesApi.ContractApi; using Bybit.Net.Objects; -using Bybit.Net.Objects.Internal.Socket; using Bybit.Net.Objects.Models.Socket.Derivatives.Contract; using Bybit.Net.Objects.Options; +using Bybit.Net.Objects.Sockets.Queries; +using Bybit.Net.Objects.Sockets.Subscriptions; using CryptoExchange.Net; using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Converters; using CryptoExchange.Net.Objects; +using CryptoExchange.Net.Objects.Sockets; using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Sockets.MessageParsing; +using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; using Microsoft.Extensions.Logging; using Newtonsoft.Json.Linq; using System; @@ -21,18 +25,16 @@ namespace Bybit.Net.Clients.DerivativesApi.ContractApi /// public class BybitSocketClientContractApi : SocketApiClient, IBybitSocketClientContractApi { + private static readonly MessagePath _reqIdPath = MessagePath.Get().Property("req_id"); + private static readonly MessagePath _topicPath = MessagePath.Get().Property("topic"); + internal BybitSocketClientContractApi(ILogger log, BybitSocketOptions options) - : base(log, options.Environment.SocketBaseAddress, options, options.ContractOptions) + : base(log, options.Environment.SocketBaseAddress.AppendPath("contract/private/v3"), options, options.ContractOptions) { - ContinueOnQueryResponse = true; UnhandledMessageExpected = true; KeepAliveInterval = TimeSpan.Zero; - SendPeriodic("Ping", options.ContractOptions.PingInterval, (connection) => - { - return new BybitRequestMessage() { Operation = "ping" }; - }); - AddGenericHandler("Heartbeat", (evnt) => { }); + RegisterPeriodicQuery("Heartbeat", TimeSpan.FromSeconds(20), x => new BybitQuery("ping", null), x => { }); } /// @@ -40,257 +42,57 @@ protected override AuthenticationProvider CreateAuthenticationProvider(ApiCreden => new BybitAuthenticationProvider(credentials); /// - public async Task> SubscribeToPositionUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitContractPositionUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - - return await SubscribeAsync(BaseAddress.AppendPath("/contract/private/v3"), - new BybitDerivativesRequestMessage() { Operation = "subscribe", CustomisedId = Guid.NewGuid().ToString(), Parameters = new[] { "user.position.contractAccount" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToUserTradeUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitContractUserTradeUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - - return await SubscribeAsync(BaseAddress.AppendPath("/contract/private/v3"), new BybitDerivativesRequestMessage() { Operation = "subscribe", CustomisedId = Guid.NewGuid().ToString(), Parameters = new[] { "user.execution.contractAccount" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToOrderUpdatesAsync(Action>> handler, CancellationToken ct = default) + public override string? GetListenerIdentifier(IMessageAccessor message) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitContractOrderUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - - return await SubscribeAsync(BaseAddress.AppendPath("/contract/private/v3"), new BybitDerivativesRequestMessage() { Operation = "subscribe", CustomisedId = Guid.NewGuid().ToString(), Parameters = new[] { "user.order.contractAccount" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToBalanceUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitContractBalanceUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); + var reqId = message.GetValue(_reqIdPath); + if (reqId != null) + return reqId; - return await SubscribeAsync(BaseAddress.AppendPath("/contract/private/v3"), new BybitDerivativesRequestMessage() { Operation = "subscribe", CustomisedId = Guid.NewGuid().ToString(), Parameters = new[] { "user.wallet.contractAccount" } }, - null, true, internalHandler, ct).ConfigureAwait(false); + return message.GetValue(_topicPath); } /// - protected override async Task> AuthenticateSocketAsync(SocketConnection socketConnection) + protected override Query? GetAuthenticationRequest() { - if (socketConnection.ApiClient.AuthenticationProvider == null) - return new CallResult(new NoApiCredentialsError()); - var expireTime = DateTimeConverter.ConvertToMilliseconds(DateTime.UtcNow.AddSeconds(30))!; - var bybitAuthProvider = (BybitAuthenticationProvider)socketConnection.ApiClient.AuthenticationProvider; - var key = bybitAuthProvider.GetApiKey(); - var sign = bybitAuthProvider.Sign($"GET/realtime{expireTime}"); - - var authRequest = new BybitRequestMessage() - { - Operation = "auth", - Parameters = new object[] - { - key, - expireTime, - sign - } - }; + var authProvider = (BybitAuthenticationProvider)AuthenticationProvider!; + var key = authProvider.GetApiKey(); + var sign = authProvider.Sign($"GET/realtime{expireTime}"); - var result = false; - var error = "unspecified error"; - await socketConnection.SendAndWaitAsync(authRequest, ClientOptions.RequestTimeout, null, 1, data => + return new BybitQuery("auth", new object[] { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["op"]?.ToString(); - if (operation != "auth") - return false; - - result = data["success"]?.Value() == true; - error = data["ret_msg"]?.ToString(); - return true; - - }).ConfigureAwait(false); - return result ? new CallResult(result) : new CallResult(new ServerError(error)); - } - - /// - protected override bool HandleQueryResponse(SocketConnection socketConnection, object request, JToken data, out CallResult callResult) - { - throw new NotImplementedException(); + key, + expireTime, + sign + }); } /// - protected override bool HandleSubscriptionResponse(SocketConnection socketConnection, SocketSubscription subscription, object request, JToken data, out CallResult? callResult) + public async Task> SubscribeToPositionUpdatesAsync(Action>> handler, CancellationToken ct = default) { - callResult = null; - if (data.Type != JTokenType.Object) - return false; - - var operation = data["op"]?.ToString(); - if (operation != "subscribe") - return false; - - var id = ((BybitDerivativesRequestMessage)request).CustomisedId; - if (!id.Equals(data["req_id"]?.ToString())) - return false; - - var success = data["success"]?.Value() == true; - if (success) - callResult = new CallResult(true); - else - callResult = new CallResult(new ServerError(data["ret_msg"]!.ToString())); - return true; + var subscription = new BybitSubscription>(_logger, new[] { "user.position.contractAccount" }, handler, true); + return await SubscribeAsync(subscription, ct).ConfigureAwait(false); } /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, object request) + public async Task> SubscribeToUserTradeUpdatesAsync(Action>> handler, CancellationToken ct = default) { - if (message.Type != JTokenType.Object) - return false; - - var topic = message["topic"]?.ToString(); - if (topic == null) - return false; - - var requestParams = ((BybitRequestMessage)request).Parameters; - if (requestParams.Any(p => topic == p.ToString())) - return true; - - if (topic.Contains('.')) - { - // Some subscriptions have topics like orderbook.ETHUSDT - // Split on `.` to get the topic and symbol - var split = topic.Split('.'); - var symbol = split.Last(); - if (symbol.Length == 0) - return false; - - var mainTopic = topic.Substring(0, topic.Length - symbol.Length - 1); - if (requestParams.Any(p => (string)p == mainTopic + ".*")) - return true; - } - - return false; + var subscription = new BybitSubscription>(_logger, new[] { "user.execution.contractAccount" }, handler, true); + return await SubscribeAsync(subscription, ct).ConfigureAwait(false); } /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, string identifier) + public async Task> SubscribeToOrderUpdatesAsync(Action>> handler, CancellationToken ct = default) { - if (identifier == "Heartbeat") - { - if (message.Type != JTokenType.Object) - return false; - - var ret = message["ret_msg"]; - if (ret == null) - return false; - - var isPing = ret.ToString() == "pong"; - if (!isPing) - return false; - - return true; - } - - if (identifier == "AccountInfo") - { - if (message.Type != JTokenType.Array) - return false; - - var updateType = ((JArray)message)[0]["e"]?.ToString(); - if (updateType == null) - return false; - - return updateType == "outboundAccountInfo" || updateType == "stop_executionReport" || updateType == "executionReport" || updateType == "order" || updateType == "ticketInfo"; - } - - return false; + var subscription = new BybitSubscription>(_logger, new[] { "user.order.contractAccount" }, handler, true); + return await SubscribeAsync(subscription, ct).ConfigureAwait(false); } /// - protected override async Task UnsubscribeAsync(SocketConnection connection, SocketSubscription subscriptionToUnsub) + public async Task> SubscribeToBalanceUpdatesAsync(Action>> handler, CancellationToken ct = default) { - var requestParams = ((BybitRequestMessage)subscriptionToUnsub.Request!).Parameters; - var message = new BybitRequestMessage { Operation = "unsubscribe", Parameters = requestParams }; - - var result = false; - await connection.SendAndWaitAsync(message, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["request"]?["op"]?.ToString(); - var args = data["request"]?["args"].Select(p => p.ToString()).ToList(); - if (operation != "unsubscribe") - return false; - - if (requestParams.Any(p => !args.Contains(p))) - return false; - - result = data["success"]?.Value() == true; - return true; - }).ConfigureAwait(false); - return result; + var subscription = new BybitSubscription>(_logger, new[] { "user.wallet.contractAccount" }, handler, true); + return await SubscribeAsync(subscription, ct).ConfigureAwait(false); } } } diff --git a/ByBit.Net/Clients/DerivativesApi/UnifiedMarginApi/BybitSocketClientUnifiedMarginApi.cs b/ByBit.Net/Clients/DerivativesApi/UnifiedMarginApi/BybitSocketClientUnifiedMarginApi.cs index 696985f8..56415030 100644 --- a/ByBit.Net/Clients/DerivativesApi/UnifiedMarginApi/BybitSocketClientUnifiedMarginApi.cs +++ b/ByBit.Net/Clients/DerivativesApi/UnifiedMarginApi/BybitSocketClientUnifiedMarginApi.cs @@ -1,16 +1,20 @@ using Bybit.Net.Interfaces.Clients.DerivativesApi.UnifiedMarginApi; using Bybit.Net.Objects; -using Bybit.Net.Objects.Internal.Socket; using Bybit.Net.Objects.Models.Derivatives.UnifiedMargin; using Bybit.Net.Objects.Models.Socket; using Bybit.Net.Objects.Models.Socket.Derivatives; using Bybit.Net.Objects.Models.Socket.Derivatives.UnifiedMargin; using Bybit.Net.Objects.Options; +using Bybit.Net.Objects.Sockets.Queries; +using Bybit.Net.Objects.Sockets.Subscriptions; using CryptoExchange.Net; using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Converters; using CryptoExchange.Net.Objects; +using CryptoExchange.Net.Objects.Sockets; using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Sockets.MessageParsing; +using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; using Microsoft.Extensions.Logging; using Newtonsoft.Json.Linq; using System; @@ -24,18 +28,15 @@ namespace Bybit.Net.Clients.DerivativesApi.UnifiedMarginApi /// public class BybitSocketClientUnifiedMarginApi : SocketApiClient, IBybitSocketClientUnifiedMarginApi { + private static readonly MessagePath _typePath = MessagePath.Get().Property("type"); + private static readonly MessagePath _opPath = MessagePath.Get().Property("op"); + internal BybitSocketClientUnifiedMarginApi(ILogger log, BybitSocketOptions options) - : base(log, options.Environment.SocketBaseAddress, options, options.UnifiedMarginOptions) + : base(log, options.Environment.SocketBaseAddress.AppendPath("/unified/private/v3"), options, options.UnifiedMarginOptions) { - ContinueOnQueryResponse = true; - UnhandledMessageExpected = true; KeepAliveInterval = TimeSpan.Zero; - SendPeriodic("Ping", options.UnifiedMarginOptions.PingInterval, (connection) => - { - return new BybitRequestMessage() { Operation = "ping" }; - }); - AddGenericHandler("Heartbeat", (evnt) => { }); + RegisterPeriodicQuery("Heartbeat", TimeSpan.FromSeconds(20), x => new BybitPingQuery(), x => { }); } /// @@ -43,289 +44,64 @@ protected override AuthenticationProvider CreateAuthenticationProvider(ApiCreden => new BybitAuthenticationProvider(credentials); /// - public async Task> SubscribeToPositionUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitUnifiedMarginPositionUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - - return await SubscribeAsync( - BaseAddress.AppendPath("/unified/private/v3"), - new BybitDerivativesRequestMessage() { Operation = "subscribe", CustomisedId = Guid.NewGuid().ToString(), Parameters = new[] { "user.position.unifiedAccount" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToUserTradeUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitDerivativesUserTradeUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - - return await SubscribeAsync( - BaseAddress.AppendPath("/unified/private/v3"), - new BybitDerivativesRequestMessage() { Operation = "subscribe", CustomisedId = Guid.NewGuid().ToString(), Parameters = new[] { "user.execution.unifiedAccount" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToOrderUpdatesAsync(Action>> handler, CancellationToken ct = default) + public override string? GetListenerIdentifier(IMessageAccessor message) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitUnifiedMarginOrderUpdate)} object: " + desResult.Error); - return; - } + var type = message.GetValue(_typePath); + if (type == "COMMAND_RESP" || type == "AUTH_RESP") + return type; - handler(data.As(desResult.Data)); - }); - - return await SubscribeAsync( - BaseAddress.AppendPath("/unified/private/v3"), - new BybitDerivativesRequestMessage() { Operation = "subscribe", CustomisedId = Guid.NewGuid().ToString(), Parameters = new[] { "user.order.unifiedAccount" } }, - null, true, internalHandler, ct).ConfigureAwait(false); + return message.GetValue(_opPath); } /// - public async Task> SubscribeToBalanceUpdatesAsync(Action> handler, CancellationToken ct = default) + protected override Query? GetAuthenticationRequest() { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitUnifiedMarginBalance)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - - return await SubscribeAsync( - BaseAddress.AppendPath("/unified/private/v3"), - new BybitDerivativesRequestMessage() { Operation = "subscribe", CustomisedId = Guid.NewGuid().ToString(), Parameters = new[] { "user.wallet.unifiedAccount" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToGreeksUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitGreeksUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - - return await SubscribeAsync( - BaseAddress.AppendPath("/unified/private/v3"), - new BybitDerivativesRequestMessage() { Operation = "subscribe", CustomisedId = Guid.NewGuid().ToString(), Parameters = new[] { "user.greeks.unifiedAccount" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - protected override async Task> AuthenticateSocketAsync(SocketConnection socketConnection) - { - if (socketConnection.ApiClient.AuthenticationProvider == null) - return new CallResult(new NoApiCredentialsError()); - var expireTime = DateTimeConverter.ConvertToMilliseconds(DateTime.UtcNow.AddSeconds(30))!; - var bybitAuthProvider = (BybitAuthenticationProvider)socketConnection.ApiClient.AuthenticationProvider; - var key = bybitAuthProvider.GetApiKey(); - var sign = bybitAuthProvider.Sign($"GET/realtime{expireTime}"); - - var authRequest = new BybitRequestMessage() - { - Operation = "auth", - Parameters = new object[] - { - key, - expireTime, - sign - } - }; + var authProvider = (BybitAuthenticationProvider)AuthenticationProvider!; + var key = authProvider.GetApiKey(); + var sign = authProvider.Sign($"GET/realtime{expireTime}"); - var result = false; - var error = "unspecified error"; - await socketConnection.SendAndWaitAsync(authRequest, ClientOptions.RequestTimeout, null, 1, data => + return new BybitUnifiedQuery("auth", new object[] { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["op"]?.ToString(); - if (operation != "auth") - return false; - - result = data["success"]?.Value() == true; - error = data["ret_msg"]?.ToString(); - return true; - - }).ConfigureAwait(false); - return result ? new CallResult(result) : new CallResult(new ServerError(error)); + key, + expireTime, + sign + }); } /// - protected override bool HandleQueryResponse(SocketConnection socketConnection, object request, JToken data, out CallResult callResult) + public async Task> SubscribeToPositionUpdatesAsync(Action>> handler, CancellationToken ct = default) { - throw new NotImplementedException(); + var subscription = new BybitUnifiedSubscription>(_logger, new[] { "user.position.unifiedAccount" }, handler, true); + return await SubscribeAsync(subscription, ct).ConfigureAwait(false); } /// - protected override bool HandleSubscriptionResponse(SocketConnection socketConnection, SocketSubscription subscription, object request, JToken data, out CallResult? callResult) + public async Task> SubscribeToUserTradeUpdatesAsync(Action>> handler, CancellationToken ct = default) { - callResult = null; - if (data.Type != JTokenType.Object) - return false; - - var operation = data["op"]?.ToString(); - if (operation != "subscribe") - return false; - - var id = ((BybitDerivativesRequestMessage)request).CustomisedId; - if (!id.Equals(data["req_id"]?.ToString())) - return false; - - var success = data["success"]?.Value() == true; - if (success) - callResult = new CallResult(true); - else - callResult = new CallResult(new ServerError(data["ret_msg"]!.ToString())); - return true; + var subscription = new BybitUnifiedSubscription>(_logger, new[] { "user.execution.unifiedAccount" }, handler, true); + return await SubscribeAsync(subscription, ct).ConfigureAwait(false); } /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, object request) + public async Task> SubscribeToOrderUpdatesAsync(Action>> handler, CancellationToken ct = default) { - if (message.Type != JTokenType.Object) - return false; - - var topic = message["topic"]?.ToString(); - if (topic == null) - return false; - - var requestParams = ((BybitRequestMessage)request).Parameters; - if (requestParams.Any(p => topic == p.ToString())) - return true; - - if (topic.Contains('.')) - { - // Some subscriptions have topics like orderbook.ETHUSDT - // Split on `.` to get the topic and symbol - var split = topic.Split('.'); - var symbol = split.Last(); - if (symbol.Length == 0) - return false; - - var mainTopic = topic.Substring(0, topic.Length - symbol.Length - 1); - if (requestParams.Any(p => (string)p == mainTopic + ".*")) - return true; - } - - return false; + var subscription = new BybitUnifiedSubscription>(_logger, new[] { "user.order.unifiedAccount" }, handler, true); + return await SubscribeAsync(subscription, ct).ConfigureAwait(false); } /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, string identifier) + public async Task> SubscribeToBalanceUpdatesAsync(Action> handler, CancellationToken ct = default) { - if (identifier == "Heartbeat") - { - if (message.Type != JTokenType.Object) - return false; - - var ret = message["ret_msg"]; - if (ret == null) - return false; - - var isPing = ret.ToString() == "pong"; - if (!isPing) - return false; - - return true; - } - - if (identifier == "AccountInfo") - { - if (message.Type != JTokenType.Array) - return false; - - var updateType = ((JArray)message)[0]["e"]?.ToString(); - if (updateType == null) - return false; - - return updateType == "outboundAccountInfo" || updateType == "stop_executionReport" || updateType == "executionReport" || updateType == "order" || updateType == "ticketInfo"; - } - - return false; + var subscription = new BybitUnifiedSubscription(_logger, new[] { "user.wallet.unifiedAccount" }, handler, true); + return await SubscribeAsync(subscription, ct).ConfigureAwait(false); } /// - protected override async Task UnsubscribeAsync(SocketConnection connection, SocketSubscription subscriptionToUnsub) + public async Task> SubscribeToGreeksUpdatesAsync(Action>> handler, CancellationToken ct = default) { - var requestParams = ((BybitRequestMessage)subscriptionToUnsub.Request!).Parameters; - var message = new BybitRequestMessage { Operation = "unsubscribe", Parameters = requestParams }; - - var result = false; - await connection.SendAndWaitAsync(message, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["request"]?["op"]?.ToString(); - var args = data["request"]?["args"].Select(p => p.ToString()).ToList(); - if (operation != "unsubscribe") - return false; - - if (requestParams.Any(p => !args.Contains(p))) - return false; - - result = data["success"]?.Value() == true; - return true; - }).ConfigureAwait(false); - return result; + var subscription = new BybitUnifiedSubscription>(_logger, new[] { "user.greeks.unifiedAccount" }, handler, true); + return await SubscribeAsync(subscription, ct).ConfigureAwait(false); } } } diff --git a/ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApi.cs b/ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApi.cs index 5f3bedf2..0a6dd397 100644 --- a/ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApi.cs +++ b/ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApi.cs @@ -1,7 +1,6 @@ using Bybit.Net.Clients.CopyTradingApi; using Bybit.Net.Clients.InversePerpetualApi; using Bybit.Net.Interfaces.Clients.GeneralApi; -using Bybit.Net.Objects; using Bybit.Net.Objects.Internal; using Bybit.Net.Objects.Options; using CryptoExchange.Net; diff --git a/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApi.cs b/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApi.cs index 607922f6..bedd569c 100644 --- a/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApi.cs +++ b/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApi.cs @@ -1,5 +1,4 @@ using Bybit.Net.Interfaces.Clients.InverseFuturesApi; -using Bybit.Net.Objects; using Bybit.Net.Objects.Internal; using Bybit.Net.Objects.Options; using CryptoExchange.Net; diff --git a/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApi.cs b/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApi.cs index 48cfd2da..7dee171f 100644 --- a/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApi.cs +++ b/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApi.cs @@ -1,5 +1,4 @@ using Bybit.Net.Interfaces.Clients.InversePerpetualApi; -using Bybit.Net.Objects; using Bybit.Net.Objects.Internal; using Bybit.Net.Objects.Options; using CryptoExchange.Net; diff --git a/ByBit.Net/Clients/InversePerpetualApi/BybitSocketClientInversePerpetualApi.cs b/ByBit.Net/Clients/InversePerpetualApi/BybitSocketClientInversePerpetualApi.cs deleted file mode 100644 index d2aca671..00000000 --- a/ByBit.Net/Clients/InversePerpetualApi/BybitSocketClientInversePerpetualApi.cs +++ /dev/null @@ -1,547 +0,0 @@ -using Bybit.Net.Objects.Internal.Socket; -using Bybit.Net.Objects.Models; -using Bybit.Net.Objects.Models.Socket; -using Bybit.Net.Objects; -using CryptoExchange.Net; -using CryptoExchange.Net.Authentication; -using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Bybit.Net.Enums; -using Bybit.Net.Converters; -using Bybit.Net.Interfaces.Clients.InversePerpetualApi; -using CryptoExchange.Net.Converters; -using Bybit.Net.Objects.Options; - -namespace Bybit.Net.Clients.InversePerpetualApi -{ - /// - public class BybitSocketClientInversePerpetualApi : SocketApiClient, IBybitSocketClientInversePerpetualApi - { - internal BybitSocketClientInversePerpetualApi(ILogger log, BybitSocketOptions options) - : base(log, options.Environment.SocketBaseAddress, options, options.InversePerpetualOptions) - { - ContinueOnQueryResponse = true; - UnhandledMessageExpected = true; - KeepAliveInterval = TimeSpan.Zero; - - SendPeriodic("Ping", options.InversePerpetualOptions.PingInterval, (connection) => - { - return new BybitRequestMessage() { Operation = "ping" }; - }); - AddGenericHandler("Heartbeat", (evnt) => { }); - } - - /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) - => new BybitAuthenticationProvider(credentials); - - /// - public Task> SubscribeToTradesUpdatesAsync(Action>> handler, CancellationToken ct = default) - => SubscribeToTradeUpdatesAsync(new string[] { "*" }, handler, ct); - - /// - public Task> SubscribeToTradeUpdatesAsync(string symbol, Action>> handler, CancellationToken ct = default) - => SubscribeToTradeUpdatesAsync(new string[] { symbol }, handler, ct); - - /// - public async Task> SubscribeToTradeUpdatesAsync(IEnumerable symbols, Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitTradeUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, desResult.Data.First().Symbol)); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("realtime"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = symbols.Select(s => "trade." + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public Task> SubscribeToTickersUpdatesAsync(Action> handler, CancellationToken ct = default) - => SubscribeToTickerUpdatesAsync(new string[] { "*" }, handler, ct); - - /// - public Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - => SubscribeToTickerUpdatesAsync(new string[] { symbol }, handler, ct); - - /// - public async Task> SubscribeToTickerUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var innerData = data.Data["type"]?.ToString() == "delta" ? data.Data["data"]?["update"]?[0] : data.Data["data"]; - if (innerData == null) - return; - - var desResult = Deserialize(innerData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitTickerUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, desResult.Data.Symbol)); - - }); - return await SubscribeAsync( - BaseAddress.AppendPath("realtime"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = symbols.Select(s => "instrument_info.100ms." + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public Task> SubscribeToOrderBooksUpdatesAsync(int limit, Action>> snapshotHandler, Action>> updateHandler, CancellationToken ct = default) - => SubscribeToOrderBookUpdatesAsync(new string[] { "*" }, limit, snapshotHandler, updateHandler, ct); - - /// - public Task> SubscribeToOrderBookUpdatesAsync(string symbol, int limit, Action>> snapshotHandler, Action>> updateHandler, CancellationToken ct = default) - => SubscribeToOrderBookUpdatesAsync(new string[] { symbol }, limit, snapshotHandler, updateHandler, ct); - - /// - public async Task> SubscribeToOrderBookUpdatesAsync( - IEnumerable symbols, - int limit, - Action>> snapshotHandler, - Action>> updateHandler, - CancellationToken ct = default) - { - limit.ValidateIntValues(nameof(limit), 25, 200); - - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - if (data.Data["type"]?.ToString() == "delta") - { - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitOrderBookEntry)} object: " + desResult.Error); - return; - } - - string symbol = desResult.Data.Insert.FirstOrDefault()?.Symbol ?? desResult.Data.Update.FirstOrDefault()?.Symbol ?? desResult.Data.Delete.First().Symbol; - updateHandler(data.As(desResult.Data, symbol)); - } - else - { - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitOrderBookEntry)} object: " + desResult.Error); - return; - } - - snapshotHandler(data.As(desResult.Data, desResult.Data.First().Symbol)); - } - }); - var topic = limit == 25 ? "orderBookL2_25." : "orderBook_200.100ms."; - return await SubscribeAsync( - BaseAddress.AppendPath("realtime"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = symbols.Select(s => topic + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public Task> SubscribeToInsurancesUpdatesAsync(Action>> handler, CancellationToken ct = default) - => SubscribeToInsuranceUpdatesAsync(new string[] { "*" }, handler, ct); - - /// - public Task> SubscribeToInsuranceUpdatesAsync(string symbol, Action>> handler, CancellationToken ct = default) - => SubscribeToInsuranceUpdatesAsync(new string[] { symbol }, handler, ct); - - /// - public async Task> SubscribeToInsuranceUpdatesAsync(IEnumerable symbols, Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitInsuranceUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, desResult.Data.First().Asset)); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("realtime"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = symbols.Select(s => "insurance." + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public Task> SubscribeToKlinesUpdatesAsync(KlineInterval interval, Action>> handler, CancellationToken ct = default) - => SubscribeToKlineUpdatesAsync(new string[] { "*" }, interval, handler, ct); - - /// - public Task> SubscribeToKlineUpdatesAsync(string symbol, KlineInterval interval, Action>> handler, CancellationToken ct = default) - => SubscribeToKlineUpdatesAsync(new string[] { symbol }, interval, handler, ct); - - /// - public async Task> SubscribeToKlineUpdatesAsync(IEnumerable symbols, KlineInterval interval, Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitInsuranceUpdate)} object: " + desResult.Error); - return; - } - - var topic = data.Data["topic"]!.ToString(); - handler(data.As(desResult.Data, topic.Substring(topic.IndexOf('.') + 1))); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("realtime"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = symbols.Select(s => "klineV2." + JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) + "." + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public Task> SubscribeToLiquidationsUpdatesAsync(Action> handler, CancellationToken ct = default) - => SubscribeToLiquidationUpdatesAsync(new string[] { "*" }, handler, ct); - - /// - public Task> SubscribeToLiquidationUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - => SubscribeToLiquidationUpdatesAsync(new string[] { symbol }, handler, ct); - - /// - public async Task> SubscribeToLiquidationUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitLiquidationUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, desResult.Data.Symbol)); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("realtime"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = symbols.Select(s => "liquidation." + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToPositionUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitPositionUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("realtime"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = new[] { "position" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToUserTradeUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitUserTradeUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("realtime"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = new[] { "execution" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToOrderUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitInverseOrderUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("realtime"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = new[] { "order" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToStopOrderUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitStopOrderUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("realtime"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = new[] { "stop_order" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToBalanceUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitBalanceUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("realtime"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = new[] { "wallet" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - - /// - protected override async Task> AuthenticateSocketAsync(SocketConnection socketConnection) - { - if (socketConnection.ApiClient.AuthenticationProvider == null) - return new CallResult(new NoApiCredentialsError()); - - var expireTime = DateTimeConverter.ConvertToMilliseconds(DateTime.UtcNow.AddSeconds(30))!; - var bybitAuthProvider = (BybitAuthenticationProvider)socketConnection.ApiClient.AuthenticationProvider; - var key = bybitAuthProvider.GetApiKey(); - var sign = bybitAuthProvider.Sign($"GET/realtime{expireTime}"); - - var authRequest = new BybitRequestMessage() - { - Operation = "auth", - Parameters = new object[] - { - key, - expireTime, - sign - } - }; - - var result = false; - var error = "unspecified error"; - await socketConnection.SendAndWaitAsync(authRequest, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["request"]?["op"]?.ToString(); - var args = data["request"]?["args"].Select(p => p.ToString()).ToList(); - if (operation != "auth") - return false; - - result = data["success"]?.Value() == true; - error = data["ret_msg"]?.ToString(); - return true; - - }).ConfigureAwait(false); - return result ? new CallResult(result) : new CallResult(new ServerError(error)); - } - - /// - protected override bool HandleQueryResponse(SocketConnection socketConnection, object request, JToken data, out CallResult callResult) - { - throw new NotImplementedException(); - } - - /// - protected override bool HandleSubscriptionResponse(SocketConnection socketConnection, SocketSubscription subscription, object request, JToken data, out CallResult? callResult) - { - callResult = null; - if (data.Type != JTokenType.Object) - return false; - - var requestParams = ((BybitRequestMessage)request).Parameters; - var operation = data["request"]?["op"]?.ToString(); - var args = data["request"]?["args"].Select(p => p.ToString()).ToList(); - if (operation != "subscribe") - return false; - - if (requestParams.Any(p => !args.Contains(p))) - return false; - - var success = data["success"]?.Value() == true; - if (success) - callResult = new CallResult(true); - else - callResult = new CallResult(new ServerError(data["ret_msg"]!.ToString())); - return true; - } - - /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, object request) - { - if (message.Type != JTokenType.Object) - return false; - - var topic = message["topic"]?.ToString(); - if (topic == null) - return false; - - var requestParams = ((BybitRequestMessage)request).Parameters; - if (requestParams.Any(p => topic == p.ToString())) - return true; - - if (topic.Contains('.')) - { - // Some subscriptions have topics like orderbook.ETHUSDT - // Split on `.` to get the topic and symbol - var split = topic.Split('.'); - var symbol = split.Last(); - if (symbol.Length == 0) - return false; - - var mainTopic = topic.Substring(0, topic.Length - symbol.Length - 1); - if (requestParams.Any(p => (string)p == (mainTopic + ".*"))) - return true; - } - - return false; - } - - /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, string identifier) - { - if (identifier == "Heartbeat") - { - if (message.Type != JTokenType.Object) - return false; - - var ret = message["ret_msg"]; - if (ret == null) - return false; - - var isPing = ret.ToString() == "pong"; - if (!isPing) - return false; - - return true; - } - - if (identifier == "AccountInfo") - { - if (message.Type != JTokenType.Array) - return false; - - var updateType = ((JArray)message)[0]["e"]?.ToString(); - if (updateType == null) - return false; - - return updateType == "outboundAccountInfo" || updateType == "stop_executionReport" || updateType == "executionReport" || updateType == "order" || updateType == "ticketInfo"; - } - - return false; - } - - /// - protected override async Task UnsubscribeAsync(SocketConnection connection, SocketSubscription subscriptionToUnsub) - { - var requestParams = ((BybitRequestMessage)subscriptionToUnsub.Request!).Parameters; - var message = new BybitRequestMessage { Operation = "unsubscribe", Parameters = requestParams }; - - var result = false; - await connection.SendAndWaitAsync(message, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["request"]?["op"]?.ToString(); - var args = data["request"]?["args"].Select(p => p.ToString()).ToList(); - if (operation != "unsubscribe") - return false; - - if (requestParams.Any(p => !args.Contains(p))) - return false; - - result = data["success"]?.Value() == true; - return true; - }).ConfigureAwait(false); - return result; - } - } -} diff --git a/ByBit.Net/Clients/SpotApi/BybitRestClientBaseSpotApi.cs b/ByBit.Net/Clients/SpotApi/BybitRestClientBaseSpotApi.cs index 90b4cb68..a1cfeb19 100644 --- a/ByBit.Net/Clients/SpotApi/BybitRestClientBaseSpotApi.cs +++ b/ByBit.Net/Clients/SpotApi/BybitRestClientBaseSpotApi.cs @@ -1,5 +1,4 @@ using Bybit.Net.Enums; -using Bybit.Net.Objects; using Bybit.Net.Objects.Internal; using Bybit.Net.Objects.Options; using CryptoExchange.Net; diff --git a/ByBit.Net/Clients/SpotApi/BybitSocketClientBaseSpotApi.cs b/ByBit.Net/Clients/SpotApi/BybitSocketClientBaseSpotApi.cs deleted file mode 100644 index 1d1561d2..00000000 --- a/ByBit.Net/Clients/SpotApi/BybitSocketClientBaseSpotApi.cs +++ /dev/null @@ -1,214 +0,0 @@ -using Bybit.Net.Clients.SpotApi.v1; -using Bybit.Net.Clients.SpotApi.v2; -using Bybit.Net.Interfaces.Clients.SpotApi; -using Bybit.Net.Objects.Internal.Socket; -using Bybit.Net.Objects.Models.Socket.Spot; -using Bybit.Net.Objects.Options; -using CryptoExchange.Net; -using CryptoExchange.Net.Authentication; -using CryptoExchange.Net.Converters; -using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.SpotApi -{ - /// - /// Base client for Bybit spot socket streams clients - /// - public abstract class BybitSocketClientBaseSpotApi : SocketApiClient - { - internal BybitSocketClientBaseSpotApi(ILogger logger, string baseAddress, BybitSocketOptions options, BybitSocketApiOptions apiOptions) - : base(logger, baseAddress, options, apiOptions) - { - ContinueOnQueryResponse = true; - UnhandledMessageExpected = true; - KeepAliveInterval = TimeSpan.Zero; - - SendPeriodic("Ping", apiOptions.PingInterval, (connection) => - { - return new BybitSpotPing() { Ping = DateTimeConverter.ConvertToMilliseconds(DateTime.UtcNow)!.Value }; - }); - AddGenericHandler("Heartbeat", (evnt) => { }); - } - - /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) - => new BybitAuthenticationProvider(credentials); - - /// - /// Check auth data for valid - /// - /// Response data - /// Flag if auth is succeeded - /// Flag if response is valid - public abstract bool CheckAuth(JToken data, ref bool isSuccess); - - - /// - protected override async Task> AuthenticateSocketAsync(SocketConnection socketConnection) - { - if (socketConnection.ApiClient.AuthenticationProvider == null) - return new CallResult(new NoApiCredentialsError()); - - var expireTime = DateTimeConverter.ConvertToMilliseconds(DateTime.UtcNow.AddSeconds(30))!; - var bybitAuthProvider = (BybitAuthenticationProvider)socketConnection.ApiClient.AuthenticationProvider; - var key = bybitAuthProvider.GetApiKey(); - var sign = bybitAuthProvider.Sign($"GET/realtime{expireTime}"); - - var authRequest = new BybitRequestMessage() - { - Operation = "auth", - Parameters = new object[] - { - key, - expireTime, - sign - } - }; - - var result = false; - var error = "unspecified error"; - await socketConnection.SendAndWaitAsync(authRequest, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var isValid = (socketConnection.ApiClient as BybitSocketClientBaseSpotApi)?.CheckAuth(data, ref result) ?? false; - return isValid; - - }).ConfigureAwait(false); - return result ? new CallResult(result) : new CallResult(new ServerError(error)); - } - - /// - protected override bool HandleQueryResponse(SocketConnection socketConnection, object request, JToken data, out CallResult callResult) - { - throw new NotImplementedException(); - } - - /// - protected override bool HandleSubscriptionResponse(SocketConnection socketConnection, SocketSubscription subscription, object request, JToken data, out CallResult? callResult) - { - callResult = null; - if (data.Type != JTokenType.Object) - return false; - - var bRequest = (IBybitSpotRequestValidable)request; - var forcedExit = false; - - var success = bRequest.ValidateResponse(data, ref forcedExit); - if (forcedExit) - { - return false; - } - - if (success) - callResult = new CallResult(true); - else - callResult = new CallResult(new ServerError(data["ret_msg"]!.ToString())); - return true; - } - - /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, object request) - { - if (message.Type != JTokenType.Object) - return false; - - var topic = message["topic"]?.ToString(); - if (topic == null) - return false; - - return (request as IBybitSpotRequestValidable)?.MatchReponse(message) ?? false; - } - - /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, string identifier) - { - if (identifier == "Heartbeat") - { - if (message.Type != JTokenType.Object) - return false; - - var ret = message["ret_msg"]; - if (ret == null) - return false; - - var isPing = ret.ToString() == "pong"; - if (!isPing) - return false; - - return true; - } - - if (identifier == "AccountInfo") - { - if (message.Type != JTokenType.Array) - return false; - - var updateType = ((JArray)message)[0]["e"]?.ToString(); - if (updateType == null) - return false; - - return updateType == "outboundAccountInfo" || updateType == "stop_executionReport" || updateType == "executionReport" || updateType == "order" || updateType == "ticketInfo"; - } - - return false; - } - - /// - protected override async Task UnsubscribeAsync(SocketConnection connection, SocketSubscription subscriptionToUnsub) - { - object? message = null; - var isCheckable = false; - var clientType = GetType(); - if (clientType == typeof(BybitSocketClientSpotApiV1)) - { - var bRequest = ((BybitSpotRequestMessageV1)subscriptionToUnsub.Request!); - message = new BybitSpotRequestMessageV1 - { - Operation = bRequest.Operation, - Symbol = bRequest.Symbol, - Event = "cancel" - }; - } - else if (clientType == typeof(BybitSocketClientSpotApiV2)) - { - isCheckable = true; - var bRequest = ((BybitSpotRequestMessageV2)subscriptionToUnsub.Request!); - message = new BybitSpotRequestMessageV2 - { - Operation = bRequest.Operation, - Parameters = new Dictionary - { - { "symbol", bRequest.Parameters["symbol"] } - }, - Event = "cancel" - }; - } - - var result = false; - await connection.SendAndWaitAsync(message, ClientOptions.RequestTimeout, null, 1, data => - { - if (!isCheckable) - { - //// Got fallback message only in version 2,3. In version 1 we get a plain responseData - result = true; - return true; - } - - if (data.Type != JTokenType.Object) - return false; - - result = data["success"]?.Value() == true; - return true; - }).ConfigureAwait(false); - return result; - } - } -} diff --git a/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiV1.cs b/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiV1.cs index 06245844..68d6c4dd 100644 --- a/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiV1.cs +++ b/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiV1.cs @@ -7,7 +7,6 @@ using System.Threading.Tasks; using Bybit.Net.Enums; using Bybit.Net.Interfaces.Clients.SpotApi.v1; -using Bybit.Net.Objects; using Bybit.Net.Objects.Options; using CryptoExchange.Net.CommonObjects; using CryptoExchange.Net.Interfaces.CommonClients; diff --git a/ByBit.Net/Clients/SpotApi/v1/BybitSocketClientSpotApiV1.cs b/ByBit.Net/Clients/SpotApi/v1/BybitSocketClientSpotApiV1.cs deleted file mode 100644 index 531e938a..00000000 --- a/ByBit.Net/Clients/SpotApi/v1/BybitSocketClientSpotApiV1.cs +++ /dev/null @@ -1,288 +0,0 @@ -using Bybit.Net.Objects.Internal.Socket; -using Bybit.Net.Objects; -using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Bybit.Net.Objects.Models.Socket.Spot; -using Bybit.Net.Enums; -using Bybit.Net.Converters; -using Bybit.Net.Interfaces.Clients.SpotApi.v1; -using Bybit.Net.Objects.Options; -using CryptoExchange.Net; - -namespace Bybit.Net.Clients.SpotApi.v1 -{ - /// - public class BybitSocketClientSpotApiV1 : BybitSocketClientBaseSpotApi, IBybitSocketClientSpotApiV1 - { - internal BybitSocketClientSpotApiV1(ILogger logger, BybitSocketOptions options) - : base(logger, options.Environment.SocketBaseAddress, options, options.SpotV1Options) - { - } - - /// - public async Task> SubscribeToTradeUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalDataArray = data.Data["data"]; - if (internalDataArray == null) - return; - - var internalData = internalDataArray.First; - if (internalData == null) - { - return; - } - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotTradeUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["symbol"]?.ToString())); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/quote/ws/v1"), - new BybitSpotRequestMessageV1() - { - Operation = "trade", - Event = "sub", - Symbol = symbol - }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToOrderBookUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalDataArray = data.Data["data"]; - if (internalDataArray == null) - return; - - var internalData = internalDataArray.First; - if (internalData == null) - { - return; - } - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotOrderBookUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["symbol"]?.ToString())); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/quote/ws/v1"), - new BybitSpotRequestMessageV1() - { - Operation = "depth", - Event = "sub", - Symbol = symbol - }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToKlineUpdatesAsync(string symbol, KlineInterval interval, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalDataArray = data.Data["data"]; - if (internalDataArray == null) - return; - - var internalData = internalDataArray.First; - if (internalData == null) - { - return; - } - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotKlineUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["symbol"]?.ToString())); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/quote/ws/v1"), - new BybitSpotRequestMessageV1() - { - Operation = $"kline_{KlineIntervalSpotConverter.ToString(interval)}", - Event = "sub", - Symbol = symbol - }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalDataArray = data.Data["data"]; - if (internalDataArray == null) - return; - - var internalData = internalDataArray.First; - - if (internalData == null) - { - return; - } - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotTickerUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["symbol"]?.ToString())); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/quote/ws/v1"), - new BybitSpotRequestMessageV1() - { - Operation = "realtimes", - Event = "sub", - Symbol = symbol - }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToOrderBookMergedUpdatesAsync(string symbol, int dumpScale, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalDataArray = data.Data["data"]; - if (internalDataArray == null) - return; - - var internalData = internalDataArray.First; - if (internalData == null) - { - return; - } - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotOrderBookUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["symbol"]?.ToString())); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/quote/ws/v1"), - new BybitSpotRequestMessageV1() - { - Operation = "mergedDepth", - Event = "sub", - Symbol = symbol, - Parameters = new Dictionary - { - { "dumpScale", dumpScale } - } - }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToOrderBookDiffUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalDataArray = data.Data["data"]; - if (internalDataArray == null) - return; - - var internalData = internalDataArray.First; - if (internalData == null) - { - return; - } - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotOrderBookUpdate)} object: " + desResult.Error); - return; - } - - var symbol = data.Data["symbol"]?.ToString(); - desResult.Data.Symbol = string.IsNullOrWhiteSpace(desResult.Data.Symbol) ? symbol! : desResult.Data.Symbol; - handler(data.As(desResult.Data, symbol)); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/quote/ws/v1"), - new BybitSpotRequestMessageV1() - { - Operation = "diffDepth", - Event = "sub", - Symbol = symbol - }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToLeverageTokenUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalDataArray = data.Data["data"]; - if (internalDataArray == null) - return; - - var internalData = internalDataArray.First; - if (internalData == null) - { - return; - } - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotLeverageUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["symbol"]?.ToString())); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/quote/ws/v1"), - new BybitSpotRequestMessageV1() - { - Operation = "lt", - Event = "sub", - Symbol = "$\"{symbol}NAV\"" - }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public override bool CheckAuth(JToken data, ref bool isSuccess) - { - var auth = data["auth"]?.ToString(); - isSuccess = auth == "success"; - return auth != null; - } - } -} diff --git a/ByBit.Net/Clients/SpotApi/v2/BybitSocketClientSpotApiV2.cs b/ByBit.Net/Clients/SpotApi/v2/BybitSocketClientSpotApiV2.cs deleted file mode 100644 index 4cf723a9..00000000 --- a/ByBit.Net/Clients/SpotApi/v2/BybitSocketClientSpotApiV2.cs +++ /dev/null @@ -1,270 +0,0 @@ -using Bybit.Net.Objects.Internal.Socket; -using Bybit.Net.Objects; -using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Bybit.Net.Objects.Models.Socket.Spot; -using Bybit.Net.Enums; -using Bybit.Net.Converters; -using Bybit.Net.Interfaces.Clients.SpotApi.v2; -using Bybit.Net.Objects.Models.Spot.v1; -using Bybit.Net.Objects.Options; -using CryptoExchange.Net; - -namespace Bybit.Net.Clients.SpotApi.v2 -{ - /// - public class BybitSocketClientSpotApiV2 : BybitSocketClientBaseSpotApi, IBybitSocketClientSpotApiV2 - { - internal BybitSocketClientSpotApiV2(ILogger logger, BybitSocketOptions options) - : base(logger, options.Environment.SocketBaseAddress, options, options.SpotV2Options) - { - } - - /// - public async Task> SubscribeToTradeUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotTradeUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["params"]?["symbol"]?.ToString())); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/quote/ws/v2"), - new BybitSpotRequestMessageV2() - { - Operation = "trade", - Event = "sub", - Parameters = new Dictionary - { - { "symbol", symbol } - } - }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToOrderBookUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotOrderBookUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["params"]?["symbol"]?.ToString())); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/quote/ws/v2"), - new BybitSpotRequestMessageV2() - { - Operation = "depth", - Event = "sub", - Parameters = new Dictionary - { - { "symbol", symbol } - } - }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToKlineUpdatesAsync(string symbol, KlineInterval interval, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotKlineUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["params"]?["symbol"]?.ToString())); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/quote/ws/v2"), - new BybitSpotRequestMessageV2() - { - Operation = "kline", - Event = "sub", - Parameters = new Dictionary - { - { "symbol", symbol }, - { "klineType", JsonConvert.SerializeObject(interval, new KlineIntervalSpotConverter(false)) } - } - }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToBookPriceUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotBookPriceV1)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["params"]?["symbol"]?.ToString())); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/quote/ws/v2"), - new BybitSpotRequestMessageV2() - { - Operation = "bookTicker", - Event = "sub", - Parameters = new Dictionary - { - { "symbol", symbol } - } - }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotTickerUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["params"]?["symbol"]?.ToString())); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/quote/ws/v2"), - new BybitSpotRequestMessageV2() - { - Operation = "realtimes", - Event = "sub", - Parameters = new Dictionary - { - { "symbol", symbol } - } - }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToAccountUpdatesAsync( - Action> accountUpdateHandler, - Action> orderUpdateHandler, - Action> stopOrderUpdateHandler, - Action> tradeUpdateHandler, - CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var jArray = (JArray)data.Data; - foreach (var item in jArray) - { - var topic = item["e"]?.ToString(); - if (topic == "outboundAccountInfo") - { - var desResult = Deserialize(item); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotAccountUpdate)} object: " + desResult.Error); - return; - } - - accountUpdateHandler(data.As(desResult.Data)); - } - else if (topic == "executionReport") - { - var desResult = Deserialize(item); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotOrderUpdate)} object: " + desResult.Error); - return; - } - - orderUpdateHandler(data.As(desResult.Data)); - } - else if (topic == "stop_executionReport") - { - var desResult = Deserialize(item); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotStopOrderUpdate)} object: " + desResult.Error); - return; - } - - stopOrderUpdateHandler(data.As(desResult.Data)); - } - else if (topic == "ticketInfo") - { - var desResult = Deserialize(item); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotUserTradeUpdate)} object: " + desResult.Error); - return; - } - - tradeUpdateHandler(data.As(desResult.Data)); - } - else - { - _logger.Log(LogLevel.Warning, $"Unknown account update: " + topic); - } - } - }); - - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/ws"), - null, - "AccountInfo", true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public override bool CheckAuth(JToken data, ref bool isSuccess) - { - var auth = data["auth"]?.ToString(); - isSuccess = auth == "success"; - return auth != null; - } - } -} diff --git a/ByBit.Net/Clients/SpotApi/v3/BybitRestClientSpotApiV3.cs b/ByBit.Net/Clients/SpotApi/v3/BybitRestClientSpotApiV3.cs index 0af0a957..ae259a9e 100644 --- a/ByBit.Net/Clients/SpotApi/v3/BybitRestClientSpotApiV3.cs +++ b/ByBit.Net/Clients/SpotApi/v3/BybitRestClientSpotApiV3.cs @@ -7,7 +7,6 @@ using System.Threading.Tasks; using Bybit.Net.Enums; using Bybit.Net.Interfaces.Clients.SpotApi.v3; -using Bybit.Net.Objects; using Bybit.Net.Objects.Options; using CryptoExchange.Net.CommonObjects; using CryptoExchange.Net.Interfaces.CommonClients; diff --git a/ByBit.Net/Clients/SpotApi/v3/BybitSocketClientSpotApiV3.cs b/ByBit.Net/Clients/SpotApi/v3/BybitSocketClientSpotApiV3.cs index 1d069e22..c9801dc1 100644 --- a/ByBit.Net/Clients/SpotApi/v3/BybitSocketClientSpotApiV3.cs +++ b/ByBit.Net/Clients/SpotApi/v3/BybitSocketClientSpotApiV3.cs @@ -1,9 +1,5 @@ -using Bybit.Net.Objects.Internal.Socket; -using Bybit.Net.Objects; -using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects; using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; using System; using System.Threading; using System.Threading.Tasks; @@ -14,334 +10,122 @@ using Bybit.Net.Objects.Models.Spot.v3; using Bybit.Net.Objects.Options; using CryptoExchange.Net; +using CryptoExchange.Net.Objects.Sockets; +using CryptoExchange.Net.Authentication; +using Bybit.Net.Objects.Sockets.Queries; +using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; +using CryptoExchange.Net.Sockets.MessageParsing; +using Bybit.Net.Objects.Sockets.Subscriptions; +using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Converters; namespace Bybit.Net.Clients.SpotApi.v3 { /// - public class BybitSocketClientSpotApiV3 : BybitSocketClientBaseSpotApi, IBybitSocketClientSpotApiV3 + public class BybitSocketClientSpotApiV3 : SocketApiClient, IBybitSocketClientSpotApiV3 { + private static readonly MessagePath _reqIdPath = MessagePath.Get().Property("req_id"); + private static readonly MessagePath _topicPath = MessagePath.Get().Property("topic"); + internal BybitSocketClientSpotApiV3(ILogger logger, BybitSocketOptions options) : base(logger, options.Environment.SocketBaseAddress, options, options.SpotV3Options) { + KeepAliveInterval = TimeSpan.Zero; + + RegisterPeriodicQuery("Heartbeat", TimeSpan.FromSeconds(20), x => new BybitQuery("ping", null), x => { }); } /// - public async Task> SubscribeToTradeUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; + protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) + => new BybitAuthenticationProvider(credentials); - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotTradeUpdate)} object: " + desResult.Error); - return; - } + /// + public override string? GetListenerIdentifier(IMessageAccessor message) + { + var reqId = message.GetValue(_reqIdPath); + if (reqId != null) + return reqId; - handler(data.As(desResult.Data, data.Data["params"]?["symbol"]?.ToString())); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/public/v3"), - new BybitSpotRequestMessageV3() - { - ID = Guid.NewGuid().ToString(), - Operation = "subscribe", - Parameters = new[] - { - $"trade.{symbol}" - } - }, - null, false, internalHandler, ct).ConfigureAwait(false); + return message.GetValue(_topicPath); } /// - public async Task> SubscribeToOrderBookUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) + protected override Query? GetAuthenticationRequest() { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; + var expireTime = DateTimeConverter.ConvertToMilliseconds(DateTime.UtcNow.AddSeconds(30))!; + var authProvider = (BybitAuthenticationProvider)AuthenticationProvider!; + var key = authProvider.GetApiKey(); + var sign = authProvider.Sign($"GET/realtime{expireTime}"); - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotOrderBookUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["params"]?["symbol"]?.ToString())); + return new BybitQuery("auth", new object[] + { + key, + expireTime, + sign }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/public/v3"), - new BybitSpotRequestMessageV3() - { - ID = Guid.NewGuid().ToString(), - Operation = "subscribe", - Parameters = new[] - { - $"orderbook.40.{symbol}" - } - }, - null, false, internalHandler, ct).ConfigureAwait(false); } /// - public async Task> SubscribeToKlineUpdatesAsync(string symbol, KlineInterval interval, Action> handler, CancellationToken ct = default) + public async Task> SubscribeToTradeUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; + var subscription = new BybitSubscription(_logger, new[] { "trade." + symbol }, handler); + return await SubscribeAsync(BaseAddress.AppendPath("/spot/public/v3"), subscription, ct).ConfigureAwait(false); + } - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotKlineUpdate)} object: " + desResult.Error); - return; - } + /// + public async Task> SubscribeToOrderBookUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) + { + var subscription = new BybitSubscription(_logger, new[] { "orderbook.40." + symbol }, handler); + return await SubscribeAsync(BaseAddress.AppendPath("/spot/public/v3"), subscription, ct).ConfigureAwait(false); + } - var topic = data.Data["topic"]!.ToString(); - handler(data.As(desResult.Data, topic.Substring(topic.IndexOf('.') + 1))); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/public/v3"), - new BybitSpotRequestMessageV3() - { - ID = Guid.NewGuid().ToString(), - Operation = "subscribe", - Parameters = new[] - { - $"kline.{KlineIntervalSpotConverter.ToString(interval)}.{symbol}" - } - }, - null, false, internalHandler, ct).ConfigureAwait(false); + /// + public async Task> SubscribeToKlineUpdatesAsync(string symbol, KlineInterval interval, Action> handler, CancellationToken ct = default) + { + var subscription = new BybitSubscription(_logger, new[] { $"kline.{KlineIntervalSpotConverter.ToString(interval)}.{symbol}" }, handler); + return await SubscribeAsync(BaseAddress.AppendPath("/spot/public/v3"), subscription, ct).ConfigureAwait(false); } /// public async Task> SubscribeToBookPriceUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotBookPriceV3)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["params"]?["symbol"]?.ToString())); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/public/v3"), - new BybitSpotRequestMessageV3() - { - ID = Guid.NewGuid().ToString(), - Operation = "subscribe", - Parameters = new[] - { - $"bookticker.{symbol}" - } - }, - null, false, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription(_logger, new[] { $"bookticker.{symbol}" }, handler); + return await SubscribeAsync(BaseAddress.AppendPath("/spot/public/v3"), subscription, ct).ConfigureAwait(false); } /// public async Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotTickerUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["params"]?["symbol"]?.ToString())); - }); - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/public/v3"), - new BybitSpotRequestMessageV3() - { - ID = Guid.NewGuid().ToString(), - Operation = "subscribe", - Parameters = new[] - { - $"tickers.{symbol}" - } - }, - null, false, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription(_logger, new[] { $"tickers.{symbol}" }, handler); + return await SubscribeAsync(BaseAddress.AppendPath("/spot/public/v3"), subscription, ct).ConfigureAwait(false); } /// public async Task> SubscribeToAccountUpdatesAsync(Action> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var jArray = (JArray)internalData; - foreach (var item in jArray) - { - var desResult = Deserialize(item); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotAccountUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - } - }); - - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/private/v3"), - new BybitSpotRequestMessageV3() - { - ID = Guid.NewGuid().ToString(), - Operation = "subscribe", - Parameters = new[] - { - "outboundAccountInfo" - } - }, - null, true, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription(_logger, new[] { "outboundAccountInfo" }, handler, true); + return await SubscribeAsync(BaseAddress.AppendPath("/spot/private/v3"), subscription, ct).ConfigureAwait(false); } /// public async Task> SubscribeToUserOrdersUpdatesAsync(Action> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var jArray = (JArray)internalData; - foreach (var item in jArray) - { - var desResult = Deserialize(item); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotOrderUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - } - }); - - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/private/v3"), - new BybitSpotRequestMessageV3() - { - ID = Guid.NewGuid().ToString(), - Operation = "subscribe", - Parameters = new[] - { - "order" - } - }, - null, true, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription(_logger, new[] { "order" }, handler, true); + return await SubscribeAsync(BaseAddress.AppendPath("/spot/private/v3"), subscription, ct).ConfigureAwait(false); } /// public async Task> SubscribeToUserStopOrdersUpdatesAsync(Action> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var jArray = (JArray)internalData; - foreach (var item in jArray) - { - var desResult = Deserialize(item); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotStopOrderUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - } - }); - - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/private/v3"), - new BybitSpotRequestMessageV3() - { - ID = Guid.NewGuid().ToString(), - Operation = "subscribe", - Parameters = new[] - { - "stopOrder" - } - }, - null, true, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription(_logger, new[] { "stopOrder" }, handler, true); + return await SubscribeAsync(BaseAddress.AppendPath("/spot/private/v3"), subscription, ct).ConfigureAwait(false); } /// public async Task> SubscribeToUserTradesUpdatesAsync(Action> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var jArray = (JArray)internalData; - foreach (var item in jArray) - { - var desResult = Deserialize(item); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotUserTradeUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - } - }); - - return await SubscribeAsync( - BaseAddress.AppendPath("/spot/private/v3"), - new BybitSpotRequestMessageV3() - { - ID = Guid.NewGuid().ToString(), - Operation = "subscribe", - Parameters = new[] - { - "ticketInfo" - } - }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public override bool CheckAuth(JToken data, ref bool isSuccess) - { - var isAuthOperation = data["op"]?.ToString() == "auth"; - - var auth = data["success"]?.ToString(); - isSuccess = isAuthOperation && auth == "True"; - return auth != null; + var subscription = new BybitSubscription(_logger, new[] { "ticketInfo" }, handler, true); + return await SubscribeAsync(BaseAddress.AppendPath("/spot/private/v3"), subscription, ct).ConfigureAwait(false); } } } diff --git a/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApi.cs b/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApi.cs index 7ec7877e..c853d14c 100644 --- a/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApi.cs +++ b/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApi.cs @@ -1,11 +1,9 @@ using Bybit.Net.Interfaces.Clients.UsdPerpetualApi; -using Bybit.Net.Objects; using Bybit.Net.Objects.Internal; using Bybit.Net.Objects.Options; using CryptoExchange.Net; using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Objects.Options; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; diff --git a/ByBit.Net/Clients/UsdPerpetualApi/BybitSocketClientUsdPerpetualApi.cs b/ByBit.Net/Clients/UsdPerpetualApi/BybitSocketClientUsdPerpetualApi.cs deleted file mode 100644 index fbc98a63..00000000 --- a/ByBit.Net/Clients/UsdPerpetualApi/BybitSocketClientUsdPerpetualApi.cs +++ /dev/null @@ -1,496 +0,0 @@ -using Bybit.Net.Objects.Internal.Socket; -using Bybit.Net.Objects.Models; -using Bybit.Net.Objects.Models.Socket; -using Bybit.Net.Objects; -using CryptoExchange.Net; -using CryptoExchange.Net.Authentication; -using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using Bybit.Net.Enums; -using Bybit.Net.Converters; -using Bybit.Net.Interfaces.Clients.UsdPerpetualApi; -using CryptoExchange.Net.Converters; -using Bybit.Net.Objects.Options; - -namespace Bybit.Net.Clients.UsdPerpetualApi -{ - /// - public class BybitSocketClientUsdPerpetualApi : SocketApiClient, IBybitSocketClientUsdPerpetualApi - { - internal BybitSocketClientUsdPerpetualApi(ILogger log, BybitSocketOptions options) - : base(log, options.Environment.SocketBaseAddress, options, options.UsdPerpetualOptions) - { - ContinueOnQueryResponse = true; - UnhandledMessageExpected = true; - KeepAliveInterval = TimeSpan.Zero; - - SendPeriodic("Ping", options.UsdPerpetualOptions.PingInterval, (connection) => - { - return new BybitRequestMessage() { Operation = "ping" }; - }); - AddGenericHandler("Heartbeat", (evnt) => { }); - } - - /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) - => new BybitAuthenticationProvider(credentials); - - /// - public Task> SubscribeToTradesUpdatesAsync(Action>> handler, CancellationToken ct = default) - => SubscribeToTradeUpdatesAsync(new string[] { "*" }, handler, ct); - - /// - public Task> SubscribeToTradeUpdatesAsync(string symbol, Action>> handler, CancellationToken ct = default) - => SubscribeToTradeUpdatesAsync(new string[] { symbol }, handler, ct); - - /// - public async Task> SubscribeToTradeUpdatesAsync(IEnumerable symbols, Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitTradeUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, desResult.Data.First().Symbol)); - }); - return await SubscribeAsync( BaseAddress.AppendPath("/realtime_public"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = symbols.Select(s => "trade." + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - => SubscribeToTickerUpdatesAsync(new string[] { symbol }, handler, ct); - - /// - public async Task> SubscribeToTickerUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var innerData = data.Data["type"]?.ToString() == "delta" ? data.Data["data"]?["update"]?[0] : data.Data["data"]; - if (innerData == null) - return; - - var desResult = Deserialize(innerData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitTickerUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, desResult.Data.Symbol)); - - }); - return await SubscribeAsync(BaseAddress.AppendPath("/realtime_public"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = symbols.Select(s => "instrument_info.100ms." + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public Task> SubscribeToOrderBooksUpdatesAsync(int limit, Action>> snapshotHandler, Action>> updateHandler, CancellationToken ct = default) - => SubscribeToOrderBookUpdatesAsync(new string[] { "*" }, limit, snapshotHandler, updateHandler, ct); - - /// - public Task> SubscribeToOrderBookUpdatesAsync(string symbol, int limit, Action>> snapshotHandler, Action>> updateHandler, CancellationToken ct = default) - => SubscribeToOrderBookUpdatesAsync(new string[] { symbol }, limit, snapshotHandler, updateHandler, ct); - - /// - public async Task> SubscribeToOrderBookUpdatesAsync( - IEnumerable symbols, - int limit, - Action>> snapshotHandler, - Action>> updateHandler, - CancellationToken ct = default) - { - limit.ValidateIntValues(nameof(limit), 25, 200); - - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - if (data.Data["type"]?.ToString() == "delta") - { - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitOrderBookEntry)} object: " + desResult.Error); - return; - } - - string symbol = desResult.Data.Insert.FirstOrDefault()?.Symbol ?? desResult.Data.Update.FirstOrDefault()?.Symbol ?? desResult.Data.Delete.First().Symbol; - updateHandler(data.As(desResult.Data, symbol)); - } - else - { - var desResult = Deserialize>(internalData["order_book"]!); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitOrderBookEntry)} object: " + desResult.Error); - return; - } - - snapshotHandler(data.As(desResult.Data, desResult.Data.First().Symbol)); - } - }); - var topic = limit == 25 ? "orderBookL2_25." : "orderBook_200.100ms."; - return await SubscribeAsync(BaseAddress.AppendPath("/realtime_public"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = symbols.Select(s => topic + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public Task> SubscribeToKlineUpdatesAsync(string symbol, KlineInterval interval, Action>> handler, CancellationToken ct = default) - => SubscribeToKlineUpdatesAsync(new string[] { symbol }, interval, handler, ct); - - /// - public async Task> SubscribeToKlineUpdatesAsync(IEnumerable symbols, KlineInterval interval, Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitKlineUpdate)} object: " + desResult.Error); - return; - } - - var topic = data.Data["topic"]!.ToString(); - handler(data.As(desResult.Data, topic.Substring(topic.IndexOf('.') + 1))); - }); - return await SubscribeAsync(BaseAddress.AppendPath("/realtime_public"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = symbols.Select(s => "candle." + JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) + "." + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public Task> SubscribeToLiquidationsUpdatesAsync(Action> handler, CancellationToken ct = default) - => SubscribeToLiquidationUpdatesAsync(new string[] { "*" }, handler, ct); - - /// - public Task> SubscribeToLiquidationUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - => SubscribeToLiquidationUpdatesAsync(new string[] { symbol }, handler, ct); - - /// - public async Task> SubscribeToLiquidationUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitLiquidationUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, desResult.Data.Symbol)); - }); - return await SubscribeAsync(BaseAddress.AppendPath("/realtime_public"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = symbols.Select(s => "liquidation." + s).ToArray() }, - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToPositionUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitPositionUsdPerpetualUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - return await SubscribeAsync(BaseAddress.AppendPath("/realtime_private"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = new[] { "position" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToUserTradeUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitUserTradeUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - return await SubscribeAsync(BaseAddress.AppendPath("/realtime_private"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = new[] { "execution" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToOrderUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitUsdPerpetualOrderUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - return await SubscribeAsync(BaseAddress.AppendPath("/realtime_private"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = new[] { "order" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToStopOrderUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitUsdPerpetualStopOrderUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - return await SubscribeAsync(BaseAddress.AppendPath("/realtime_private"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = new[] { "stop_order" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToBalanceUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitBalanceUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data)); - }); - return await SubscribeAsync(BaseAddress.AppendPath("/realtime_private"), - new BybitRequestMessage() { Operation = "subscribe", Parameters = new[] { "wallet" } }, - null, true, internalHandler, ct).ConfigureAwait(false); - } - - - /// - protected override async Task> AuthenticateSocketAsync(SocketConnection socketConnection) - { - if (socketConnection.ApiClient.AuthenticationProvider == null) - return new CallResult(new NoApiCredentialsError()); - - var expireTime = DateTimeConverter.ConvertToMilliseconds(DateTime.UtcNow.AddSeconds(30))!; - var bybitAuthProvider = (BybitAuthenticationProvider)socketConnection.ApiClient.AuthenticationProvider; - var key = bybitAuthProvider.GetApiKey(); - var sign = bybitAuthProvider.Sign($"GET/realtime{expireTime}"); - - var authRequest = new BybitRequestMessage() - { - Operation = "auth", - Parameters = new object[] - { - key, - expireTime, - sign - } - }; - - var result = false; - var error = "unspecified error"; - await socketConnection.SendAndWaitAsync(authRequest, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["request"]?["op"]?.ToString(); - var args = data["request"]?["args"].Select(p => p.ToString()).ToList(); - if (operation != "auth") - return false; - - result = data["success"]?.Value() == true; - error = data["ret_msg"]?.ToString(); - return true; - }).ConfigureAwait(false); - return result ? new CallResult(result) : new CallResult(new ServerError(error)); - } - - /// - protected override bool HandleQueryResponse(SocketConnection socketConnection, object request, JToken data, out CallResult callResult) - { - throw new NotImplementedException(); - } - - /// - protected override bool HandleSubscriptionResponse(SocketConnection socketConnection, SocketSubscription subscription, object request, JToken data, out CallResult? callResult) - { - callResult = null; - if (data.Type != JTokenType.Object) - return false; - - var requestParams = ((BybitRequestMessage)request).Parameters; - var operation = data["request"]?["op"]?.ToString(); - var args = data["request"]?["args"].Select(p => p.ToString()).ToList(); - if (operation != "subscribe") - return false; - - if (requestParams.Any(p => !args.Contains(p))) - return false; - - var success = data["success"]?.Value() == true; - if (success) - callResult = new CallResult(true); - else - callResult = new CallResult(new ServerError(data["ret_msg"]!.ToString())); - return true; - } - - /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, object request) - { - if (message.Type != JTokenType.Object) - return false; - - var topic = message["topic"]?.ToString(); - if (topic == null) - return false; - - var requestParams = ((BybitRequestMessage)request).Parameters; - if (requestParams.Any(p => topic == p.ToString())) - return true; - - if (topic.Contains('.')) - { - // Some subscriptions have topics like orderbook.ETHUSDT - // Split on `.` to get the topic and symbol - var split = topic.Split('.'); - var symbol = split.Last(); - if (symbol.Length == 0) - return false; - - var mainTopic = topic.Substring(0, topic.Length - symbol.Length - 1); - if (requestParams.Any(p => (string)p == (mainTopic + ".*"))) - return true; - } - - return false; - } - - /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, string identifier) - { - if (identifier == "Heartbeat") - { - if (message.Type != JTokenType.Object) - return false; - - var ret = message["ret_msg"]; - if (ret == null) - return false; - - var isPing = ret.ToString() == "pong"; - if (!isPing) - return false; - - return true; - } - - if (identifier == "AccountInfo") - { - if (message.Type != JTokenType.Array) - return false; - - var updateType = ((JArray)message)[0]["e"]?.ToString(); - if (updateType == null) - return false; - - return updateType == "outboundAccountInfo" || updateType == "stop_executionReport" || updateType == "executionReport" || updateType == "order" || updateType == "ticketInfo"; - } - - return false; - } - - /// - protected override async Task UnsubscribeAsync(SocketConnection connection, SocketSubscription subscriptionToUnsub) - { - var requestParams = ((BybitRequestMessage)subscriptionToUnsub.Request!).Parameters; - var message = new BybitRequestMessage { Operation = "unsubscribe", Parameters = requestParams }; - - var result = false; - await connection.SendAndWaitAsync(message, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["request"]?["op"]?.ToString(); - var args = data["request"]?["args"].Select(p => p.ToString()).ToList(); - if (operation != "unsubscribe") - return false; - - if (requestParams.Any(p => !args.Contains(p))) - return false; - - result = data["success"]?.Value() == true; - return true; - }).ConfigureAwait(false); - return result; - } - } -} diff --git a/ByBit.Net/Clients/V5/BybitRestClientApi.cs b/ByBit.Net/Clients/V5/BybitRestClientApi.cs index 49070ffa..7fd550a5 100644 --- a/ByBit.Net/Clients/V5/BybitRestClientApi.cs +++ b/ByBit.Net/Clients/V5/BybitRestClientApi.cs @@ -1,5 +1,4 @@ -using Bybit.Net.Objects; -using Bybit.Net.Objects.Internal; +using Bybit.Net.Objects.Internal; using CryptoExchange.Net; using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Objects; diff --git a/ByBit.Net/Clients/V5/BybitSocketClientBaseApi.cs b/ByBit.Net/Clients/V5/BybitSocketClientBaseApi.cs index 4def3773..b45186d7 100644 --- a/ByBit.Net/Clients/V5/BybitSocketClientBaseApi.cs +++ b/ByBit.Net/Clients/V5/BybitSocketClientBaseApi.cs @@ -1,20 +1,18 @@ -using Bybit.Net.Objects; -using Bybit.Net.Objects.Internal.Socket; -using CryptoExchange.Net; +using CryptoExchange.Net; using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Threading; -using CryptoExchange.Net.Sockets; using CryptoExchange.Net.Objects; using Bybit.Net.Objects.Models.V5; using Bybit.Net.Enums; using CryptoExchange.Net.Converters; using Bybit.Net.Interfaces.Clients.V5; using Bybit.Net.Objects.Options; +using CryptoExchange.Net.Objects.Sockets; +using Bybit.Net.Objects.Sockets.Subscriptions; namespace Bybit.Net.Clients.V5 { @@ -34,7 +32,6 @@ internal BybitSocketClientBaseApi(ILogger log, BybitSocketOptions options, strin { _baseEndpoint = baseEndpoint; - ContinueOnQueryResponse = true; UnhandledMessageExpected = true; KeepAliveInterval = TimeSpan.Zero; } @@ -46,58 +43,19 @@ public Task> SubscribeToTradeUpdatesAsync(string /// public async Task> SubscribeToTradeUpdatesAsync(IEnumerable symbols, Action>> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitTrade)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, desResult.Data.First().Symbol)); - }); - - return await SubscribeAsync( - BaseAddress + _baseEndpoint, - new BybitV5RequestMessage("subscribe", symbols.Select(s => "publicTrade." + s).ToArray(), ExchangeHelpers.NextId().ToString()), - null, false, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription>(_logger, symbols.Select(s => $"publicTrade.{s}").ToArray(), handler); + return await SubscribeAsync(BaseAddress + _baseEndpoint, subscription, ct).ConfigureAwait(false); } /// - public Task> SubscribeToOrderbookUpdatesAsync(string symbol, int depth, Action> snapshotHandler, Action> updateHandler, CancellationToken ct = default) - => SubscribeToOrderbookUpdatesAsync(new string[] { symbol }, depth, snapshotHandler, updateHandler, ct); + public Task> SubscribeToOrderbookUpdatesAsync(string symbol, int depth, Action> updateHandler, CancellationToken ct = default) + => SubscribeToOrderbookUpdatesAsync(new string[] { symbol }, depth, updateHandler, ct); /// - public async Task> SubscribeToOrderbookUpdatesAsync(IEnumerable symbols, int depth, Action> snapshotHandler, Action> updateHandler, CancellationToken ct = default) + public async Task> SubscribeToOrderbookUpdatesAsync(IEnumerable symbols, int depth, Action> updateHandler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitOrderbook)} object: " + desResult.Error); - return; - } - - if (data.Data["type"]?.ToString() == "snapshot") - snapshotHandler(data.As(desResult.Data, desResult.Data.Symbol)); - else - updateHandler(data.As(desResult.Data, desResult.Data.Symbol)); - }); - - return await SubscribeAsync( - BaseAddress + _baseEndpoint, - new BybitV5RequestMessage("subscribe", symbols.Select(s => $"orderbook.{depth}.{s}").ToArray(), ExchangeHelpers.NextId().ToString()), - null, false, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription(_logger, symbols.Select(s => $"orderbook.{depth}.{s}").ToArray(), updateHandler); + return await SubscribeAsync(BaseAddress + _baseEndpoint, subscription, ct).ConfigureAwait(false); } /// @@ -107,27 +65,8 @@ public Task> SubscribeToKlineUpdatesAsync(string /// public async Task> SubscribeToKlineUpdatesAsync(IEnumerable symbols, KlineInterval interval, Action>> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitKlineUpdate)} object: " + desResult.Error); - return; - } - - var topic = data.Data["topic"]!.ToString(); - handler(data.As(desResult.Data, topic.Substring(topic.IndexOf('.') + 1))); - }); - - return await SubscribeAsync( - BaseAddress + _baseEndpoint, - new BybitV5RequestMessage("subscribe", symbols.Select(s => $"kline.{EnumConverter.GetString(interval)}.{s}").ToArray(), ExchangeHelpers.NextId().ToString()), - null, false, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription>(_logger, symbols.Select(x => $"kline.{EnumConverter.GetString(interval)}.{x}").ToArray(), handler); + return await SubscribeAsync(BaseAddress + _baseEndpoint, subscription, ct).ConfigureAwait(false); } /// @@ -137,26 +76,8 @@ public Task> SubscribeToLiquidationUpdatesAsync(s /// public async Task> SubscribeToLiquidationUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitLiquidation)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["topic"]!.ToString().Split('.').Last())); - }); - - return await SubscribeAsync( - BaseAddress + _baseEndpoint, - new BybitV5RequestMessage("subscribe", symbols.Select(s => $"liquidation.{s}").ToArray(), ExchangeHelpers.NextId().ToString()), - null, false, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription(_logger, symbols.Select(x => $"liquidation.{x}").ToArray(), handler); + return await SubscribeAsync(BaseAddress + _baseEndpoint, subscription, ct).ConfigureAwait(false); } } } diff --git a/ByBit.Net/Clients/V5/BybitSocketClientInverseApi.cs b/ByBit.Net/Clients/V5/BybitSocketClientInverseApi.cs index bf300016..f69b6e11 100644 --- a/ByBit.Net/Clients/V5/BybitSocketClientInverseApi.cs +++ b/ByBit.Net/Clients/V5/BybitSocketClientInverseApi.cs @@ -1,20 +1,17 @@ using Bybit.Net.Interfaces.Clients.V5; -using Bybit.Net.Objects; -using Bybit.Net.Objects.Internal.Socket; using Bybit.Net.Objects.Models.V5; using Bybit.Net.Objects.Options; -using CryptoExchange.Net; +using Bybit.Net.Objects.Sockets.Queries; +using Bybit.Net.Objects.Sockets.Subscriptions; using CryptoExchange.Net.Authentication; -using CryptoExchange.Net.Converters; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects.Sockets; +using CryptoExchange.Net.Sockets.MessageParsing; +using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; @@ -23,169 +20,39 @@ namespace Bybit.Net.Clients.V5 /// public class BybitSocketClientInverseApi : BybitSocketClientBaseApi, IBybitSocketClientInverseApi { + private static readonly MessagePath _reqIdPath = MessagePath.Get().Property("req_id"); + private static readonly MessagePath _topicPath = MessagePath.Get().Property("topic"); + internal BybitSocketClientInverseApi(ILogger log, BybitSocketOptions options) : base(log, options, "/v5/public/inverse") { - SendPeriodic("Ping", options.V5Options.PingInterval, (connection) => - { - return new BybitV5RequestMessage("ping", Array.Empty(), ExchangeHelpers.NextId().ToString()); - }); - AddGenericHandler("Heartbeat", (evnt) => { }); + RegisterPeriodicQuery("Heartbeat", TimeSpan.FromSeconds(20), x => new BybitQuery("ping", null), x => { }); } - - /// - public Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - => SubscribeToTickerUpdatesAsync(new string[] { symbol }, handler, ct); - /// - public async Task> SubscribeToTickerUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) + public override string? GetListenerIdentifier(IMessageAccessor message) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitLinearTickerUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["topic"]!.ToString().Split('.').Last())); - }); + var reqId = message.GetValue(_reqIdPath); + if (reqId != null) + return reqId; - return await SubscribeAsync( - BaseAddress + _baseEndpoint, - new BybitV5RequestMessage("subscribe", symbols.Select(s => $"tickers.{s}").ToArray(), ExchangeHelpers.NextId().ToString()), - null, false, internalHandler, ct).ConfigureAwait(false); + return message.GetValue(_topicPath); } - /// - protected override Task> AuthenticateSocketAsync(SocketConnection socketConnection) => throw new NotImplementedException(); - - /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => new BybitAuthenticationProvider(credentials); - /// - protected override bool HandleQueryResponse(SocketConnection socketConnection, object request, JToken data, out CallResult callResult) => throw new NotImplementedException(); - /// - protected override bool HandleSubscriptionResponse(SocketConnection socketConnection, SocketSubscription subscription, object request, JToken data, out CallResult? callResult) - { - callResult = null; - if (data.Type != JTokenType.Object) - return false; - - var messageRequestId = data["req_id"]?.ToString(); - if (messageRequestId != null) - { - // Matched based on request id - var id = ((BybitV5RequestMessage)request).RequestId; - if (id != messageRequestId) - return false; - - var success1 = data["success"]?.Value() == true; - if (success1) - callResult = new CallResult(true); - else - callResult = new CallResult(new ServerError(data["ret_msg"]!.ToString())); - return true; - } - - // No request id - var success = data["success"]?.Value(); - if (success == null) - return false; - - callResult = success == true ? new CallResult(true) : new CallResult(new ServerError(data.ToString())); - return true; - } /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, object request) - { - if (message.Type != JTokenType.Object) - return false; - - var topic = message["topic"]?.ToString(); - if (topic == null) - return false; - - var requestParams = ((BybitV5RequestMessage)request).Parameters; - if (requestParams.Any(p => topic == p.ToString())) - return true; - - if (topic.Contains('.')) - { - // Some subscriptions have topics like orderbook.ETHUSDT - // Split on `.` to get the topic and symbol - var split = topic.Split('.'); - var symbol = split.Last(); - if (symbol.Length == 0) - return false; - - var mainTopic = topic.Substring(0, topic.Length - symbol.Length - 1); - if (requestParams.Any(p => (string)p == mainTopic + ".*")) - return true; - } - - return false; - } + public Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) + => SubscribeToTickerUpdatesAsync(new string[] { symbol }, handler, ct); /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, string identifier) + public async Task> SubscribeToTickerUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) { - if (identifier == "Heartbeat") - { - if (message.Type != JTokenType.Object) - return false; - - var ret = message["ret_msg"] ?? message["op"]; - if (ret == null) - return false; - - var isPing = ret.ToString() == "pong"; - if (!isPing) - return false; - - return true; - } - - return false; + var subscription = new BybitSubscription(_logger, symbols.Select(x => $"tickers.{x}").ToArray(), handler); + return await SubscribeAsync(BaseAddress + _baseEndpoint, subscription, ct).ConfigureAwait(false); } /// - protected override async Task UnsubscribeAsync(SocketConnection connection, SocketSubscription subscriptionToUnsub) - { - var requestParams = ((BybitV5RequestMessage)subscriptionToUnsub.Request!).Parameters; - var message = new BybitV5RequestMessage("unsubscribe", requestParams, ExchangeHelpers.NextId().ToString()); - - var result = false; - await connection.SendAndWaitAsync(message, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var messageRequestId = data["req_id"]?.ToString(); - if (messageRequestId != null) - { - // Matched based on request id - var id = message.RequestId; - if (id != messageRequestId) - return false; - - return true; - } - - // No request id - var success = data["success"]?.Value(); - if (success == null) - return false; - - return true; - }).ConfigureAwait(false); - return result; - } + protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => new BybitAuthenticationProvider(credentials); + } } diff --git a/ByBit.Net/Clients/V5/BybitSocketClientLinearApi.cs b/ByBit.Net/Clients/V5/BybitSocketClientLinearApi.cs index 93d713dc..4d55a2e1 100644 --- a/ByBit.Net/Clients/V5/BybitSocketClientLinearApi.cs +++ b/ByBit.Net/Clients/V5/BybitSocketClientLinearApi.cs @@ -1,20 +1,17 @@ using Bybit.Net.Interfaces.Clients.V5; -using Bybit.Net.Objects; -using Bybit.Net.Objects.Internal.Socket; using Bybit.Net.Objects.Models.V5; using Bybit.Net.Objects.Options; -using CryptoExchange.Net; +using Bybit.Net.Objects.Sockets.Queries; +using Bybit.Net.Objects.Sockets.Subscriptions; using CryptoExchange.Net.Authentication; -using CryptoExchange.Net.Converters; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects.Sockets; +using CryptoExchange.Net.Sockets.MessageParsing; +using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; @@ -23,207 +20,37 @@ namespace Bybit.Net.Clients.V5 /// public class BybitSocketClientLinearApi : BybitSocketClientBaseApi, IBybitSocketClientLinearApi { + private static readonly MessagePath _reqIdPath = MessagePath.Get().Property("req_id"); + private static readonly MessagePath _topicPath = MessagePath.Get().Property("topic"); + internal BybitSocketClientLinearApi(ILogger log, BybitSocketOptions options) : base(log, options, "/v5/public/linear") { - SendPeriodic("Ping", options.V5Options.PingInterval, (connection) => - { - return new BybitV5RequestMessage("ping", Array.Empty(), ExchangeHelpers.NextId().ToString()); - }); - AddGenericHandler("Heartbeat", (evnt) => { }); - } - - - /// - public Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - => SubscribeToTickerUpdatesAsync(new string[] { symbol }, handler, ct); - - /// - public async Task> SubscribeToTickerUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitLinearTickerUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["topic"]!.ToString().Split('.').Last())); - }); - - return await SubscribeAsync( - BaseAddress + _baseEndpoint, - new BybitV5RequestMessage("subscribe", symbols.Select(s => $"tickers.{s}").ToArray(), ExchangeHelpers.NextId().ToString()), - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - protected override async Task> AuthenticateSocketAsync(SocketConnection socketConnection) - { - if (socketConnection.ApiClient.AuthenticationProvider == null) - return new CallResult(new NoApiCredentialsError()); - - var expireTime = DateTimeConverter.ConvertToMilliseconds(DateTime.UtcNow.AddSeconds(30))!; - var bybitAuthProvider = (BybitAuthenticationProvider)socketConnection.ApiClient.AuthenticationProvider; - var key = bybitAuthProvider.GetApiKey(); - var sign = bybitAuthProvider.Sign($"GET/realtime{expireTime}"); - - var authRequest = new BybitRequestMessage() - { - Operation = "auth", - Parameters = new object[] - { - key, - expireTime, - sign - } - }; - - var result = false; - var error = "unspecified error"; - await socketConnection.SendAndWaitAsync(authRequest, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["op"]?.ToString(); - if (operation != "auth") - return false; - - result = data["success"]?.Value() == true; - error = data["ret_msg"]?.ToString(); - return true; - - }).ConfigureAwait(false); - return result ? new CallResult(result) : new CallResult(new ServerError(error)); + RegisterPeriodicQuery("Heartbeat", TimeSpan.FromSeconds(20), x => new BybitQuery("ping", null), x => { }); } /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => new BybitAuthenticationProvider(credentials); - /// - protected override bool HandleQueryResponse(SocketConnection socketConnection, object request, JToken data, out CallResult callResult) => throw new NotImplementedException(); - /// - protected override bool HandleSubscriptionResponse(SocketConnection socketConnection, SocketSubscription subscription, object request, JToken data, out CallResult? callResult) + public override string? GetListenerIdentifier(IMessageAccessor message) { - callResult = null; - if (data.Type != JTokenType.Object) - return false; - - var messageRequestId = data["req_id"]?.ToString(); - if (messageRequestId != null) - { - // Matched based on request id - var id = ((BybitV5RequestMessage)request).RequestId; - if (id != messageRequestId) - return false; - - var success1 = data["success"]?.Value() == true; - if (success1) - callResult = new CallResult(true); - else - callResult = new CallResult(new ServerError(data["ret_msg"]!.ToString())); - return true; - } - - // No request id - var success = data["success"]?.Value(); - if (success == null) - return false; + var reqId = message.GetValue(_reqIdPath); + if (reqId != null) + return reqId; - callResult = success == true ? new CallResult(true) : new CallResult(new ServerError(data.ToString())); - return true; + return message.GetValue(_topicPath); } /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, object request) - { - if (message.Type != JTokenType.Object) - return false; - - var topic = message["topic"]?.ToString(); - if (topic == null) - return false; - - var requestParams = ((BybitV5RequestMessage)request).Parameters; - if (requestParams.Any(p => topic == p.ToString())) - return true; - - if (topic.Contains('.')) - { - // Some subscriptions have topics like orderbook.ETHUSDT - // Split on `.` to get the topic and symbol - var split = topic.Split('.'); - var symbol = split.Last(); - if (symbol.Length == 0) - return false; - - var mainTopic = topic.Substring(0, topic.Length - symbol.Length - 1); - if (requestParams.Any(p => (string)p == mainTopic + ".*")) - return true; - } - - return false; - } + public Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) + => SubscribeToTickerUpdatesAsync(new string[] { symbol }, handler, ct); /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, string identifier) + public async Task> SubscribeToTickerUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) { - if (identifier == "Heartbeat") - { - if (message.Type != JTokenType.Object) - return false; - - var ret = message["ret_msg"] ?? message["op"]; - if (ret == null) - return false; - - var isPing = ret.ToString() == "pong"; - if (!isPing) - return false; - - return true; - } - - return false; + var subscription = new BybitSubscription(_logger, symbols.Select(x => $"tickers.{x}").ToArray(), handler); + return await SubscribeAsync(BaseAddress + _baseEndpoint, subscription, ct).ConfigureAwait(false); } /// - protected override async Task UnsubscribeAsync(SocketConnection connection, SocketSubscription subscriptionToUnsub) - { - var requestParams = ((BybitV5RequestMessage)subscriptionToUnsub.Request!).Parameters; - var message = new BybitV5RequestMessage("unsubscribe", requestParams, ExchangeHelpers.NextId().ToString()); - - var result = false; - await connection.SendAndWaitAsync(message, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var messageRequestId = data["req_id"]?.ToString(); - if (messageRequestId != null) - { - // Matched based on request id - var id = message.RequestId; - if (id != messageRequestId) - return false; - - return true; - } - - // No request id - var success = data["success"]?.Value(); - if (success == null) - return false; - - return true; - }).ConfigureAwait(false); - return result; - } + protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => new BybitAuthenticationProvider(credentials); } } diff --git a/ByBit.Net/Clients/V5/BybitSocketClientOptionApi.cs b/ByBit.Net/Clients/V5/BybitSocketClientOptionApi.cs index 853d82f8..1005aded 100644 --- a/ByBit.Net/Clients/V5/BybitSocketClientOptionApi.cs +++ b/ByBit.Net/Clients/V5/BybitSocketClientOptionApi.cs @@ -1,14 +1,14 @@ using Bybit.Net.Interfaces.Clients.V5; -using Bybit.Net.Objects.Internal.Socket; using Bybit.Net.Objects.Models.V5; using Bybit.Net.Objects.Options; -using CryptoExchange.Net; +using Bybit.Net.Objects.Sockets.Queries; +using Bybit.Net.Objects.Sockets.Subscriptions; using CryptoExchange.Net.Authentication; -using CryptoExchange.Net.Converters; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects.Sockets; +using CryptoExchange.Net.Sockets.MessageParsing; +using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; @@ -20,215 +20,51 @@ namespace Bybit.Net.Clients.V5 /// public class BybitSocketClientOptionApi : BybitSocketClientBaseApi, IBybitSocketClientOptionApi { + private static readonly MessagePath _typePath = MessagePath.Get().Property("type"); + private static readonly MessagePath _successPath = MessagePath.Get().Property("data").Property("successTopics"); + private static readonly MessagePath _failPath = MessagePath.Get().Property("data").Property("failTopics"); + private static readonly MessagePath _topicPath = MessagePath.Get().Property("topic"); + private static readonly MessagePath _opPath = MessagePath.Get().Property("op"); + internal BybitSocketClientOptionApi(ILogger log, BybitSocketOptions options) : base(log, options, "/v5/public/option") { - SendPeriodic("Ping", options.V5Options.PingInterval, (connection) => - { - return new BybitV5RequestMessage("ping", Array.Empty(), ExchangeHelpers.NextId().ToString()); - }); - AddGenericHandler("Heartbeat", (evnt) => { }); - } - - /// - public Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - => SubscribeToTickerUpdatesAsync(new string[] { symbol }, handler, ct); - - /// - public async Task> SubscribeToTickerUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitLinearTickerUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["topic"]!.ToString().Split('.').Last())); - }); - - return await SubscribeAsync( - BaseAddress + _baseEndpoint, - new BybitV5RequestMessage("subscribe", symbols.Select(s => $"tickers.{s}").ToArray(), ExchangeHelpers.NextId().ToString()), - null, false, internalHandler, ct).ConfigureAwait(false); + RegisterPeriodicQuery("Heartbeat", TimeSpan.FromSeconds(20), x => new BybitPingQuery(), x => { }); } /// - protected override async Task> AuthenticateSocketAsync(SocketConnection socketConnection) + public override string? GetListenerIdentifier(IMessageAccessor message) { - if (socketConnection.ApiClient.AuthenticationProvider == null) - return new CallResult(new NoApiCredentialsError()); - - var expireTime = DateTimeConverter.ConvertToMilliseconds(DateTime.UtcNow.AddSeconds(30))!; - var bybitAuthProvider = (BybitAuthenticationProvider)socketConnection.ApiClient.AuthenticationProvider; - var key = bybitAuthProvider.GetApiKey(); - var sign = bybitAuthProvider.Sign($"GET/realtime{expireTime}"); - - var authRequest = new BybitRequestMessage() - { - Operation = "auth", - Parameters = new object[] - { - key, - expireTime, - sign - } - }; - - var result = false; - var error = "unspecified error"; - await socketConnection.SendAndWaitAsync(authRequest, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["op"]?.ToString(); - if (operation != "auth") - return false; - - result = data["success"]?.Value() == true; - error = data["ret_msg"]?.ToString(); - return true; - - }).ConfigureAwait(false); - return result ? new CallResult(result) : new CallResult(new ServerError(error)); - } - - /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => new BybitAuthenticationProvider(credentials); - /// - protected override bool HandleQueryResponse(SocketConnection socketConnection, object request, JToken data, out CallResult callResult) => throw new NotImplementedException(); - /// - protected override bool HandleSubscriptionResponse(SocketConnection socketConnection, SocketSubscription subscription, object request, JToken data, out CallResult? callResult) - { - callResult = null; - if (data.Type != JTokenType.Object) - return false; - - var messageRequestId = data["req_id"]?.ToString(); - if (messageRequestId != null) + var type = message.GetValue(_typePath); + if (type == "COMMAND_RESP") { - // Matched based on request id - var id = ((BybitV5RequestMessage)request).RequestId; - if (id != messageRequestId) - return false; + var success = message.GetValues(_successPath); + if (success == null) + return null; - var success1 = data["success"]?.Value() == true; - if (success1) - callResult = new CallResult(true); - else - callResult = new CallResult(new ServerError(data["ret_msg"]!.ToString())); - return true; + success.AddRange(message.GetValues(_failPath)); + return "resp" + string.Join("-", success.OrderBy(s => s)); } - // No request id - // Check subs - var success = data["success"]?.Value(); - if (success == null) - return false; - - var topics = data["data"]?["successTopics"]?.ToObject(); - if (topics == null) - return false; + var op = message.GetValue(_opPath); + if (op == "pong") + return "pong"; - var requestTopics = ((BybitV5RequestMessage)request).Parameters; - if (!topics.All(requestTopics.Contains)) - return false; - - callResult = success == true ? new CallResult(true) : new CallResult(new ServerError(data.ToString())); - return true; + return message.GetValue(_topicPath); } /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, object request) - { - if (message.Type != JTokenType.Object) - return false; - - var topic = message["topic"]?.ToString(); - if (topic == null) - return false; - - var requestParams = ((BybitV5RequestMessage)request).Parameters; - if (requestParams.Any(p => topic == p.ToString())) - return true; - - if (topic.Contains('.')) - { - // Some subscriptions have topics like orderbook.ETHUSDT - // Split on `.` to get the topic and symbol - var split = topic.Split('.'); - var symbol = split.Last(); - if (symbol.Length == 0) - return false; - - var mainTopic = topic.Substring(0, topic.Length - symbol.Length - 1); - if (requestParams.Any(p => (string)p == mainTopic + ".*")) - return true; - } - - return false; - } + public Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) + => SubscribeToTickerUpdatesAsync(new string[] { symbol }, handler, ct); /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, string identifier) + public async Task> SubscribeToTickerUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) { - if (identifier == "Heartbeat") - { - if (message.Type != JTokenType.Object) - return false; - - var ret = message["ret_msg"] ?? message["op"]; - if (ret == null) - return false; - - var isPing = ret.ToString() == "pong"; - if (!isPing) - return false; - - return true; - } - - return false; + var subscription = new BybitOptionsSubscription(_logger, symbols.Select(x => $"tickers.{x}").ToArray(), handler); + return await SubscribeAsync(BaseAddress + _baseEndpoint, subscription, ct).ConfigureAwait(false); } /// - protected override async Task UnsubscribeAsync(SocketConnection connection, SocketSubscription subscriptionToUnsub) - { - var requestParams = ((BybitV5RequestMessage)subscriptionToUnsub.Request!).Parameters; - var message = new BybitV5RequestMessage("unsubscribe", requestParams, ExchangeHelpers.NextId().ToString()); - - var result = false; - await connection.SendAndWaitAsync(message, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var messageRequestId = data["req_id"]?.ToString(); - if (messageRequestId != null) - { - // Matched based on request id - var id = message.RequestId; - if (id != messageRequestId) - return false; - - return true; - } - - // No request id - var success = data["success"]?.Value(); - if (success == null) - return false; - - return true; - }).ConfigureAwait(false); - return result; - } + protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => new BybitAuthenticationProvider(credentials); } } diff --git a/ByBit.Net/Clients/V5/BybitSocketClientPrivateApi.cs b/ByBit.Net/Clients/V5/BybitSocketClientPrivateApi.cs index 7ad9faeb..e3b30083 100644 --- a/ByBit.Net/Clients/V5/BybitSocketClientPrivateApi.cs +++ b/ByBit.Net/Clients/V5/BybitSocketClientPrivateApi.cs @@ -1,18 +1,19 @@ using Bybit.Net.Interfaces.Clients.V5; -using Bybit.Net.Objects; -using Bybit.Net.Objects.Internal.Socket; using Bybit.Net.Objects.Models.V5; using Bybit.Net.Objects.Options; +using Bybit.Net.Objects.Sockets.Queries; +using Bybit.Net.Objects.Sockets.Subscriptions; using CryptoExchange.Net; using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Converters; using CryptoExchange.Net.Objects; +using CryptoExchange.Net.Objects.Sockets; using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Sockets.MessageParsing; +using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; -using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -21,315 +22,80 @@ namespace Bybit.Net.Clients.V5 /// public class BybitSocketClientPrivateApi : SocketApiClient, IBybitSocketClientPrivateApi { + private static readonly MessagePath _reqIdPath = MessagePath.Get().Property("req_id"); + private static readonly MessagePath _topicPath = MessagePath.Get().Property("topic"); + internal BybitSocketClientPrivateApi(ILogger logger, BybitSocketOptions options) - : base(logger, ((BybitEnvironment)options.Environment).SocketBaseAddress, options, options.V5Options) + : base(logger, options.Environment.SocketBaseAddress, options, options.V5Options) { - ContinueOnQueryResponse = true; UnhandledMessageExpected = true; KeepAliveInterval = TimeSpan.Zero; - SendPeriodic("Ping", options.V5Options.PingInterval, (connection) => - { - return new BybitV5RequestMessage("ping", Array.Empty(), ExchangeHelpers.NextId().ToString()); - }); - AddGenericHandler("Heartbeat", (evnt) => { }); + RegisterPeriodicQuery("Heartbeat", TimeSpan.FromSeconds(20), x => new BybitQuery("ping", null), x => { }); } /// - public async Task> SubscribeToPositionUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitPositionUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["topic"]!.ToString().Split('.').Last())); - }); - - return await SubscribeAsync( - BaseAddress.AppendPath("/v5/private"), - new BybitV5RequestMessage("subscribe", new[] { "position" }, ExchangeHelpers.NextId().ToString()), - null, true, internalHandler, ct).ConfigureAwait(false); - } - - /// - public async Task> SubscribeToUserTradeUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitUserTradeUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["topic"]!.ToString().Split('.').Last())); - }); - - return await SubscribeAsync( - BaseAddress.AppendPath("/v5/private"), - new BybitV5RequestMessage("subscribe", new[] { "execution" }, ExchangeHelpers.NextId().ToString()), - null, true, internalHandler, ct).ConfigureAwait(false); - } + protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => new BybitAuthenticationProvider(credentials); /// - public async Task> SubscribeToOrderUpdatesAsync(Action>> handler, CancellationToken ct = default) + protected override Query? GetAuthenticationRequest() { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitOrderUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["topic"]!.ToString().Split('.').Last())); - }); - - return await SubscribeAsync( - BaseAddress.AppendPath("/v5/private"), - new BybitV5RequestMessage("subscribe", new[] { "order" }, ExchangeHelpers.NextId().ToString()), - null, true, internalHandler, ct).ConfigureAwait(false); - } + var expireTime = DateTimeConverter.ConvertToMilliseconds(DateTime.UtcNow.AddSeconds(30))!; + var authProvider = (BybitAuthenticationProvider)AuthenticationProvider!; + var key = authProvider.GetApiKey(); + var sign = authProvider.Sign($"GET/realtime{expireTime}"); - /// - public async Task> SubscribeToWalletUpdatesAsync(Action>> handler, CancellationToken ct = default) - { - var internalHandler = new Action>(data => + return new BybitQuery("auth", new object[] { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitBalance)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["topic"]!.ToString().Split('.').Last())); + key, + expireTime, + sign }); - - return await SubscribeAsync( - BaseAddress.AppendPath("/v5/private"), - new BybitV5RequestMessage("subscribe", new[] { "wallet" }, ExchangeHelpers.NextId().ToString()), - null, true, internalHandler, ct).ConfigureAwait(false); } /// - public async Task> SubscribeToGreekUpdatesAsync(Action>> handler, CancellationToken ct = default) + public override string? GetListenerIdentifier(IMessageAccessor message) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitGreeks)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["topic"]!.ToString().Split('.').Last())); - }); + var reqId = message.GetValue(_reqIdPath); + if (reqId != null) + return reqId; - return await SubscribeAsync( - BaseAddress.AppendPath("/v5/private"), - new BybitV5RequestMessage("subscribe", new[] { "greeks" }, ExchangeHelpers.NextId().ToString()), - null, true, internalHandler, ct).ConfigureAwait(false); + return message.GetValue(_topicPath); } /// - protected override async Task> AuthenticateSocketAsync(SocketConnection socketConnection) + public async Task> SubscribeToPositionUpdatesAsync(Action>> handler, CancellationToken ct = default) { - if (socketConnection.ApiClient.AuthenticationProvider == null) - return new CallResult(new NoApiCredentialsError()); - - var expireTime = DateTimeConverter.ConvertToMilliseconds(DateTime.UtcNow.AddSeconds(30))!; - var bybitAuthProvider = (BybitAuthenticationProvider)socketConnection.ApiClient.AuthenticationProvider; - var key = bybitAuthProvider.GetApiKey(); - var sign = bybitAuthProvider.Sign($"GET/realtime{expireTime}"); - - var authRequest = new BybitRequestMessage() - { - Operation = "auth", - Parameters = new object[] - { - key, - expireTime, - sign - } - }; - - var result = false; - var error = "unspecified error"; - await socketConnection.SendAndWaitAsync(authRequest, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["op"]?.ToString(); - if (operation != "auth") - return false; - - result = data["success"]?.Value() == true; - error = data["ret_msg"]?.ToString(); - return true; - - }).ConfigureAwait(false); - return result ? new CallResult(result) : new CallResult(new ServerError(error)); + var subscription = new BybitSubscription>(_logger, new[] { "position" }, handler, true); + return await SubscribeAsync(BaseAddress.AppendPath("/v5/private"), subscription, ct).ConfigureAwait(false); } /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => new BybitAuthenticationProvider(credentials); - /// - protected override bool HandleQueryResponse(SocketConnection socketConnection, object request, JToken data, out CallResult callResult) => throw new NotImplementedException(); - /// - protected override bool HandleSubscriptionResponse(SocketConnection socketConnection, SocketSubscription subscription, object request, JToken data, out CallResult? callResult) + public async Task> SubscribeToUserTradeUpdatesAsync(Action>> handler, CancellationToken ct = default) { - callResult = null; - if (data.Type != JTokenType.Object) - return false; - - var messageRequestId = data["req_id"]?.ToString(); - if (messageRequestId != null) - { - // Matched based on request id - var id = ((BybitV5RequestMessage)request).RequestId; - if (id != messageRequestId) - return false; - - var success1 = data["success"]?.Value() == true; - if (success1) - callResult = new CallResult(true); - else - callResult = new CallResult(new ServerError(data["ret_msg"]!.ToString())); - return true; - } - - // No request id - // Check subs - var success = data["success"]?.Value(); - if (success == null) - return false; - - var topics = data["data"]?["successTopics"]?.ToObject(); - if (topics == null) - return false; - - var requestTopics = ((BybitV5RequestMessage)request).Parameters; - if (!topics.All(requestTopics.Contains)) - return false; - - callResult = success == true ? new CallResult(true) : new CallResult(new ServerError(data.ToString())); - return true; + var subscription = new BybitSubscription>(_logger, new[] { "execution" }, handler, true); + return await SubscribeAsync(BaseAddress.AppendPath("/v5/private"), subscription, ct).ConfigureAwait(false); } /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, object request) + public async Task> SubscribeToOrderUpdatesAsync(Action>> handler, CancellationToken ct = default) { - if (message.Type != JTokenType.Object) - return false; - - var topic = message["topic"]?.ToString(); - if (topic == null) - return false; - - var requestParams = ((BybitV5RequestMessage)request).Parameters; - if (requestParams.Any(p => topic == p.ToString())) - return true; - - if (topic.Contains('.')) - { - // Some subscriptions have topics like orderbook.ETHUSDT - // Split on `.` to get the topic and symbol - var split = topic.Split('.'); - var symbol = split.Last(); - if (symbol.Length == 0) - return false; - - var mainTopic = topic.Substring(0, topic.Length - symbol.Length - 1); - if (requestParams.Any(p => (string)p == mainTopic + ".*")) - return true; - } - - return false; + var subscription = new BybitSubscription>(_logger, new[] { "order" }, handler, true); + return await SubscribeAsync(BaseAddress.AppendPath("/v5/private"), subscription, ct).ConfigureAwait(false); } /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, string identifier) + public async Task> SubscribeToWalletUpdatesAsync(Action>> handler, CancellationToken ct = default) { - if (identifier == "Heartbeat") - { - if (message.Type != JTokenType.Object) - return false; - - var ret = message["ret_msg"] ?? message["op"]; - if (ret == null) - return false; - - var isPing = ret.ToString() == "pong"; - if (!isPing) - return false; - - return true; - } - - return false; + var subscription = new BybitSubscription>(_logger, new[] { "wallet" }, handler, true); + return await SubscribeAsync(BaseAddress.AppendPath("/v5/private"), subscription, ct).ConfigureAwait(false); } /// - protected override async Task UnsubscribeAsync(SocketConnection connection, SocketSubscription subscriptionToUnsub) + public async Task> SubscribeToGreekUpdatesAsync(Action>> handler, CancellationToken ct = default) { - var requestParams = ((BybitV5RequestMessage)subscriptionToUnsub.Request!).Parameters; - var message = new BybitV5RequestMessage("unsubscribe", requestParams, ExchangeHelpers.NextId().ToString()); - - var result = false; - await connection.SendAndWaitAsync(message, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var messageRequestId = data["req_id"]?.ToString(); - if (messageRequestId != null) - { - // Matched based on request id - var id = message.RequestId; - if (id != messageRequestId) - return false; - - return true; - } - - // No request id - var success = data["success"]?.Value(); - if (success == null) - return false; - - return true; - }).ConfigureAwait(false); - return result; + var subscription = new BybitSubscription>(_logger, new[] { "greeks" }, handler, true); + return await SubscribeAsync(BaseAddress.AppendPath("/v5/private"), subscription, ct).ConfigureAwait(false); } } } diff --git a/ByBit.Net/Clients/V5/BybitSocketClientSpotApi.cs b/ByBit.Net/Clients/V5/BybitSocketClientSpotApi.cs index 4c324711..ba34eff0 100644 --- a/ByBit.Net/Clients/V5/BybitSocketClientSpotApi.cs +++ b/ByBit.Net/Clients/V5/BybitSocketClientSpotApi.cs @@ -1,16 +1,16 @@ using Bybit.Net.Enums; using Bybit.Net.Interfaces.Clients.V5; -using Bybit.Net.Objects; -using Bybit.Net.Objects.Internal.Socket; using Bybit.Net.Objects.Models.V5; using Bybit.Net.Objects.Options; -using CryptoExchange.Net; +using Bybit.Net.Objects.Sockets.Queries; +using Bybit.Net.Objects.Sockets.Subscriptions; using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Converters; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects.Sockets; +using CryptoExchange.Net.Sockets.MessageParsing; +using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; @@ -22,43 +22,37 @@ namespace Bybit.Net.Clients.V5 /// public class BybitSocketClientSpotApi : BybitSocketClientBaseApi, IBybitSocketClientSpotApi { + private static readonly MessagePath _reqIdPath = MessagePath.Get().Property("req_id"); + private static readonly MessagePath _topicPath = MessagePath.Get().Property("topic"); + internal BybitSocketClientSpotApi(ILogger logger, BybitSocketOptions options) : base(logger, options, "/v5/public/spot") { - SendPeriodic("Ping", options.V5Options.PingInterval, (connection) => - { - return new BybitV5RequestMessage("ping", Array.Empty(), ExchangeHelpers.NextId().ToString()); - }); - AddGenericHandler("Heartbeat", (evnt) => { }); + RegisterPeriodicQuery("Heartbeat", TimeSpan.FromSeconds(20), x => new BybitQuery("ping", null), x => { }); } /// - public Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) - => SubscribeToTickerUpdatesAsync(new string[] { symbol }, handler, ct); + protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => new BybitAuthenticationProvider(credentials); /// - public async Task> SubscribeToTickerUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) + public override string? GetListenerIdentifier(IMessageAccessor message) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; + var reqId = message.GetValue(_reqIdPath); + if (reqId != null) + return reqId; - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitSpotTickerUpdate)} object: " + desResult.Error); - return; - } + return message.GetValue(_topicPath); + } - handler(data.As(desResult.Data, data.Data["topic"]!.ToString().Split('.').Last())); - }); + /// + public Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default) + => SubscribeToTickerUpdatesAsync(new string[] { symbol }, handler, ct); - return await SubscribeAsync( - BaseAddress + _baseEndpoint, - new BybitV5RequestMessage("subscribe", symbols.Select(s => $"tickers.{s}").ToArray(), ExchangeHelpers.NextId().ToString()), - null, false, internalHandler, ct).ConfigureAwait(false); + /// + public async Task> SubscribeToTickerUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) + { + var subscription = new BybitSubscription(_logger, symbols.Select(x => "tickers." + x).ToArray(), handler); + return await SubscribeAsync(BaseAddress + _baseEndpoint, subscription, ct).ConfigureAwait(false); } /// @@ -68,26 +62,8 @@ public Task> SubscribeToLeveragedTokenKlineUpdate /// public async Task> SubscribeToLeveragedTokenKlineUpdatesAsync(IEnumerable symbols, KlineInterval interval, Action>> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize>(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitKlineUpdate)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["topic"]!.ToString().Split('.').Last())); - }); - - return await SubscribeAsync( - BaseAddress + _baseEndpoint, - new BybitV5RequestMessage("subscribe", symbols.Select(s => $"kline_lt.{EnumConverter.GetString(interval)}.{s}").ToArray(), ExchangeHelpers.NextId().ToString()), - null, false, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription>(_logger, symbols.Select(x => $"kline_lt.{EnumConverter.GetString(interval)}.{x}").ToArray(), handler); + return await SubscribeAsync(BaseAddress + _baseEndpoint, subscription, ct).ConfigureAwait(false); } /// @@ -97,26 +73,8 @@ public Task> SubscribeToLeveragedTokenTickerUpdat /// public async Task> SubscribeToLeveragedTokenTickerUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitLeveragedTokenTicker)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["topic"]!.ToString().Split('.').Last())); - }); - - return await SubscribeAsync( - BaseAddress + _baseEndpoint, - new BybitV5RequestMessage("subscribe", symbols.Select(s => $"tickers_lt.{s}").ToArray(), ExchangeHelpers.NextId().ToString()), - null, false, internalHandler, ct).ConfigureAwait(false); + var subscription = new BybitSubscription(_logger, symbols.Select(x => $"tickers_lt.{x}").ToArray(), handler); + return await SubscribeAsync(BaseAddress + _baseEndpoint, subscription, ct).ConfigureAwait(false); } /// @@ -126,189 +84,8 @@ public Task> SubscribeToLeveragedTokenNavUpdatesA /// public async Task> SubscribeToLeveragedTokenNavUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default) { - var internalHandler = new Action>(data => - { - var internalData = data.Data["data"]; - if (internalData == null) - return; - - var desResult = Deserialize(internalData); - if (!desResult) - { - _logger.Log(LogLevel.Warning, $"Failed to deserialize {nameof(BybitLeveragedTokenNav)} object: " + desResult.Error); - return; - } - - handler(data.As(desResult.Data, data.Data["topic"]!.ToString().Split('.').Last())); - }); - - return await SubscribeAsync( - BaseAddress + _baseEndpoint, - new BybitV5RequestMessage("subscribe", symbols.Select(s => $"lt.{s}").ToArray(), ExchangeHelpers.NextId().ToString()), - null, false, internalHandler, ct).ConfigureAwait(false); - } - - /// - protected override async Task> AuthenticateSocketAsync(SocketConnection socketConnection) - { - if (socketConnection.ApiClient.AuthenticationProvider == null) - return new CallResult(new NoApiCredentialsError()); - - var expireTime = DateTimeConverter.ConvertToMilliseconds(DateTime.UtcNow.AddSeconds(30))!; - var bybitAuthProvider = (BybitAuthenticationProvider)socketConnection.ApiClient.AuthenticationProvider; - var key = bybitAuthProvider.GetApiKey(); - var sign = bybitAuthProvider.Sign($"GET/realtime{expireTime}"); - - var authRequest = new BybitRequestMessage() - { - Operation = "auth", - Parameters = new object[] - { - key, - expireTime, - sign - } - }; - - var result = false; - var error = "unspecified error"; - await socketConnection.SendAndWaitAsync(authRequest, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var operation = data["op"]?.ToString(); - if (operation != "auth") - return false; - - result = data["success"]?.Value() == true; - error = data["ret_msg"]?.ToString(); - return true; - - }).ConfigureAwait(false); - return result ? new CallResult(result) : new CallResult(new ServerError(error)); - } - - /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => new BybitAuthenticationProvider(credentials); - /// - protected override bool HandleQueryResponse(SocketConnection socketConnection, object request, JToken data, out CallResult callResult) => throw new NotImplementedException(); - /// - protected override bool HandleSubscriptionResponse(SocketConnection socketConnection, SocketSubscription subscription, object request, JToken data, out CallResult? callResult) - { - callResult = null; - if (data.Type != JTokenType.Object) - return false; - - var messageRequestId = data["req_id"]?.ToString(); - if (messageRequestId != null) - { - // Matched based on request id - var id = ((BybitV5RequestMessage)request).RequestId; - if (id != messageRequestId) - return false; - - var success1 = data["success"]?.Value() == true; - if (success1) - callResult = new CallResult(true); - else - callResult = new CallResult(new ServerError(data["ret_msg"]!.ToString())); - return true; - } - - // No request id - var success = data["success"]?.Value(); - if (success == null) - return false; - - callResult = success == true ? new CallResult(true) : new CallResult(new ServerError(data.ToString())); - return true; - } - - /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, object request) - { - if (message.Type != JTokenType.Object) - return false; - - var topic = message["topic"]?.ToString(); - if (topic == null) - return false; - - var requestParams = ((BybitV5RequestMessage)request).Parameters; - if (requestParams.Any(p => topic == p.ToString())) - return true; - - if (topic.Contains('.')) - { - // Some subscriptions have topics like orderbook.ETHUSDT - // Split on `.` to get the topic and symbol - var split = topic.Split('.'); - var symbol = split.Last(); - if (symbol.Length == 0) - return false; - - var mainTopic = topic.Substring(0, topic.Length - symbol.Length - 1); - if (requestParams.Any(p => (string)p == mainTopic + ".*")) - return true; - } - - return false; - } - - /// - protected override bool MessageMatchesHandler(SocketConnection socketConnection, JToken message, string identifier) - { - if (identifier == "Heartbeat") - { - if (message.Type != JTokenType.Object) - return false; - - var ret = message["ret_msg"] ?? message["op"]; - if (ret == null) - return false; - - var isPing = ret.ToString() == "pong"; - if (!isPing) - return false; - - return true; - } - - return false; - } - - /// - protected override async Task UnsubscribeAsync(SocketConnection connection, SocketSubscription subscriptionToUnsub) - { - var requestParams = ((BybitV5RequestMessage)subscriptionToUnsub.Request!).Parameters; - var message = new BybitV5RequestMessage("unsubscribe", requestParams, ExchangeHelpers.NextId().ToString()); - - var result = false; - await connection.SendAndWaitAsync(message, ClientOptions.RequestTimeout, null, 1, data => - { - if (data.Type != JTokenType.Object) - return false; - - var messageRequestId = data["req_id"]?.ToString(); - if (messageRequestId != null) - { - // Matched based on request id - var id = message.RequestId; - if (id != messageRequestId) - return false; - - return true; - } - - // No request id - var success = data["success"]?.Value(); - if (success == null) - return false; - - return true; - }).ConfigureAwait(false); - return result; + var subscription = new BybitSubscription(_logger, symbols.Select(x => $"lt.{x}").ToArray(), handler); + return await SubscribeAsync(BaseAddress + _baseEndpoint, subscription, ct).ConfigureAwait(false); } } } diff --git a/ByBit.Net/Enums/CancelType.cs b/ByBit.Net/Enums/CancelType.cs index 466a8047..f3f58574 100644 --- a/ByBit.Net/Enums/CancelType.cs +++ b/ByBit.Net/Enums/CancelType.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Bybit.Net.Enums +namespace Bybit.Net.Enums { /// /// Cancel type diff --git a/ByBit.Net/Enums/SubAccountStatus.cs b/ByBit.Net/Enums/SubAccountStatus.cs index f0ee4cf6..24d03484 100644 --- a/ByBit.Net/Enums/SubAccountStatus.cs +++ b/ByBit.Net/Enums/SubAccountStatus.cs @@ -1,7 +1,4 @@ using CryptoExchange.Net.Attributes; -using System; -using System.Collections.Generic; -using System.Text; namespace Bybit.Net.Enums { diff --git a/ByBit.Net/Enums/V5/PositionIdx.cs b/ByBit.Net/Enums/V5/PositionIdx.cs index dc347d67..4cf124d8 100644 --- a/ByBit.Net/Enums/V5/PositionIdx.cs +++ b/ByBit.Net/Enums/V5/PositionIdx.cs @@ -1,7 +1,4 @@ using CryptoExchange.Net.Attributes; -using System; -using System.Collections.Generic; -using System.Text; namespace Bybit.Net.Enums.V5 { diff --git a/ByBit.Net/ExtensionMethods/CryptoClientExtensions.cs b/ByBit.Net/ExtensionMethods/CryptoClientExtensions.cs new file mode 100644 index 00000000..578b1e96 --- /dev/null +++ b/ByBit.Net/ExtensionMethods/CryptoClientExtensions.cs @@ -0,0 +1,25 @@ +using Bybit.Net.Clients; +using Bybit.Net.Interfaces.Clients; + +namespace CryptoExchange.Net.Interfaces +{ + /// + /// Extensions for the ICryptoRestClient and ICryptoSocketClient interfaces + /// + public static class CryptoClientExtensions + { + /// + /// Get the Bybit REST Api client + /// + /// + /// + public static IBybitRestClient Bybit(this ICryptoRestClient baseClient) => baseClient.TryGet(() => new BybitRestClient()); + + /// + /// Get the Bybit Websocket Api client + /// + /// + /// + public static IBybitSocketClient Bybit(this ICryptoSocketClient baseClient) => baseClient.TryGet(() => new BybitSocketClient()); + } +} diff --git a/ByBit.Net/BybitHelpers.cs b/ByBit.Net/ExtensionMethods/ServiceCollectionExtensions.cs similarity index 89% rename from ByBit.Net/BybitHelpers.cs rename to ByBit.Net/ExtensionMethods/ServiceCollectionExtensions.cs index 8ab9f9ea..74da1bbf 100644 --- a/ByBit.Net/BybitHelpers.cs +++ b/ByBit.Net/ExtensionMethods/ServiceCollectionExtensions.cs @@ -1,20 +1,20 @@ using Bybit.Net.Clients; +using Bybit.Net.Interfaces; using Bybit.Net.Interfaces.Clients; -using Bybit.Net.Objects; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Net.Http; -using System.Net; using Bybit.Net.Objects.Options; -using Bybit.Net.Interfaces; using Bybit.Net.SymbolOrderBooks; +using CryptoExchange.Net.Clients; +using CryptoExchange.Net.Interfaces; +using System; +using System.Net; +using System.Net.Http; -namespace Bybit.Net +namespace Microsoft.Extensions.DependencyInjection { /// - /// Helpers + /// Extensions for DI /// - public static class BybitHelpers + public static class ServiceCollectionExtensions { /// /// Add the IBybitClient and IBybitSocketClient to the sevice collection so they can be injected @@ -57,8 +57,9 @@ public static IServiceCollection AddBybit( return handler; }); + services.AddTransient(); + services.AddTransient(); services.AddSingleton(); - services.AddTransient(); services.AddTransient(x => x.GetRequiredService().V5Api.CommonSpotClient); if (socketClientLifeTime == null) services.AddSingleton(); diff --git a/ByBit.Net/Interfaces/Clients/CopyTradingApi/IBybitSocketClientCopyTradingApi.cs b/ByBit.Net/Interfaces/Clients/CopyTradingApi/IBybitSocketClientCopyTradingApi.cs deleted file mode 100644 index b55dd5d0..00000000 --- a/ByBit.Net/Interfaces/Clients/CopyTradingApi/IBybitSocketClientCopyTradingApi.cs +++ /dev/null @@ -1,53 +0,0 @@ -using Bybit.Net.Objects.Models.CopyTrading; -using CryptoExchange.Net.Interfaces; -using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.UsdPerpetualApi -{ - /// - /// Bybit copy trading streams - /// - public interface IBybitSocketClientCopyTradingApi: ISocketApiClient - { - /// - /// Subscribe to user position updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToPositionUpdatesAsync(Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to user trade updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToUserTradeUpdatesAsync(Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to user order updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderUpdatesAsync(Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to user balance updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToBalanceUpdatesAsync(Action> handler, CancellationToken ct = default); - } -} diff --git a/ByBit.Net/Interfaces/Clients/DerivativesApi/ContractApi/IBybitRestClientContractApi.cs b/ByBit.Net/Interfaces/Clients/DerivativesApi/ContractApi/IBybitRestClientContractApi.cs index 562d812d..a3ae77de 100644 --- a/ByBit.Net/Interfaces/Clients/DerivativesApi/ContractApi/IBybitRestClientContractApi.cs +++ b/ByBit.Net/Interfaces/Clients/DerivativesApi/ContractApi/IBybitRestClientContractApi.cs @@ -1,6 +1,4 @@ -using CryptoExchange.Net.Interfaces; - -namespace Bybit.Net.Interfaces.Clients.DerivativesApi.ContractApi +namespace Bybit.Net.Interfaces.Clients.DerivativesApi.ContractApi { /// /// Bybit contract API endpoints diff --git a/ByBit.Net/Interfaces/Clients/DerivativesApi/ContractApi/IBybitSocketClientContractApi.cs b/ByBit.Net/Interfaces/Clients/DerivativesApi/ContractApi/IBybitSocketClientContractApi.cs index b85e26c8..fce27e90 100644 --- a/ByBit.Net/Interfaces/Clients/DerivativesApi/ContractApi/IBybitSocketClientContractApi.cs +++ b/ByBit.Net/Interfaces/Clients/DerivativesApi/ContractApi/IBybitSocketClientContractApi.cs @@ -1,7 +1,7 @@ using Bybit.Net.Objects.Models.Socket.Derivatives.Contract; using CryptoExchange.Net.Interfaces; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects.Sockets; using System; using System.Collections.Generic; using System.Threading; diff --git a/ByBit.Net/Interfaces/Clients/DerivativesApi/IBybitSocketClientDerivativesPublicApi.cs b/ByBit.Net/Interfaces/Clients/DerivativesApi/IBybitSocketClientDerivativesPublicApi.cs index dbfbb0eb..34fe12ed 100644 --- a/ByBit.Net/Interfaces/Clients/DerivativesApi/IBybitSocketClientDerivativesPublicApi.cs +++ b/ByBit.Net/Interfaces/Clients/DerivativesApi/IBybitSocketClientDerivativesPublicApi.cs @@ -3,7 +3,7 @@ using Bybit.Net.Objects.Models.Socket.Derivatives; using CryptoExchange.Net.Interfaces; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects.Sockets; using System; using System.Collections.Generic; using System.Threading; @@ -22,12 +22,11 @@ public interface IBybitSocketClientDerivativesPublicApi : ISocketApiClient /// /// Asset category /// The amount of rows to receive updates for. Either 1, 25, 50, 100, 200. - /// The event handler for the snapshot messages - /// The event handler for the update messages + /// The event handler for the messages /// The symbol to receive updates for /// Cancellation token for closing this subscription /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderBookUpdatesAsync(StreamDerivativesCategory category, string symbol, int limit, Action> snapshotHandler, Action> deltaHandler, CancellationToken ct = default); + Task> SubscribeToOrderBookUpdatesAsync(StreamDerivativesCategory category, string symbol, int limit, Action> handler, CancellationToken ct = default); /// /// Subscribe to orderbook updates @@ -35,12 +34,11 @@ public interface IBybitSocketClientDerivativesPublicApi : ISocketApiClient /// /// Asset category /// The amount of rows to receive updates for. Either 1, 25, 50, 100, 200. - /// The event handler for the snapshot messages - /// The event handler for the update messages + /// The event handler for the messages /// List of symbols to receive updates for /// Cancellation token for closing this subscription /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderBooksUpdatesAsync(StreamDerivativesCategory category, IEnumerable symbols, int limit, Action> snapshotHandler, Action> deltaHandler, CancellationToken ct = default); + Task> SubscribeToOrderBooksUpdatesAsync(StreamDerivativesCategory category, IEnumerable symbols, int limit, Action> handler, CancellationToken ct = default); /// /// Subscribe to public trade updates @@ -71,11 +69,10 @@ public interface IBybitSocketClientDerivativesPublicApi : ISocketApiClient /// /// Asset category /// The symbol to receive updates for - /// Snapshot handler - /// Update handler + /// Data handler /// Cancellation token for closing this subscription /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTickerUpdatesAsync(StreamDerivativesCategory category, string symbol, Action> snapshotHandler, Action> updateHandler, CancellationToken ct = default); + Task> SubscribeToTickerUpdatesAsync(StreamDerivativesCategory category, string symbol, Action> handler, CancellationToken ct = default); /// /// Subscribe to ticker updates. Note that for a symbol the first update is a snapshot, containing all info. After that only partial updates are given for @@ -84,11 +81,10 @@ public interface IBybitSocketClientDerivativesPublicApi : ISocketApiClient /// /// Asset category /// List of symbols to receive updates for - /// Snapshot handler - /// Update handler + /// Data handler /// Cancellation token for closing this subscription /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTickersUpdatesAsync(StreamDerivativesCategory category, IEnumerable symbols, Action> snapshotHandler, Action> updateHandler, CancellationToken ct = default); + Task> SubscribeToTickersUpdatesAsync(StreamDerivativesCategory category, IEnumerable symbols, Action> handler, CancellationToken ct = default); /// /// Subscribe to kline (candlestick) updates diff --git a/ByBit.Net/Interfaces/Clients/DerivativesApi/UnifiedMarginApi/IBybitRestClientUnifiedMarginApi.cs b/ByBit.Net/Interfaces/Clients/DerivativesApi/UnifiedMarginApi/IBybitRestClientUnifiedMarginApi.cs index cb40ffdd..1f93a297 100644 --- a/ByBit.Net/Interfaces/Clients/DerivativesApi/UnifiedMarginApi/IBybitRestClientUnifiedMarginApi.cs +++ b/ByBit.Net/Interfaces/Clients/DerivativesApi/UnifiedMarginApi/IBybitRestClientUnifiedMarginApi.cs @@ -1,6 +1,4 @@ -using CryptoExchange.Net.Interfaces; - -namespace Bybit.Net.Interfaces.Clients.DerivativesApi.UnifiedMarginApi +namespace Bybit.Net.Interfaces.Clients.DerivativesApi.UnifiedMarginApi { /// /// Bybit Unified Margin API endpoints diff --git a/ByBit.Net/Interfaces/Clients/DerivativesApi/UnifiedMarginApi/IBybitSocketClientUnifiedMarginApi.cs b/ByBit.Net/Interfaces/Clients/DerivativesApi/UnifiedMarginApi/IBybitSocketClientUnifiedMarginApi.cs index d9c1bb0a..f680055e 100644 --- a/ByBit.Net/Interfaces/Clients/DerivativesApi/UnifiedMarginApi/IBybitSocketClientUnifiedMarginApi.cs +++ b/ByBit.Net/Interfaces/Clients/DerivativesApi/UnifiedMarginApi/IBybitSocketClientUnifiedMarginApi.cs @@ -4,7 +4,7 @@ using Bybit.Net.Objects.Models.Socket.Derivatives.UnifiedMargin; using CryptoExchange.Net.Interfaces; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects.Sockets; using System; using System.Collections.Generic; using System.Threading; diff --git a/ByBit.Net/Interfaces/Clients/IBybitSocketClient.cs b/ByBit.Net/Interfaces/Clients/IBybitSocketClient.cs index d5adb507..469c22a0 100644 --- a/ByBit.Net/Interfaces/Clients/IBybitSocketClient.cs +++ b/ByBit.Net/Interfaces/Clients/IBybitSocketClient.cs @@ -1,9 +1,6 @@ using Bybit.Net.Interfaces.Clients.DerivativesApi; using Bybit.Net.Interfaces.Clients.DerivativesApi.ContractApi; using Bybit.Net.Interfaces.Clients.DerivativesApi.UnifiedMarginApi; -using Bybit.Net.Interfaces.Clients.InversePerpetualApi; -using Bybit.Net.Interfaces.Clients.SpotApi.v1; -using Bybit.Net.Interfaces.Clients.SpotApi.v2; using Bybit.Net.Interfaces.Clients.SpotApi.v3; using Bybit.Net.Interfaces.Clients.UsdPerpetualApi; using Bybit.Net.Interfaces.Clients.V5; @@ -17,31 +14,11 @@ namespace Bybit.Net.Interfaces.Clients /// public interface IBybitSocketClient : ISocketClient { - /// - /// USD perpetual streams - /// - public IBybitSocketClientUsdPerpetualApi UsdPerpetualApi { get; } - /// - /// Spot streams v1 - /// - public IBybitSocketClientSpotApiV1 SpotV1Api { get; } - /// - /// Spot streams v2 - /// - public IBybitSocketClientSpotApiV2 SpotV2Api { get; } /// /// Spot streams v3 /// public IBybitSocketClientSpotApiV3 SpotV3Api { get; } /// - /// Inverse perpetual streams - /// - public IBybitSocketClientInversePerpetualApi InversePerpetualApi { get; } - /// - /// Copy trading streams - /// - public IBybitSocketClientCopyTradingApi CopyTradingApi { get; } - /// /// Derivatives public streams /// public IBybitSocketClientDerivativesPublicApi DerivativesApi { get; } diff --git a/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitSocketClientInversePerpetualApi.cs b/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitSocketClientInversePerpetualApi.cs deleted file mode 100644 index ec7b5bcc..00000000 --- a/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitSocketClientInversePerpetualApi.cs +++ /dev/null @@ -1,258 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Models; -using Bybit.Net.Objects.Models.Socket; -using CryptoExchange.Net.Interfaces; -using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.InversePerpetualApi -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 16/30 OCTOBER, USE V5 API INSTEAD] Bybit inverse perpetual streams - /// - public interface IBybitSocketClientInversePerpetualApi : ISocketApiClient - { - /// - /// Subscribe to public trade updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTradesUpdatesAsync(Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to public trade updates - /// - /// - /// The symbol to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTradeUpdatesAsync(string symbol, Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to public trade updates - /// - /// - /// The symbols to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTradeUpdatesAsync(IEnumerable symbols, Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to ticker updates. Note that for a symbol the first update is a snapshot, containing all info. After that only partial updates are given for - /// properties which have changed. If a property in the update is `null` it isn't changed and should be ignored. - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTickersUpdatesAsync(Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to ticker updates. Note that for a symbol the first update is a snapshot, containing all info. After that only partial updates are given for - /// properties which have changed. If a property in the update is `null` it isn't changed and should be ignored. - /// - /// - /// The symbol to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to ticker updates. Note that for a symbol the first update is a snapshot, containing all info. After that only partial updates are given for - /// properties which have changed. If a property in the update is `null` it isn't changed and should be ignored. - /// - /// - /// The symbols to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTickerUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to orderbook updates - /// - /// - /// - /// The amount of rows to receive updates for. Either 25 or 200. - /// The event handler for the initial snapshot data - /// The event handler for the update messages - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderBooksUpdatesAsync(int limit, Action>> snapshotHandler, Action>> updateHandler, CancellationToken ct = default); - - /// - /// Subscribe to orderbook updates - /// - /// - /// - /// The amount of rows to receive updates for. Either 25 or 200. - /// The symbol to receive updates for - /// The event handler for the initial snapshot data - /// The event handler for the update messages - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderBookUpdatesAsync(string symbol, int limit, Action>> snapshotHandler, Action>> updateHandler, CancellationToken ct = default); - - /// - /// Subscribe to orderbook updates - /// - /// - /// - /// The amount of rows to receive updates for. Either 25 or 200. - /// The symbols to receive updates for - /// The event handler for the initial snapshot data - /// The event handler for the update messages - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderBookUpdatesAsync( - IEnumerable symbols, - int limit, - Action>> snapshotHandler, - Action>> updateHandler, - CancellationToken ct = default); - - /// - /// Subscribe to insurance fund updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToInsurancesUpdatesAsync(Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to insurance fund updates - /// - /// - /// The symbol to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToInsuranceUpdatesAsync(string symbol, Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to insurance fund updates - /// - /// - /// The symbols to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToInsuranceUpdatesAsync(IEnumerable symbols, Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to kline (candlestick) updates - /// - /// - /// The interval of the klines - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToKlinesUpdatesAsync(KlineInterval interval, Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to kline (candlestick) updates - /// - /// - /// The interval of the klines - /// The symbol to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToKlineUpdatesAsync(string symbol, KlineInterval interval, Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to kline (candlestick) updates - /// - /// - /// The interval of the klines - /// The symbols to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToKlineUpdatesAsync(IEnumerable symbols, KlineInterval interval, Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to liquidation order updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToLiquidationsUpdatesAsync(Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to liquidation order updates - /// - /// - /// The symbol to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToLiquidationUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to liquidation order updates - /// - /// - /// The symbols to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToLiquidationUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to user position updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToPositionUpdatesAsync(Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to user trade updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToUserTradeUpdatesAsync(Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to user order updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderUpdatesAsync(Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to user stop order updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToStopOrderUpdatesAsync(Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to user balance updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToBalanceUpdatesAsync(Action>> handler, CancellationToken ct = default); - } -} diff --git a/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiAccountV1.cs b/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiAccountV1.cs index 8258eeae..ab8c681b 100644 --- a/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiAccountV1.cs +++ b/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiAccountV1.cs @@ -1,5 +1,4 @@ using Bybit.Net.Objects.Models.Spot; -using CryptoExchange.Net.Interfaces; using CryptoExchange.Net.Objects; using System.Collections.Generic; using System.Threading; diff --git a/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitSocketClientSpotApiV1.cs b/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitSocketClientSpotApiV1.cs deleted file mode 100644 index 7730cd2b..00000000 --- a/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitSocketClientSpotApiV1.cs +++ /dev/null @@ -1,89 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Models.Socket.Spot; -using CryptoExchange.Net.Interfaces; -using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.SpotApi.v1 -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 16 OCTOBER, USE V5 API INSTEAD] Bybit spot streams - /// - public interface IBybitSocketClientSpotApiV1 : ISocketApiClient - { - /// - /// Subscribe to public trade updates - /// - /// - /// The symbol - /// Data handler - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTradeUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to order book updates - /// - /// - /// The symbol - /// Data handler - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderBookUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to kline updates - /// - /// - /// The symbol - /// Interval of the kline data - /// Data handler - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToKlineUpdatesAsync(string symbol, KlineInterval interval, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to ticker updates - /// - /// - /// The symbol - /// Data handler - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to aggregated order book updates - /// - /// - /// The symbol - /// It refers to the number of decimal places, eg 1 for 50000.5 or 0 for 50000 - /// Data handler - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderBookMergedUpdatesAsync(string symbol, int dumpScale, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to diff of order book updates - /// - /// - /// The symbol - /// Data handler - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderBookDiffUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to leverage token net value updates - /// - /// - /// The symbol - /// Data handler - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToLeverageTokenUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default); - } -} diff --git a/ByBit.Net/Interfaces/Clients/SpotApi/v2/IBybitSocketClientSpotApiV2.cs b/ByBit.Net/Interfaces/Clients/SpotApi/v2/IBybitSocketClientSpotApiV2.cs deleted file mode 100644 index de6dc7ab..00000000 --- a/ByBit.Net/Interfaces/Clients/SpotApi/v2/IBybitSocketClientSpotApiV2.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Models.Socket.Spot; -using Bybit.Net.Objects.Models.Spot.v1; -using CryptoExchange.Net.Interfaces; -using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.SpotApi.v2 -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 16/30 OCTOBER, USE V5 API INSTEAD] Bybit spot streams - /// - public interface IBybitSocketClientSpotApiV2 : ISocketApiClient - { - /// - /// Subscribe to public trade updates - /// - /// - /// The symbol - /// Data handler - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTradeUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to order book updates - /// - /// - /// The symbol - /// Data handler - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderBookUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to kline updates - /// - /// - /// The symbol - /// Interval of the kline data - /// Data handler - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToKlineUpdatesAsync(string symbol, KlineInterval interval, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to book price updates - /// - /// - /// The symbol - /// Data handler - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToBookPriceUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to ticker updates - /// - /// - /// The symbol - /// Data handler - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to account data updates - /// - /// - /// Account(balance) update handler - /// Order update handler - /// SL/TP order update handler - /// User trade update handler - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToAccountUpdatesAsync( - Action> accountUpdateHandler, - Action> orderUpdateHandler, - Action> stopOrderUpdateHandler, - Action> tradeUpdateHandler, - CancellationToken ct = default); - } -} diff --git a/ByBit.Net/Interfaces/Clients/SpotApi/v3/IBybitRestClientSpotApiAccountV3.cs b/ByBit.Net/Interfaces/Clients/SpotApi/v3/IBybitRestClientSpotApiAccountV3.cs index 1c08f0f8..e4e77366 100644 --- a/ByBit.Net/Interfaces/Clients/SpotApi/v3/IBybitRestClientSpotApiAccountV3.cs +++ b/ByBit.Net/Interfaces/Clients/SpotApi/v3/IBybitRestClientSpotApiAccountV3.cs @@ -1,5 +1,4 @@ using Bybit.Net.Objects.Models.Spot; -using CryptoExchange.Net.Interfaces; using CryptoExchange.Net.Objects; using System.Collections.Generic; using System.Threading; diff --git a/ByBit.Net/Interfaces/Clients/SpotApi/v3/IBybitSocketClientSpotApiV3.cs b/ByBit.Net/Interfaces/Clients/SpotApi/v3/IBybitSocketClientSpotApiV3.cs index a48c4baf..4865240e 100644 --- a/ByBit.Net/Interfaces/Clients/SpotApi/v3/IBybitSocketClientSpotApiV3.cs +++ b/ByBit.Net/Interfaces/Clients/SpotApi/v3/IBybitSocketClientSpotApiV3.cs @@ -1,12 +1,12 @@ using Bybit.Net.Enums; using Bybit.Net.Objects.Models.Socket.Spot; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; using System; using System.Threading; using System.Threading.Tasks; using Bybit.Net.Objects.Models.Spot.v3; using CryptoExchange.Net.Interfaces; +using CryptoExchange.Net.Objects.Sockets; namespace Bybit.Net.Interfaces.Clients.SpotApi.v3 { diff --git a/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitSocketClientUsdPerpetualApi.cs b/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitSocketClientUsdPerpetualApi.cs deleted file mode 100644 index 099e1113..00000000 --- a/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitSocketClientUsdPerpetualApi.cs +++ /dev/null @@ -1,209 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Models; -using Bybit.Net.Objects.Models.Socket; -using CryptoExchange.Net.Interfaces; -using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.UsdPerpetualApi -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 16/30 OCTOBER, USE V5 API INSTEAD] Bybit usd perpetual streams - /// - public interface IBybitSocketClientUsdPerpetualApi : ISocketApiClient - { - /// - /// Subscribe to public trade updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTradesUpdatesAsync(Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to public trade updates - /// - /// - /// The symbol to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTradeUpdatesAsync(string symbol, Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to public trade updates - /// - /// - /// The symbols to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTradeUpdatesAsync(IEnumerable symbols, Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to ticker updates. Note that for a symbol the first update is a snapshot, containing all info. After that only partial updates are given for - /// properties which have changed. If a property in the update is `null` it isn't changed and should be ignored. - /// - /// - /// The symbol to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTickerUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to ticker updates. Note that for a symbol the first update is a snapshot, containing all info. After that only partial updates are given for - /// properties which have changed. If a property in the update is `null` it isn't changed and should be ignored. - /// - /// - /// The symbols to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToTickerUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to orderbook updates - /// - /// - /// - /// The amount of rows to receive updates for. Either 25 or 200. - /// The event handler for the initial snapshot data - /// The event handler for the update messages - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderBooksUpdatesAsync(int limit, Action>> snapshotHandler, Action>> updateHandler, CancellationToken ct = default); - - /// - /// Subscribe to orderbook updates - /// - /// - /// - /// The amount of rows to receive updates for. Either 25 or 200. - /// The symbol to receive updates for - /// The event handler for the initial snapshot data - /// The event handler for the update messages - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderBookUpdatesAsync(string symbol, int limit, Action>> snapshotHandler, Action>> updateHandler, CancellationToken ct = default); - - /// - /// Subscribe to orderbook updates - /// - /// - /// - /// The amount of rows to receive updates for. Either 25 or 200. - /// The symbols to receive updates for - /// The event handler for the initial snapshot data - /// The event handler for the update messages - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderBookUpdatesAsync( - IEnumerable symbols, - int limit, - Action>> snapshotHandler, - Action>> updateHandler, - CancellationToken ct = default); - - /// - /// Subscribe to kline (candlestick) updates - /// - /// - /// The interval of the klines - /// The symbol to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToKlineUpdatesAsync(string symbol, KlineInterval interval, Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to kline (candlestick) updates - /// - /// - /// The interval of the klines - /// The symbols to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToKlineUpdatesAsync(IEnumerable symbols, KlineInterval interval, Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to liquidation order updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToLiquidationsUpdatesAsync(Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to liquidation order updates - /// - /// - /// The symbol to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToLiquidationUpdatesAsync(string symbol, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to liquidation order updates - /// - /// - /// The symbols to receive updates for - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToLiquidationUpdatesAsync(IEnumerable symbols, Action> handler, CancellationToken ct = default); - - /// - /// Subscribe to user position updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToPositionUpdatesAsync(Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to user trade updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToUserTradeUpdatesAsync(Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to user order updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToOrderUpdatesAsync(Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to user stop order updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToStopOrderUpdatesAsync(Action>> handler, CancellationToken ct = default); - - /// - /// Subscribe to user balance updates - /// - /// - /// The event handler for the received data - /// Cancellation token for closing this subscription - /// A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected - Task> SubscribeToBalanceUpdatesAsync(Action>> handler, CancellationToken ct = default); - } -} diff --git a/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientBaseApi.cs b/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientBaseApi.cs index 863d1ff9..243111bf 100644 --- a/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientBaseApi.cs +++ b/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientBaseApi.cs @@ -2,7 +2,7 @@ using Bybit.Net.Objects.Models.V5; using CryptoExchange.Net.Interfaces; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects.Sockets; using System; using System.Collections.Generic; using System.Threading; @@ -43,11 +43,10 @@ public interface IBybitSocketClientBaseApi : ISocketApiClient /// /// The symbols to subscribe /// The order book depth - /// Handler for a snapshot update. Snapshot updates contain the full order book - /// Handler for updates. These will only contain the changed entries + /// Update handler /// Cancellation token. Cancelling will cancel the subscription /// - Task> SubscribeToOrderbookUpdatesAsync(IEnumerable symbols, int depth, Action> snapshotHandler, Action> updateHandler, CancellationToken ct = default); + Task> SubscribeToOrderbookUpdatesAsync(IEnumerable symbols, int depth, Action> updateHandler, CancellationToken ct = default); /// /// Subscribe to order book updates @@ -55,11 +54,10 @@ public interface IBybitSocketClientBaseApi : ISocketApiClient /// /// The symbol to subscribe /// The order book depth - /// Handler for a snapshot update. Snapshot updates contain the full order book - /// Handler for updates. These will only contain the changed entries + /// Update handler /// Cancellation token. Cancelling will cancel the subscription /// - Task> SubscribeToOrderbookUpdatesAsync(string symbol, int depth, Action> snapshotHandler, Action> updateHandler, CancellationToken ct = default); + Task> SubscribeToOrderbookUpdatesAsync(string symbol, int depth, Action> updateHandler, CancellationToken ct = default); /// /// Subscribe to public trade updates diff --git a/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientInverseApi.cs b/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientInverseApi.cs index 27836696..ede05ef5 100644 --- a/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientInverseApi.cs +++ b/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientInverseApi.cs @@ -1,6 +1,6 @@ using Bybit.Net.Objects.Models.V5; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects.Sockets; using System; using System.Collections.Generic; using System.Threading; diff --git a/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientLinearApi.cs b/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientLinearApi.cs index 970c5605..cf188bbf 100644 --- a/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientLinearApi.cs +++ b/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientLinearApi.cs @@ -1,6 +1,6 @@ using Bybit.Net.Objects.Models.V5; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects.Sockets; using System; using System.Collections.Generic; using System.Threading; diff --git a/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientOptionApi.cs b/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientOptionApi.cs index 56f337b5..f2788ace 100644 --- a/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientOptionApi.cs +++ b/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientOptionApi.cs @@ -1,6 +1,6 @@ using Bybit.Net.Objects.Models.V5; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects.Sockets; using System; using System.Collections.Generic; using System.Threading; diff --git a/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientPrivateApi.cs b/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientPrivateApi.cs index 4587cb5f..257713a7 100644 --- a/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientPrivateApi.cs +++ b/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientPrivateApi.cs @@ -1,7 +1,7 @@ using Bybit.Net.Objects.Models.V5; using CryptoExchange.Net.Interfaces; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects.Sockets; using System; using System.Collections.Generic; using System.Threading; diff --git a/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientSpotApi.cs b/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientSpotApi.cs index f632fbc6..fb960be8 100644 --- a/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientSpotApi.cs +++ b/ByBit.Net/Interfaces/Clients/V5/IBybitSocketClientSpotApi.cs @@ -1,7 +1,7 @@ using Bybit.Net.Enums; using Bybit.Net.Objects.Models.V5; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects.Sockets; using System; using System.Collections.Generic; using System.Threading; diff --git a/ByBit.Net/Objects/Internal/BybitBalanceWrapper.cs b/ByBit.Net/Objects/Internal/BybitBalanceWrapper.cs index 592db9af..0897d0e5 100644 --- a/ByBit.Net/Objects/Internal/BybitBalanceWrapper.cs +++ b/ByBit.Net/Objects/Internal/BybitBalanceWrapper.cs @@ -1,5 +1,4 @@ -using Bybit.Net.Objects.Models; -using Bybit.Net.Objects.Models.Spot; +using Bybit.Net.Objects.Models.Spot; using Newtonsoft.Json; using System; using System.Collections.Generic; diff --git a/ByBit.Net/Objects/Internal/BybitSpotPing.cs b/ByBit.Net/Objects/Internal/BybitSpotPing.cs deleted file mode 100644 index 8de7ff6c..00000000 --- a/ByBit.Net/Objects/Internal/BybitSpotPing.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models.Socket.Spot -{ - internal class BybitSpotPing - { - [JsonProperty("ping")] - public long Ping { get; set; } - } -} diff --git a/ByBit.Net/Objects/Internal/Socket/BybitRequestMessage.cs b/ByBit.Net/Objects/Internal/Socket/BybitRequestMessage.cs deleted file mode 100644 index 7eb2fddf..00000000 --- a/ByBit.Net/Objects/Internal/Socket/BybitRequestMessage.cs +++ /dev/null @@ -1,186 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; -using Bybit.Net.Interfaces.Clients.SpotApi; -using Newtonsoft.Json.Linq; - -namespace Bybit.Net.Objects.Internal.Socket -{ - internal class BybitRequestMessage - { - [JsonProperty("op")] - public string Operation { get; set; } = string.Empty; - [JsonProperty("args")] - public object[] Parameters { get; set; } = Array.Empty(); - } - - internal class BybitDerivativesRequestMessage : BybitRequestMessage - { - [JsonProperty("req_id")] - public string CustomisedId { get; set; } = string.Empty; - } - - internal class BybitSpotRequestMessageV1 : BybitSpotRequestMessageV2, IBybitSpotRequestValidable - { - [JsonProperty("symbol")] - public string Symbol { get; set; } = string.Empty; - - /// - /// Got fallback message only in version 2,3. In version 1 we get a plain responseData - public new bool ValidateResponse(JToken responseData, ref bool forcedExit) - { - forcedExit = false; - - var symbols = responseData["symbol"]?.ToString().Split(',').ToList(); - var requestSymbols = Symbol?.Split(',').ToList(); - - var success = responseData["data"]?.Any() ?? false; - var topic = responseData["topic"]?.ToString(); - - if (topic != null && !Operation.StartsWith(topic)) - { - forcedExit = true; - return success; - } - - if (requestSymbols.Any(p => symbols?.Contains(p) != true)) - { - forcedExit = true; - return success; - } - - return success; - } - - /// - public new bool MatchReponse(JToken responseData) - { - var topic = responseData["topic"]?.ToString(); - - var symbol = responseData["symbol"]?.ToString(); - var requestSymbols = Symbol.Split(',').ToList(); - - if (!Operation.StartsWith(topic)) - return false; - - if (!requestSymbols.Contains(symbol)) - return false; - - var klineInterval = responseData["params"]?["klineType"]?.ToString(); - if (klineInterval != null && Parameters.ContainsKey("klineType")) - { - if (klineInterval != (string)Parameters["klineType"]) - return false; - } - - return true; - } - } - - internal class BybitSpotRequestMessageV2 : IBybitSpotRequestValidable - { - [JsonProperty("topic")] - public string Operation { get; set; } = string.Empty; - [JsonProperty("params")] - public Dictionary Parameters { get; set; } = new Dictionary(); - [JsonProperty("event")] - public string Event { get; set; } = string.Empty; - - /// - public bool ValidateResponse(JToken responseData, ref bool forcedExit) - { - forcedExit = false; - var operation = responseData["event"]?.ToString(); - var success = responseData["msg"]?.Value() == "Success"; - - if (operation != "sub") - { - forcedExit = true; - return success; - } - - var symbols = responseData["params"]?["symbol"]?.ToString().Split(',').ToList(); - var requestSymbols = Parameters["symbol"]?.ToString().Split(',').ToList(); - var topic = responseData["topic"]?.ToString(); - - if (topic != null && !Operation.StartsWith(topic)) - { - forcedExit = true; - return success; - } - - if (requestSymbols.Any(p => symbols?.Contains(p) != true)) - { - forcedExit = true; - return success; - } - - return success; - } - - /// - public bool MatchReponse(JToken responseData) - { - var topic = responseData["topic"]?.ToString(); - - var symbol = responseData["params"]?["symbol"]?.ToString(); - var requestSymbols = Parameters["symbol"].ToString().Split(',').ToList(); - - if (!Operation.StartsWith(topic)) - return false; - - if (!requestSymbols.Contains(symbol)) - return false; - - var klineInterval = responseData["params"]?["klineType"]?.ToString(); - if (klineInterval != null && Parameters.ContainsKey("klineType")) - { - if (klineInterval != (string)Parameters["klineType"]) - return false; - } - - return true; - } - } - - internal class BybitSpotRequestMessageV3 : IBybitSpotRequestValidable - { - [JsonProperty("req_id")] - public string ID { get; set; } = string.Empty; - [JsonProperty("op")] - public string Operation { get; set; } = string.Empty; - [JsonProperty("args")] - public object[] Parameters { get; set; } = Array.Empty(); - - /// - public bool ValidateResponse(JToken responseData, ref bool forcedExit) - { - forcedExit = false; - var operation = responseData["op"]?.ToString(); - var success = responseData["success"]?.Value() == true; - var req_id = responseData["req_id"]?.ToString(); - - if (operation != "subscribe") - { - forcedExit = true; - return success; - } - - if (req_id != ID) - { - forcedExit = true; - return success; - } - - return success; - } - - /// - public bool MatchReponse(JToken responseData) - { - var topic = responseData["topic"]?.ToString(); - return Parameters.Any(p => topic == p.ToString()); - } - } -} diff --git a/ByBit.Net/Objects/Internal/Socket/BybitResponseMessage.cs b/ByBit.Net/Objects/Internal/Socket/BybitResponseMessage.cs deleted file mode 100644 index 924934ab..00000000 --- a/ByBit.Net/Objects/Internal/Socket/BybitResponseMessage.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Internal.Socket -{ - internal class BybitResponseMessage - { - public bool Success { get; set; } - [JsonProperty("ret_msg")] - public bool ReturnMessage { get; set; } - [JsonProperty("conn_id")] - public string ConnectionId { get; set; } = string.Empty; - public BybitRequestMessage Request { get; set; } = default!; - } -} diff --git a/ByBit.Net/Objects/Internal/Socket/BybitV5RequestMessage.cs b/ByBit.Net/Objects/Internal/Socket/BybitV5RequestMessage.cs deleted file mode 100644 index bf8a03fd..00000000 --- a/ByBit.Net/Objects/Internal/Socket/BybitV5RequestMessage.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Internal.Socket -{ - internal class BybitV5RequestMessage - { - [JsonProperty("op")] - public string Operation { get; set; } - [JsonProperty("args")] - public object[] Parameters { get; set; } - [JsonProperty("req_id")] - public string RequestId { get; set; } - - public BybitV5RequestMessage(string operation, object[] parameters, string requestId) - { - Operation = operation; - Parameters = parameters; - RequestId = requestId; - } - } -} diff --git a/ByBit.Net/Objects/Models/Derivatives/UnifiedMargin/BybitUnifiedMarginOrder.cs b/ByBit.Net/Objects/Models/Derivatives/UnifiedMargin/BybitUnifiedMarginOrder.cs index 88775f83..121042f2 100644 --- a/ByBit.Net/Objects/Models/Derivatives/UnifiedMargin/BybitUnifiedMarginOrder.cs +++ b/ByBit.Net/Objects/Models/Derivatives/UnifiedMargin/BybitUnifiedMarginOrder.cs @@ -1,6 +1,4 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; +using Newtonsoft.Json; namespace Bybit.Net.Objects.Models.Derivatives.UnifiedMargin { diff --git a/ByBit.Net/Objects/Models/Socket/Derivatives/BybitDerivativesTickerUpdate.cs b/ByBit.Net/Objects/Models/Socket/Derivatives/BybitDerivativesTickerUpdate.cs deleted file mode 100644 index f3f4cb12..00000000 --- a/ByBit.Net/Objects/Models/Socket/Derivatives/BybitDerivativesTickerUpdate.cs +++ /dev/null @@ -1,77 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models.Socket.Derivatives -{ - /// - /// Derivatives ticker update - /// - public class BybitDerivativesTickerUpdate - { - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - - /// - /// Price change direction - /// - [JsonConverter(typeof(TickDirectionConverter))] - public TickDirection TickDirection { get; set; } - - /// - /// Price change percentage since 24 hours ago - /// - [JsonProperty("price24hPcnt")] - public decimal? PriceChangePercentage24H { get; set; } - - /// - /// Last trade price - /// - public decimal LastPrice { get; set; } - - /// - /// Turnover in the last 24 hours - /// - public decimal? Turnover24H { get; set; } - - /// - /// Volume in the last 24 hours - /// - public decimal? Volume24H { get; set; } - - /// - /// Funding rate - /// - public decimal? FundingRate { get; set; } - - /// - /// Next settlement time of capital cost - /// - [JsonConverter(typeof(DateTimeConverter))] - public DateTime? NextFundingTime { get; set; } - - /// - /// Bid 1 price - /// - public decimal? Bid1Price { get; set; } - - /// - /// Bid 1 size - /// - public decimal? Bid1Size { get; set; } - - /// - /// Ask 1 price - /// - public decimal? Ask1Price { get; set; } - - /// - /// Ask 1 size - /// - public decimal? Ask1Size { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/V5/BybitAccountTypeInfo.cs b/ByBit.Net/Objects/Models/V5/BybitAccountTypeInfo.cs index e7e55e27..7fcc80c8 100644 --- a/ByBit.Net/Objects/Models/V5/BybitAccountTypeInfo.cs +++ b/ByBit.Net/Objects/Models/V5/BybitAccountTypeInfo.cs @@ -1,7 +1,6 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; -using System.Text; namespace Bybit.Net.Objects.Models.V5 { diff --git a/ByBit.Net/Objects/Models/V5/BybitApiKeyInfo.cs b/ByBit.Net/Objects/Models/V5/BybitApiKeyInfo.cs index 0ea5bed7..2ae1f789 100644 --- a/ByBit.Net/Objects/Models/V5/BybitApiKeyInfo.cs +++ b/ByBit.Net/Objects/Models/V5/BybitApiKeyInfo.cs @@ -1,5 +1,4 @@ -using Bybit.Net.Converters; -using CryptoExchange.Net.Converters; +using CryptoExchange.Net.Converters; using Newtonsoft.Json; using System; using System.Collections.Generic; diff --git a/ByBit.Net/Objects/Models/V5/BybitFeeRate.cs b/ByBit.Net/Objects/Models/V5/BybitFeeRate.cs index 1e9e92ae..f5952b2f 100644 --- a/ByBit.Net/Objects/Models/V5/BybitFeeRate.cs +++ b/ByBit.Net/Objects/Models/V5/BybitFeeRate.cs @@ -1,7 +1,4 @@ using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Text; namespace Bybit.Net.Objects.Models.V5 { diff --git a/ByBit.Net/Objects/Models/V5/BybitHistoricalVolatility.cs b/ByBit.Net/Objects/Models/V5/BybitHistoricalVolatility.cs index 1ac4542c..ef6b23f6 100644 --- a/ByBit.Net/Objects/Models/V5/BybitHistoricalVolatility.cs +++ b/ByBit.Net/Objects/Models/V5/BybitHistoricalVolatility.cs @@ -1,8 +1,6 @@ using CryptoExchange.Net.Converters; using Newtonsoft.Json; using System; -using System.Collections.Generic; -using System.Text; namespace Bybit.Net.Objects.Models.V5 { diff --git a/ByBit.Net/Objects/Models/V5/BybitKline.cs b/ByBit.Net/Objects/Models/V5/BybitKline.cs index 40575fcc..156a323c 100644 --- a/ByBit.Net/Objects/Models/V5/BybitKline.cs +++ b/ByBit.Net/Objects/Models/V5/BybitKline.cs @@ -1,6 +1,5 @@ using CryptoExchange.Net.Converters; using Newtonsoft.Json; -using System; namespace Bybit.Net.Objects.Models.V5 { diff --git a/ByBit.Net/Objects/Models/V5/BybitLeverageToken.cs b/ByBit.Net/Objects/Models/V5/BybitLeverageToken.cs index edea5a8b..3d6998ef 100644 --- a/ByBit.Net/Objects/Models/V5/BybitLeverageToken.cs +++ b/ByBit.Net/Objects/Models/V5/BybitLeverageToken.cs @@ -3,7 +3,6 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; -using System.Text; namespace Bybit.Net.Objects.Models.V5 { diff --git a/ByBit.Net/Objects/Models/V5/BybitLinearInverseSymbol.cs b/ByBit.Net/Objects/Models/V5/BybitLinearInverseSymbol.cs index 2fb398e1..53e8fedb 100644 --- a/ByBit.Net/Objects/Models/V5/BybitLinearInverseSymbol.cs +++ b/ByBit.Net/Objects/Models/V5/BybitLinearInverseSymbol.cs @@ -1,5 +1,4 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; +using Bybit.Net.Enums; using CryptoExchange.Net.Converters; using Newtonsoft.Json; using System; diff --git a/ByBit.Net/Objects/Models/V5/BybitLinearInverseTicker.cs b/ByBit.Net/Objects/Models/V5/BybitLinearInverseTicker.cs index 4e77f2ff..adf427ec 100644 --- a/ByBit.Net/Objects/Models/V5/BybitLinearInverseTicker.cs +++ b/ByBit.Net/Objects/Models/V5/BybitLinearInverseTicker.cs @@ -1,6 +1,4 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; +using CryptoExchange.Net.Converters; using Newtonsoft.Json; using System; diff --git a/ByBit.Net/Objects/Models/V5/BybitOperationResult.cs b/ByBit.Net/Objects/Models/V5/BybitOperationResult.cs index 64713dd9..e53d8229 100644 --- a/ByBit.Net/Objects/Models/V5/BybitOperationResult.cs +++ b/ByBit.Net/Objects/Models/V5/BybitOperationResult.cs @@ -1,5 +1,4 @@ -using Bybit.Net.Converters; -using CryptoExchange.Net.Converters; +using CryptoExchange.Net.Converters; using Newtonsoft.Json; namespace Bybit.Net.Objects.Models.V5 diff --git a/ByBit.Net/Objects/Models/V5/BybitOptionSymbol.cs b/ByBit.Net/Objects/Models/V5/BybitOptionSymbol.cs index efebb75f..ea6b4249 100644 --- a/ByBit.Net/Objects/Models/V5/BybitOptionSymbol.cs +++ b/ByBit.Net/Objects/Models/V5/BybitOptionSymbol.cs @@ -1,5 +1,4 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; +using Bybit.Net.Enums; using CryptoExchange.Net.Converters; using Newtonsoft.Json; using System; diff --git a/ByBit.Net/Objects/Models/V5/BybitOptionTickerUpdate.cs b/ByBit.Net/Objects/Models/V5/BybitOptionTickerUpdate.cs index 4b44662c..c4d5656b 100644 --- a/ByBit.Net/Objects/Models/V5/BybitOptionTickerUpdate.cs +++ b/ByBit.Net/Objects/Models/V5/BybitOptionTickerUpdate.cs @@ -1,7 +1,4 @@ using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Text; namespace Bybit.Net.Objects.Models.V5 { diff --git a/ByBit.Net/Objects/Models/V5/BybitOrder.cs b/ByBit.Net/Objects/Models/V5/BybitOrder.cs index e67539f3..787bb661 100644 --- a/ByBit.Net/Objects/Models/V5/BybitOrder.cs +++ b/ByBit.Net/Objects/Models/V5/BybitOrder.cs @@ -1,5 +1,4 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; +using Bybit.Net.Enums; using CryptoExchange.Net.Converters; using Newtonsoft.Json; using System; diff --git a/ByBit.Net/Objects/Models/V5/BybitOrderbook.cs b/ByBit.Net/Objects/Models/V5/BybitOrderbook.cs index 4112c638..3f912bcf 100644 --- a/ByBit.Net/Objects/Models/V5/BybitOrderbook.cs +++ b/ByBit.Net/Objects/Models/V5/BybitOrderbook.cs @@ -3,7 +3,6 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; -using System.Text; namespace Bybit.Net.Objects.Models.V5 { diff --git a/ByBit.Net/Objects/Models/V5/BybitResponse.cs b/ByBit.Net/Objects/Models/V5/BybitResponse.cs index 8e2c714a..d4f8d58f 100644 --- a/ByBit.Net/Objects/Models/V5/BybitResponse.cs +++ b/ByBit.Net/Objects/Models/V5/BybitResponse.cs @@ -3,7 +3,6 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; -using System.Text; namespace Bybit.Net.Objects.Models.V5 { diff --git a/ByBit.Net/Objects/Models/V5/BybitRiskLimit.cs b/ByBit.Net/Objects/Models/V5/BybitRiskLimit.cs index e12e5d63..026a6d40 100644 --- a/ByBit.Net/Objects/Models/V5/BybitRiskLimit.cs +++ b/ByBit.Net/Objects/Models/V5/BybitRiskLimit.cs @@ -1,5 +1,4 @@ -using Bybit.Net.Converters; -using CryptoExchange.Net.Converters; +using CryptoExchange.Net.Converters; using Newtonsoft.Json; namespace Bybit.Net.Objects.Models.V5 diff --git a/ByBit.Net/Objects/Models/V5/BybitSetMarginModeResult.cs b/ByBit.Net/Objects/Models/V5/BybitSetMarginModeResult.cs index 5e8ba881..0538e49a 100644 --- a/ByBit.Net/Objects/Models/V5/BybitSetMarginModeResult.cs +++ b/ByBit.Net/Objects/Models/V5/BybitSetMarginModeResult.cs @@ -1,7 +1,6 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; -using System.Text; namespace Bybit.Net.Objects.Models.V5 { diff --git a/ByBit.Net/Objects/Models/V5/BybitSetRiskLimit.cs b/ByBit.Net/Objects/Models/V5/BybitSetRiskLimit.cs index e1d3a7ca..adabb668 100644 --- a/ByBit.Net/Objects/Models/V5/BybitSetRiskLimit.cs +++ b/ByBit.Net/Objects/Models/V5/BybitSetRiskLimit.cs @@ -1,9 +1,6 @@ using Bybit.Net.Enums; using CryptoExchange.Net.Converters; using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Text; namespace Bybit.Net.Objects.Models.V5 { diff --git a/ByBit.Net/Objects/Models/V5/BybitSpotMarginLeverageStatus.cs b/ByBit.Net/Objects/Models/V5/BybitSpotMarginLeverageStatus.cs index d150a12b..8544e518 100644 --- a/ByBit.Net/Objects/Models/V5/BybitSpotMarginLeverageStatus.cs +++ b/ByBit.Net/Objects/Models/V5/BybitSpotMarginLeverageStatus.cs @@ -1,5 +1,4 @@ -using Bybit.Net.Converters; -using CryptoExchange.Net.Converters; +using CryptoExchange.Net.Converters; using Newtonsoft.Json; namespace Bybit.Net.Objects.Models.V5 diff --git a/ByBit.Net/Objects/Models/V5/BybitSpotMarginStatus.cs b/ByBit.Net/Objects/Models/V5/BybitSpotMarginStatus.cs index 13c3ee6f..05146f35 100644 --- a/ByBit.Net/Objects/Models/V5/BybitSpotMarginStatus.cs +++ b/ByBit.Net/Objects/Models/V5/BybitSpotMarginStatus.cs @@ -1,5 +1,4 @@ -using Bybit.Net.Converters; -using CryptoExchange.Net.Converters; +using CryptoExchange.Net.Converters; using Newtonsoft.Json; namespace Bybit.Net.Objects.Models.V5 diff --git a/ByBit.Net/Objects/Models/V5/BybitSpotSymbol.cs b/ByBit.Net/Objects/Models/V5/BybitSpotSymbol.cs index a00737d3..6395f53f 100644 --- a/ByBit.Net/Objects/Models/V5/BybitSpotSymbol.cs +++ b/ByBit.Net/Objects/Models/V5/BybitSpotSymbol.cs @@ -1,5 +1,4 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; +using Bybit.Net.Enums; using CryptoExchange.Net.Converters; using Newtonsoft.Json; diff --git a/ByBit.Net/Objects/Models/V5/BybitTransactionLog.cs b/ByBit.Net/Objects/Models/V5/BybitTransactionLog.cs index 8cd1e714..adc34b67 100644 --- a/ByBit.Net/Objects/Models/V5/BybitTransactionLog.cs +++ b/ByBit.Net/Objects/Models/V5/BybitTransactionLog.cs @@ -2,8 +2,6 @@ using CryptoExchange.Net.Converters; using Newtonsoft.Json; using System; -using System.Collections.Generic; -using System.Text; namespace Bybit.Net.Objects.Models.V5 { diff --git a/ByBit.Net/Objects/Models/V5/BybitUserAssetInfo.cs b/ByBit.Net/Objects/Models/V5/BybitUserAssetInfo.cs index 2b32b3ec..7dfeb42d 100644 --- a/ByBit.Net/Objects/Models/V5/BybitUserAssetInfo.cs +++ b/ByBit.Net/Objects/Models/V5/BybitUserAssetInfo.cs @@ -1,5 +1,4 @@ -using Bybit.Net.Converters; -using CryptoExchange.Net.Converters; +using CryptoExchange.Net.Converters; using Newtonsoft.Json; using System; using System.Collections.Generic; diff --git a/ByBit.Net/Objects/Options/BybitOrdeBookOptions.cs b/ByBit.Net/Objects/Options/BybitOrdeBookOptions.cs index b9bdb023..9e94aa47 100644 --- a/ByBit.Net/Objects/Options/BybitOrdeBookOptions.cs +++ b/ByBit.Net/Objects/Options/BybitOrdeBookOptions.cs @@ -1,7 +1,5 @@ using CryptoExchange.Net.Objects.Options; using System; -using System.Collections.Generic; -using System.Text; namespace Bybit.Net.Objects.Options { diff --git a/ByBit.Net/Objects/Sockets/BybitOptionsQueryResponse.cs b/ByBit.Net/Objects/Sockets/BybitOptionsQueryResponse.cs new file mode 100644 index 00000000..3cb82113 --- /dev/null +++ b/ByBit.Net/Objects/Sockets/BybitOptionsQueryResponse.cs @@ -0,0 +1,30 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace Bybit.Net.Objects.Sockets +{ + internal class BybitOptionsQueryResponse + { + [JsonProperty("success")] + public bool Success { get; set; } + [JsonProperty("ret_msg")] + public string Message { get; set; } = string.Empty; + [JsonProperty("conn_id")] + public string ConnectionId { get; set; } = string.Empty; + [JsonProperty("type")] + public string Type { get; set; } = string.Empty; + [JsonProperty("req_id")] + public string RequestId { get; set; } = string.Empty; + + [JsonProperty("data")] + public BybitOptionsQueryData Data { get; set; } = null!; + } + + internal class BybitOptionsQueryData + { + [JsonProperty("failTopics")] + public List FailedTopics { get; set; } = new List(); + [JsonProperty("successTopics")] + public List SuccessTopics { get; set; } = new List(); + } +} diff --git a/ByBit.Net/Objects/Sockets/BybitPong.cs b/ByBit.Net/Objects/Sockets/BybitPong.cs new file mode 100644 index 00000000..3b026620 --- /dev/null +++ b/ByBit.Net/Objects/Sockets/BybitPong.cs @@ -0,0 +1,10 @@ +using Newtonsoft.Json; + +namespace Bybit.Net.Objects.Sockets +{ + internal class BybitPong + { + [JsonProperty("pong")] + public string Operation { get; set; } = string.Empty; + } +} diff --git a/ByBit.Net/Objects/Sockets/BybitQueryResponse.cs b/ByBit.Net/Objects/Sockets/BybitQueryResponse.cs new file mode 100644 index 00000000..ea4076ce --- /dev/null +++ b/ByBit.Net/Objects/Sockets/BybitQueryResponse.cs @@ -0,0 +1,18 @@ +using Newtonsoft.Json; + +namespace Bybit.Net.Objects.Sockets +{ + internal class BybitQueryResponse + { + [JsonProperty("success")] + public bool Success { get; set; } + [JsonProperty("ret_msg")] + public string Message { get; set; } = string.Empty; + [JsonProperty("conn_id")] + public string ConnectionId { get; set; } = string.Empty; + [JsonProperty("req_id")] + public string RequestId { get; set; } = string.Empty; + [JsonProperty("op")] + public string Operation { get; set; } = string.Empty; + } +} diff --git a/ByBit.Net/Objects/Sockets/BybitRequestMessage.cs b/ByBit.Net/Objects/Sockets/BybitRequestMessage.cs new file mode 100644 index 00000000..537d442f --- /dev/null +++ b/ByBit.Net/Objects/Sockets/BybitRequestMessage.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace Bybit.Net.Objects.Sockets +{ + internal class BybitRequestMessage + { + [JsonProperty("req_id")] + public string RequestId { get; set; } = string.Empty; + [JsonProperty("op")] + public string Operation { get; set; } = string.Empty; + [JsonProperty("args", NullValueHandling = NullValueHandling.Ignore)] + public List? Args { get; set; } + } +} diff --git a/ByBit.Net/Objects/Sockets/BybitSpotSocketEvent.cs b/ByBit.Net/Objects/Sockets/BybitSpotSocketEvent.cs new file mode 100644 index 00000000..07083c13 --- /dev/null +++ b/ByBit.Net/Objects/Sockets/BybitSpotSocketEvent.cs @@ -0,0 +1,19 @@ +using CryptoExchange.Net.Converters; +using Newtonsoft.Json; +using System; + +namespace Bybit.Net.Objects.Sockets +{ + internal class BybitSpotSocketEvent + { + [JsonProperty("topic")] + public string Topic { get; set; } = string.Empty; + [JsonProperty("type")] + public string Type { get; set; } = string.Empty; + [JsonConverter(typeof(DateTimeConverter))] + [JsonProperty("ts")] + public DateTime Timestamp { get; set; } + [JsonProperty("data")] + public T Data { get; set; } = default!; + } +} diff --git a/ByBit.Net/Objects/Sockets/Queries/BybitOptionsQuery.cs b/ByBit.Net/Objects/Sockets/Queries/BybitOptionsQuery.cs new file mode 100644 index 00000000..42c83de3 --- /dev/null +++ b/ByBit.Net/Objects/Sockets/Queries/BybitOptionsQuery.cs @@ -0,0 +1,28 @@ +using CryptoExchange.Net; +using CryptoExchange.Net.Objects; +using CryptoExchange.Net.Objects.Sockets; +using CryptoExchange.Net.Sockets; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Bybit.Net.Objects.Sockets.Queries +{ + internal class BybitOptionsQuery : Query + { + public override HashSet ListenerIdentifiers { get; set; } + + public BybitOptionsQuery(string op, params object[] args) : base(new BybitRequestMessage { RequestId = ExchangeHelpers.NextId().ToString(), Operation = op, Args = args?.ToList() }, false, 1) + { + ListenerIdentifiers = new HashSet() { "resp" + string.Join("-", args.OrderBy(a => a)) }; + } + + public override Task> HandleMessageAsync(SocketConnection connection, DataEvent message) + { + if (!message.Data.Success) + return Task.FromResult(new CallResult(new ServerError(message.Data.Message))); + + return Task.FromResult(new CallResult(message.Data)); + } + } +} diff --git a/ByBit.Net/Objects/Sockets/Queries/BybitPingQuery.cs b/ByBit.Net/Objects/Sockets/Queries/BybitPingQuery.cs new file mode 100644 index 00000000..3898cce9 --- /dev/null +++ b/ByBit.Net/Objects/Sockets/Queries/BybitPingQuery.cs @@ -0,0 +1,16 @@ +using CryptoExchange.Net; +using CryptoExchange.Net.Sockets; +using System.Collections.Generic; + +namespace Bybit.Net.Objects.Sockets.Queries +{ + internal class BybitPingQuery : Query + { + public override HashSet ListenerIdentifiers { get; set; } + + public BybitPingQuery() : base(new BybitRequestMessage { RequestId = ExchangeHelpers.NextId().ToString(), Operation = "ping", Args = null }, false, 1) + { + ListenerIdentifiers = new HashSet() { "pong" }; + } + } +} diff --git a/ByBit.Net/Objects/Sockets/Queries/BybitQuery.cs b/ByBit.Net/Objects/Sockets/Queries/BybitQuery.cs new file mode 100644 index 00000000..3917dc33 --- /dev/null +++ b/ByBit.Net/Objects/Sockets/Queries/BybitQuery.cs @@ -0,0 +1,28 @@ +using CryptoExchange.Net; +using CryptoExchange.Net.Objects; +using CryptoExchange.Net.Objects.Sockets; +using CryptoExchange.Net.Sockets; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Bybit.Net.Objects.Sockets.Queries +{ + internal class BybitQuery : Query + { + public override HashSet ListenerIdentifiers { get; set; } + + public BybitQuery(string op, params object[]? args) : base(new BybitRequestMessage { RequestId = ExchangeHelpers.NextId().ToString(), Operation = op, Args = args?.ToList() }, false, 1) + { + ListenerIdentifiers = new HashSet() { ((BybitRequestMessage)Request).RequestId }; + } + + public override Task> HandleMessageAsync(SocketConnection connection, DataEvent message) + { + if (!message.Data.Success) + return Task.FromResult(new CallResult(new ServerError(message.Data.Message))); + + return Task.FromResult(new CallResult(message.Data)); + } + } +} diff --git a/ByBit.Net/Objects/Sockets/Queries/BybitUnifiedQuery.cs b/ByBit.Net/Objects/Sockets/Queries/BybitUnifiedQuery.cs new file mode 100644 index 00000000..b429c986 --- /dev/null +++ b/ByBit.Net/Objects/Sockets/Queries/BybitUnifiedQuery.cs @@ -0,0 +1,31 @@ +using CryptoExchange.Net; +using CryptoExchange.Net.Objects; +using CryptoExchange.Net.Objects.Sockets; +using CryptoExchange.Net.Sockets; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Bybit.Net.Objects.Sockets.Queries +{ + internal class BybitUnifiedQuery : Query + { + public override HashSet ListenerIdentifiers { get; set; } + + public BybitUnifiedQuery(string op, params object[] args) : base(new BybitRequestMessage { RequestId = ExchangeHelpers.NextId().ToString(), Operation = op, Args = args?.ToList() }, false, 1) + { + if (op == "auth") + ListenerIdentifiers = new HashSet() { "AUTH_RESP" }; + else + ListenerIdentifiers = new HashSet() { "COMMAND_RESP" }; + } + + public override Task> HandleMessageAsync(SocketConnection connection, DataEvent message) + { + if (!message.Data.Success) + return Task.FromResult(new CallResult(new ServerError(message.Data.Message))); + + return Task.FromResult(new CallResult(message.Data)); + } + } +} diff --git a/ByBit.Net/Objects/Sockets/Subscriptions/BybitOptionsSubscription.cs b/ByBit.Net/Objects/Sockets/Subscriptions/BybitOptionsSubscription.cs new file mode 100644 index 00000000..986f80af --- /dev/null +++ b/ByBit.Net/Objects/Sockets/Subscriptions/BybitOptionsSubscription.cs @@ -0,0 +1,44 @@ +using Bybit.Net.Objects.Sockets.Queries; +using CryptoExchange.Net.Objects; +using CryptoExchange.Net.Objects.Sockets; +using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Bybit.Net.Objects.Sockets.Subscriptions +{ + internal class BybitOptionsSubscription : Subscription + { + private string[] _topics; + private Action> _handler; + public override HashSet ListenerIdentifiers { get; set; } + + public BybitOptionsSubscription(ILogger logger, string[] topics, Action> handler, bool auth = false) : base(logger, auth) + { + _topics = topics; + _handler = handler; + ListenerIdentifiers = new HashSet(topics); + } + + public override Task DoHandleMessageAsync(SocketConnection connection, DataEvent message) + { + var data = (BybitSpotSocketEvent)message.Data; + _handler?.Invoke(message.As(data.Data, data.Topic, data.Type == "snapshot" ? SocketUpdateType.Snapshot : SocketUpdateType.Update)); + return Task.FromResult(new CallResult(null)); + } + + public override Type? GetMessageType(IMessageAccessor message) => typeof(BybitSpotSocketEvent); + + public override Query? GetSubQuery(SocketConnection connection) + { + return new BybitOptionsQuery("subscribe", _topics); + } + public override Query? GetUnsubQuery() + { + return new BybitOptionsQuery("unsubscribe", _topics); + } + } +} diff --git a/ByBit.Net/Objects/Sockets/Subscriptions/BybitSubscription.cs b/ByBit.Net/Objects/Sockets/Subscriptions/BybitSubscription.cs new file mode 100644 index 00000000..c932fe82 --- /dev/null +++ b/ByBit.Net/Objects/Sockets/Subscriptions/BybitSubscription.cs @@ -0,0 +1,44 @@ +using Bybit.Net.Objects.Sockets.Queries; +using CryptoExchange.Net.Objects; +using CryptoExchange.Net.Objects.Sockets; +using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Bybit.Net.Objects.Sockets.Subscriptions +{ + internal class BybitSubscription : Subscription + { + private string[] _topics; + private Action> _handler; + public override HashSet ListenerIdentifiers { get; set; } + + public BybitSubscription(ILogger logger, string[] topics, Action> handler, bool auth = false) : base(logger, auth) + { + _topics = topics; + _handler = handler; + ListenerIdentifiers = new HashSet(topics); + } + + public override Task DoHandleMessageAsync(SocketConnection connection, DataEvent message) + { + var data = (BybitSpotSocketEvent)message.Data; + _handler?.Invoke(message.As(data.Data, data.Topic, data.Type == "snapshot" ? SocketUpdateType.Snapshot : SocketUpdateType.Update)); + return Task.FromResult(new CallResult(null)); + } + + public override Type? GetMessageType(IMessageAccessor message) => typeof(BybitSpotSocketEvent); + + public override Query? GetSubQuery(SocketConnection connection) + { + return new BybitQuery("subscribe", _topics); + } + public override Query? GetUnsubQuery() + { + return new BybitQuery("unsubscribe", _topics); + } + } +} diff --git a/ByBit.Net/Objects/Sockets/Subscriptions/BybitUnifiedSubscription.cs b/ByBit.Net/Objects/Sockets/Subscriptions/BybitUnifiedSubscription.cs new file mode 100644 index 00000000..972665bf --- /dev/null +++ b/ByBit.Net/Objects/Sockets/Subscriptions/BybitUnifiedSubscription.cs @@ -0,0 +1,44 @@ +using Bybit.Net.Objects.Sockets.Queries; +using CryptoExchange.Net.Objects; +using CryptoExchange.Net.Objects.Sockets; +using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Sockets.MessageParsing.Interfaces; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Bybit.Net.Objects.Sockets.Subscriptions +{ + internal class BybitUnifiedSubscription : Subscription + { + private string[] _topics; + private Action> _handler; + public override HashSet ListenerIdentifiers { get; set; } + + public BybitUnifiedSubscription(ILogger logger, string[] topics, Action> handler, bool auth = false) : base(logger, auth) + { + _topics = topics; + _handler = handler; + ListenerIdentifiers = new HashSet(topics); + } + + public override Task DoHandleMessageAsync(SocketConnection connection, DataEvent message) + { + var data = (BybitSpotSocketEvent)message.Data; + _handler?.Invoke(message.As(data.Data, data.Topic, data.Type == "snapshot" ? SocketUpdateType.Snapshot : SocketUpdateType.Update)); + return Task.FromResult(new CallResult(null)); + } + + public override Type? GetMessageType(IMessageAccessor message) => typeof(BybitSpotSocketEvent); + + public override Query? GetSubQuery(SocketConnection connection) + { + return new BybitUnifiedQuery("subscribe", _topics); + } + public override Query? GetUnsubQuery() + { + return new BybitUnifiedQuery("unsubscribe", _topics); + } + } +} diff --git a/ByBit.Net/SymbolOrderBooks/BybitOrderBookFactory.cs b/ByBit.Net/SymbolOrderBooks/BybitOrderBookFactory.cs index 5dff87c2..f7bfaa05 100644 --- a/ByBit.Net/SymbolOrderBooks/BybitOrderBookFactory.cs +++ b/ByBit.Net/SymbolOrderBooks/BybitOrderBookFactory.cs @@ -6,8 +6,6 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System; -using System.Collections.Generic; -using System.Text; namespace Bybit.Net.SymbolOrderBooks { diff --git a/ByBit.Net/SymbolOrderBooks/BybitSymbolOrderBook.cs b/ByBit.Net/SymbolOrderBooks/BybitSymbolOrderBook.cs index 7da9ed8c..80d18be6 100644 --- a/ByBit.Net/SymbolOrderBooks/BybitSymbolOrderBook.cs +++ b/ByBit.Net/SymbolOrderBooks/BybitSymbolOrderBook.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using CryptoExchange.Net.Objects; using CryptoExchange.Net.OrderBook; -using CryptoExchange.Net.Sockets; using Microsoft.Extensions.Logging; using Bybit.Net.Interfaces.Clients; using Bybit.Net.Clients; @@ -10,6 +9,7 @@ using Bybit.Net.Enums; using Bybit.Net.Objects.Models.V5; using Bybit.Net.Objects.Options; +using CryptoExchange.Net.Objects.Sockets; namespace Bybit.Net.SymbolOrderBooks { @@ -68,11 +68,11 @@ protected override async Task> DoStartAsync(Cance { CallResult result; if (_category == Category.Spot) - result = await _socketClient.V5SpotApi.SubscribeToOrderbookUpdatesAsync(Symbol, _depth, ProcessSnapshotUpdate, ProcessPartialUpdate).ConfigureAwait(false); - else if(_category == Category.Option) - result = await _socketClient.V5OptionsApi.SubscribeToOrderbookUpdatesAsync(Symbol, _depth, ProcessSnapshotUpdate, ProcessPartialUpdate).ConfigureAwait(false); + result = await _socketClient.V5SpotApi.SubscribeToOrderbookUpdatesAsync(Symbol, _depth, ProcessUpdate).ConfigureAwait(false); + else if (_category == Category.Option) + result = await _socketClient.V5OptionsApi.SubscribeToOrderbookUpdatesAsync(Symbol, _depth, ProcessUpdate).ConfigureAwait(false); else - result = await _socketClient.V5LinearApi.SubscribeToOrderbookUpdatesAsync(Symbol, _depth, ProcessSnapshotUpdate, ProcessPartialUpdate).ConfigureAwait(false); + result = await _socketClient.V5LinearApi.SubscribeToOrderbookUpdatesAsync(Symbol, _depth, ProcessUpdate).ConfigureAwait(false); if (!result) return result; @@ -83,7 +83,7 @@ protected override async Task> DoStartAsync(Cance return result.AsError(new CancellationRequestedError()); } Status = OrderBookStatus.Syncing; - + var setResult = await WaitForSetOrderBookAsync(_initialDataTimeout, ct).ConfigureAwait(false); return setResult ? result : new CallResult(setResult.Error!); } @@ -93,14 +93,12 @@ protected override void DoReset() { } - private void ProcessSnapshotUpdate(DataEvent data) + private void ProcessUpdate(DataEvent data) { - SetInitialOrderBook(data.Data.UpdateId, data.Data.Bids, data.Data.Asks); - } - - private void ProcessPartialUpdate(DataEvent data) - { - UpdateOrderBook(data.Data.UpdateId, data.Data.Bids, data.Data.Asks); + if (data.UpdateType == SocketUpdateType.Snapshot) + SetInitialOrderBook(data.Data.UpdateId, data.Data.Bids, data.Data.Asks); + else + UpdateOrderBook(data.Data.UpdateId, data.Data.Bids, data.Data.Asks); } /// diff --git a/Bybit.UnitTests/InterfacesTests.cs b/Bybit.UnitTests/InterfacesTests.cs index 31621fa5..dea8cf7c 100644 --- a/Bybit.UnitTests/InterfacesTests.cs +++ b/Bybit.UnitTests/InterfacesTests.cs @@ -8,7 +8,7 @@ using Bybit.Net.Clients; using Bybit.Net.Clients.SpotApi; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Sockets; +using CryptoExchange.Net.Objects.Sockets; using NUnit.Framework; namespace Bybit.UnitTests diff --git a/README.md b/README.md index 85d8b38c..2bff4546 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,122 @@ -# Bybit.Net -[![.NET](https://github.com/JKorf/Bybit.Net/actions/workflows/dotnet.yml/badge.svg)](https://github.com/JKorf/Bybit.Net/actions/workflows/dotnet.yml) [![Nuget version](https://img.shields.io/nuget/v/Bybit.net.svg)](https://www.nuget.org/packages/Bybit.Net) [![Nuget downloads](https://img.shields.io/nuget/dt/Bybit.Net.svg)](https://www.nuget.org/packages/Bybit.Net) +# ![.Bybit.Net](https://github.com/JKorf/Bybit.Net/blob/main/ByBit.Net/Icon/icon.png?raw=true) Bybit.Net + +[![.NET](https://img.shields.io/github/actions/workflow/status/JKorf/Bybit.Net/dotnet.yml?style=for-the-badge)](https://github.com/JKorf/Bybit.Net/actions/workflows/dotnet.yml) ![License](https://img.shields.io/github/license/JKorf/Bitget.Net?style=for-the-badge) Bybit.Net is a wrapper around the Bybit API as described on [Bybit](https://bybit-exchange.github.io/docs/spot/#t-introduction), including all features the API provides using clear and readable objects, both for the REST as the websocket API's. + +## Supported Frameworks +The library is targeting both `.NET Standard 2.0` and `.NET Standard 2.1` for optimal compatibility + +|.NET implementation|Version Support| +|--|--| +|.NET Core|`2.0` and higher| +|.NET Framework|`4.6.1` and higher| +|Mono|`5.4` and higher| +|Xamarin.iOS|`10.14` and higher| +|Xamarin.Android|`8.0` and higher| +|UWP|`10.0.16299` and higher| +|Unity|`2018.1` and higher| + +## Get the library +[![Nuget version](https://img.shields.io/nuget/v/Bybit.net.svg?style=for-the-badge)](https://www.nuget.org/packages/Bybit.Net) [![Nuget downloads](https://img.shields.io/nuget/dt/Bybit.Net.svg?style=for-the-badge)](https://www.nuget.org/packages/Bybit.Net) + + dotnet add package Bybit.Net + +## How to use +* REST Endpoints + ```csharp + // Get the ETH/USDT ticker via rest request + var restClient = new BybitRestClient(); + var tickerResult = await restClient.V5Api.ExchangeData.GetSpotTickersAsync("ETHUSDT"); + var lastPrice = tickerResult.Data.List.First().LastPrice; + ``` +* Websocket streams + ```csharp + // Subscribe to ETH/USDT ticker updates via the websocket API + var socketClient = new BybitSocketClient(); + var tickerSubscriptionResult = socketClient.V5SpotApi.SubscribeToTickerUpdatesAsync("ETHUSDT", (update) => + { + var lastPrice = update.Data.LastPrice; + }); + ``` + +For information on the clients, dependency injection, response processing and more see the [documentation](https://jkorf.github.io/CryptoExchange.Net), or have a look at the examples [here](https://github.com/JKorf/CryptoExchange.Net/tree/master/Examples). + +## CryptoExchange.Net +Bybit.Net is based on the [CryptoExchange.Net](https://github.com/JKorf/CryptoExchange.Net) base library. Other exchange API implementations based on the CryptoExchange.Net base library are available and follow the same logic. + +CryptoExchange.Net also allows for [easy access to different exchange API's](https://jkorf.github.io/CryptoExchange.Net#idocs_common). + +|Exchange|Repository|Nuget| +|--|--|--| +|Binance|[JKorf/Binance.Net](https://github.com/JKorf/Binance.Net)|[![Nuget version](https://img.shields.io/nuget/v/Binance.net.svg?style=flat-square)](https://www.nuget.org/packages/Binance.Net)| +|Bitfinex|[JKorf/Bitfinex.Net](https://github.com/JKorf/Bitfinex.Net)|[![Nuget version](https://img.shields.io/nuget/v/Bitfinex.net.svg?style=flat-square)](https://www.nuget.org/packages/Bitfinex.Net)| +|Bitget|[JKorf/Bitget.Net](https://github.com/JKorf/Bitget.Net)|[![Nuget version](https://img.shields.io/nuget/v/Bybit.net.svg?style=flat-square)](https://www.nuget.org/packages/JK.Bitget.Net)| +|CoinEx|[JKorf/CoinEx.Net](https://github.com/JKorf/CoinEx.Net)|[![Nuget version](https://img.shields.io/nuget/v/CoinEx.net.svg?style=flat-square)](https://www.nuget.org/packages/CoinEx.Net)| +|CoinGecko|[JKorf/CoinGecko.Net](https://github.com/JKorf/CoinGecko.Net)|[![Nuget version](https://img.shields.io/nuget/v/CoinGecko.net.svg?style=flat-square)](https://www.nuget.org/packages/CoinGecko.Net)| +|Huobi/HTX|[JKorf/Huobi.Net](https://github.com/JKorf/Huobi.Net)|[![Nuget version](https://img.shields.io/nuget/v/Huobi.net.svg?style=flat-square)](https://www.nuget.org/packages/Huobi.Net)| +|Kraken|[JKorf/Kraken.Net](https://github.com/JKorf/Kraken.Net)|[![Nuget version](https://img.shields.io/nuget/v/KrakenExchange.net.svg?style=flat-square)](https://www.nuget.org/packages/KrakenExchange.Net)| +|Kucoin|[JKorf/Kucoin.Net](https://github.com/JKorf/Kucoin.Net)|[![Nuget version](https://img.shields.io/nuget/v/Kucoin.net.svg?style=flat-square)](https://www.nuget.org/packages/Kucoin.Net)| +|Mexc|[JKorf/Mexc.Net](https://github.com/JKorf/Mexc.Net)|[![Nuget version](https://img.shields.io/nuget/v/JK.Mexc.net.svg?style=flat-square)](https://www.nuget.org/packages/JK.Mexc.Net)| +|OKX|[JKorf/OKX.Net](https://github.com/JKorf/OKX.Net)|[![Nuget version](https://img.shields.io/nuget/v/JK.OKX.net.svg?style=flat-square)](https://www.nuget.org/packages/JK.OKX.Net)| -**If you think something is broken, something is missing or have any questions, please open an [Issue](https://github.com/JKorf/Bybit.Net/issues)** - -[Documentation](https://jkorf.github.io/Bybit.Net/) +## Discord +[![Nuget version](https://img.shields.io/discord/847020490588422145?style=for-the-badge)](https://discord.gg/MSpeEtSY8t) +A Discord server is available [here](https://discord.gg/MSpeEtSY8t). Feel free to join for discussion and/or questions around the CryptoExchange.Net and implementation libraries. -## Installation -`dotnet add package Bybit.Net` +## Supported functionality + +### V5 Api +|API|Supported|Location| +|--|--:|--| +|Market|✓|`restClient.V5Api.ExchangeData`| +|Trade|✓|`restClient.V5Api.Account` / `restClient.V5Api.Trading`| +|Position|✓|`restClient.V5Api.Account` / `restClient.V5Api.Trading`| +|Pre-Upgrade|X|| +|Account|✓|`restClient.V5Api.Account`| +|Asset|✓|`restClient.V5Api.Account`| +|Spot Leverage Token|✓|`restClient.V5Api.ExchangeData` / `restClient.V5Api.Trading`| +|Spot Margin Trade (UTA)|✓|`restClient.V5Api.Account`| +|Spot Margin Trade (Classic)|X|| +|Institutional Loan|X|| +|C2C Lending|X|| +|Broken|✓|`restClient.V5Api.Account`| +|Websocket Stream Public|✓|`socketClient.V5SpotApi` / `socketClient.V5LinearApi` / `socketClient.V5InverseApi` / `socketClient.V5OptionsApi`| +|Websocket Stream Private|✓|`socketClient.V5PrivateApi`| + +### V3 Derivatives +|API|Supported|Location| +|--|--:|--| +|Rest Market|✓|`restClient.DerivativesApi.ExchangeData`| +|Rest Contract|✓|`restClient.DerivativesApi.Account` / `restClient.DerivativesApi.Trading`| +|Websocket Public|✓|`restClient.V5Api.DerivativesApi`| +|Websocket Private|✓|`restClient.V5Api.DerivativesApi`| + +### V3 Spot +|API|Supported|Location| +|--|--:|--| +|Rest Market data|✓|`restClient.SpotV3Api.ExchangeData`| +|Rest Trade|✓|`restClient.SpotV3Api.Trading`| +|Rest Wallet Balance|✓|`restClient.SpotV3Api.Account`| +|Rest Leveraged Token|X|| +|Rest Cross Margin Trade|✓|`restClient.SpotV3Api.Trading`| +|Rest Institutional Loan|X|| +|Websocket Public|✓|`restClient.SpotV3Api`| +|Websocket Private|✓|`restClient.SpotV3Api`| + +### V3 Account Asset +|API|Supported|Location| +|--|--:|--| +|*|X|| + +### V3 Tax +|API|Supported|Location| +|--|--:|--| +|*|X|| ## Support the project I develop and maintain this package on my own for free in my spare time, any support is greatly appreciated. -### Referral link -Sign up using the following referral link to pay a small percentage of the trading fees you pay to support the project instead of paying them straight to Bybit. This doesn't cost you a thing! -[Link](https://partner.bybit.com/b/jkorf) - ### Donate Make a one time donation in a crypto currency of your choice. If you prefer to donate a currency not listed here please contact me. @@ -26,10 +126,14 @@ Make a one time donation in a crypto currency of your choice. If you prefer to d ### Sponsor Alternatively, sponsor me on Github using [Github Sponsors](https://github.com/sponsors/JKorf). -## Discord -A Discord server is available [here](https://discord.gg/MSpeEtSY8t). Feel free to join for discussion and/or questions around the CryptoExchange.Net and implementation libraries. - ## Release notes +* Version 3.4.0-beta1 - 06 Feb 2024 + * Updated CryptoExchange.Net and implemented reworked websocket message handling. For release notes for the CryptoExchange.Net base library see: https://github.com/JKorf/CryptoExchange.Net/tree/beta?tab=readme-ov-file#release-notes + * Fixed issue in DI registration causing http client to not be correctly injected + * Combined update and snapshot handlers for orderbook updates in favor of the UpdateType in the DataEvent wrapper + * Removed excessive constructor overload for BybitRestClient + * Removed deprecated socket APIs + * Version 3.3.0 - 19 Jan 2024 * Added V5Api.Account.GetBrokerEarningsAsync endpoint * Added V5Api.Account.GetBrokerAccountInfoAsync endpoint From 3fd0879ef133b9e18a0b5cbc9aaf36c2300e1c3d Mon Sep 17 00:00:00 2001 From: JKorf Date: Sun, 25 Feb 2024 14:54:53 +0100 Subject: [PATCH 02/17] Updated version info and docs --- ByBit.Net/Bybit.Net.csproj | 8 ++++---- README.md | 13 +++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/ByBit.Net/Bybit.Net.csproj b/ByBit.Net/Bybit.Net.csproj index 879e0bdb..253f6987 100644 --- a/ByBit.Net/Bybit.Net.csproj +++ b/ByBit.Net/Bybit.Net.csproj @@ -7,12 +7,12 @@ Bybit.Net JKorf - 3.4.0-beta1 + 3.4.0 3.4.0 3.4.0 - Bybit.Net is a .Net wrapper for the Bybit API. It includes all features the API provides, REST API and Websocket, using clear and readable objects including but not limited to Reading market info, Placing and managing orders and Reading balances and funds + Bybit.Net is a client library for accessing the Bybit REST and Websocket API. All data is mapped to readable models and enum values. Additional features include an implementation for maintaining a client side order book, easy integration with other exchange client libraries and more. false - Bybit Bybit.Net C# .Net CryptoCurrency Exchange API wrapper + Bybit;Bybit.Net;Bybit Client;Bybit API;CryptoCurrency;CryptoCurrency Exchange git https://github.com/JKorf/Bybit.Net.git https://github.com/JKorf/Bybit.Net @@ -21,7 +21,7 @@ README.md en true - 3.4.0-beta1 - Updated CryptoExchange.Net and implemented reworked websocket message handling. For release notes for the CryptoExchange.Net base library see: https://github.com/JKorf/CryptoExchange.Net/tree/beta?tab=readme-ov-file#release-notes, Fixed issue in DI registration causing http client to not be correctly injected, Combined update and snapshot handlers for orderbook updates in favor of the UpdateType in the DataEvent wrapper, Removed excessive constructor overload for BybitRestClient, Removed deprecated socket APIs + https://github.com/JKorf/Bybit.Net?tab=readme-ov-file#release-notes Bybit.Net.xml diff --git a/README.md b/README.md index 2bff4546..c0e179be 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ [![.NET](https://img.shields.io/github/actions/workflow/status/JKorf/Bybit.Net/dotnet.yml?style=for-the-badge)](https://github.com/JKorf/Bybit.Net/actions/workflows/dotnet.yml) ![License](https://img.shields.io/github/license/JKorf/Bitget.Net?style=for-the-badge) -Bybit.Net is a wrapper around the Bybit API as described on [Bybit](https://bybit-exchange.github.io/docs/spot/#t-introduction), including all features the API provides using clear and readable objects, both for the REST as the websocket API's. - +Bybit.Net is a client library for accessing the [Bybit REST and Websocket API](https://bybit-exchange.github.io/docs/spot/#t-introduction). All data is mapped to readable models and enum values. Additional features include an implementation for maintaining a client side order book, easy integration with other exchange client libraries and more. + ## Supported Frameworks The library is targeting both `.NET Standard 2.0` and `.NET Standard 2.1` for optimal compatibility @@ -121,18 +121,19 @@ I develop and maintain this package on my own for free in my spare time, any sup Make a one time donation in a crypto currency of your choice. If you prefer to donate a currency not listed here please contact me. **Btc**: bc1qz0jv0my7fc60rxeupr23e75x95qmlq6489n8gh -**Eth**: 0x8E21C4d955975cB645589745ac0c46ECA8FAE504 +**Eth**: 0xcb1b63aCF9fef2755eBf4a0506250074496Ad5b7 ### Sponsor Alternatively, sponsor me on Github using [Github Sponsors](https://github.com/sponsors/JKorf). ## Release notes -* Version 3.4.0-beta1 - 06 Feb 2024 - * Updated CryptoExchange.Net and implemented reworked websocket message handling. For release notes for the CryptoExchange.Net base library see: https://github.com/JKorf/CryptoExchange.Net/tree/beta?tab=readme-ov-file#release-notes +* Version 3.4.0 - 25 Feb 2024 + * Updated CryptoExchange.Net and implemented reworked websocket message handling. For release notes for the CryptoExchange.Net base library see: https://github.com/JKorf/CryptoExchange.Net?tab=readme-ov-file#release-notes * Fixed issue in DI registration causing http client to not be correctly injected * Combined update and snapshot handlers for orderbook updates in favor of the UpdateType in the DataEvent wrapper - * Removed excessive constructor overload for BybitRestClient + * Removed redundant BybitRestClient constructor overload * Removed deprecated socket APIs + * Updated some namespaces * Version 3.3.0 - 19 Jan 2024 * Added V5Api.Account.GetBrokerEarningsAsync endpoint From 576986f6457dfe7d146538da633d6c0a7727bb17 Mon Sep 17 00:00:00 2001 From: JKorf Date: Sun, 25 Feb 2024 16:25:30 +0100 Subject: [PATCH 03/17] Fixed docs reference --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c0e179be..d518e971 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ CryptoExchange.Net also allows for [easy access to different exchange API's](htt |--|--|--| |Binance|[JKorf/Binance.Net](https://github.com/JKorf/Binance.Net)|[![Nuget version](https://img.shields.io/nuget/v/Binance.net.svg?style=flat-square)](https://www.nuget.org/packages/Binance.Net)| |Bitfinex|[JKorf/Bitfinex.Net](https://github.com/JKorf/Bitfinex.Net)|[![Nuget version](https://img.shields.io/nuget/v/Bitfinex.net.svg?style=flat-square)](https://www.nuget.org/packages/Bitfinex.Net)| -|Bitget|[JKorf/Bitget.Net](https://github.com/JKorf/Bitget.Net)|[![Nuget version](https://img.shields.io/nuget/v/Bybit.net.svg?style=flat-square)](https://www.nuget.org/packages/JK.Bitget.Net)| +|Bitget|[JKorf/Bitget.Net](https://github.com/JKorf/Bitget.Net)|[![Nuget version](https://img.shields.io/nuget/v/JK.Bitget.net.svg?style=flat-square)](https://www.nuget.org/packages/JK.Bitget.Net)| |CoinEx|[JKorf/CoinEx.Net](https://github.com/JKorf/CoinEx.Net)|[![Nuget version](https://img.shields.io/nuget/v/CoinEx.net.svg?style=flat-square)](https://www.nuget.org/packages/CoinEx.Net)| |CoinGecko|[JKorf/CoinGecko.Net](https://github.com/JKorf/CoinGecko.Net)|[![Nuget version](https://img.shields.io/nuget/v/CoinGecko.net.svg?style=flat-square)](https://www.nuget.org/packages/CoinGecko.Net)| |Huobi/HTX|[JKorf/Huobi.Net](https://github.com/JKorf/Huobi.Net)|[![Nuget version](https://img.shields.io/nuget/v/Huobi.net.svg?style=flat-square)](https://www.nuget.org/packages/Huobi.Net)| From 729069478fc2ae03590cf89fc2d8d880f162246a Mon Sep 17 00:00:00 2001 From: JKorf Date: Mon, 26 Feb 2024 13:36:20 +0100 Subject: [PATCH 04/17] Fixed V3 spot model --- .../Models/Spot/v3/BybitSpotUserTradeV3.cs | 55 ++++++++++--------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/ByBit.Net/Objects/Models/Spot/v3/BybitSpotUserTradeV3.cs b/ByBit.Net/Objects/Models/Spot/v3/BybitSpotUserTradeV3.cs index d3aa111f..313267bb 100644 --- a/ByBit.Net/Objects/Models/Spot/v3/BybitSpotUserTradeV3.cs +++ b/ByBit.Net/Objects/Models/Spot/v3/BybitSpotUserTradeV3.cs @@ -10,77 +10,80 @@ namespace Bybit.Net.Objects.Models.Spot public class BybitSpotUserTradeV3 { /// - /// Trade id + /// Transaction id /// + [JsonProperty("id")] public long Id { get; set; } /// /// Symbol /// + [JsonProperty("symbol")] public string Symbol { get; set; } = string.Empty; /// - /// Symbol name + /// Order id /// - public string SymbolName { get; set; } = string.Empty; + [JsonProperty("orderId")] + public long OrderId { get; set; } /// /// Order id /// - public long OrderId { get; set; } + [JsonProperty("tradeId")] + public long TradeId { get; set; } /// - /// Matching order id + /// Order id /// + [JsonProperty("matchOrderId")] public long MatchOrderId { get; set; } /// /// Trade price /// + [JsonProperty("orderPrice")] public decimal Price { get; set; } /// /// Trade quantity /// - [JsonProperty("qty")] + [JsonProperty("orderQty")] public decimal Quantity { get; set; } /// /// Fee /// - [JsonProperty("commission")] + [JsonProperty("execFee")] public decimal Fee { get; set; } /// /// Fee asset /// - [JsonProperty("commissionAsset")] + [JsonProperty("feeTokenId")] public string FeeAsset { get; set; } = string.Empty; /// + /// Create time + /// + [JsonProperty("creatTime"), JsonConverter(typeof(DateTimeConverter))] + public DateTime CreateTime { get; set; } + /// /// Trade time /// - [JsonProperty("time"), JsonConverter(typeof(DateTimeConverter))] + [JsonProperty("executionTime"), JsonConverter(typeof(DateTimeConverter))] public DateTime TradeTime { get; set; } /// /// Is buyer /// - public bool IsBuyer { get; set; } + [JsonConverter(typeof(BoolConverter))] [JsonProperty("isBuyer")] - private int isBuyer { get => IsBuyer ? 1 : 0; set => IsBuyer = value == 1; } + public bool IsBuyer { get; set; } /// /// Is maker /// - public bool IsMaker { get; set; } + [JsonConverter(typeof(BoolConverter))] [JsonProperty("isMaker")] - private int isMaker { get => IsMaker ? 1 : 0; set => IsMaker = value == 1; } - /// - /// Fee details - /// - [JsonProperty("fee")] - public BybitTradeFee FeeDetails { get; set; } = default!; - /// - /// Fee otken id - /// - public string FeeTokenId { get; set; } = string.Empty; - /// - /// Trading fee - /// - public decimal FeeAmount { get; set; } + public bool IsMaker { get; set; } /// /// Maker rebate /// + [JsonProperty("makerRebate")] public decimal MakerRebate { get; set; } + /// + /// Block trade id + /// + public string? BlockTradeId { get; set; } = string.Empty; } } From 8d626482aff6534f1bf7e614409e98ae96de72d2 Mon Sep 17 00:00:00 2001 From: Luuk Holleman Date: Mon, 26 Feb 2024 13:57:07 +0100 Subject: [PATCH 05/17] Added missing id (#192) --- ByBit.Net/Objects/Models/V5/BybitTransactionLog.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ByBit.Net/Objects/Models/V5/BybitTransactionLog.cs b/ByBit.Net/Objects/Models/V5/BybitTransactionLog.cs index adc34b67..f518b648 100644 --- a/ByBit.Net/Objects/Models/V5/BybitTransactionLog.cs +++ b/ByBit.Net/Objects/Models/V5/BybitTransactionLog.cs @@ -10,6 +10,10 @@ namespace Bybit.Net.Objects.Models.V5 /// public class BybitTransactionLog { + /// + /// Unique id + /// + public string Id { get; set; } = string.Empty; /// /// Symbol /// From 79113ba75b89969cf092991f2248320d399379aa Mon Sep 17 00:00:00 2001 From: JKorf Date: Mon, 26 Feb 2024 14:20:32 +0100 Subject: [PATCH 06/17] Updated BybitPositionModel --- ByBit.Net/Objects/Models/V5/BybitPosition.cs | 28 ++++++- .../V5/Trading/GetPositionsAsync2.txt | 45 +++++++++++ Bybit.UnitTests/JsonToObjectComparer.cs | 74 ++++++++++--------- 3 files changed, 108 insertions(+), 39 deletions(-) create mode 100644 Bybit.UnitTests/JsonResponses/V5/Trading/GetPositionsAsync2.txt diff --git a/ByBit.Net/Objects/Models/V5/BybitPosition.cs b/ByBit.Net/Objects/Models/V5/BybitPosition.cs index 80baac70..0cdaea3e 100644 --- a/ByBit.Net/Objects/Models/V5/BybitPosition.cs +++ b/ByBit.Net/Objects/Models/V5/BybitPosition.cs @@ -66,7 +66,7 @@ private decimal? EntryPrice /// Position status /// [JsonConverter(typeof(EnumConverter))] - public PositionStatus PositionStatus { get; set; } + public PositionStatus? PositionStatus { get; set; } /// /// Leverage /// @@ -99,7 +99,7 @@ private decimal? EntryPrice /// [JsonConverter(typeof(EnumConverter))] [JsonProperty("tpslMode")] - public StopLossTakeProfitMode TakeProfitStopLossMode { get; set; } + public StopLossTakeProfitMode? TakeProfitStopLossMode { get; set; } /// /// Take profit price /// @@ -132,13 +132,13 @@ private decimal? EntryPrice /// [JsonProperty("createdTime")] [JsonConverter(typeof(DateTimeConverter))] - public DateTime CreateTime { get; set; } + public DateTime? CreateTime { get; set; } /// /// Updated timestamp /// [JsonProperty("updatedTime")] [JsonConverter(typeof(DateTimeConverter))] - public DateTime UpdateTime { get; set; } + public DateTime? UpdateTime { get; set; } /// /// Whether to add margin automatically /// @@ -149,5 +149,25 @@ private decimal? EntryPrice /// [JsonProperty("positionBalance")] public decimal? PositionBalance { get; set; } + /// + /// Is reduce only position + /// + [JsonProperty("isReduceOnly")] + public bool? IsReduceOnly { get; set; } + /// + /// When IsReduceOnly = true: the timestamp when the MMR will be forcibly adjusted by the system. When IsReduceOnly = false: the timestamp when the MMR had been adjusted by system + /// + [JsonProperty("mmrSysUpdatedTime")] + public DateTime? MaintenanceMarginUpdateTime { get; set; } + /// + /// When IsReduceOnly = true: the timestamp when the leverage will be forcibly adjusted by the system. When IsReduceOnly = false: the timestamp when the leverage had been adjusted by system + /// + [JsonProperty("leverageSysUpdatedTime")] + public DateTime? LeverageUpdateTime { get; set; } + /// + /// Cross sequence, used to associate each fill and each position update + /// + [JsonProperty("seq")] + public long Sequence { get; set; } } } diff --git a/Bybit.UnitTests/JsonResponses/V5/Trading/GetPositionsAsync2.txt b/Bybit.UnitTests/JsonResponses/V5/Trading/GetPositionsAsync2.txt new file mode 100644 index 00000000..f684dee0 --- /dev/null +++ b/Bybit.UnitTests/JsonResponses/V5/Trading/GetPositionsAsync2.txt @@ -0,0 +1,45 @@ +{ +"retCode": 0, +"retMsg": "OK", +"result": { +"nextPageCursor": "", +"category": "linear", +"list": [ +{ +"symbol": "BTCPERP", +"leverage": "10", +"autoAddMargin": 0, +"avgPrice": "", +"liqPrice": "", +"riskLimitValue": "100000", +"takeProfit": "", +"positionValue": "", +"tpslMode": "", +"isReduceOnly": false, +"riskId": 10001, +"trailingStop": "", +"unrealisedPnl": "", +"markPrice": "", +"adlRankIndicator": 0, +"cumRealisedPnl": "", +"positionMM": "", +"createdTime": "", +"positionIdx": 0, +"positionIM": "", +"seq": -1, +"updatedTime": "", +"side": "", +"bustPrice": "", +"positionBalance": "", +"leverageSysUpdatedTime": "", +"size": "0", +"positionStatus": "", +"mmrSysUpdatedTime": "", +"stopLoss": "", +"tradeMode": 0 +} +] +}, +"retExtInfo": {}, +"time": 1708114419364 +} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonToObjectComparer.cs b/Bybit.UnitTests/JsonToObjectComparer.cs index 57ceef97..5d305b8a 100644 --- a/Bybit.UnitTests/JsonToObjectComparer.cs +++ b/Bybit.UnitTests/JsonToObjectComparer.cs @@ -61,49 +61,53 @@ public async Task ProcessSubject( continue; } - FileStream file = null; - try + for (var i = 0; i < 5; i++) { - var filePath = Path.Combine(path, $"{method.Name}.txt"); - file = File.OpenRead(filePath); - unusedJsonFiles.Remove(filePath); - } - catch (FileNotFoundException) - { - skippedMethods.Add(method.Name); - continue; - } + FileStream file = null; + try + { + var filePath = Path.Combine(path, $"{method.Name}{(i == 0 ? "" : i.ToString())}.txt"); + file = File.OpenRead(filePath); + unusedJsonFiles.Remove(filePath); + } + catch (FileNotFoundException) + { + if (i == 0) + skippedMethods.Add(method.Name); + continue; + } - var buffer = new byte[file.Length]; - await file.ReadAsync(buffer, 0, buffer.Length); - file.Close(); + var buffer = new byte[file.Length]; + await file.ReadAsync(buffer, 0, buffer.Length); + file.Close(); - var json = Encoding.UTF8.GetString(buffer); - var client = _clientFunc(json); + var json = Encoding.UTF8.GetString(buffer); + var client = _clientFunc(json); - var parameters = method.GetParameters(); - var input = new List(); - foreach (var parameter in parameters) - { - if (parametersToSetNull?.Contains(parameter.Name) == true && parameter.ParameterType != typeof(int)) - input.Add(null); - else - input.Add(TestHelpers.GetTestValue(parameter.ParameterType, 1)); - } + var parameters = method.GetParameters(); + var input = new List(); + foreach (var parameter in parameters) + { + if (parametersToSetNull?.Contains(parameter.Name) == true && parameter.ParameterType != typeof(int)) + input.Add(null); + else + input.Add(TestHelpers.GetTestValue(parameter.ParameterType, 1)); + } - // act - var result = (CallResult)await TestHelpers.InvokeAsync(method, getSubject(client), input.ToArray()); + // act + var result = (CallResult)await TestHelpers.InvokeAsync(method, getSubject(client), input.ToArray()); - // asset - Assert.Null(result.Error, method.Name); + // asset + Assert.Null(result.Error, method.Name); - var resultProp = result.GetType().GetProperty("Data", BindingFlags.Public | BindingFlags.Instance); - if (resultProp == null) - // No result - continue; + var resultProp = result.GetType().GetProperty("Data", BindingFlags.Public | BindingFlags.Instance); + if (resultProp == null) + // No result + continue; - var resultData = resultProp.GetValue(result); - ProcessData(method.Name, resultData, json, useNestedJsonPropertyForCompare, useNestedJsonPropertyForAllCompare, ignoreProperties, takeFirstItemForCompare); + var resultData = resultProp.GetValue(result); + ProcessData(method.Name, resultData, json, useNestedJsonPropertyForCompare, useNestedJsonPropertyForAllCompare, ignoreProperties, takeFirstItemForCompare); + } } if (unusedJsonFiles.Any()) From 8d440d6b5553f7e0cff5d7fcd3c542508059b8b7 Mon Sep 17 00:00:00 2001 From: JKorf Date: Mon, 26 Feb 2024 15:54:49 +0100 Subject: [PATCH 07/17] Update V5 and SpotV3 order models --- .../Clients/V5/BybitRestClientApiTrading.cs | 2 +- ByBit.Net/Enums/CancelType.cs | 4 + ByBit.Net/Enums/OcoTriggerType.cs | 26 +++ .../Models/Spot/v3/BybitSpotOrderV3.cs | 159 ++++++++++++------ ByBit.Net/Objects/Models/V5/BybitOrder.cs | 44 ++++- 5 files changed, 185 insertions(+), 50 deletions(-) create mode 100644 ByBit.Net/Enums/OcoTriggerType.cs diff --git a/ByBit.Net/Clients/V5/BybitRestClientApiTrading.cs b/ByBit.Net/Clients/V5/BybitRestClientApiTrading.cs index eb26ef0f..47c12e66 100644 --- a/ByBit.Net/Clients/V5/BybitRestClientApiTrading.cs +++ b/ByBit.Net/Clients/V5/BybitRestClientApiTrading.cs @@ -345,7 +345,7 @@ public async Task> #region Get Open Orders /// - public async Task>> GetOrdersAsync( + public async Task>> GetOrdersAsync( Category category, string? symbol = null, string? baseAsset = null, diff --git a/ByBit.Net/Enums/CancelType.cs b/ByBit.Net/Enums/CancelType.cs index f3f58574..8941e313 100644 --- a/ByBit.Net/Enums/CancelType.cs +++ b/ByBit.Net/Enums/CancelType.cs @@ -78,6 +78,10 @@ public enum CancelType /// CancelByDCP, /// + /// Cancel by Self match prevention + /// + CancelBySmp, + /// /// Unknown /// Unknown diff --git a/ByBit.Net/Enums/OcoTriggerType.cs b/ByBit.Net/Enums/OcoTriggerType.cs new file mode 100644 index 00000000..933a8ff8 --- /dev/null +++ b/ByBit.Net/Enums/OcoTriggerType.cs @@ -0,0 +1,26 @@ +using CryptoExchange.Net.Attributes; + +namespace Bybit.Net.Enums +{ + /// + /// Oco trigger type + /// + public enum OcoTriggerType + { + /// + /// Trigger by unknown + /// + [Map("OcoTriggerByUnknown")] + OcoTriggerByUnknown, + /// + /// Trigger by take profit + /// + [Map("OcoTriggerTp")] + OcoTriggerTp, + /// + /// Trigger by stop loss + /// + [Map("OcoTriggerBySl")] + OcoTriggerBySl + } +} diff --git a/ByBit.Net/Objects/Models/Spot/v3/BybitSpotOrderV3.cs b/ByBit.Net/Objects/Models/Spot/v3/BybitSpotOrderV3.cs index 08ff8e72..9be12de1 100644 --- a/ByBit.Net/Objects/Models/Spot/v3/BybitSpotOrderV3.cs +++ b/ByBit.Net/Objects/Models/Spot/v3/BybitSpotOrderV3.cs @@ -9,94 +9,157 @@ namespace Bybit.Net.Objects.Models.Spot.v3 /// /// Spot order info /// - public class BybitSpotOrderV3 : BybitSpotOrderBase + public class BybitSpotOrderV3 { /// - /// Account ID + /// Account id /// [JsonProperty("accountId")] - public new string AccountId { get; set; } = string.Empty; + public string AccountId { get; set; } = string.Empty; /// - /// Order price + /// Symbol /// - [JsonProperty("orderPrice")] - private decimal OrderPrice - { - get { return Price; } - set { Price = value; } - } + [JsonProperty("symbol")] + public string Symbol { get; set; } = string.Empty; /// - /// Trigger price + /// Client order id /// - [JsonProperty("triggerPrice")] - public decimal TriggerPrice { get; set; } + [JsonProperty("orderLinkId")] + public string? ClientOrderId { get; set; } + + /// + /// Order id + /// + [JsonProperty("orderId")] + public string OrderId { get; set; } = string.Empty; + + /// + /// Order price + /// + [JsonProperty("orderPrice")] + public decimal Price { get; set; } /// /// Order quantity /// [JsonProperty("orderQty")] - private decimal OrderQuantity - { - get { return Quantity; } - set { Quantity = value; } - } + public decimal Quantity { get; set; } /// - /// Type + /// Quantity filled /// - [JsonConverter(typeof(OrderTypeSpotConverter))] - [JsonProperty("orderType")] - private OrderType OrderType - { - get { return Type; } - set { Type = value; } - } + [JsonProperty("execQty")] + public decimal QuantityFilled { get; set; } /// - /// Average execution price + /// Value of the order + /// + [JsonProperty("cummulativeQuoteQty")] + public decimal QuoteQuantity { get; set; } + + /// + /// Average fill price /// [JsonProperty("avgPrice")] public decimal AveragePrice { get; set; } + /// - /// Ice berg quantity + /// Order status /// - [JsonProperty("icebergQty")] - public decimal? IcebergQuantity { get; set; } + [JsonProperty("status")] + [JsonConverter(typeof(OrderStatusSpotConverter))] + public OrderStatus Status { get; set; } + /// - /// Creation time + /// Time in force /// - [JsonConverter(typeof(DateTimeConverter))] - [JsonProperty("createTime")] - public DateTime CreateTime { get; set; } + [JsonProperty("timeInForce")] + [JsonConverter(typeof(TimeInForceSpotConverter))] + public TimeInForce TimeInForce { get; set; } + /// - /// Last update time + /// Order type /// - [JsonConverter(typeof(DateTimeConverter))] - [JsonProperty("updateTime")] - public DateTime UpdateTime { get; set; } + [JsonProperty("orderType")] + [JsonConverter(typeof(OrderTypeSpotConverter))] + public OrderType OrderType { get; set; } + + /// + /// Order side + /// + [JsonProperty("side")] + [JsonConverter(typeof(OrderSideConverter))] + public OrderSide OrderSide { get; set; } + /// /// Stop price /// - public decimal? StopPrice { get; set; } + [JsonProperty("stopPrice")] + public decimal StopPrice { get; set; } + /// - /// Quantity executed + /// Iceberg quantity /// - [JsonProperty("execQty")] - public decimal QuantityFilled { get; set; } + [JsonProperty("icebergQty")] + public decimal IcebergQuantity { get; set; } + /// - /// Quote quantity + /// Create time /// - [JsonProperty("cummulativeQuoteQty")] - public decimal QuoteQuantity { get; set; } + [JsonProperty("createTime"), JsonConverter(typeof(DateTimeConverter))] + public DateTime? CreateTime { get; set; } + + /// + /// Update time + /// + [JsonProperty("updateTime"), JsonConverter(typeof(DateTimeConverter))] + public DateTime? UpdateTime { get; set; } /// /// Is working /// - /// 0:valid, 1:invalid - [JsonProperty("isWorking")] - [JsonConverter(typeof(BoolConverter))] + [JsonProperty("isWorking"), JsonConverter(typeof(BoolConverter))] public bool IsWorking { get; set; } + + /// + /// Quantity reserved for order + /// + [JsonProperty("locked")] + public decimal Locked { get; set; } + + /// + /// Block trade id + /// + [JsonProperty("blockTradeId")] + public string BlockTradeId { get; set; } = string.Empty; + + /// + /// Cancel type + /// + [JsonProperty("cancelType"), JsonConverter(typeof(EnumConverter))] + public CancelType? CancelType { get; set; } + + /// + /// Self match prevention type + /// + [JsonProperty("smpType"), JsonConverter(typeof(EnumConverter))] + public SelfMatchPreventionType? SelfMatchPreventionType { get; set; } + /// + /// Self match prevention group, 0 by default + /// + [JsonProperty("smpGroup")] + public int? SelfMatchPreventionGroup { get; set; } + /// + /// The counterparty's orderID which triggers this SMP execution + /// + [JsonProperty("smpOrderId")] + public string? SelfMatchPreventionOrderId { get; set; } + /// + /// Trigger price + /// + [JsonProperty("triggerPrice")] + public decimal? TriggerPrice { get; set; } } } diff --git a/ByBit.Net/Objects/Models/V5/BybitOrder.cs b/ByBit.Net/Objects/Models/V5/BybitOrder.cs index 787bb661..ff8977a5 100644 --- a/ByBit.Net/Objects/Models/V5/BybitOrder.cs +++ b/ByBit.Net/Objects/Models/V5/BybitOrder.cs @@ -1,4 +1,5 @@ using Bybit.Net.Enums; +using Bybit.Net.Enums.V5; using CryptoExchange.Net.Converters; using Newtonsoft.Json; using System; @@ -50,7 +51,7 @@ public class BybitOrder /// Position mode /// [JsonProperty("positionIdx")] - public PositionMode? PositionMode { get; set; } + public Enums.V5.PositionMode? PositionMode { get; set; } /// /// Order status /// @@ -178,5 +179,46 @@ public class BybitOrder [JsonProperty("updatedTime")] [JsonConverter(typeof(DateTimeConverter))] public DateTime UpdateTime { get; set; } + /// + /// Order create type + /// + [JsonProperty("createType")] + public string? CreateType { get; set; } + /// + /// Market unit for quantity + /// + [JsonProperty("marketUnit"), JsonConverter(typeof(EnumConverter))] + public MarketUnit? MarketUnit { get; set; } + /// + /// Oco trigger type + /// + [JsonProperty("ocoTriggerType"), JsonConverter(typeof(EnumConverter))] + public OcoTriggerType? OcoTriggerType { get; set; } + /// + /// Take profit limit price + /// + [JsonProperty("tpLimitPrice")] + public decimal? TakeProfitLimitPrice { get; set; } + /// + /// Stop loss limit price + /// + [JsonProperty("slLimitPrice")] + public decimal? StopLossLimitPrice { get; set; } + + /// + /// Self match prevention type + /// + [JsonProperty("smpType"), JsonConverter(typeof(EnumConverter))] + public SelfMatchPreventionType? SelfMatchPreventionType { get; set; } + /// + /// Self match prevention group, 0 by default + /// + [JsonProperty("smpGroup")] + public int? SelfMatchPreventionGroup { get; set; } + /// + /// The counterparty's orderID which triggers this SMP execution + /// + [JsonProperty("smpOrderId")] + public string? SelfMatchPreventionOrderId { get; set; } } } From bc05fb7e3039b575a187d911b62127b25b28ab22 Mon Sep 17 00:00:00 2001 From: JKorf Date: Mon, 26 Feb 2024 17:11:24 +0100 Subject: [PATCH 08/17] Removed deprecated V1 and V2 API's --- ByBit.Net/Clients/BybitRestClient.cs | 30 - ByBit.Net/Clients/BybitSocketClient.cs | 1 - .../GeneralApi/BybitRestClientGeneralApi.cs | 101 ---- .../BybitRestClientGeneralApiTransfer.cs | 236 -------- ...ybitRestClientGeneralApiWithdrawDeposit.cs | 210 ------- .../BybitRestClientInverseFuturesApi.cs | 134 ----- ...BybitRestClientInverseFuturesApiAccount.cs | 323 ----------- ...RestClientInverseFuturesApiExchangeData.cs | 211 ------- ...BybitRestClientInverseFuturesApiTrading.cs | 527 ----------------- .../BybitRestClientInversePerpetualApi.cs | 134 ----- ...bitRestClientInversePerpetualApiAccount.cs | 314 ----------- ...stClientInversePerpetualApiExchangeData.cs | 245 -------- ...bitRestClientInversePerpetualApiTrading.cs | 523 ----------------- .../v1/BybitRestClientSpotApiAccountV1.cs | 50 -- .../BybitRestClientSpotApiExchangeDataV1.cs | 207 ------- .../v1/BybitRestClientSpotApiTradingV1.cs | 235 -------- .../SpotApi/v1/BybitRestClientSpotApiV1.cs | 319 ----------- .../BybitRestClientUsdPerpetualApi.cs | 133 ----- .../BybitRestClientUsdPerpetualApiAccount.cs | 377 ------------- ...itRestClientUsdPerpetualApiExchangeData.cs | 242 -------- .../BybitRestClientUsdPerpetualApiTrading.cs | 533 ------------------ .../GeneralApi/IBybitRestClientGeneralApi.cs | 20 - .../IBybitRestClientGeneralApiTransfer.cs | 173 ------ ...ybitRestClientGeneralApiWithdrawDeposit.cs | 159 ------ .../Interfaces/Clients/IBybitRestClient.cs | 25 - .../Interfaces/Clients/IBybitSocketClient.cs | 1 - .../IBybitRestClientInverseFuturesApi.cs | 26 - ...BybitRestClientInverseFuturesApiAccount.cs | 208 ------- ...RestClientInverseFuturesApiExchangeData.cs | 138 ----- ...BybitRestClientInverseFuturesApiTrading.cs | 269 --------- .../IBybitRestClientInversePerpetualApi.cs | 26 - ...bitRestClientInversePerpetualApiAccount.cs | 217 ------- ...stClientInversePerpetualApiExchangeData.cs | 159 ------ ...bitRestClientInversePerpetualApiTrading.cs | 264 --------- .../v1/IBybitRestClientSpotApiAccountV1.cs | 31 - .../IBybitRestClientSpotApiExchangeDataV1.cs | 136 ----- .../v1/IBybitRestClientSpotApiTradingV1.cs | 152 ----- .../SpotApi/v1/IBybitRestClientSpotApiV1.cs | 33 -- .../IBybitRestClientUsdPerpetualApi.cs | 26 - .../IBybitRestClientUsdPerpetualApiAccount.cs | 242 -------- ...itRestClientUsdPerpetualApiExchangeData.cs | 157 ------ .../IBybitRestClientUsdPerpetualApiTrading.cs | 274 --------- .../Models/Spot/v3/BybitSpotOrderV3.cs | 8 +- ByBit.Net/Objects/Options/BybitRestOptions.cs | 18 - .../Objects/Options/BybitSocketOptions.cs | 30 - Bybit.UnitTests/JsonTests.cs | 193 ------- Bybit.UnitTests/TestHelpers.cs | 22 +- 47 files changed, 5 insertions(+), 8087 deletions(-) delete mode 100644 ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApi.cs delete mode 100644 ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApiTransfer.cs delete mode 100644 ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApiWithdrawDeposit.cs delete mode 100644 ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApi.cs delete mode 100644 ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApiAccount.cs delete mode 100644 ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApiExchangeData.cs delete mode 100644 ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApiTrading.cs delete mode 100644 ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApi.cs delete mode 100644 ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApiAccount.cs delete mode 100644 ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApiExchangeData.cs delete mode 100644 ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApiTrading.cs delete mode 100644 ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiAccountV1.cs delete mode 100644 ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiExchangeDataV1.cs delete mode 100644 ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiTradingV1.cs delete mode 100644 ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiV1.cs delete mode 100644 ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApi.cs delete mode 100644 ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApiAccount.cs delete mode 100644 ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApiExchangeData.cs delete mode 100644 ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApiTrading.cs delete mode 100644 ByBit.Net/Interfaces/Clients/GeneralApi/IBybitRestClientGeneralApi.cs delete mode 100644 ByBit.Net/Interfaces/Clients/GeneralApi/IBybitRestClientGeneralApiTransfer.cs delete mode 100644 ByBit.Net/Interfaces/Clients/GeneralApi/IBybitRestClientGeneralApiWithdrawDeposit.cs delete mode 100644 ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApi.cs delete mode 100644 ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApiAccount.cs delete mode 100644 ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApiExchangeData.cs delete mode 100644 ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApiTrading.cs delete mode 100644 ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApi.cs delete mode 100644 ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApiAccount.cs delete mode 100644 ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApiExchangeData.cs delete mode 100644 ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApiTrading.cs delete mode 100644 ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiAccountV1.cs delete mode 100644 ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiExchangeDataV1.cs delete mode 100644 ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiTradingV1.cs delete mode 100644 ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiV1.cs delete mode 100644 ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApi.cs delete mode 100644 ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApiAccount.cs delete mode 100644 ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApiExchangeData.cs delete mode 100644 ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApiTrading.cs diff --git a/ByBit.Net/Clients/BybitRestClient.cs b/ByBit.Net/Clients/BybitRestClient.cs index 6ba6b447..a610abbc 100644 --- a/ByBit.Net/Clients/BybitRestClient.cs +++ b/ByBit.Net/Clients/BybitRestClient.cs @@ -1,17 +1,7 @@ using Bybit.Net.Clients.CopyTradingApi; -using Bybit.Net.Clients.GeneralApi; -using Bybit.Net.Clients.InverseFuturesApi; -using Bybit.Net.Clients.InversePerpetualApi; -using Bybit.Net.Clients.UsdPerpetualApi; using Bybit.Net.Interfaces.Clients; using Bybit.Net.Interfaces.Clients.CopyTradingApi; -using Bybit.Net.Interfaces.Clients.GeneralApi; -using Bybit.Net.Interfaces.Clients.InverseFuturesApi; -using Bybit.Net.Interfaces.Clients.InversePerpetualApi; -using Bybit.Net.Interfaces.Clients.SpotApi.v1; -using Bybit.Net.Interfaces.Clients.UsdPerpetualApi; using CryptoExchange.Net; -using Bybit.Net.Clients.SpotApi.v1; using Bybit.Net.Clients.SpotApi.v3; using Bybit.Net.Interfaces.Clients.SpotApi.v3; using Bybit.Net.Interfaces.Clients.DerivativesApi; @@ -27,19 +17,9 @@ namespace Bybit.Net.Clients /// public class BybitRestClient : BaseRestClient, IBybitRestClient { - /// - public IBybitRestClientGeneralApi GeneralApi { get; } - /// - public IBybitRestClientSpotApiV1 SpotApiV1 { get; } /// public IBybitRestClientSpotApiV3 SpotApiV3 { get; } /// - public IBybitRestClientInversePerpetualApi InversePerpetualApi { get; } - /// - public IBybitRestClientInverseFuturesApi InverseFuturesApi { get; } - /// - public IBybitRestClientUsdPerpetualApi UsdPerpetualApi { get; } - /// public IBybitRestClientCopyTradingApi CopyTradingApi { get; } /// public IBybitRestClientDerivativesApi DerivativesApi { get; } @@ -69,12 +49,7 @@ public BybitRestClient(HttpClient? httpClient, ILoggerFactory? loggerFactory, Ac optionsDelegate(options); Initialize(options); - InversePerpetualApi = AddApiClient(new BybitRestClientInversePerpetualApi(_logger, httpClient, options)); - InverseFuturesApi = AddApiClient(new BybitRestClientInverseFuturesApi(_logger, httpClient, options)); - UsdPerpetualApi = AddApiClient(new BybitRestClientUsdPerpetualApi(_logger, httpClient, options)); - SpotApiV1 = AddApiClient(new BybitRestClientSpotApiV1(_logger, httpClient, options)); SpotApiV3 = AddApiClient(new BybitRestClientSpotApiV3(_logger, httpClient, options)); - GeneralApi = AddApiClient(new BybitRestClientGeneralApi(_logger, this, httpClient, options)); CopyTradingApi = AddApiClient(new BybitRestClientCopyTradingApi(_logger, httpClient, options)); DerivativesApi = AddApiClient(new BybitRestClientDerivativesApi(_logger, httpClient, options)); V5Api = AddApiClient(new V5.BybitRestClientApi(_logger, httpClient, options)); @@ -96,12 +71,7 @@ public static void SetDefaultOptions(Action optionsDelegate) /// public void SetApiCredentials(ApiCredentials credentials) { - InversePerpetualApi.SetApiCredentials(credentials); - InverseFuturesApi.SetApiCredentials(credentials); - UsdPerpetualApi.SetApiCredentials(credentials); - SpotApiV1.SetApiCredentials(credentials); SpotApiV3.SetApiCredentials(credentials); - GeneralApi.SetApiCredentials(credentials); CopyTradingApi.SetApiCredentials(credentials); DerivativesApi.SetApiCredentials(credentials); V5Api.SetApiCredentials(credentials); diff --git a/ByBit.Net/Clients/BybitSocketClient.cs b/ByBit.Net/Clients/BybitSocketClient.cs index c94bb105..83bb1a1e 100644 --- a/ByBit.Net/Clients/BybitSocketClient.cs +++ b/ByBit.Net/Clients/BybitSocketClient.cs @@ -1,7 +1,6 @@ using CryptoExchange.Net; using System; using Bybit.Net.Interfaces.Clients; -using Bybit.Net.Interfaces.Clients.UsdPerpetualApi; using Bybit.Net.Interfaces.Clients.SpotApi.v3; using Bybit.Net.Interfaces.Clients.DerivativesApi.UnifiedMarginApi; using Bybit.Net.Interfaces.Clients.DerivativesApi.ContractApi; diff --git a/ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApi.cs b/ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApi.cs deleted file mode 100644 index 0a6dd397..00000000 --- a/ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApi.cs +++ /dev/null @@ -1,101 +0,0 @@ -using Bybit.Net.Clients.CopyTradingApi; -using Bybit.Net.Clients.InversePerpetualApi; -using Bybit.Net.Interfaces.Clients.GeneralApi; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Options; -using CryptoExchange.Net; -using CryptoExchange.Net.Authentication; -using CryptoExchange.Net.Objects; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.GeneralApi -{ - /// - public class BybitRestClientGeneralApi : RestApiClient, IBybitRestClientGeneralApi - { - private readonly BybitRestClient _baseClient; - - /// - /// Options - /// - public new BybitRestOptions ClientOptions => (BybitRestOptions)base.ClientOptions; - - /// - public IBybitRestClientGeneralApiTransfer Transfer { get; } - /// - public IBybitRestClientGeneralApiWithdrawDeposit WithdrawDeposit { get; } - - #region ctor - internal BybitRestClientGeneralApi(ILogger logger, BybitRestClient restClient, HttpClient? httpClient, BybitRestOptions options) : - base(logger, httpClient, options.Environment.RestBaseAddress, options, options.InversePerpetualOptions) - { - if (!string.IsNullOrEmpty(options.Referer)) - { - StandardRequestHeaders = new Dictionary - { - { "x-referer", options.Referer! } - }; - } - - _baseClient = restClient; - - Transfer = new BybitRestClientGeneralApiTransfer(this); - WithdrawDeposit = new BybitRestClientGeneralApiWithdrawDeposit(this); - - requestBodyFormat = RequestBodyFormat.Json; - ParameterPositions[HttpMethod.Delete] = HttpMethodParameterPosition.InUri; - } - #endregion - - /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) - => new BybitAuthenticationProvider(credentials); - - /// - /// Get url for an endpoint - /// - /// - /// - internal Uri GetUrl(string endpoint) - { - return new Uri(BaseAddress.AppendPath(endpoint)); - } - - internal async Task> SendRequestAsync( - Uri uri, - HttpMethod method, - CancellationToken cancellationToken, - Dictionary? parameters = null, - bool signed = false, - JsonSerializer? deserializer = null) - { - var result = await base.SendRequestAsync>(uri, method, cancellationToken, parameters, signed, deserializer: deserializer).ConfigureAwait(false); - if (!result) - return result.As(default); - - if (result.Data.ReturnCode != 0) - return result.AsError(new ServerError(result.Data.ReturnCode, result.Data.ReturnMessage)); - - return result.As(result.Data.Result); - } - - - /// - protected override Task> GetServerTimestampAsync() - => _baseClient.InversePerpetualApi.ExchangeData.GetServerTimeAsync(); - - /// - public override TimeSyncInfo? GetTimeSyncInfo() - => new TimeSyncInfo(_logger, (ApiOptions.AutoTimestamp ?? ClientOptions.AutoTimestamp), (ApiOptions.TimestampRecalculationInterval ?? ClientOptions.TimestampRecalculationInterval), BybitRestClientInversePerpetualApi._timeSyncState); - - /// - public override TimeSpan? GetTimeOffset() - => BybitRestClientCopyTradingApi._timeSyncState.TimeOffset; - } -} diff --git a/ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApiTransfer.cs b/ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApiTransfer.cs deleted file mode 100644 index cd5303b8..00000000 --- a/ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApiTransfer.cs +++ /dev/null @@ -1,236 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Bybit.Net.Interfaces.Clients.GeneralApi; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net; -using CryptoExchange.Net.Converters; -using CryptoExchange.Net.Objects; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.GeneralApi -{ - /// - public class BybitRestClientGeneralApiTransfer : IBybitRestClientGeneralApiTransfer - { - private BybitRestClientGeneralApi _baseClient; - - internal BybitRestClientGeneralApiTransfer(BybitRestClientGeneralApi baseClient) - { - _baseClient = baseClient; - } - - #region Create internal transfer - - /// - public async Task> CreateInternalTransferAsync(string transferId, string asset, decimal quantity, AccountType fromAccountType, AccountType toAccountType, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "transfer_id", transferId }, - { "coin", asset }, - { "amount", quantity.ToString(CultureInfo.InvariantCulture) }, - { "from_account_type", EnumConverter.GetString(fromAccountType)! }, - { "to_account_type", EnumConverter.GetString(toAccountType)! }, - }; - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("asset/v1/private/transfer"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Create subaccount transfer - - /// - public async Task> CreateSubAccountTransferAsync(string transferId, string asset, decimal quantity, string subAccountId, TransferType type, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "transfer_id", transferId }, - { "coin", asset }, - { "amount", quantity.ToString(CultureInfo.InvariantCulture) }, - { "sub_user_id", subAccountId }, - { "type", EnumConverter.GetString(type)! }, - }; - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("asset/v1/private/sub-member/transfer"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get transfer history - - /// - public async Task>>> GetTransferHistoryAsync( - string? transferId = null, - string? asset = null, - TransferStatus? status = null, - DateTime? startTime = null, - DateTime? endTime = null, - SearchDirection? direction = null, - int? limit = null, - string? cursor = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("transfer_id", transferId); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("status", EnumConverter.GetString(status)); - parameters.AddOptionalParameter("start_time", DateTimeConverter.ConvertToMilliseconds(startTime)); - parameters.AddOptionalParameter("end_time", DateTimeConverter.ConvertToMilliseconds(endTime)); - parameters.AddOptionalParameter("direction", transferId); - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("direction", direction == null ? null : JsonConvert.SerializeObject(direction, new SearchDirectionConverter(false))); - parameters.AddOptionalParameter("cursor", cursor); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("asset/v1/private/transfer/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get subaccount transfer history - - /// - public async Task>>> GetSubAccountTransferHistoryAsync( - string? transferId = null, - string? asset = null, - TransferStatus? status = null, - DateTime? startTime = null, - DateTime? endTime = null, - SearchDirection? direction = null, - int? limit = null, - string? cursor = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("transfer_id", transferId); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("status", EnumConverter.GetString(status)); - parameters.AddOptionalParameter("start_time", DateTimeConverter.ConvertToMilliseconds(startTime)); - parameters.AddOptionalParameter("end_time", DateTimeConverter.ConvertToMilliseconds(endTime)); - parameters.AddOptionalParameter("direction", transferId); - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("direction", direction == null ? null : JsonConvert.SerializeObject(direction, new SearchDirectionConverter(false))); - parameters.AddOptionalParameter("cursor", cursor); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("asset/v1/private/sub-member/transfer/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get subaccounts - - /// - public async Task> GetSubAccountsAsync(long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("asset/v1/private/sub-member/member-ids"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Enable Subaccounts Universal Transfer - - /// - public async Task EnableSubaccountsUniversalTransferAsync(IEnumerable? subaccountIds = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("transferable_sub_ids", subaccountIds == null ? null : string.Join(",", subaccountIds)); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("/asset/v1/private/transferable-subs/save"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - return result.AsDataless(); - } - - #endregion - - #region Enable Subaccounts Universal Transfer - - /// - public async Task> UniversalTransferAsync(string transferId, string asset, decimal quantity, string fromMemberId, string toMemberId, AccountType fromAccountType, AccountType toAccountType, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "transfer_id", transferId }, - { "coin", asset }, - { "amount", quantity.ToString(CultureInfo.InvariantCulture) }, - { "from_member_id", fromMemberId }, - { "to_member_id", toMemberId }, - { "from_account_type", EnumConverter.GetString(fromAccountType) }, - { "to_account_type", EnumConverter.GetString(toAccountType) }, - }; - - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("/asset/v1/private/universal/transfer"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get universal transfer history - - /// - public async Task>>> GetUniversalTransferHistoryAsync( - string? transferId = null, - string? asset = null, - TransferStatus? status = null, - DateTime? startTime = null, - DateTime? endTime = null, - SearchDirection? direction = null, - int? limit = null, - string? cursor = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("transfer_id", transferId); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("status", EnumConverter.GetString(status)); - parameters.AddOptionalParameter("start_time", DateTimeConverter.ConvertToMilliseconds(startTime)); - parameters.AddOptionalParameter("end_time", DateTimeConverter.ConvertToMilliseconds(endTime)); - parameters.AddOptionalParameter("direction", transferId); - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("direction", direction == null ? null : JsonConvert.SerializeObject(direction, new SearchDirectionConverter(false))); - parameters.AddOptionalParameter("cursor", cursor); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("asset/v1/private/universal/transfer/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get transfer balance - - /// - public async Task> GetAssetBalanceAsync(AccountType accountType, string asset, long? receiveWindow = null, CancellationToken ct = default) - { - string queryUrl = "asset/v3/private/transfer/account-coin/balance/query"; - - var parameters = new Dictionary() - { - { "accountType", EnumConverter.GetString(accountType) }, - { "coin", asset } - }; - - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl(queryUrl), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - } -} diff --git a/ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApiWithdrawDeposit.cs b/ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApiWithdrawDeposit.cs deleted file mode 100644 index d9e3f64f..00000000 --- a/ByBit.Net/Clients/GeneralApi/BybitRestClientGeneralApiWithdrawDeposit.cs +++ /dev/null @@ -1,210 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Bybit.Net.Interfaces.Clients.GeneralApi; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net; -using CryptoExchange.Net.Converters; -using CryptoExchange.Net.Objects; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.GeneralApi -{ - /// - public class BybitRestClientGeneralApiWithdrawDeposit : IBybitRestClientGeneralApiWithdrawDeposit - { - private readonly BybitRestClientGeneralApi _baseClient; - - internal BybitRestClientGeneralApiWithdrawDeposit(BybitRestClientGeneralApi baseClient) - { - _baseClient = baseClient; - } - - #region Get supported deposit methods - - /// - public async Task>> GetSupportedDepositMethodsAsync( - string? asset = null, - string? network = null, - int? page = null, - int? pageSize = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("chain", network); - parameters.AddOptionalParameter("page_index", page); - parameters.AddOptionalParameter("page_size", pageSize); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("/asset/v1/public/deposit/allowed-deposit-list"), HttpMethod.Get, ct, parameters, false).ConfigureAwait(false); - return result.As(result.Data?.ConfigList!); - } - - #endregion - - #region Get deposit history - - /// - public async Task>>> GetDepositHistoryAsync( - string? asset = null, - DateTime? startTime = null, - DateTime? endTime = null, - SearchDirection? direction = null, - int? limit = null, - string? cursor = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("start_time", DateTimeConverter.ConvertToSeconds(startTime)); - parameters.AddOptionalParameter("end_time", DateTimeConverter.ConvertToSeconds(endTime)); - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("direction", direction == null ? null : JsonConvert.SerializeObject(direction, new SearchDirectionConverter(false))); - parameters.AddOptionalParameter("cursor", cursor); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("/asset/v1/private/deposit/record/query"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get withdrawal history - - /// - public async Task>>> GetWithdrawalHistoryAsync( - string? withdrawalId = null, - string? asset = null, - DateTime? startTime = null, - DateTime? endTime = null, - SearchDirection? direction = null, - int? limit = null, - string? cursor = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("withdraw_id", withdrawalId); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("start_time", DateTimeConverter.ConvertToSeconds(startTime)); - parameters.AddOptionalParameter("end_time", DateTimeConverter.ConvertToSeconds(endTime)); - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("direction", direction == null ? null : JsonConvert.SerializeObject(direction, new SearchDirectionConverter(false))); - parameters.AddOptionalParameter("cursor", cursor); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("/asset/v1/private/withdraw/record/query"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get asset info - - /// - public async Task>> GetAssetInfoAsync( - string? asset = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("/asset/v1/private/coin-info/query"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - return result.As>(result.Data?.Data); - } - - #endregion - - #region Get account info - - /// - public async Task>> GetAccountInfoAsync( - string? asset = null, - string? accountType = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("account_type", accountType); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("/asset/v1/private/asset-info/query"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Withdraw - - /// - public async Task> WithdrawAsync( - string asset, - string network, - string address, - decimal quantity, - string? tag = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "coin", asset }, - { "chain", network }, - { "address", address }, - { "amount", quantity.ToString(CultureInfo.InvariantCulture) } - }; - parameters.AddOptionalParameter("tag", tag); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("/asset/v1/private/withdraw"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Cancel withdrawal - - /// - public async Task CancelWithdrawalAsync( - string withdrawalId, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "id", withdrawalId } - }; - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("/asset/v1/private/withdraw/cancel"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - return result.AsDataless(); - } - - #endregion - - #region Get account info - - /// - public async Task> GetDepositAddressesAsync( - string asset, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("/asset/v1/private/deposit/address"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - } -} diff --git a/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApi.cs b/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApi.cs deleted file mode 100644 index bedd569c..00000000 --- a/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApi.cs +++ /dev/null @@ -1,134 +0,0 @@ -using Bybit.Net.Interfaces.Clients.InverseFuturesApi; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Options; -using CryptoExchange.Net; -using CryptoExchange.Net.Authentication; -using CryptoExchange.Net.Objects; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.InverseFuturesApi -{ - /// - public class BybitRestClientInverseFuturesApi : RestApiClient, IBybitRestClientInverseFuturesApi - { - - internal static TimeSyncState _timeSyncState = new TimeSyncState("Inverse Futures Api"); - /// - /// Options - /// - public new BybitRestOptions ClientOptions => (BybitRestOptions)base.ClientOptions; - - /// - public IBybitRestClientInverseFuturesApiAccount Account { get; } - /// - public IBybitRestClientInverseFuturesApiExchangeData ExchangeData { get; } - /// - public IBybitRestClientInverseFuturesApiTrading Trading { get; } - - #region ctor - internal BybitRestClientInverseFuturesApi(ILogger logger, HttpClient? httpClient, BybitRestOptions options) : - base(logger, httpClient, options.Environment.RestBaseAddress, options, options.InverseFuturesOptions) - { - if (!string.IsNullOrEmpty(options.Referer)) - { - StandardRequestHeaders = new Dictionary - { - { "x-referer", options.Referer! } - }; - } - - manualParseError = true; - - Account = new BybitRestClientInverseFuturesApiAccount(this); - ExchangeData = new BybitRestClientInverseFuturesApiExchangeData(this); - Trading = new BybitRestClientInverseFuturesApiTrading(this); - - requestBodyFormat = RequestBodyFormat.FormData; - ParameterPositions[HttpMethod.Delete] = HttpMethodParameterPosition.InUri; - } - #endregion - - /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) - => new BybitAuthenticationProvider(credentials); - - /// - /// Get url for an endpoint - /// - /// - /// - internal Uri GetUrl(string endpoint) - { - return new Uri(BaseAddress.AppendPath(endpoint)); - } - - /// - protected override Task TryParseErrorAsync(JToken data) - { - var responseCode = data["ret_code"]; - if (responseCode != null && responseCode.ToString() != "0") - { - var errorMessage = data["ret_msg"]; - return Task.FromResult(new ServerError(responseCode.Value(), errorMessage!.ToString()))!; - } - - return Task.FromResult(null); - } - - internal async Task>> SendRequestWrapperAsync( - Uri uri, - HttpMethod method, - CancellationToken cancellationToken, - Dictionary? parameters = null, - bool signed = false, - JsonSerializer? deserializer = null, - bool ignoreRatelimit = false) where T : class - { - var result = await base.SendRequestAsync>(uri, method, cancellationToken, parameters, signed, deserializer: deserializer, ignoreRatelimit: ignoreRatelimit).ConfigureAwait(false); - if (!result) - return result.As>(default); - - if (result.Data.ReturnCode != 0) - return result.AsError>(new ServerError(result.Data.ReturnCode, result.Data.ReturnMessage)); - - return result.As(result.Data); - } - - internal async Task> SendRequestAsync( - Uri uri, - HttpMethod method, - CancellationToken cancellationToken, - Dictionary? parameters = null, - bool signed = false, - JsonSerializer? deserializer = null) - { - var result = await base.SendRequestAsync>(uri, method, cancellationToken, parameters, signed, deserializer: deserializer).ConfigureAwait(false); - if (!result) - return result.As(default); - - if (result.Data.ReturnCode != 0) - return result.AsError(new ServerError(result.Data.ReturnCode, result.Data.ReturnMessage)); - - return result.As(result.Data.Result); - } - - /// - protected override Task> GetServerTimestampAsync() - => ExchangeData.GetServerTimeAsync(); - - /// - public override TimeSyncInfo? GetTimeSyncInfo() - => new TimeSyncInfo(_logger, (ApiOptions.AutoTimestamp ?? ClientOptions.AutoTimestamp), (ApiOptions.TimestampRecalculationInterval ?? ClientOptions.TimestampRecalculationInterval), _timeSyncState); - - /// - public override TimeSpan? GetTimeOffset() - => _timeSyncState.TimeOffset; - } -} diff --git a/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApiAccount.cs b/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApiAccount.cs deleted file mode 100644 index 5a4c9001..00000000 --- a/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApiAccount.cs +++ /dev/null @@ -1,323 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Bybit.Net.Interfaces.Clients.InverseFuturesApi; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net; -using CryptoExchange.Net.Converters; -using CryptoExchange.Net.Objects; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.InverseFuturesApi -{ - /// - public class BybitRestClientInverseFuturesApiAccount : IBybitRestClientInverseFuturesApiAccount - { - private BybitRestClientInverseFuturesApi _baseClient; - - internal BybitRestClientInverseFuturesApiAccount(BybitRestClientInverseFuturesApi baseClient) - { - _baseClient = baseClient; - } - - #region Get risk limit - - /// - public async Task>> GetRiskLimitAsync(string? symbol = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("symbol", symbol); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/risk-limit/list"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Set risk limit - - /// - public async Task> SetRiskLimitAsync(string symbol, long riskId, PositionMode? mode = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "risk_id", riskId.ToString(CultureInfo.InvariantCulture) }, - }; - parameters.AddOptionalParameter("position_idx", mode == null ? null : JsonConvert.SerializeObject(mode, new PositionModeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/position/risk-limit"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get positions - /// - public async Task>> GetPositionAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>(_baseClient.GetUrl("futures/private/position/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - if (!result) - return result.As>(default); - - foreach (var position in result.Data) - position.Data.IsValid = position.IsValid; - - return result.As(result.Data.Select(d => d.Data)); - } - - - /// - public async Task>> GetPositionsAsync(long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>(_baseClient.GetUrl("futures/private/position/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - if (!result) - return result.As>(default); - - foreach (var position in result.Data) - position.Data.IsValid = position.IsValid; - - return result.As(result.Data.Select(d => d.Data)); - } - - #endregion - - #region Change margin - - /// - public async Task> ChangeMarginAsync(string symbol, PositionMode mode, decimal margin, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "position_idx", JsonConvert.SerializeObject(mode, new PositionModeConverter(false)) }, - { "margin", margin.ToString(CultureInfo.InvariantCulture) }, - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/position/change-position-margin"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Set leverage - - /// - public async Task> SetLeverageAsync(string symbol, decimal buyLeverage, decimal sellLeverage, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "buy_leverage", buyLeverage.ToString(CultureInfo.InvariantCulture) }, - { "sell_leverage", sellLeverage.ToString(CultureInfo.InvariantCulture) }, - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/position/leverage/save"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get Profit And Loss History - - /// - public async Task>>> GetProfitAndLossHistoryAsync(string symbol, DateTime? startTime = null, DateTime? endTime = null, TradeType? type = null, int? page = null, int? pageSize = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - parameters.AddOptionalParameter("start_time", DateTimeConverter.ConvertToSeconds(startTime)); - parameters.AddOptionalParameter("end_time", DateTimeConverter.ConvertToSeconds(endTime)); - parameters.AddOptionalParameter("exec_type", type == null ? null : JsonConvert.SerializeObject(type.Value, new TradeTypeConverter(false))); - parameters.AddOptionalParameter("page", page?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("limit", pageSize?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("futures/private/trade/closed-pnl/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - if (result && result.Data.Data == null) - result.Data.Data = new BybitPnlEntry[0]; - - return result; - } - - #endregion - - #region Set full / partial position mode - - /// - public async Task> SetFullPartialPositionModeAsync(string symbol, StopLossTakeProfitMode mode, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "tp_sl_mode", JsonConvert.SerializeObject(mode, new StopLossTakeProfitModeConverter(false)) }, - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/tpsl/switch-mode"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Set position mode - - /// - public async Task SetPositionModeAsync(string symbol, string asset, bool hedgeMode, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - if (string.IsNullOrWhiteSpace(asset)) - { - parameters.Add("symbol", symbol); - } - else if (string.IsNullOrWhiteSpace(symbol)) - { - parameters.Add("coin", asset); - } - else - { - throw new ArgumentNullException("One of 'coin' or 'symbol' parameters is required!"); - } - - parameters.Add("mode", hedgeMode ? 3 : 0); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/position/switch-mode"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - return result.AsDataless(); - } - - #endregion - - #region Set isolated mode - - /// - public async Task SetIsolatedPositionModeAsync(string symbol, bool isIsolated, decimal buyLeverage, decimal sellLeverage, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "is_isolated", isIsolated.ToString() }, - { "buy_leverage", buyLeverage.ToString(CultureInfo.InvariantCulture) }, - { "sell_leverage", sellLeverage.ToString(CultureInfo.InvariantCulture) }, - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/position/switch-isolated"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - return result.AsDataless(); - } - - #endregion - - #region Get balances - - /// - public async Task>> GetBalancesAsync(string? asset = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/private/wallet/balance"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get wallet fund history - - /// - public async Task>> GetWalletFundHistoryAsync(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, WalletFundType? type = null, int? pageSize = null, int? page = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("start_date", startTime?.ToString("yyyy-MM-dd")); - parameters.AddOptionalParameter("end_date", endTime?.ToString("yyyy-MM-dd")); - parameters.AddOptionalParameter("wallet_fund_type", type == null ? null : JsonConvert.SerializeObject(type, new WalletFundTypeConverter(false))); - parameters.AddOptionalParameter("page", page?.ToString()); - parameters.AddOptionalParameter("limit", pageSize?.ToString()); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("v2/private/wallet/fund/records"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - if (!result) - return result.As>(default); - - if (result.Data.Data == null) - return result.As>(new BybitWalletFundRecord[0]); - - return result.As(result.Data.Data); - } - - #endregion - - #region Get withdrawal history - - /// - public async Task>> GetWithdrawalHistoryAsync(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, WithdrawStatus? status = null, int? pageSize = null, int? page = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("start_date", startTime?.ToString("yyyy-MM-dd")); - parameters.AddOptionalParameter("end_date", endTime?.ToString("yyyy-MM-dd")); - parameters.AddOptionalParameter("status", status == null ? null : JsonConvert.SerializeObject(status, new WithdrawStatusConverter(false))); - parameters.AddOptionalParameter("page", page?.ToString()); - parameters.AddOptionalParameter("limit", pageSize?.ToString()); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("v2/private/wallet/withdraw/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - if (!result) - return result.As>(default); - - if (result.Data.Data == null) - return result.As>(new BybitWithdrawal[0]); - - return result.As(result.Data.Data); - } - - #endregion - - #region Get asset exchange history - - /// - public async Task>> GetAssetExchangeHistoryAsync(long? fromId = null, SearchDirection? direction = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("from", fromId?.ToString()); - parameters.AddOptionalParameter("direction", direction == null ? null : JsonConvert.SerializeObject(direction, new SearchDirectionConverter(false))); - parameters.AddOptionalParameter("limit", limit?.ToString()); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/private/exchange-order/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get api key info - - /// - public async Task>> GetApiKeyInfoAsync(long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/private/account/api-key"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - } -} diff --git a/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApiExchangeData.cs b/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApiExchangeData.cs deleted file mode 100644 index ab7cdc28..00000000 --- a/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApiExchangeData.cs +++ /dev/null @@ -1,211 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Bybit.Net.Interfaces.Clients.InverseFuturesApi; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net; -using CryptoExchange.Net.Converters; -using CryptoExchange.Net.Objects; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.InverseFuturesApi -{ - /// - public class BybitRestClientInverseFuturesApiExchangeData : IBybitRestClientInverseFuturesApiExchangeData - { - private BybitRestClientInverseFuturesApi _baseClient; - - internal BybitRestClientInverseFuturesApiExchangeData(BybitRestClientInverseFuturesApi baseClient) - { - _baseClient = baseClient; - } - - #region Get klines - - /// - public async Task>> GetKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "interval", JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) }, - { "from", DateTimeConverter.ConvertToSeconds(from)! }, - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/kline/list"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get trade history - - /// - public async Task>> GetTradeHistoryAsync(string symbol, long? fromId = null, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("fromId", fromId?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/trading-records"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get mark price klines - - /// - public async Task>> GetMarkPriceKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "interval", JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) }, - { "from", DateTimeConverter.ConvertToSeconds(from)! }, - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/mark-price-kline"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get index price klines - - /// - public async Task>> GetIndexPriceKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "interval", JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) }, - { "from", DateTimeConverter.ConvertToSeconds(from) }, - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/index-price-kline"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get server time - - /// - public async Task> GetServerTimeAsync(CancellationToken ct = default) - { - var result = await _baseClient.SendRequestWrapperAsync(_baseClient.GetUrl("v2/public/time"), HttpMethod.Get, ct, null, ignoreRatelimit: true).ConfigureAwait(false); - if (!result) - return result.As(default); - - return result.As(result.Data.Timestamp); - } - - #endregion - - #region Get announcements - - /// - public async Task>> GetAnnouncementsAsync(CancellationToken ct = default) - { - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/announcement"), HttpMethod.Get, ct, null).ConfigureAwait(false); - } - - #endregion - - #region Get order book - - /// - public async Task>> GetOrderBookAsync(string symbol, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/orderBook/L2"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get ticker - - /// - public async Task>> GetTickerAsync(string? symbol = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("symbol", symbol); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/tickers"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get symbols - - /// - public async Task>> GetSymbolsAsync(CancellationToken ct = default) - { - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/symbols"), HttpMethod.Get, ct).ConfigureAwait(false); - } - - #endregion - - #region Get open interest - - /// - public async Task>> GetOpenInterestAsync(string symbol, DataPeriod period, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "period", JsonConvert.SerializeObject(period, new DataPeriodConverter(false)) } - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/open-interest"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get recent big trades - - /// - public async Task>> GetRecentBigTradesAsync(string symbol, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/big-deal"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get long short ratio - - /// - public async Task>> GetLongShortRatioAsync(string symbol, DataPeriod period, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "period", JsonConvert.SerializeObject(period, new DataPeriodConverter(false)) } - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/account-ratio"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - } -} diff --git a/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApiTrading.cs b/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApiTrading.cs deleted file mode 100644 index 7c64c1c5..00000000 --- a/ByBit.Net/Clients/InverseFuturesApi/BybitRestClientInverseFuturesApiTrading.cs +++ /dev/null @@ -1,527 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Bybit.Net.Interfaces.Clients.InverseFuturesApi; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net; -using CryptoExchange.Net.Converters; -using CryptoExchange.Net.Objects; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.InverseFuturesApi -{ - /// - public class BybitRestClientInverseFuturesApiTrading : IBybitRestClientInverseFuturesApiTrading - { - private BybitRestClientInverseFuturesApi _baseClient; - - internal BybitRestClientInverseFuturesApiTrading(BybitRestClientInverseFuturesApi baseClient) - { - _baseClient = baseClient; - } - - #region Place order - - /// - public async Task> PlaceOrderAsync( - string symbol, - OrderSide side, - OrderType type, - PositionMode positionMode, - decimal quantity, - TimeInForce timeInForce, - decimal? price = null, - bool? closeOnTrigger = null, - string? clientOrderId = null, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - bool? reduceOnly = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "side", JsonConvert.SerializeObject(side, new OrderSideConverter(false)) }, - { "position_idx", JsonConvert.SerializeObject(positionMode, new PositionModeConverter(false)) }, - { "symbol", symbol }, - { "order_type", JsonConvert.SerializeObject(type, new OrderTypeConverter(false)) }, - { "qty", quantity.ToString(CultureInfo.InvariantCulture) }, - { "time_in_force", JsonConvert.SerializeObject(timeInForce, new TimeInForceConverter(false)) }, - }; - - parameters.AddOptionalParameter("price", price?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("close_on_trigger", closeOnTrigger?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("reduce_only", reduceOnly?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/order/create"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get orders - - /// - public async Task>>> GetOrdersAsync( - string symbol, - OrderStatus? status = null, - SearchDirection? direction = null, - int? limit = null, - string? cursor = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("order_status", status == null ? null : JsonConvert.SerializeObject(status, new OrderStatusConverter(false))); - parameters.AddOptionalParameter("direction", direction == null ? null : JsonConvert.SerializeObject(direction, new SearchDirectionConverter(false))); - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("cursor", cursor); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("futures/private/order/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Cancel order - - /// - public async Task> CancelOrderAsync( - string symbol, - string? orderId = null, - string? clientOrderId = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (orderId == null && clientOrderId == null || orderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(orderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("order_id", orderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/order/cancel"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Cancel all order - - /// - public async Task>> CancelAllOrdersAsync( - string symbol, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>(_baseClient.GetUrl("futures/private/order/cancelAll"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - if (result && result.Data == null) - return result.As>(new BybitCanceledOrder[0]); - - return result; - } - - #endregion - - #region Modify order - - /// - public async Task> ModifyOrderAsync( - string symbol, - string? orderId = null, - string? clientOrderId = null, - decimal? newPrice = null, - decimal? newQuantity = null, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (orderId == null && clientOrderId == null || orderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(orderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("p_r_price", newPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("p_r_qty", newQuantity?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("order_id", orderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/order/replace"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Get open orders realtime - - /// - public async Task> GetOpenOrderRealTimeAsync( - string symbol, - string? orderId = null, - string? clientOrderId = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (orderId == null && clientOrderId == null || orderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(orderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - parameters.AddOptionalParameter("order_id", orderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/order"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - /// - public async Task>> GetOpenOrdersRealTimeAsync( - string symbol, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("futures/private/order"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Place conditional order - - /// - public async Task> PlaceConditionalOrderAsync( - string symbol, - OrderSide side, - OrderType type, - PositionMode positionMode, - decimal quantity, - decimal basePrice, - decimal triggerPrice, - TimeInForce timeInForce, - decimal? price = null, - TriggerType? triggerType = null, - bool? closeOnTrigger = null, - string? clientOrderId = null, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "side", JsonConvert.SerializeObject(side, new OrderSideConverter(false)) }, - { "position_idx", JsonConvert.SerializeObject(positionMode, new PositionModeConverter(false)) }, - { "symbol", symbol }, - { "order_type", JsonConvert.SerializeObject(type, new OrderTypeConverter(false)) }, - { "qty", quantity.ToString(CultureInfo.InvariantCulture) }, - { "base_price", basePrice.ToString(CultureInfo.InvariantCulture) }, - { "stop_px", triggerPrice.ToString(CultureInfo.InvariantCulture) }, - { "time_in_force", JsonConvert.SerializeObject(timeInForce, new TimeInForceConverter(false)) }, - }; - - parameters.AddOptionalParameter("trigger_by", triggerType == null ? null : JsonConvert.SerializeObject(triggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("price", price?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("close_on_trigger", closeOnTrigger?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/stop-order/create"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get conditional orders - - /// - public async Task>>> GetConditionalOrdersAsync( - string symbol, - StopOrderStatus? status = null, - SearchDirection? direction = null, - int? limit = null, - string? cursor = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("order_status", status == null ? null : JsonConvert.SerializeObject(status, new StopOrderStatusConverter(false))); - parameters.AddOptionalParameter("direction", direction == null ? null : JsonConvert.SerializeObject(direction, new SearchDirectionConverter(false))); - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("cursor", cursor); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("futures/private/stop-order/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Cancel conditional order - - /// - public async Task> CancelConditionalOrderAsync( - string symbol, - string? stopOrderId = null, - string? clientOrderId = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (stopOrderId == null && clientOrderId == null || stopOrderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(stopOrderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("stop_order_id", stopOrderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/stop-order/cancel"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Cancel all conditional orders - - /// - public async Task>> CancelAllConditionalOrdersAsync( - string symbol, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>(_baseClient.GetUrl("futures/private/stop-order/cancelAll"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - if (result && result.Data == null) - return result.As>(new BybitCanceledConditionalOrder[0]); - - return result; - } - - #endregion - - #region Modify order - - /// - public async Task> ModifyConditionalOrderAsync( - string symbol, - string? stopOrderId = null, - string? clientOrderId = null, - decimal? newPrice = null, - decimal? newTriggerPrice = null, - decimal? newQuantity = null, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (stopOrderId == null && clientOrderId == null || stopOrderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(stopOrderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("p_r_price", newPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("p_r_qty", newQuantity?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("p_r_trigger_price", newTriggerPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_order_id", stopOrderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/stop-order/replace"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Get open orders realtime - - /// - public async Task> GetOpenConditionalOrderRealTimeAsync( - string symbol, - string? stopOrderId = null, - string? clientOrderId = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (stopOrderId == null && clientOrderId == null || stopOrderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(stopOrderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - parameters.AddOptionalParameter("stop_order_id", stopOrderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/stop-order"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - /// - public async Task>> GetOpenConditionalOrdersRealTimeAsync( - string symbol, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("futures/private/stop-order"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region User trades - - /// - public async Task>> GetUserTradesAsync( - string symbol, - string? orderId = null, - DateTime? startTime = null, - int? page = null, - int? pageSize = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - parameters.AddOptionalParameter("order_id", orderId); - parameters.AddOptionalParameter("start_time", DateTimeConverter.ConvertToMilliseconds(startTime)); - parameters.AddOptionalParameter("page", page?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("limit", pageSize?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/execution/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - if (!result) - return result.As>(default); - - if (result.Data.Trades == null) - return result.As>(new BybitUserTrade[0]); - - return result.As(result.Data.Trades); - } - - #endregion - - #region Set Trading Stop - /// - public async Task> SetTradingStopAsync( - string symbol, - PositionMode positionMode, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - decimal? trailingStopPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - decimal? trailingStopTriggerPrice = null, - decimal? takeProfitQuantity = null, - decimal? stopLossQuantity = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "position_idx", JsonConvert.SerializeObject(positionMode, new PositionModeConverter(false)) } - }; - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("trailing_stop", trailingStopPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("new_trailing_active", trailingStopTriggerPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("sl_size", stopLossQuantity?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_size", takeProfitQuantity?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("futures/private/position/trading-stop"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - #endregion - } -} diff --git a/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApi.cs b/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApi.cs deleted file mode 100644 index 7dee171f..00000000 --- a/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApi.cs +++ /dev/null @@ -1,134 +0,0 @@ -using Bybit.Net.Interfaces.Clients.InversePerpetualApi; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Options; -using CryptoExchange.Net; -using CryptoExchange.Net.Authentication; -using CryptoExchange.Net.Objects; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.InversePerpetualApi -{ - /// - public class BybitRestClientInversePerpetualApi : RestApiClient, IBybitRestClientInversePerpetualApi - { - internal static TimeSyncState _timeSyncState = new TimeSyncState("Inverse Perpetual Api"); - - /// - /// Options - /// - public new BybitRestOptions ClientOptions => (BybitRestOptions)base.ClientOptions; - - /// - public IBybitRestClientInversePerpetualApiAccount Account { get; } - /// - public IBybitRestClientInversePerpetualApiExchangeData ExchangeData { get; } - /// - public IBybitRestClientInversePerpetualApiTrading Trading { get; } - - #region ctor - internal BybitRestClientInversePerpetualApi(ILogger logger, HttpClient? httpClient, BybitRestOptions options) : - base(logger, httpClient, options.Environment.RestBaseAddress, options, options.InversePerpetualOptions) - { - if (!string.IsNullOrEmpty(options.Referer)) - { - StandardRequestHeaders = new Dictionary - { - { "x-referer", options.Referer! } - }; - } - - manualParseError = true; - - Account = new BybitRestClientInversePerpetualApiAccount(this); - ExchangeData = new BybitRestClientInversePerpetualApiExchangeData(this); - Trading = new BybitRestClientInversePerpetualApiTrading(this); - - requestBodyFormat = RequestBodyFormat.FormData; - ParameterPositions[HttpMethod.Delete] = HttpMethodParameterPosition.InUri; - } - #endregion - - /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) - => new BybitAuthenticationProvider(credentials); - - /// - /// Get url for an endpoint - /// - /// - /// - internal Uri GetUrl(string endpoint) - { - return new Uri(BaseAddress.AppendPath(endpoint)); - } - - /// - protected override Task TryParseErrorAsync(JToken data) - { - var responseCode = data["ret_code"]; - if (responseCode != null && responseCode.ToString() != "0") - { - var errorMessage = data["ret_msg"]; - return Task.FromResult(new ServerError(responseCode.Value(), errorMessage!.ToString()))!; - } - - return Task.FromResult(null); - } - - internal async Task>> SendRequestWrapperAsync( - Uri uri, - HttpMethod method, - CancellationToken cancellationToken, - Dictionary? parameters = null, - bool signed = false, - JsonSerializer? deserializer = null, - bool ignoreRatelimit = false) where T : class - { - var result = await base.SendRequestAsync>(uri, method, cancellationToken, parameters, signed, deserializer: deserializer, ignoreRatelimit: ignoreRatelimit).ConfigureAwait(false); - if (!result) - return result.As>(default); - - if (result.Data.ReturnCode != 0) - return result.AsError>(new ServerError(result.Data.ReturnCode, result.Data.ReturnMessage)); - - return result.As(result.Data); - } - - internal async Task> SendRequestAsync( - Uri uri, - HttpMethod method, - CancellationToken cancellationToken, - Dictionary? parameters = null, - bool signed = false, - JsonSerializer? deserializer = null) - { - var result = await base.SendRequestAsync>(uri, method, cancellationToken, parameters, signed, deserializer: deserializer).ConfigureAwait(false); - if (!result) - return result.As(default); - - if (result.Data.ReturnCode != 0) - return result.AsError(new ServerError(result.Data.ReturnCode, result.Data.ReturnMessage)); - - return result.As(result.Data.Result); - } - - /// - protected override Task> GetServerTimestampAsync() - => ExchangeData.GetServerTimeAsync(); - - /// - public override TimeSyncInfo? GetTimeSyncInfo() - => new TimeSyncInfo(_logger, (ApiOptions.AutoTimestamp ?? ClientOptions.AutoTimestamp), (ApiOptions.TimestampRecalculationInterval ?? ClientOptions.TimestampRecalculationInterval), _timeSyncState); - - /// - public override TimeSpan? GetTimeOffset() - => _timeSyncState.TimeOffset; - } -} diff --git a/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApiAccount.cs b/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApiAccount.cs deleted file mode 100644 index 3a06b46d..00000000 --- a/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApiAccount.cs +++ /dev/null @@ -1,314 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Bybit.Net.Interfaces.Clients.InversePerpetualApi; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net; -using CryptoExchange.Net.Converters; -using CryptoExchange.Net.Objects; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.InversePerpetualApi -{ - /// - public class BybitRestClientInversePerpetualApiAccount : IBybitRestClientInversePerpetualApiAccount - { - private BybitRestClientInversePerpetualApi _baseClient; - - internal BybitRestClientInversePerpetualApiAccount(BybitRestClientInversePerpetualApi baseClient) - { - _baseClient = baseClient; - } - - #region Get risk limit - - /// - public async Task>> GetRiskLimitAsync(string? symbol = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("symbol", symbol); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/risk-limit/list"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Set risk limit - - /// - public async Task> SetRiskLimitAsync(string symbol, long riskId, PositionMode? mode = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "risk_id", riskId.ToString(CultureInfo.InvariantCulture) }, - }; - parameters.AddOptionalParameter("position_idx", mode == null ? null : JsonConvert.SerializeObject(mode, new PositionModeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/position/risk-limit"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get positions - /// - public async Task> GetPositionAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/position/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - /// - public async Task>> GetPositionsAsync(long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/private/position/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - if (!result) - return result.As>(default); - - foreach (var position in result.Data) - position.Data.IsValid = position.IsValid; - - return result.As(result.Data.Select(d => d.Data)); - } - - #endregion - - #region Change margin - - /// - public async Task> ChangeMarginAsync(string symbol, decimal margin, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "margin", margin.ToString(CultureInfo.InvariantCulture) }, - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/position/change-position-margin"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Set leverage - - /// - public async Task> SetLeverageAsync(string symbol, decimal leverage, bool? leverageOnly = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "leverage", leverage.ToString(CultureInfo.InvariantCulture) } - }; - parameters.AddOptionalParameter("leverage_only", leverageOnly); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/position/leverage/save"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get Profit And Loss History - - /// - public async Task>>> GetProfitAndLossHistoryAsync(string symbol, DateTime? startTime = null, DateTime? endTime = null, TradeType? type = null, int? page = null, int? pageSize = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - parameters.AddOptionalParameter("start_time", DateTimeConverter.ConvertToSeconds(startTime)); - parameters.AddOptionalParameter("end_time", DateTimeConverter.ConvertToSeconds(endTime)); - parameters.AddOptionalParameter("exec_type", type == null ? null : JsonConvert.SerializeObject(type.Value, new TradeTypeConverter(false))); - parameters.AddOptionalParameter("page", page?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("limit", pageSize?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("v2/private/trade/closed-pnl/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - if (result && result.Data.Data == null) - result.Data.Data = new BybitPnlEntry[0]; - - return result; - } - - #endregion - - #region Set full / partial position mode - - /// - public async Task> SetFullPartialPositionModeAsync(string symbol, StopLossTakeProfitMode mode, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "tp_sl_mode", JsonConvert.SerializeObject(mode, new StopLossTakeProfitModeConverter(false)) }, - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/tpsl/switch-mode"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Set isolated mode - - /// - public async Task SetIsolatedPositionModeAsync(string symbol, bool isIsolated, decimal buyLeverage, decimal sellLeverage, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "is_isolated", isIsolated.ToString() }, - { "buy_leverage", buyLeverage.ToString(CultureInfo.InvariantCulture) }, - { "sell_leverage", sellLeverage.ToString(CultureInfo.InvariantCulture) }, - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/position/switch-isolated"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - return result.AsDataless(); - } - - #endregion - - #region Get balances - - /// - public async Task>> GetBalancesAsync(string? asset = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/private/wallet/balance"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get last user funding fee - - /// - public async Task> GetLastUserFundingFeeAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("symbol", symbol); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/funding/prev-funding"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get predicted user funding fee - - /// - public async Task> GetPredictedUserFundingFeeAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("symbol", symbol); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/funding/predicted-funding"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get wallet fund history - - /// - public async Task>> GetWalletFundHistoryAsync(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, WalletFundType? type = null, int? pageSize = null, int? page = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("start_date", startTime?.ToString("yyyy-MM-dd")); - parameters.AddOptionalParameter("end_date", endTime?.ToString("yyyy-MM-dd")); - parameters.AddOptionalParameter("wallet_fund_type", type == null ? null : JsonConvert.SerializeObject(type, new WalletFundTypeConverter(false))); - parameters.AddOptionalParameter("page", page?.ToString()); - parameters.AddOptionalParameter("limit", pageSize?.ToString()); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("v2/private/wallet/fund/records"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - if (!result) - return result.As>(default); - - if (result.Data.Data == null) - return result.As>(new BybitWalletFundRecord[0]); - - return result.As(result.Data.Data); - } - - #endregion - - #region Get withdrawal history - - /// - public async Task>> GetWithdrawalHistoryAsync(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, WithdrawStatus? status = null, int? pageSize = null, int? page = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("start_date", startTime?.ToString("yyyy-MM-dd")); - parameters.AddOptionalParameter("end_date", endTime?.ToString("yyyy-MM-dd")); - parameters.AddOptionalParameter("status", status == null ? null : JsonConvert.SerializeObject(status, new WithdrawStatusConverter(false))); - parameters.AddOptionalParameter("page", page?.ToString()); - parameters.AddOptionalParameter("limit", pageSize?.ToString()); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("v2/private/wallet/withdraw/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - if (!result) - return result.As>(default); - - if (result.Data.Data == null) - return result.As>(new BybitWithdrawal[0]); - - return result.As(result.Data.Data); - } - - #endregion - - #region Get asset exchange history - - /// - public async Task>> GetAssetExchangeHistoryAsync(long? fromId = null, SearchDirection? direction = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("from", fromId?.ToString()); - parameters.AddOptionalParameter("direction", direction == null ? null : JsonConvert.SerializeObject(direction, new SearchDirectionConverter(false))); - parameters.AddOptionalParameter("limit", limit?.ToString()); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/private/exchange-order/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get api key info - - /// - public async Task>> GetApiKeyInfoAsync(long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/private/account/api-key"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - } -} diff --git a/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApiExchangeData.cs b/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApiExchangeData.cs deleted file mode 100644 index a55c3192..00000000 --- a/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApiExchangeData.cs +++ /dev/null @@ -1,245 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Bybit.Net.Interfaces.Clients.InversePerpetualApi; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net; -using CryptoExchange.Net.Converters; -using CryptoExchange.Net.Objects; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.InversePerpetualApi -{ - /// - public class BybitRestClientInversePerpetualApiExchangeData : IBybitRestClientInversePerpetualApiExchangeData - { - private BybitRestClientInversePerpetualApi _baseClient; - - internal BybitRestClientInversePerpetualApiExchangeData(BybitRestClientInversePerpetualApi baseClient) - { - _baseClient = baseClient; - } - - #region Get klines - - /// - public async Task>> GetKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "interval", JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) }, - { "from", DateTimeConverter.ConvertToSeconds(from)! }, - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/kline/list"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get trade history - - /// - public async Task>> GetTradeHistoryAsync(string symbol, long? fromId = null, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("fromId", fromId?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/trading-records"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get last funding rate - - /// - public async Task> GetLastFundingRateAsync(string symbol, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/public/funding/prev-funding-rate"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get mark price klines - - /// - public async Task>> GetMarkPriceKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "interval", JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) }, - { "from", DateTimeConverter.ConvertToSeconds(from)! }, - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/mark-price-kline"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get index price klines - - /// - public async Task>> GetIndexPriceKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "interval", JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) }, - { "from", DateTimeConverter.ConvertToSeconds(from) }, - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/index-price-kline"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get premium index price klines - - /// - public async Task>> GetPremiumIndexKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "interval", JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) }, - { "from", DateTimeConverter.ConvertToSeconds(from)! }, - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/premium-index-kline"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get server time - - /// - public async Task> GetServerTimeAsync(CancellationToken ct = default) - { - var result = await _baseClient.SendRequestWrapperAsync(_baseClient.GetUrl("v2/public/time"), HttpMethod.Get, ct, null, ignoreRatelimit: true).ConfigureAwait(false); - if (!result) - return result.As(default); - - return result.As(result.Data.Timestamp); - } - - #endregion - - #region Get announcement - - /// - public async Task>> GetAnnouncementsAsync(CancellationToken ct = default) - { - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/announcement"), HttpMethod.Get, ct, null).ConfigureAwait(false); - } - - #endregion - - #region Get order book - - /// - public async Task>> GetOrderBookAsync(string symbol, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/orderBook/L2"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get tickers - - /// - public async Task>> GetTickersAsync(string? symbol = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("symbol", symbol); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/tickers"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get symbols - - /// - public async Task>> GetSymbolsAsync(CancellationToken ct = default) - { - var parameters = new Dictionary(); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/symbols"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get open interest - - /// - public async Task>> GetOpenInterestAsync(string symbol, DataPeriod period, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "period", JsonConvert.SerializeObject(period, new DataPeriodConverter(false)) } - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/open-interest"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get recent big trades - - /// - public async Task>> GetRecentBigTradesAsync(string symbol, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/big-deal"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get long short ratio - - /// - public async Task>> GetLongShortRatioAsync(string symbol, DataPeriod period, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "period", JsonConvert.SerializeObject(period, new DataPeriodConverter(false)) } - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/account-ratio"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - } -} diff --git a/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApiTrading.cs b/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApiTrading.cs deleted file mode 100644 index 497a9b16..00000000 --- a/ByBit.Net/Clients/InversePerpetualApi/BybitRestClientInversePerpetualApiTrading.cs +++ /dev/null @@ -1,523 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Bybit.Net.Interfaces.Clients.InversePerpetualApi; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net; -using CryptoExchange.Net.Converters; -using CryptoExchange.Net.Objects; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.InversePerpetualApi -{ - /// - public class BybitRestClientInversePerpetualApiTrading : IBybitRestClientInversePerpetualApiTrading - { - private BybitRestClientInversePerpetualApi _baseClient; - - internal BybitRestClientInversePerpetualApiTrading(BybitRestClientInversePerpetualApi baseClient) - { - _baseClient = baseClient; - } - - #region Place order - - /// - public async Task> PlaceOrderAsync( - string symbol, - OrderSide side, - OrderType type, - decimal quantity, - TimeInForce timeInForce, - decimal? price = null, - bool? closeOnTrigger = null, - string? clientOrderId = null, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - bool? reduceOnly = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "side", JsonConvert.SerializeObject(side, new OrderSideConverter(false)) }, - { "symbol", symbol }, - { "order_type", JsonConvert.SerializeObject(type, new OrderTypeConverter(false)) }, - { "qty", quantity.ToString(CultureInfo.InvariantCulture) }, - { "time_in_force", JsonConvert.SerializeObject(timeInForce, new TimeInForceConverter(false)) }, - }; - - parameters.AddOptionalParameter("price", price?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("close_on_trigger", closeOnTrigger?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("reduce_only", reduceOnly?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/order/create"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get orders - - /// - public async Task>>> GetOrdersAsync( - string symbol, - OrderStatus? status = null, - SearchDirection? direction = null, - int? limit = null, - string? cursor = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("order_status", status == null ? null : JsonConvert.SerializeObject(status, new OrderStatusConverter(false))); - parameters.AddOptionalParameter("direction", direction == null ? null : JsonConvert.SerializeObject(direction, new SearchDirectionConverter(false))); - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("cursor", cursor); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("v2/private/order/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Cancel order - - /// - public async Task> CancelOrderAsync( - string symbol, - string? orderId = null, - string? clientOrderId = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (orderId == null && clientOrderId == null || orderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(orderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("order_id", orderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/order/cancel"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Cancel all order - - /// - public async Task>> CancelAllOrdersAsync( - string symbol, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/private/order/cancelAll"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - if (result && result.Data == null) - return result.As>(new BybitCanceledOrder[0]); - - return result; - } - - #endregion - - #region Modify order - - /// - public async Task> ModifyOrderAsync( - string symbol, - string? orderId = null, - string? clientOrderId = null, - decimal? newPrice = null, - decimal? newQuantity = null, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (orderId == null && clientOrderId == null || orderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(orderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("p_r_price", newPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("p_r_qty", newQuantity?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("order_id", orderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/order/replace"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Get open orders realtime - - /// - public async Task> GetOpenOrderRealTimeAsync( - string symbol, - string? orderId = null, - string? clientOrderId = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (orderId == null && clientOrderId == null || orderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(orderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - parameters.AddOptionalParameter("order_id", orderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/order"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - /// - public async Task>> GetOpenOrdersRealTimeAsync( - string symbol, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/private/order"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Place conditional order - - /// - public async Task> PlaceConditionalOrderAsync( - string symbol, - OrderSide side, - OrderType type, - PositionMode positionMode, - decimal quantity, - decimal basePrice, - decimal triggerPrice, - TimeInForce timeInForce, - decimal? price = null, - TriggerType? triggerType = null, - bool? closeOnTrigger = null, - string? clientOrderId = null, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "side", JsonConvert.SerializeObject(side, new OrderSideConverter(false)) }, - { "position_idx", JsonConvert.SerializeObject(positionMode, new PositionModeConverter(false)) }, - { "symbol", symbol }, - { "order_type", JsonConvert.SerializeObject(type, new OrderTypeConverter(false)) }, - { "qty", quantity.ToString(CultureInfo.InvariantCulture) }, - { "base_price", basePrice.ToString(CultureInfo.InvariantCulture) }, - { "stop_px", triggerPrice.ToString(CultureInfo.InvariantCulture) }, - { "time_in_force", JsonConvert.SerializeObject(timeInForce, new TimeInForceConverter(false)) }, - }; - - parameters.AddOptionalParameter("trigger_by", triggerType == null ? null : JsonConvert.SerializeObject(triggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("price", price?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("close_on_trigger", closeOnTrigger?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/stop-order/create"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get conditional orders - - /// - public async Task>>> GetConditionalOrdersAsync( - string symbol, - StopOrderStatus? status = null, - SearchDirection? direction = null, - int? limit = null, - string? cursor = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("order_status", status == null ? null : JsonConvert.SerializeObject(status, new StopOrderStatusConverter(false))); - parameters.AddOptionalParameter("direction", direction == null ? null : JsonConvert.SerializeObject(direction, new SearchDirectionConverter(false))); - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("cursor", cursor); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("v2/private/stop-order/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Cancel conditional order - - /// - public async Task> CancelConditionalOrderAsync( - string symbol, - string? stopOrderId = null, - string? clientOrderId = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (stopOrderId == null && clientOrderId == null || stopOrderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(stopOrderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("stop_order_id", stopOrderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/stop-order/cancel"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Cancel all conditional orders - - /// - public async Task>> CancelAllConditionalOrdersAsync( - string symbol, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/private/stop-order/cancelAll"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - if (result && result.Data == null) - return result.As>(new BybitCanceledConditionalOrder[0]); - - return result; - } - - #endregion - - #region Modify order - - /// - public async Task> ModifyConditionalOrderAsync( - string symbol, - string? stopOrderId = null, - string? clientOrderId = null, - decimal? newPrice = null, - decimal? newTriggerPrice = null, - decimal? newQuantity = null, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (stopOrderId == null && clientOrderId == null || stopOrderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(stopOrderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("p_r_price", newPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("p_r_qty", newQuantity?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("p_r_trigger_price", newTriggerPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_order_id", stopOrderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/stop-order/replace"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Get open orders realtime - - /// - public async Task> GetOpenConditionalOrderRealTimeAsync( - string symbol, - string? stopOrderId = null, - string? clientOrderId = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (stopOrderId == null && clientOrderId == null || stopOrderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(stopOrderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - parameters.AddOptionalParameter("stop_order_id", stopOrderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/stop-order"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - /// - public async Task>> GetOpenConditionalOrdersRealTimeAsync( - string symbol, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/private/stop-order"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region User trades - - /// - public async Task>> GetUserTradesAsync( - string symbol, - string? orderId = null, - DateTime? startTime = null, - int? page = null, - int? pageSize = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - parameters.AddOptionalParameter("order_id", orderId); - parameters.AddOptionalParameter("start_time", DateTimeConverter.ConvertToMilliseconds(startTime)); - parameters.AddOptionalParameter("page", page?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("limit", pageSize?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/execution/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - if (!result) - return result.As>(default); - - if (result.Data.Trades == null) - return result.As>(new BybitUserTrade[0]); - - return result.As(result.Data.Trades); - } - - #endregion - - #region Set Trading Stop - /// - public async Task> SetTradingStopAsync( - string symbol, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - decimal? trailingStopPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - decimal? trailingStopTriggerPrice = null, - decimal? takeProfitQuantity = null, - decimal? stopLossQuantity = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("trailing_stop", trailingStopPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("new_trailing_active", trailingStopTriggerPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("sl_size", stopLossQuantity?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_size", takeProfitQuantity?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("v2/private/position/trading-stop"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - #endregion - } -} diff --git a/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiAccountV1.cs b/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiAccountV1.cs deleted file mode 100644 index 2249f7ab..00000000 --- a/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiAccountV1.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Bybit.Net.Interfaces.Clients.SpotApi.v1; -using Bybit.Net.Objects.Models.Spot; -using CryptoExchange.Net; -using CryptoExchange.Net.Objects; -using System.Collections.Generic; -using System.Globalization; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.SpotApi.v1 -{ - /// - public class BybitRestClientSpotApiAccountV1 : IBybitRestClientSpotApiAccountV1 - { - private BybitRestClientBaseSpotApi _baseClient; - - internal BybitRestClientSpotApiAccountV1(BybitRestClientBaseSpotApi baseClient) - { - _baseClient = baseClient; - } - - #region Get balances - - /// - public async Task>> GetBalancesAsync(long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/v1/account"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - return result.As(result.Data?.Balances!); - } - - #endregion - - #region Get margin account info - - /// - public async Task> GetMarginAccountInfoAsync(long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/v1/cross-margin/accounts/balance"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - } -} diff --git a/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiExchangeDataV1.cs b/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiExchangeDataV1.cs deleted file mode 100644 index c6c02147..00000000 --- a/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiExchangeDataV1.cs +++ /dev/null @@ -1,207 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net; -using CryptoExchange.Net.Converters; -using CryptoExchange.Net.Objects; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using Bybit.Net.Objects.Models.Spot; -using Bybit.Net.Interfaces.Clients.SpotApi.v1; -using Bybit.Net.Objects.Models.Spot.v1; - -namespace Bybit.Net.Clients.SpotApi.v1 -{ - /// - public class BybitRestClientSpotApiExchangeDataV1 : IBybitRestClientSpotApiExchangeDataV1 - { - private BybitRestClientBaseSpotApi _baseClient; - - internal BybitRestClientSpotApiExchangeDataV1(BybitRestClientBaseSpotApi baseClient) - { - _baseClient = baseClient; - } - - #region Get server time - - /// - public async Task> GetServerTimeAsync(CancellationToken ct = default) - { - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/v1/time"), HttpMethod.Get, ct, null, ignoreRatelimit: true).ConfigureAwait(false); - return result.As(result.Data?.ServerTime ?? default); - } - - #endregion - - #region Get symbols - - /// - public async Task>> GetSymbolsAsync(CancellationToken ct = default) - { - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("spot/v1/symbols"), HttpMethod.Get, ct, null).ConfigureAwait(false); - } - - #endregion - - #region Get Order book - - /// - public async Task> GetOrderBookAsync(string symbol, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/quote/v1/depth"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get Merged order book - - /// - public async Task> GetMergedOrderBookAsync(string symbol, int? scale = null, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("scale", scale?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/quote/v1/depth/merged"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get trade history - - /// - public async Task>> GetTradeHistoryAsync(string symbol, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("spot/quote/v1/trades"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get klines - - /// - public async Task>> GetKlinesAsync(string symbol, KlineInterval interval, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "interval", JsonConvert.SerializeObject(interval, new KlineIntervalSpotConverter(false)) } - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("startTime", DateTimeConverter.ConvertToMilliseconds(startTime)); - parameters.AddOptionalParameter("endTime", DateTimeConverter.ConvertToMilliseconds(endTime)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("spot/quote/v1/kline"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get ticker - - /// - public async Task> GetTickerAsync(string symbol, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/quote/v1/ticker/24hr"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get tickers - - /// - public async Task>> GetTickersAsync(CancellationToken ct = default) - { - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("spot/quote/v1/ticker/24hr"), HttpMethod.Get, ct, null).ConfigureAwait(false); - } - - #endregion - - #region Get price - - /// - public async Task> GetPriceAsync(string symbol, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/quote/v1/ticker/price"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get prices - - /// - public async Task>> GetPricesAsync(CancellationToken ct = default) - { - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("spot/quote/v1/ticker/price"), HttpMethod.Get, ct, null).ConfigureAwait(false); - } - - #endregion - - #region Get book price - - /// - public async Task> GetBookPriceAsync(string symbol, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/quote/v1/ticker/book_ticker"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get prices - - /// - public async Task>> GetBookPricesAsync(CancellationToken ct = default) - { - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("spot/quote/v1/ticker/book_ticker"), HttpMethod.Get, ct, null).ConfigureAwait(false); - } - - #endregion - - #region Get Borrow info - - /// - public async Task> GetBorrowInterestAndQuotaAsync(string asset, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "currency", asset } - }; - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/v1/cross-margin/loan-info"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - } -} diff --git a/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiTradingV1.cs b/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiTradingV1.cs deleted file mode 100644 index 3ca6a90c..00000000 --- a/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiTradingV1.cs +++ /dev/null @@ -1,235 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Bybit.Net.Objects.Models.Spot; -using CryptoExchange.Net; -using CryptoExchange.Net.CommonObjects; -using CryptoExchange.Net.Converters; -using CryptoExchange.Net.Objects; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using Bybit.Net.Interfaces.Clients.SpotApi.v1; -using Bybit.Net.Objects.Models.Spot.v1; - -namespace Bybit.Net.Clients.SpotApi.v1 -{ - /// - public class BybitRestClientSpotApiTradingV1 : IBybitRestClientSpotApiTradingV1 - { - private readonly BybitRestClientBaseSpotApi _baseClient; - - internal BybitRestClientSpotApiTradingV1(BybitRestClientBaseSpotApi baseClient) - { - _baseClient = baseClient; - } - - #region Place order - - /// - public async Task> PlaceOrderAsync(string symbol, OrderSide side, OrderType type, decimal quantity, decimal? price = null, TimeInForce? timeInForce = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "side", JsonConvert.SerializeObject(side, new OrderSideConverter(false)) }, - { "type", JsonConvert.SerializeObject(type, new OrderTypeSpotConverter(false)) }, - { "qty", quantity.ToString(CultureInfo.InvariantCulture) } - }; - parameters.AddOptionalParameter("price", price?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("timeInForce", timeInForce == null ? null : JsonConvert.SerializeObject(timeInForce, new TimeInForceSpotConverter(false))); - parameters.AddOptionalParameter("orderLinkId", clientOrderId); - parameters.AddOptionalParameter("agentSource", _baseClient.ClientOptions.Referer); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/v1/order"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - if (result) - _baseClient.InvokeOrderPlaced(new OrderId { SourceObject = result.Data, Id = result.Data.Id.ToString(CultureInfo.InvariantCulture) }); - return result; - } - - #endregion - - #region Get order - - /// - public async Task> GetOrderAsync(long? orderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default) - { - if (orderId == null && clientOrderId == null || orderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(orderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary(); - parameters.AddOptionalParameter("orderId", orderId); - parameters.AddOptionalParameter("orderLinkId", clientOrderId); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/v1/order"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get open orders - - /// - public async Task>> GetOpenOrdersAsync(string? symbol = null, long? orderId = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("orderId", orderId); - parameters.AddOptionalParameter("symbol", symbol); - parameters.AddOptionalParameter("limit", limit); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("spot/v1/open-orders"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get open orders - - /// - public async Task>> GetOrdersAsync(string? symbol = null, long? orderId = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("orderId", orderId); - parameters.AddOptionalParameter("symbol", symbol); - parameters.AddOptionalParameter("limit", limit); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("spot/v1/history-orders"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Cancel order - - /// - public async Task> CancelOrderAsync(long? orderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default) - { - if (orderId == null && clientOrderId == null || orderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(orderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary(); - parameters.AddOptionalParameter("orderId", orderId); - parameters.AddOptionalParameter("orderLinkId", clientOrderId); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/v1/order"), HttpMethod.Delete, ct, parameters, true).ConfigureAwait(false); - if (result) - _baseClient.InvokeOrderCanceled(new OrderId { SourceObject = result.Data, Id = result.Data.Id.ToString(CultureInfo.InvariantCulture) }); - return result; - } - - #endregion - - #region Cancel MultipleOrders - /// - public async Task CancelMultipleOrderAsync(string symbol, OrderSide? side = null, IEnumerable? orderTypes = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("side", side.HasValue ? JsonConvert.SerializeObject(side, new OrderSideConverter(false)) : null); - parameters.AddOptionalParameter("orderTypes", orderTypes != null && orderTypes.Any() ? string.Join(",", orderTypes.Select(o => JsonConvert.SerializeObject(o, new OrderTypeConverter(false)))) : null); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/order/batch-cancel"), HttpMethod.Delete, ct, parameters, true).ConfigureAwait(false); - return result.AsDataless(); - } - #endregion - - #region Get user trades - - /// - public async Task>> GetUserTradesAsync(string? symbol = null, long? fromId = null, long? toId = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("fromId", fromId); - parameters.AddOptionalParameter("toId", toId); - parameters.AddOptionalParameter("symbol", symbol); - parameters.AddOptionalParameter("limit", limit); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("spot/v1/myTrades"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Cross marging - - #region Place borrow order - - /// - public async Task> PlaceBorrowOrderAsync(string asset, decimal quantity, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "currency", asset }, - { "qty", quantity.ToString(CultureInfo.InvariantCulture) } - }; - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/v1/cross-margin/loan"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Place repay order - - /// - public async Task> PlaceRepayOrderAsync(string asset, decimal quantity, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "currency", asset }, - { "qty", quantity.ToString(CultureInfo.InvariantCulture) } - }; - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("spot/v1/cross-margin/repay"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get borrow info - - /// - public async Task>> GetBorrowRecordsAsync(DateTime? startTime = null, DateTime? endTime = null, string? asset = null, BorrowStatus? status = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("startTime", DateTimeConverter.ConvertToMilliseconds(startTime)); - parameters.AddOptionalParameter("endTime", DateTimeConverter.ConvertToMilliseconds(endTime)); - parameters.AddOptionalParameter("currency", asset); - parameters.AddOptionalParameter("status", EnumConverter.GetString(status)); - parameters.AddOptionalParameter("limit", limit); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("spot/v1/cross-margin/order"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get repayment history - - /// - public async Task>> GetRepayRecordsAsync(DateTime? startTime = null, DateTime? endTime = null, string? asset = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("startTime", DateTimeConverter.ConvertToMilliseconds(startTime)); - parameters.AddOptionalParameter("endTime", DateTimeConverter.ConvertToMilliseconds(endTime)); - parameters.AddOptionalParameter("currency", asset); - parameters.AddOptionalParameter("limit", limit); - parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("spot/v1/cross-margin/repay/history"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #endregion - } -} diff --git a/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiV1.cs b/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiV1.cs deleted file mode 100644 index 68d6c4dd..00000000 --- a/ByBit.Net/Clients/SpotApi/v1/BybitRestClientSpotApiV1.cs +++ /dev/null @@ -1,319 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using Bybit.Net.Enums; -using Bybit.Net.Interfaces.Clients.SpotApi.v1; -using Bybit.Net.Objects.Options; -using CryptoExchange.Net.CommonObjects; -using CryptoExchange.Net.Interfaces.CommonClients; -using CryptoExchange.Net.Objects; -using Microsoft.Extensions.Logging; - -namespace Bybit.Net.Clients.SpotApi.v1 -{ - /// - public class BybitRestClientSpotApiV1 : BybitRestClientBaseSpotApi, IBybitRestClientSpotApiV1 - { - /// - public IBybitRestClientSpotApiAccountV1 Account { get; } - /// - public IBybitRestClientSpotApiExchangeDataV1 ExchangeData { get; } - /// - public IBybitRestClientSpotApiTradingV1 Trading { get; } - #region ctor - internal BybitRestClientSpotApiV1(ILogger log, HttpClient? httpClient, BybitRestOptions options) - : base(log, httpClient, options.Environment.RestBaseAddress, options, options.SpotOptions) - { - if (!string.IsNullOrEmpty(options.Referer)) - { - StandardRequestHeaders = new Dictionary - { - { "x-referer", options.Referer! } - }; - } - - Account = new BybitRestClientSpotApiAccountV1(this); - ExchangeData = new BybitRestClientSpotApiExchangeDataV1(this); - Trading = new BybitRestClientSpotApiTradingV1(this); - } - #endregion - - - #region Common interface - - /// - public override async Task>> GetSymbolsAsync(CancellationToken ct) - { - var result = await ExchangeData.GetSymbolsAsync(ct: ct).ConfigureAwait(false); - if (!result) - return result.As>(null); - - return result.As(result.Data.Select(r => new Symbol - { - SourceObject = r, - Name = r.Name, - MinTradeQuantity = r.MinOrderQuantity, - PriceStep = r.PricePrecision, - QuantityStep = r.BasePrecision - })); - } - - /// - public override async Task>> GetTickersAsync(CancellationToken ct) - { - var result = await ExchangeData.GetTickersAsync(ct: ct).ConfigureAwait(false); - if (!result) - return result.As>(null); - - return result.As(result.Data.Select(r => new Ticker - { - SourceObject = r, - Symbol = r.Symbol, - HighPrice = r.HighPrice, - LastPrice = r.LastPrice, - LowPrice = r.LowPrice, - Price24H = r.OpenPrice, - Volume = r.Volume - })); - } - - /// - public override async Task> GetTickerAsync(string symbol, CancellationToken ct) - { - if (string.IsNullOrEmpty(symbol)) - throw new ArgumentException(nameof(symbol) + " required for Bybit " + nameof(ISpotClient.GetTickerAsync), nameof(symbol)); - - var result = await ExchangeData.GetTickerAsync(symbol, ct: ct).ConfigureAwait(false); - if (!result) - return result.As(null); - - return result.As(new Ticker - { - SourceObject = result.Data, - Symbol = result.Data.Symbol, - HighPrice = result.Data.HighPrice, - LastPrice = result.Data.LastPrice, - LowPrice = result.Data.LowPrice, - Price24H = result.Data.OpenPrice, - Volume = result.Data.Volume - }); - } - - /// - public override async Task>> GetKlinesAsync(string symbol, TimeSpan timespan, DateTime? startTime, DateTime? endTime, int? limit, CancellationToken ct) - { - if (string.IsNullOrEmpty(symbol)) - throw new ArgumentException(nameof(symbol) + " required for Bybit " + nameof(ISpotClient.GetKlinesAsync), nameof(symbol)); - - var result = await ExchangeData.GetKlinesAsync(symbol, TimeSpanToInterval(timespan), startTime, endTime, limit, ct: ct).ConfigureAwait(false); - if (!result) - return result.As>(null); - - return result.As(result.Data.Select(r => new Kline - { - SourceObject = r, - HighPrice = r.HighPrice, - LowPrice = r.LowPrice, - Volume = r.Volume, - ClosePrice = r.ClosePrice, - OpenPrice = r.OpenPrice, - OpenTime = r.OpenTime - })); - } - - /// - public override async Task> GetOrderBookAsync(string symbol, CancellationToken ct) - { - if (string.IsNullOrEmpty(symbol)) - throw new ArgumentException(nameof(symbol) + " required for Bybit " + nameof(ISpotClient.GetOrderBookAsync), nameof(symbol)); - - var result = await ExchangeData.GetOrderBookAsync(symbol, ct: ct).ConfigureAwait(false); - if (!result) - return result.As(null); - - return result.As(new OrderBook - { - SourceObject = result.Data, - Asks = result.Data.Asks.Select(a => new OrderBookEntry { Price = a.Price, Quantity = a.Quantity }), - Bids = result.Data.Bids.Select(b => new OrderBookEntry { Price = b.Price, Quantity = b.Quantity }) - }); - } - - /// - public override async Task>> GetRecentTradesAsync(string symbol, CancellationToken ct) - { - if (string.IsNullOrEmpty(symbol)) - throw new ArgumentException(nameof(symbol) + " required for Bybit " + nameof(ISpotClient.GetRecentTradesAsync), nameof(symbol)); - - var result = await ExchangeData.GetTradeHistoryAsync(symbol).ConfigureAwait(false); - if (!result) - return result.As>(null); - - return result.As(result.Data.Select(r => new Trade - { - SourceObject = r, - Price = r.Price, - Quantity = r.Quantity, - Symbol = symbol, - Timestamp = r.TradeTime - })); - } - - /// - public override async Task> PlaceOrderAsync(string symbol, CommonOrderSide side, CommonOrderType type, decimal quantity, decimal? price, string? accountId, string? clientOrderId, CancellationToken ct) - { - if (string.IsNullOrEmpty(symbol)) - throw new ArgumentException(nameof(symbol) + " required for Bybit " + nameof(ISpotClient.PlaceOrderAsync), nameof(symbol)); - - var result = await Trading.PlaceOrderAsync( - symbol, - side == CommonOrderSide.Buy ? OrderSide.Buy : OrderSide.Sell, - type == CommonOrderType.Limit ? OrderType.Limit : OrderType.Market, - quantity, - price, - type == CommonOrderType.Limit ? TimeInForce.GoodTillCanceled : (TimeInForce?)null, - clientOrderId: clientOrderId, - ct: ct).ConfigureAwait(false); - if (!result) - return result.As(null); - - return result.As(new OrderId - { - SourceObject = result.Data, - Id = result.Data.Id.ToString(CultureInfo.InvariantCulture) - }); - } - - /// - public override async Task> GetOrderAsync(string orderId, string? symbol, CancellationToken ct) - { - if (!long.TryParse(orderId, out var id)) - throw new ArgumentException($"Invalid order id for Bybit {nameof(ISpotClient.GetOrderAsync)}", nameof(orderId)); - - var result = await Trading.GetOrderAsync(id, ct: ct).ConfigureAwait(false); - if (!result) - return result.As(null); - - return result.As(new Order - { - SourceObject = result.Data, - Id = result.Data.Id.ToString(CultureInfo.InvariantCulture), - Price = result.Data.Price, - Quantity = result.Data.Quantity, - QuantityFilled = result.Data.QuantityFilled, - Timestamp = result.Data.CreateTime, - Symbol = result.Data.Symbol, - Side = result.Data.Side == OrderSide.Buy ? CommonOrderSide.Buy : CommonOrderSide.Sell, - Type = result.Data.Type == OrderType.Limit ? CommonOrderType.Limit : result.Data.Type == OrderType.Market ? CommonOrderType.Market : CommonOrderType.Other, - Status = result.Data.Status == OrderStatus.Canceled ? CommonOrderStatus.Canceled : result.Data.Status == OrderStatus.Filled ? CommonOrderStatus.Filled : CommonOrderStatus.Active - }); - } - - /// - public override async Task>> GetOrderTradesAsync(string orderId, string? symbol, CancellationToken ct) - { - if (!long.TryParse(orderId, out var id)) - throw new ArgumentException($"Invalid order id for Bybit {nameof(ISpotClient.GetOrderAsync)}", nameof(orderId)); - - var result = await Trading.GetUserTradesAsync(fromId: id, toId: long.Parse(orderId), ct: ct).ConfigureAwait(false); - if (!result) - return result.As>(null); - - return result.As(result.Data.Select(r => new UserTrade - { - SourceObject = r, - Id = r.Id.ToString(CultureInfo.InvariantCulture), - OrderId = r.OrderId.ToString(CultureInfo.InvariantCulture), - Symbol = r.Symbol, - Fee = r.Fee, - FeeAsset = r.FeeAsset, - Price = r.Price, - Quantity = r.Quantity, - Timestamp = r.TradeTime - })); - } - - /// - public override async Task>> GetOpenOrdersAsync(string? symbol, CancellationToken ct) - { - var result = await Trading.GetOpenOrdersAsync(symbol, ct: ct).ConfigureAwait(false); - if (!result) - return result.As>(null); - - return result.As(result.Data.Select(r => new Order - { - SourceObject = r, - Id = r.Id.ToString(CultureInfo.InvariantCulture), - Price = r.Price, - Quantity = r.Quantity, - QuantityFilled = r.QuantityFilled, - Timestamp = r.CreateTime, - Symbol = r.Symbol, - Side = r.Side == OrderSide.Buy ? CommonOrderSide.Buy : CommonOrderSide.Sell, - Type = r.Type == OrderType.Limit ? CommonOrderType.Limit: r.Type == OrderType.Market ? CommonOrderType.Market: CommonOrderType.Other, - Status = r.Status == OrderStatus.Canceled ? CommonOrderStatus.Canceled: r.Status == OrderStatus.Filled ? CommonOrderStatus.Filled: CommonOrderStatus.Active - })); - } - - /// - public override async Task>> GetClosedOrdersAsync(string? symbol, CancellationToken ct) - { - var result = await Trading.GetOrdersAsync(symbol, ct: ct).ConfigureAwait(false); - if (!result) - return result.As>(null); - - return result.As(result.Data.Select(r => new Order - { - SourceObject = r, - Id = r.Id.ToString(CultureInfo.InvariantCulture), - Price = r.Price, - Quantity = r.Quantity, - QuantityFilled = r.QuantityFilled, - Timestamp = r.CreateTime, - Symbol = r.Symbol, - Side = r.Side == OrderSide.Buy ? CommonOrderSide.Buy : CommonOrderSide.Sell, - Type = r.Type == OrderType.Limit ? CommonOrderType.Limit : r.Type == OrderType.Market ? CommonOrderType.Market : CommonOrderType.Other, - Status = r.Status == OrderStatus.Canceled ? CommonOrderStatus.Canceled : r.Status == OrderStatus.Filled ? CommonOrderStatus.Filled : CommonOrderStatus.Active - })); - } - - /// - public override async Task> CancelOrderAsync(string orderId, string? symbol, CancellationToken ct) - { - if (!long.TryParse(orderId, out var id)) - throw new ArgumentException($"Invalid order id for Bybit {nameof(ISpotClient.GetOrderAsync)}", nameof(orderId)); - - var result = await Trading.CancelOrderAsync(id, ct: ct).ConfigureAwait(false); - if (!result) - return result.As(null); - - return result.As(new OrderId { SourceObject = result.Data, Id = result.Data.Id.ToString(CultureInfo.InvariantCulture) }); - } - - /// - public override async Task>> GetBalancesAsync(string? accountId, CancellationToken ct) - { - var result = await Account.GetBalancesAsync(ct: ct).ConfigureAwait(false); - if (!result) - return result.As>(null); - - return result.As(result.Data.Select(r => new Balance - { - SourceObject = r, - Asset = r.Asset, - Available = r.Available, - Total = r.Total - })); - } - - #endregion - - /// - protected override Task> GetServerTimestampAsync() - => ExchangeData.GetServerTimeAsync(); - } -} diff --git a/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApi.cs b/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApi.cs deleted file mode 100644 index c853d14c..00000000 --- a/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApi.cs +++ /dev/null @@ -1,133 +0,0 @@ -using Bybit.Net.Interfaces.Clients.UsdPerpetualApi; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Options; -using CryptoExchange.Net; -using CryptoExchange.Net.Authentication; -using CryptoExchange.Net.Objects; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.UsdPerpetualApi -{ - /// - public class BybitRestClientUsdPerpetualApi : RestApiClient, IBybitRestClientUsdPerpetualApi - { - internal static TimeSyncState _timeSyncState = new TimeSyncState("USD Perpetual Api"); - - /// - /// Options - /// - public new BybitRestOptions ClientOptions => (BybitRestOptions)base.ClientOptions; - - /// - public IBybitRestClientUsdPerpetualApiAccount Account { get; } - /// - public IBybitRestClientUsdPerpetualApiExchangeData ExchangeData { get; } - /// - public IBybitRestClientUsdPerpetualApiTrading Trading { get; } - - #region ctor - internal BybitRestClientUsdPerpetualApi(ILogger logger, HttpClient? httpClient, BybitRestOptions options) : - base(logger, httpClient, options.Environment.RestBaseAddress, options, options.UsdPerpetualOptions) - { - if (!string.IsNullOrEmpty(options.Referer)) - { - StandardRequestHeaders = new Dictionary - { - { "x-referer", options.Referer! } - }; - } - - manualParseError = true; - - Account = new BybitRestClientUsdPerpetualApiAccount(this); - ExchangeData = new BybitRestClientUsdPerpetualApiExchangeData(this); - Trading = new BybitRestClientUsdPerpetualApiTrading(this); - requestBodyFormat = RequestBodyFormat.FormData; - ParameterPositions[HttpMethod.Delete] = HttpMethodParameterPosition.InUri; - } - #endregion - - /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) - => new BybitAuthenticationProvider(credentials); - - /// - /// Get url for an endpoint - /// - /// - /// - internal Uri GetUrl(string endpoint) - { - return new Uri(BaseAddress.AppendPath(endpoint)); - } - - /// - protected override Task TryParseErrorAsync(JToken data) - { - var responseCode = data["ret_code"]; - if (responseCode != null && responseCode.ToString() != "0") - { - var errorMessage = data["ret_msg"]; - return Task.FromResult(new ServerError(responseCode.Value(), errorMessage!.ToString()))!; - } - - return Task.FromResult(null); - } - - internal async Task>> SendRequestWrapperAsync( - Uri uri, - HttpMethod method, - CancellationToken cancellationToken, - Dictionary? parameters = null, - bool signed = false, - JsonSerializer? deserializer = null, - bool ignoreRatelimit = false) where T : class - { - var result = await base.SendRequestAsync>(uri, method, cancellationToken, parameters, signed, deserializer: deserializer, ignoreRatelimit: ignoreRatelimit).ConfigureAwait(false); - if (!result) - return result.As>(default); - - if (result.Data.ReturnCode != 0) - return result.AsError>(new ServerError(result.Data.ReturnCode, result.Data.ReturnMessage)); - - return result.As(result.Data); - } - - internal async Task> SendRequestAsync( - Uri uri, - HttpMethod method, - CancellationToken cancellationToken, - Dictionary? parameters = null, - bool signed = false, - JsonSerializer? deserializer = null) - { - var result = await base.SendRequestAsync>(uri, method, cancellationToken, parameters, signed, deserializer: deserializer).ConfigureAwait(false); - if (!result) - return result.As(default); - - if (result.Data.ReturnCode != 0) - return result.AsError(new ServerError(result.Data.ReturnCode, result.Data.ReturnMessage)); - - return result.As(result.Data.Result); - } - - /// - protected override Task> GetServerTimestampAsync() - => ExchangeData.GetServerTimeAsync(); - - /// - public override TimeSyncInfo? GetTimeSyncInfo() - => new TimeSyncInfo(_logger, (ApiOptions.AutoTimestamp ?? ClientOptions.AutoTimestamp), (ApiOptions.TimestampRecalculationInterval ?? ClientOptions.TimestampRecalculationInterval), _timeSyncState); - - /// - public override TimeSpan? GetTimeOffset() - => _timeSyncState.TimeOffset; - } -} diff --git a/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApiAccount.cs b/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApiAccount.cs deleted file mode 100644 index 8d84cd1c..00000000 --- a/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApiAccount.cs +++ /dev/null @@ -1,377 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Bybit.Net.Interfaces.Clients.UsdPerpetualApi; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net; -using CryptoExchange.Net.Converters; -using CryptoExchange.Net.Objects; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.UsdPerpetualApi -{ - /// - public class BybitRestClientUsdPerpetualApiAccount : IBybitRestClientUsdPerpetualApiAccount - { - private BybitRestClientUsdPerpetualApi _baseClient; - - internal BybitRestClientUsdPerpetualApiAccount(BybitRestClientUsdPerpetualApi baseClient) - { - _baseClient = baseClient; - } - - #region Get last funding rate - - /// - public async Task> GetUserLastFundingFeeAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/funding/prev-funding"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get predicted funding rate - - /// - public async Task> GetUserPredictedFundingRateAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/funding/predicted-funding"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get risk limit - - /// - public async Task>> GetRiskLimitAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("public/linear/risk-limit"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Set risk limit - - /// - public async Task> SetRiskLimitAsync(string symbol, OrderSide side, long riskId, PositionMode? positionMode = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "side", JsonConvert.SerializeObject(side, new OrderSideConverter(false)) }, - { "risk_id", riskId.ToString(CultureInfo.InvariantCulture) }, - }; - parameters.AddOptionalParameter("position_idx", positionMode == null ? null : JsonConvert.SerializeObject(positionMode, new PositionModeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/position/set-risk"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get position - - /// - public async Task>> GetPositionAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("private/linear/position/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get positions - - /// - public async Task>> GetPositionsAsync(long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>(_baseClient.GetUrl("private/linear/position/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - if (!result) - return result.As>(default); - - foreach (var position in result.Data) - position.Data.IsValid = position.IsValid; - - return result.As(result.Data.Select(d => d.Data)); - } - - #endregion - - #region Set auto add margin - - /// - public async Task SetAutoAddMarginAsync(string symbol, OrderSide side, bool autoAddMargin, PositionMode? positionMode = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "side", JsonConvert.SerializeObject(side, new OrderSideConverter(false)) }, - { "auto_add_margin", autoAddMargin.ToString(CultureInfo.InvariantCulture) }, - }; - parameters.AddOptionalParameter("position_idx", positionMode == null ? null : JsonConvert.SerializeObject(positionMode, new PositionModeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/position/set-auto-add-margin"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - return result.AsDataless(); - } - - #endregion - - #region Add / Reduce margin - - /// - public async Task> AddReduceMarginAsync(string symbol, OrderSide side, decimal margin, PositionMode? positionMode = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "side", JsonConvert.SerializeObject(side, new OrderSideConverter(false)) }, - { "margin", margin.ToString(CultureInfo.InvariantCulture) }, - }; - parameters.AddOptionalParameter("position_idx", positionMode == null ? null : JsonConvert.SerializeObject(positionMode, new PositionModeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/position/add-margin"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Set leverage - - /// - public async Task SetLeverageAsync(string symbol, decimal buyLeverage, decimal sellLeverage, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "buy_leverage", buyLeverage.ToString(CultureInfo.InvariantCulture) }, - { "sell_leverage", sellLeverage.ToString(CultureInfo.InvariantCulture) }, - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/position/set-leverage"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - return result.AsDataless(); - } - - #endregion - - #region Get Profit And Loss History - - /// - public async Task>>> GetProfitAndLossHistoryAsync(string symbol, DateTime? startTime = null, DateTime? endTime = null, TradeType? type = null, int? page = null, int? pageSize = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - parameters.AddOptionalParameter("start_time", DateTimeConverter.ConvertToSeconds(startTime)); - parameters.AddOptionalParameter("end_time", DateTimeConverter.ConvertToSeconds(endTime)); - parameters.AddOptionalParameter("exec_type", type == null ? null : JsonConvert.SerializeObject(type.Value, new TradeTypeConverter(false))); - parameters.AddOptionalParameter("page", page?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("limit", pageSize?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("private/linear/trade/closed-pnl/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - if (result && result.Data.Data == null) - result.Data.Data = new BybitPnlEntry[0]; - - return result; - } - - #endregion - - #region Set full / partial position mode - - /// - public async Task> SetFullPartialPositionModeAsync(string symbol, StopLossTakeProfitMode mode, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "tp_sl_mode", JsonConvert.SerializeObject(mode, new StopLossTakeProfitModeConverter(false)) }, - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/tpsl/switch-mode"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Set Position Mode Switch - - /// - public async Task SetPositionModeAsync(string symbol, string asset, bool hedgeMode, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - if (string.IsNullOrWhiteSpace(asset)) - { - parameters.Add("symbol", symbol); - } - else if (string.IsNullOrWhiteSpace(symbol)) - { - parameters.Add("coin", asset); - } - else - { - throw new ArgumentNullException("One of 'coin' or 'symbol' parameters is required!"); - } - - parameters.Add("mode", hedgeMode ? "BothSide" : "MergedSingle"); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/position/switch-mode"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - return result.AsDataless(); - } - - #endregion - - #region Set position mode - - /// - public async Task SetIsolatedPositionModeAsync(string symbol, bool isIsolated, decimal buyLeverage, decimal sellLeverage, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "is_isolated", isIsolated.ToString() }, - { "buy_leverage", buyLeverage.ToString(CultureInfo.InvariantCulture) }, - { "sell_leverage", sellLeverage.ToString(CultureInfo.InvariantCulture) }, - }; - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/position/switch-isolated"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - return result.AsDataless(); - } - - #endregion - - #region Get balances - - /// - public async Task>> GetBalancesAsync(string? asset = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/private/wallet/balance"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get wallet fund history - - /// - public async Task>> GetWalletFundHistoryAsync(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, WalletFundType? type = null, int? pageSize = null, int? page = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("start_date", startTime?.ToString("yyyy-MM-dd")); - parameters.AddOptionalParameter("end_date", endTime?.ToString("yyyy-MM-dd")); - parameters.AddOptionalParameter("wallet_fund_type", type == null ? null : JsonConvert.SerializeObject(type, new WalletFundTypeConverter(false))); - parameters.AddOptionalParameter("page", page?.ToString()); - parameters.AddOptionalParameter("limit", pageSize?.ToString()); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("v2/private/wallet/fund/records"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - if (!result) - return result.As>(default); - - if (result.Data.Data == null) - return result.As>(new BybitWalletFundRecord[0]); - - return result.As(result.Data.Data); - } - - #endregion - - #region Get withdrawal history - - /// - public async Task>> GetWithdrawalHistoryAsync(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, WithdrawStatus? status = null, int? pageSize = null, int? page = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("coin", asset); - parameters.AddOptionalParameter("start_date", startTime?.ToString("yyyy-MM-dd")); - parameters.AddOptionalParameter("end_date", endTime?.ToString("yyyy-MM-dd")); - parameters.AddOptionalParameter("status", status == null ? null : JsonConvert.SerializeObject(status, new WithdrawStatusConverter(false))); - parameters.AddOptionalParameter("page", page?.ToString()); - parameters.AddOptionalParameter("limit", pageSize?.ToString()); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("v2/private/wallet/withdraw/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - if (!result) - return result.As>(default); - - if (result.Data.Data == null) - return result.As>(new BybitWithdrawal[0]); - - return result.As(result.Data.Data); - } - - #endregion - - #region Get asset exchange history - - /// - public async Task>> GetAssetExchangeHistoryAsync(long? fromId = null, SearchDirection? direction = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("from", fromId?.ToString()); - parameters.AddOptionalParameter("direction", direction == null ? null : JsonConvert.SerializeObject(direction, new SearchDirectionConverter(false))); - parameters.AddOptionalParameter("limit", limit?.ToString()); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/private/exchange-order/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get api key info - - /// - public async Task>> GetApiKeyInfoAsync(long? receiveWindow = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/private/account/api-key"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - } -} diff --git a/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApiExchangeData.cs b/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApiExchangeData.cs deleted file mode 100644 index 3cbeedbb..00000000 --- a/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApiExchangeData.cs +++ /dev/null @@ -1,242 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Bybit.Net.Interfaces.Clients.UsdPerpetualApi; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net; -using CryptoExchange.Net.Converters; -using CryptoExchange.Net.Objects; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.UsdPerpetualApi -{ - /// - public class BybitRestClientUsdPerpetualApiExchangeData : IBybitRestClientUsdPerpetualApiExchangeData - { - private BybitRestClientUsdPerpetualApi _baseClient; - - internal BybitRestClientUsdPerpetualApiExchangeData(BybitRestClientUsdPerpetualApi baseClient) - { - _baseClient = baseClient; - } - - #region Get klines - - /// - public async Task>> GetKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "interval", JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) }, - { "from", DateTimeConverter.ConvertToSeconds(from)! }, - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("public/linear/kline"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get trade history - - /// - public async Task>> GetTradeHistoryAsync(string symbol, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("public/linear/recent-trading-records"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get last funding rate - - /// - public async Task> GetLastFundingRateAsync(string symbol, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("public/linear/funding/prev-funding-rate"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get mark price klines - - /// - public async Task>> GetMarkPriceKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "interval", JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) }, - { "from", DateTimeConverter.ConvertToSeconds(from)! }, - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("public/linear/mark-price-kline"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get index price klines - - /// - public async Task>> GetIndexPriceKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "interval", JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) }, - { "from", DateTimeConverter.ConvertToSeconds(from) }, - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("public/linear/index-price-kline"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get premium index price klines - - /// - public async Task>> GetPremiumIndexKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "interval", JsonConvert.SerializeObject(interval, new KlineIntervalConverter(false)) }, - { "from", DateTimeConverter.ConvertToSeconds(from) }, - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("public/linear/premium-index-kline"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get server time - - /// - public async Task> GetServerTimeAsync(CancellationToken ct = default) - { - var result = await _baseClient.SendRequestWrapperAsync(_baseClient.GetUrl("v2/public/time"), HttpMethod.Get, ct, null, ignoreRatelimit: true).ConfigureAwait(false); - if (!result) - return result.As(default); - - return result.As(result.Data.Timestamp); - } - - #endregion - - #region Get announcement - - /// - public async Task>> GetAnnouncementsAsync(CancellationToken ct = default) - { - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/announcement"), HttpMethod.Get, ct, null).ConfigureAwait(false); - } - - #endregion - - #region Get order book - - /// - public async Task>> GetOrderBookAsync(string symbol, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/orderBook/L2"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get ticker - - /// - public async Task>> GetTickerAsync(string? symbol = null, CancellationToken ct = default) - { - var parameters = new Dictionary(); - parameters.AddOptionalParameter("symbol", symbol); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/tickers"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get symbols - - /// - public async Task>> GetSymbolsAsync(CancellationToken ct = default) - { - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/symbols"), HttpMethod.Get, ct, null).ConfigureAwait(false); - } - - #endregion - - #region Get open interest - - /// - public async Task>> GetOpenInterestAsync(string symbol, DataPeriod period, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "period", JsonConvert.SerializeObject(period, new DataPeriodConverter(false)) } - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/open-interest"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get recent big trades - - /// - public async Task>> GetRecentBigTradesAsync(string symbol, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol } - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/big-deal"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - - #region Get long short ratio - - /// - public async Task>> GetLongShortRatioAsync(string symbol, DataPeriod period, int? limit = null, CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "period", JsonConvert.SerializeObject(period, new DataPeriodConverter(false)) } - }; - parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("v2/public/account-ratio"), HttpMethod.Get, ct, parameters).ConfigureAwait(false); - } - - #endregion - } -} diff --git a/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApiTrading.cs b/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApiTrading.cs deleted file mode 100644 index a262a9a7..00000000 --- a/ByBit.Net/Clients/UsdPerpetualApi/BybitRestClientUsdPerpetualApiTrading.cs +++ /dev/null @@ -1,533 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Bybit.Net.Interfaces.Clients.UsdPerpetualApi; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net; -using CryptoExchange.Net.Converters; -using CryptoExchange.Net.Objects; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Clients.UsdPerpetualApi -{ - /// - public class BybitRestClientUsdPerpetualApiTrading : IBybitRestClientUsdPerpetualApiTrading - { - private BybitRestClientUsdPerpetualApi _baseClient; - - internal BybitRestClientUsdPerpetualApiTrading(BybitRestClientUsdPerpetualApi baseClient) - { - _baseClient = baseClient; - } - - #region Place order - - /// - public async Task> PlaceOrderAsync( - string symbol, - OrderSide side, - OrderType type, - decimal quantity, - TimeInForce timeInForce, - bool reduceOnly, - bool closeOnTrigger, - decimal? price = null, - string? clientOrderId = null, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - PositionMode? positionMode = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "side", JsonConvert.SerializeObject(side, new OrderSideConverter(false)) }, - { "symbol", symbol }, - { "order_type", JsonConvert.SerializeObject(type, new OrderTypeConverter(false)) }, - { "qty", quantity.ToString(CultureInfo.InvariantCulture) }, - { "time_in_force", JsonConvert.SerializeObject(timeInForce, new TimeInForceConverter(false)) }, - { "reduce_only", reduceOnly.ToString() }, - { "close_on_trigger", closeOnTrigger.ToString() } - }; - - parameters.AddOptionalParameter("price", price?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("position_idx", positionMode == null ? null : JsonConvert.SerializeObject(positionMode, new PositionModeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/order/create"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get orders - - /// - public async Task>>> GetOrdersAsync( - string symbol, - string? orderId = null, - string? clientOrderId = null, - OrderStatus? status = null, - SortOrder? order = null, - int? pageSize = null, - int? page = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("order_id", orderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("order_status", status == null ? null : JsonConvert.SerializeObject(status, new OrderStatusConverter(false))); - parameters.AddOptionalParameter("order", order == null ? null : JsonConvert.SerializeObject(order, new SortOrderConverter(false))); - parameters.AddOptionalParameter("limit", pageSize?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("page", page?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("private/linear/order/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Cancel order - - /// - public async Task> CancelOrderAsync( - string symbol, - string? orderId = null, - string? clientOrderId = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (orderId == null && clientOrderId == null || orderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(orderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("order_id", orderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/order/cancel"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Cancel all order - - /// - public async Task>> CancelAllOrdersAsync( - string symbol, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>(_baseClient.GetUrl("private/linear/order/cancel-all"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - if (result && result.Data == null) - return result.As>(new string[0]); - - return result; - } - - #endregion - - #region Modify order - - /// - public async Task> ModifyOrderAsync( - string symbol, - string? orderId = null, - string? clientOrderId = null, - decimal? newPrice = null, - decimal? newQuantity = null, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (orderId == null && clientOrderId == null || orderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(orderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("p_r_price", newPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("p_r_qty", newQuantity?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("order_id", orderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/order/replace"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Get open orders realtime - - /// - public async Task> GetOpenOrderRealTimeAsync( - string symbol, - string? orderId = null, - string? clientOrderId = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (orderId == null && clientOrderId == null || orderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(orderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - parameters.AddOptionalParameter("order_id", orderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/order/search"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - /// - public async Task>> GetOpenOrdersRealTimeAsync( - string symbol, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("private/linear/order/search"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Place conditional order - - /// - public async Task> PlaceConditionalOrderAsync( - string symbol, - OrderSide side, - OrderType type, - decimal quantity, - decimal basePrice, - decimal triggerPrice, - TimeInForce timeInForce, - bool closeOnTrigger, - bool reduceOnly, - decimal? price = null, - TriggerType? triggerType = null, - string? clientOrderId = null, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - PositionMode? positionMode = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "side", JsonConvert.SerializeObject(side, new OrderSideConverter(false)) }, - { "symbol", symbol }, - { "order_type", JsonConvert.SerializeObject(type, new OrderTypeConverter(false)) }, - { "qty", quantity.ToString(CultureInfo.InvariantCulture) }, - { "base_price", basePrice.ToString(CultureInfo.InvariantCulture) }, - { "stop_px", triggerPrice.ToString(CultureInfo.InvariantCulture) }, - { "time_in_force", JsonConvert.SerializeObject(timeInForce, new TimeInForceConverter(false)) }, - { "close_on_trigger", closeOnTrigger.ToString(CultureInfo.InvariantCulture) }, - { "reduce_only", reduceOnly.ToString(CultureInfo.InvariantCulture) }, - }; - - parameters.AddOptionalParameter("trigger_by", triggerType == null ? null : JsonConvert.SerializeObject(triggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("price", price?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("position_idx", positionMode == null ? null : JsonConvert.SerializeObject(positionMode, new PositionModeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/stop-order/create"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Get conditional orders - - /// - public async Task>>> GetConditionalOrdersAsync( - string symbol, - string? orderId = null, - string? clientOrderId = null, - OrderStatus? status = null, - SortOrder? order = null, - int? pageSize = null, - int? page = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("stop_order_id", orderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("stop_order_status", status == null ? null : JsonConvert.SerializeObject(status, new OrderStatusConverter(false))); - parameters.AddOptionalParameter("order", order == null ? null : JsonConvert.SerializeObject(order, new SortOrderConverter(false))); - parameters.AddOptionalParameter("limit", pageSize?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("page", page?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("private/linear/stop-order/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Cancel conditional order - - /// - public async Task> CancelConditionalOrderAsync( - string symbol, - string? stopOrderId = null, - string? clientOrderId = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (stopOrderId == null && clientOrderId == null || stopOrderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(stopOrderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("stop_order_id", stopOrderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/stop-order/cancel"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Cancel all conditional orders - - /// - public async Task>> CancelAllConditionalOrdersAsync( - string symbol, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync>(_baseClient.GetUrl("private/linear/stop-order/cancel-all"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - if (result && result.Data == null) - return result.As>(new string[0]); - - return result; - } - - #endregion - - #region Modify order - - /// - public async Task> ModifyConditionalOrderAsync( - string symbol, - string? stopOrderId = null, - string? clientOrderId = null, - decimal? newPrice = null, - decimal? newTriggerPrice = null, - decimal? newQuantity = null, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (stopOrderId == null && clientOrderId == null || stopOrderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(stopOrderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("p_r_price", newPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("p_r_qty", newQuantity?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("p_r_trigger_price", newTriggerPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_order_id", stopOrderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/stop-order/replace"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region Get open orders realtime - - /// - public async Task> GetOpenConditionalOrderRealTimeAsync( - string symbol, - string? stopOrderId = null, - string? clientOrderId = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - if (stopOrderId == null && clientOrderId == null || stopOrderId != null && clientOrderId != null) - throw new ArgumentException($"1 of {nameof(stopOrderId)} or {nameof(clientOrderId)} should be provided"); - - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - parameters.AddOptionalParameter("stop_order_id", stopOrderId); - parameters.AddOptionalParameter("order_link_id", clientOrderId); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/stop-order/search"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - /// - public async Task>> GetOpenConditionalOrdersRealTimeAsync( - string symbol, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>(_baseClient.GetUrl("private/linear/stop-order/search"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - - } - - #endregion - - #region User trades - - /// - public async Task>>> GetUserTradesAsync( - string symbol, - DateTime? startTime = null, - DateTime? endTime = null, - int? page = null, - int? pageSize = null, - TradeType? type = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - }; - parameters.AddOptionalParameter("exec_type", type == null ? null : JsonConvert.SerializeObject(type, new TradeTypeConverter(false))); - parameters.AddOptionalParameter("start_time", DateTimeConverter.ConvertToMilliseconds(startTime)); - parameters.AddOptionalParameter("end_time", DateTimeConverter.ConvertToMilliseconds(endTime)); - parameters.AddOptionalParameter("page", page?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("limit", pageSize?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - return await _baseClient.SendRequestAsync>>(_baseClient.GetUrl("private/linear/trade/execution/list"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false); - } - - #endregion - - #region Set Trading Stop - /// - public async Task SetTradingStopAsync( - string symbol, - PositionSide side, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - decimal? trailingStopPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - decimal? takeProfitQuantity = null, - decimal? stopLossQuantity = null, - PositionMode? positionMode = null, - long? receiveWindow = null, - CancellationToken ct = default) - { - var parameters = new Dictionary() - { - { "symbol", symbol }, - { "side", JsonConvert.SerializeObject(side, new PositionSideConverter(false)) } - }; - parameters.AddOptionalParameter("take_profit", takeProfitPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("stop_loss", stopLossPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("trailing_stop", trailingStopPrice?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_trigger_by", takeProfitTriggerType == null ? null : JsonConvert.SerializeObject(takeProfitTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_trigger_by", stopLossTriggerType == null ? null : JsonConvert.SerializeObject(stopLossTriggerType, new TriggerTypeConverter(false))); - parameters.AddOptionalParameter("sl_size", stopLossQuantity?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("tp_size", takeProfitQuantity?.ToString(CultureInfo.InvariantCulture)); - parameters.AddOptionalParameter("position_idx", positionMode == null ? null : JsonConvert.SerializeObject(positionMode, new PositionModeConverter(false))); - parameters.AddOptionalParameter("recv_window", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? _baseClient.ClientOptions.ReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); - - var result = await _baseClient.SendRequestAsync(_baseClient.GetUrl("private/linear/position/trading-stop"), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false); - return result.AsDataless(); - } - #endregion - } -} diff --git a/ByBit.Net/Interfaces/Clients/GeneralApi/IBybitRestClientGeneralApi.cs b/ByBit.Net/Interfaces/Clients/GeneralApi/IBybitRestClientGeneralApi.cs deleted file mode 100644 index d6b2a40e..00000000 --- a/ByBit.Net/Interfaces/Clients/GeneralApi/IBybitRestClientGeneralApi.cs +++ /dev/null @@ -1,20 +0,0 @@ -using CryptoExchange.Net.Interfaces; -using System; - -namespace Bybit.Net.Interfaces.Clients.GeneralApi -{ - /// - /// Bybit general API endpoints - /// - public interface IBybitRestClientGeneralApi : IRestApiClient, IDisposable - { - /// - /// Endpoints related to asset transfer - /// - IBybitRestClientGeneralApiTransfer Transfer { get; } - /// - /// Endpoint related to withrawing/depositing - /// - IBybitRestClientGeneralApiWithdrawDeposit WithdrawDeposit { get; } - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/GeneralApi/IBybitRestClientGeneralApiTransfer.cs b/ByBit.Net/Interfaces/Clients/GeneralApi/IBybitRestClientGeneralApiTransfer.cs deleted file mode 100644 index 49ff34e9..00000000 --- a/ByBit.Net/Interfaces/Clients/GeneralApi/IBybitRestClientGeneralApiTransfer.cs +++ /dev/null @@ -1,173 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net.Objects; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.GeneralApi -{ - /// - /// Bybit asset transfer endpoints - /// - public interface IBybitRestClientGeneralApiTransfer - { - /// - /// Create a new transfer from one account type to the other - /// - /// - /// A generated UUID, should be unique - /// The asset to transfer - /// Quantity to transfer - /// From account - /// To account - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> CreateInternalTransferAsync(string transferId, string asset, decimal quantity, AccountType fromAccountType, AccountType toAccountType, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Create a new transfer for a subaccount - /// - /// - /// A generated UUID, should be unique - /// The asset to transfer - /// Quantity to transfer - /// The sub account id - /// The type of the transfer - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> CreateSubAccountTransferAsync(string transferId, string asset, decimal quantity, string subAccountId, TransferType type, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get history of transfers - /// - /// - /// Filter by transfer id - /// Filter by asset - /// Filter by status - /// Filter by start time - /// Filter by end time - /// Filter by direction - /// Max amount of results - /// Page cursor - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetTransferHistoryAsync( - string? transferId = null, - string? asset = null, - TransferStatus? status = null, - DateTime? startTime = null, - DateTime? endTime = null, - SearchDirection? direction = null, - int? limit = null, - string? cursor = null, - long? receiveWindow = null, - CancellationToken ct = default); - - /// - /// Get history of sub account transfers - /// - /// - /// Filter by transfer id - /// Filter by asset - /// Filter by status - /// Filter by start time - /// Filter by end time - /// Filter by direction - /// Max amount of results - /// Page cursor - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetSubAccountTransferHistoryAsync( - string? transferId = null, - string? asset = null, - TransferStatus? status = null, - DateTime? startTime = null, - DateTime? endTime = null, - SearchDirection? direction = null, - int? limit = null, - string? cursor = null, - long? receiveWindow = null, - CancellationToken ct = default); - - /// - /// Get a list of subaccount ids - /// - /// - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> GetSubAccountsAsync(long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Enable universal transfers between sub accounts - /// - /// - /// Sub account ids to enable - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task EnableSubaccountsUniversalTransferAsync(IEnumerable? subaccountIds = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Create a new universal transfer - /// - /// - /// Unique id - /// Asset - /// Quantity - /// From id - /// To id - /// From type - /// To type - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> UniversalTransferAsync(string transferId, string asset, decimal quantity, string fromMemberId, string toMemberId, AccountType fromAccountType, AccountType toAccountType, long? receiveWindow = null, CancellationToken ct = default); - - - /// - /// Get history of universal account transfers - /// - /// - /// Filter by transfer id - /// Filter by asset - /// Filter by status - /// Filter by start time - /// Filter by end time - /// Filter by direction - /// Max amount of results - /// Page cursor - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetUniversalTransferHistoryAsync( - string? transferId = null, - string? asset = null, - TransferStatus? status = null, - DateTime? startTime = null, - DateTime? endTime = null, - SearchDirection? direction = null, - int? limit = null, - string? cursor = null, - long? receiveWindow = null, - CancellationToken ct = default); - - /// - /// Coin balance for an account type including Earn - /// - /// - /// Account type - /// Asset - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> GetAssetBalanceAsync(AccountType accountType, string asset, long? receiveWindow = null, CancellationToken ct = default); - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/GeneralApi/IBybitRestClientGeneralApiWithdrawDeposit.cs b/ByBit.Net/Interfaces/Clients/GeneralApi/IBybitRestClientGeneralApiWithdrawDeposit.cs deleted file mode 100644 index 5bd3b0e5..00000000 --- a/ByBit.Net/Interfaces/Clients/GeneralApi/IBybitRestClientGeneralApiWithdrawDeposit.cs +++ /dev/null @@ -1,159 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net.Objects; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.GeneralApi -{ - /// - /// Bybit withdrawal and deposit endpoints - /// - public interface IBybitRestClientGeneralApiWithdrawDeposit - { - /// - /// Get deposit information - /// - /// - /// Filter by asset - /// Filter by network - /// Page number - /// Page size - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetSupportedDepositMethodsAsync( - string? asset = null, - string? network = null, - int? page = null, - int? pageSize = null, - long? receiveWindow = null, - CancellationToken ct = default); - - /// - /// Get deposit history - /// - /// - /// Filter by asset - /// Filter by start time - /// Filter by end time - /// Filter by direction - /// Max amount of results - /// Page cursor - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetDepositHistoryAsync( - string? asset = null, - DateTime? startTime = null, - DateTime? endTime = null, - SearchDirection? direction = null, - int? limit = null, - string? cursor = null, - long? receiveWindow = null, - CancellationToken ct = default); - - /// - /// Get withdrawal history - /// - /// - /// Filter by withdrawal id - /// Filter by asset - /// Filter by start time - /// Filter by end time - /// Filter by direction - /// Max amount of results - /// Page cursor - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetWithdrawalHistoryAsync( - string? withdrawalId = null, - string? asset = null, - DateTime? startTime = null, - DateTime? endTime = null, - SearchDirection? direction = null, - int? limit = null, - string? cursor = null, - long? receiveWindow = null, - CancellationToken ct = default); - - /// - /// Get asset information regarding withdrawal/deposits - /// - /// - /// Filter by asset - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetAssetInfoAsync( - string? asset = null, - long? receiveWindow = null, - CancellationToken ct = default); - - /// - /// Get account info - /// - /// - /// Filter asset - /// Filter account type - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetAccountInfoAsync( - string? asset = null, - string? accountType = null, - long? receiveWindow = null, - CancellationToken ct = default); - - /// - /// Create a withdrawal request - /// - /// - /// Asset to withdraw - /// Network to use - /// Address to withdraw to, should be whitelisted - /// Quantity to withdraw - /// Tag - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> WithdrawAsync( - string asset, - string network, - string address, - decimal quantity, - string? tag = null, - long? receiveWindow = null, - CancellationToken ct = default); - - /// - /// Cancel withdrawal - /// - /// - /// Id to cancel - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task CancelWithdrawalAsync( - string withdrawalId, - long? receiveWindow = null, - CancellationToken ct = default); - - /// - /// Get deposit addresses for an asset - /// - /// - /// The asset to get addresses for - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> GetDepositAddressesAsync( - string asset, - long? receiveWindow = null, - CancellationToken ct = default); - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/IBybitRestClient.cs b/ByBit.Net/Interfaces/Clients/IBybitRestClient.cs index ef376aba..e1cf8b19 100644 --- a/ByBit.Net/Interfaces/Clients/IBybitRestClient.cs +++ b/ByBit.Net/Interfaces/Clients/IBybitRestClient.cs @@ -1,11 +1,6 @@ using Bybit.Net.Interfaces.Clients.CopyTradingApi; using Bybit.Net.Interfaces.Clients.DerivativesApi; -using Bybit.Net.Interfaces.Clients.GeneralApi; -using Bybit.Net.Interfaces.Clients.InverseFuturesApi; -using Bybit.Net.Interfaces.Clients.InversePerpetualApi; -using Bybit.Net.Interfaces.Clients.SpotApi.v1; using Bybit.Net.Interfaces.Clients.SpotApi.v3; -using Bybit.Net.Interfaces.Clients.UsdPerpetualApi; using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Interfaces; @@ -16,26 +11,6 @@ namespace Bybit.Net.Interfaces.Clients /// public interface IBybitRestClient: IRestClient { - /// - /// General API endpoints - /// - IBybitRestClientGeneralApi GeneralApi { get; } - /// - /// Inverse perpetual API endpoints - /// - IBybitRestClientInversePerpetualApi InversePerpetualApi { get; } - /// - /// USD perpetual API endpoints - /// - IBybitRestClientUsdPerpetualApi UsdPerpetualApi { get; } - /// - /// Inverse futures API endpoints - /// - IBybitRestClientInverseFuturesApi InverseFuturesApi { get; } - /// - /// Spot API endpoints (v1) - /// - IBybitRestClientSpotApiV1 SpotApiV1 { get; } /// /// Spot API endpoints (v3) /// diff --git a/ByBit.Net/Interfaces/Clients/IBybitSocketClient.cs b/ByBit.Net/Interfaces/Clients/IBybitSocketClient.cs index 469c22a0..8c81e754 100644 --- a/ByBit.Net/Interfaces/Clients/IBybitSocketClient.cs +++ b/ByBit.Net/Interfaces/Clients/IBybitSocketClient.cs @@ -2,7 +2,6 @@ using Bybit.Net.Interfaces.Clients.DerivativesApi.ContractApi; using Bybit.Net.Interfaces.Clients.DerivativesApi.UnifiedMarginApi; using Bybit.Net.Interfaces.Clients.SpotApi.v3; -using Bybit.Net.Interfaces.Clients.UsdPerpetualApi; using Bybit.Net.Interfaces.Clients.V5; using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Interfaces; diff --git a/ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApi.cs b/ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApi.cs deleted file mode 100644 index 54345465..00000000 --- a/ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApi.cs +++ /dev/null @@ -1,26 +0,0 @@ -using CryptoExchange.Net.Interfaces; -using System; - -namespace Bybit.Net.Interfaces.Clients.InverseFuturesApi -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 16/30 OCTOBER, USE V5 API INSTEAD] Bybit inverse futures API endpoints - /// - public interface IBybitRestClientInverseFuturesApi : IRestApiClient, IDisposable - { - /// - /// Endpoints related to account settings, info or actions - /// - IBybitRestClientInverseFuturesApiAccount Account { get; } - - /// - /// Endpoints related to retrieving market and system data - /// - IBybitRestClientInverseFuturesApiExchangeData ExchangeData { get; } - - /// - /// Endpoints related to orders and trades - /// - IBybitRestClientInverseFuturesApiTrading Trading { get; } - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApiAccount.cs b/ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApiAccount.cs deleted file mode 100644 index f72e6f17..00000000 --- a/ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApiAccount.cs +++ /dev/null @@ -1,208 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net.Objects; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.InverseFuturesApi -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 30 OCTOBER, USE V5 API INSTEAD] Bybit account endpoints. Account endpoints include balance info, withdraw/deposit info and requesting and account settings - /// - public interface IBybitRestClientInverseFuturesApiAccount - { - #region Risk - - /// - /// Get position risk limit - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetRiskLimitAsync(string? symbol = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Set position risk - /// - /// - /// The symbol - /// The risk id to set - /// Position mode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> SetRiskLimitAsync(string symbol, long riskId, PositionMode? mode = null, long? receiveWindow = null, CancellationToken ct = default); - - #endregion - - #region Positions - - /// - /// Get user positions for a symbol - /// - /// - /// Filter by symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetPositionAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get user positions - /// - /// - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetPositionsAsync(long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Change margin - /// - /// - /// The symbol - /// The position mode - /// The margin - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> ChangeMarginAsync(string symbol, PositionMode mode, decimal margin, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Set leerage - /// - /// - /// The symbol - /// Buy leverage - /// Sell leverage - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> SetLeverageAsync(string symbol, decimal buyLeverage, decimal sellLeverage, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Switch beteen onway and hedge position mode. - /// If you are in One-Way Mode, you can only open one position on Buy or Sell side; - /// If you are in Hedge Mode, you can open both Buy and Sell side positions simultaneously. - /// - /// - /// Symbol. Required if not passing coin - /// Currency alias. Required if not passing symbol - /// Hedgemode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task SetPositionModeAsync(string symbol, string asset, bool hedgeMode, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Switch between full or partial Stop loss/Take profit mode - /// - /// - /// The symbol - /// New mode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> SetFullPartialPositionModeAsync(string symbol, StopLossTakeProfitMode mode, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Switch between cross and isolated mode. - /// - /// - /// The symbol - /// Is isolated - /// Buy leverage - /// Sell leverage - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task SetIsolatedPositionModeAsync(string symbol, bool isIsolated, decimal buyLeverage, decimal sellLeverage, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get user's profit and loss records - /// - /// - /// The symbol to get records for - /// Filter by startTime - /// Filter by endTime - /// Filter by type - /// Page - /// Page size - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetProfitAndLossHistoryAsync(string symbol, DateTime? startTime = null, DateTime? endTime = null, TradeType? type = null, int? page = null, int? pageSize = null, long? receiveWindow = null, CancellationToken ct = default); - - #endregion - - #region Wallet - - /// - /// Get wallet balances - /// - /// - /// Filter by asset - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetBalancesAsync(string? asset = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get wallet fund endpoints - /// - /// - /// Filter by asset - /// Filter by start time - /// Filter by end time - /// Filter by type - /// Page size - /// Page - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetWalletFundHistoryAsync(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, WalletFundType? type = null, int? pageSize = null, int? page = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get withdrawal history - /// - /// - /// Filter by asset - /// Filter by start time - /// Filter by end time - /// Filter by status - /// Page size - /// Page - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetWithdrawalHistoryAsync(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, WithdrawStatus? status = null, int? pageSize = null, int? page = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get asset exchange history - /// - /// - /// Filter by id - /// Filter by direction - /// Max records - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetAssetExchangeHistoryAsync(long? fromId = null, SearchDirection? direction = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default); - - #endregion - - /// - /// Get Api key info - /// - /// - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetApiKeyInfoAsync(long? receiveWindow = null, CancellationToken ct = default); - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApiExchangeData.cs b/ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApiExchangeData.cs deleted file mode 100644 index 1af36588..00000000 --- a/ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApiExchangeData.cs +++ /dev/null @@ -1,138 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net.Objects; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.InverseFuturesApi -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 16 OCTOBER, USE V5 API INSTEAD] Bybit exchange data endpoints. Exchange data includes market data (tickers, order books, etc) and system status. - /// - public interface IBybitRestClientInverseFuturesApiExchangeData - { - /// - /// Get the server time - /// - /// - /// Cancellation token - /// - Task> GetServerTimeAsync(CancellationToken ct = default); - - /// - /// The API announcements for the last 30 days - /// - /// - /// Cancellation token - /// - Task>> GetAnnouncementsAsync(CancellationToken ct = default); - - /// - /// Get all supported symbols - /// - /// - /// Cancellation token - /// - Task>> GetSymbolsAsync(CancellationToken ct = default); - - /// - /// The ticker info for a symbol - /// - /// - /// The symbol - /// Cancellation token - /// - Task>> GetTickerAsync(string? symbol = null, CancellationToken ct = default); - - /// - /// Get public trade history - /// - /// - /// The symbol - /// Filter by records after this id - /// Max amount of results - /// Cancellation token - /// - Task>> GetTradeHistoryAsync(string symbol, long? fromId = null, int? limit = null, CancellationToken ct = default); - - /// - /// Get the current order book for a symbol - /// - /// - /// The symbol - /// Cancellation token - /// - Task>> GetOrderBookAsync(string symbol, CancellationToken ct = default); - - /// - /// Get price klines - /// - /// - /// Symbol of the klines - /// Interval of the kline data - /// Start time of the data - /// Max amount of candles - /// Cancellation token - /// - Task>> GetKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default); - - /// - /// Get index price klines - /// - /// - /// Symbol of the klines - /// Interval of the kline data - /// Start time of the data - /// Max amount of candles - /// Cancellation token - /// - Task>> GetIndexPriceKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default); - - /// - /// Get mark price klines - /// - /// - /// Symbol of the klines - /// Interval of the kline data - /// Start time of the data - /// Max amount of candles - /// Cancellation token - /// - Task>> GetMarkPriceKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default); - - /// - /// Get long/short ratio - /// - /// - /// The symbol - /// The data period - /// Max amount of results - /// Cancellation token - /// - Task>> GetLongShortRatioAsync(string symbol, DataPeriod period, int? limit = null, CancellationToken ct = default); - - /// - /// Gets the total amount of unsettled contracts. In other words, the total number of contracts held in open positions. - /// - /// - /// The symbol - /// The period of data - /// Max amount of results - /// Cancellation token - /// - Task>> GetOpenInterestAsync(string symbol, DataPeriod period, int? limit = null, CancellationToken ct = default); - - /// - /// Obtain filled orders worth more than 500,000 USD within the last 24h. - /// - /// - /// The symbol - /// The max amount of results - /// Cancellation token - /// - Task>> GetRecentBigTradesAsync(string symbol, int? limit = null, CancellationToken ct = default); - - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApiTrading.cs b/ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApiTrading.cs deleted file mode 100644 index 4b2dcfc8..00000000 --- a/ByBit.Net/Interfaces/Clients/InverseFuturesApi/IBybitRestClientInverseFuturesApiTrading.cs +++ /dev/null @@ -1,269 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net.Objects; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.InverseFuturesApi -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 30 OCTOBER, USE V5 API INSTEAD] Bybit trading endpoints, placing and managing orders. - /// - public interface IBybitRestClientInverseFuturesApiTrading - { - #region Orders - /// - /// Place a new order - /// - /// - /// The symbol - /// Order side - /// Order type - /// Position mode - /// Quantity - /// Time in force - /// Price - /// True means your position can only reduce in size if this order is triggered - /// For a closing order. It can only reduce your position, not increase it. If the account has insufficient available balance when the closing order is triggered, then other active orders of similar contracts will be cancelled or reduced. It can be used to ensure your stop loss reduces your position regardless of current available margin. - /// Client order id - /// Take profit price, only take effect upon opening the position - /// Stop loss price, only take effect upon opening the position - /// Take profit trigger price type, default: LastPrice - /// Stop loss trigger price type, default: LastPrice - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> PlaceOrderAsync(string symbol, OrderSide side, OrderType type, PositionMode positionMode, decimal quantity, TimeInForce timeInForce, decimal? price = null, bool? closeOnTrigger = null, string? clientOrderId = null, decimal? takeProfitPrice = null, decimal? stopLossPrice = null, TriggerType? takeProfitTriggerType = null, TriggerType? stopLossTriggerType = null, bool? reduceOnly = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Change an exising order. Either orderId or clientOrderId should be provided - /// - /// - /// The symbol - /// Stop order id - /// Client order id - /// New price to set - /// New quantity to set - /// New take profit price - /// New stop loss price - /// New take profit trigger type - /// New stop loss profit price - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> ModifyOrderAsync(string symbol, string? orderId = null, string? clientOrderId = null, decimal? newPrice = null, decimal? newQuantity = null, decimal? takeProfitPrice = null, decimal? stopLossPrice = null, TriggerType? takeProfitTriggerType = null, TriggerType? stopLossTriggerType = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get order information. Either orderId or clientOrderId should be provided - /// - /// - /// The symbol - /// - /// - /// - /// - /// - Task> GetOpenOrderRealTimeAsync(string symbol, string? orderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get order information for up to 500 orders - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetOpenOrdersRealTimeAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get orders - /// - /// - /// The symbol - /// Filter by status - /// Filter by direction - /// Max amount of results - /// Page cursor - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetOrdersAsync(string symbol, OrderStatus? status = null, SearchDirection? direction = null, int? limit = null, string? cursor = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Cancel an order, either orderId or clientOrderId should be provided - /// - /// - /// The symbol - /// The id of the order to cancel - /// The client order id of the conditional order to cancel - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> CancelOrderAsync(string symbol, string? orderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Cancel all active orders for a symbol - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> CancelAllOrdersAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - #endregion - - #region Conditional orders - /// - /// Place a new conditional order - /// - /// - /// The symbol - /// Order side - /// Order type - /// Position mode - /// Quantity - /// It will be used to compare with the value of trigger price, to decide whether your conditional order will be triggered by crossing trigger price from upper side or lower side. Mainly used to identify the expected direction of the current conditional order. - /// Trigger price - /// Time in force - /// Price - /// Trigger type - /// For a closing order. It can only reduce your position, not increase it. If the account has insufficient available balance when the closing order is triggered, then other active orders of similar contracts will be cancelled or reduced. It can be used to ensure your stop loss reduces your position regardless of current available margin. - /// Client order id - /// Take profit price, only take effect upon opening the position - /// Stop loss price, only take effect upon opening the position - /// Take profit trigger price type, default: LastPrice - /// Stop loss trigger price type, default: LastPrice - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> PlaceConditionalOrderAsync(string symbol, OrderSide side, OrderType type, PositionMode positionMode, decimal quantity, decimal basePrice, decimal triggerPrice, TimeInForce timeInForce, decimal? price = null, TriggerType? triggerType = null, bool? closeOnTrigger = null, string? clientOrderId = null, decimal? takeProfitPrice = null, decimal? stopLossPrice = null, TriggerType? takeProfitTriggerType = null, TriggerType? stopLossTriggerType = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Change an exising order. Either stopOrderId or clientOrderId should be provided - /// - /// - /// The symbol - /// Stop order id - /// Client order id - /// New price to set - /// New trigger price to set - /// New quantity to set - /// New take profit price - /// New stop loss price - /// New take profit trigger type - /// New stop loss profit price - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> ModifyConditionalOrderAsync(string symbol, string? stopOrderId = null, string? clientOrderId = null, decimal? newPrice = null, decimal? newTriggerPrice = null, decimal? newQuantity = null, decimal? takeProfitPrice = null, decimal? stopLossPrice = null, TriggerType? takeProfitTriggerType = null, TriggerType? stopLossTriggerType = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get a list of conditional orders - /// - /// - /// The symbol - /// Filter by status - /// Filter by direction - /// Max number of results - /// Page cursor - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetConditionalOrdersAsync(string symbol, StopOrderStatus? status = null, SearchDirection? direction = null, int? limit = null, string? cursor = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get conditional order information. Either stopOrderId or clientOrderId should be provided - /// - /// - /// The symbol - /// The order id - /// The client order id - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> GetOpenConditionalOrderRealTimeAsync(string symbol, string? stopOrderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get order information for up to 10 conditional orders - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetOpenConditionalOrdersRealTimeAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Cancel a conditional order, either stopOrderId or clientOrderId should be provided - /// - /// - /// The symbol - /// The id of the conditional order to cancel - /// The client order id of the conditional order to cancel - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> CancelConditionalOrderAsync(string symbol, string? stopOrderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Cancel all active conditional orders for a symbol - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> CancelAllConditionalOrdersAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - #endregion - - /// - /// Get executed user trades - /// - /// - /// The symbol - /// Filter by order id - /// Filter by start time - /// Page - /// Page size - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetUserTradesAsync(string symbol, string? orderId = null, DateTime? startTime = null, int? page = null, int? pageSize = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Set take profit, stop loss, and trailing stop for your open position - /// - /// - /// The symbol - /// The position mode - /// The new take profit price. Setting it to null will not change the value, setting it to 0 will remove the current TakeProfit - /// The new stop loss price. Setting it to null will not change the value, setting it to 0 will remove the current StopLoss - /// Setting it to null will not change the value, setting it to 0 will remove the current TrailingStop - /// Take profit trigger type, defaults to LastPrice - /// Stop loss trigger type, defaults to LastPrice - /// Trailing stop trigger price. Trailing stops are triggered only when the price reaches the specified price. Trailing stops are triggered immediately by default. - /// Take profit quantity when in Partial mode - /// Stop loss quantity when in Partial mode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> SetTradingStopAsync( - string symbol, - PositionMode positionMode, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - decimal? trailingStopPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - decimal? trailingStopTriggerPrice = null, - decimal? takeProfitQuantity = null, - decimal? stopLossQuantity = null, - long? receiveWindow = null, - CancellationToken ct = default); - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApi.cs b/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApi.cs deleted file mode 100644 index 40e9a4f6..00000000 --- a/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApi.cs +++ /dev/null @@ -1,26 +0,0 @@ -using CryptoExchange.Net.Interfaces; -using System; - -namespace Bybit.Net.Interfaces.Clients.InversePerpetualApi -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 16/30 OCTOBER, USE V5 API INSTEAD] Bybit inverse perpetual API endpoints - /// - public interface IBybitRestClientInversePerpetualApi : IRestApiClient, IDisposable - { - /// - /// Endpoints related to account settings, info or actions - /// - IBybitRestClientInversePerpetualApiAccount Account { get; } - - /// - /// Endpoints related to retrieving market and system data - /// - IBybitRestClientInversePerpetualApiExchangeData ExchangeData { get; } - - /// - /// Endpoints related to orders and trades - /// - IBybitRestClientInversePerpetualApiTrading Trading { get; } - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApiAccount.cs b/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApiAccount.cs deleted file mode 100644 index fcc99687..00000000 --- a/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApiAccount.cs +++ /dev/null @@ -1,217 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net.Objects; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.InversePerpetualApi -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 30 OCTOBER, USE V5 API INSTEAD] Bybit account endpoints. Account endpoints include balance info, withdraw/deposit info and requesting and account settings - /// - public interface IBybitRestClientInversePerpetualApiAccount - { - #region Risk limit - - /// - /// Get position risk limit - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetRiskLimitAsync(string? symbol = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Set position risk - /// - /// - /// The symbol - /// The risk id to set - /// Position mode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> SetRiskLimitAsync(string symbol, long riskId, PositionMode? mode = null, long? receiveWindow = null, CancellationToken ct = default); - - #endregion - - #region Positions - - /// - /// Get user position for a symbol - /// - /// - /// Symbol to retrieve position for - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> GetPositionAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get user positions - /// - /// - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetPositionsAsync(long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Change margin - /// - /// - /// The symbol - /// The margin - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> ChangeMarginAsync(string symbol, decimal margin, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Set leverage - /// - /// - /// The symbol - /// Leverage, must be greater than 0 and less than the risk limit leverage - /// Use this parameter to set leverage while in cross margin mode. If this field is set to false, when leverage is equal to 0 the position will use cross margin; when leverage is greater than 0 the position will use isolated margin. If this field is set to true, you can set leverage in cross margin with leverage. leverage must be greater than 0. - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> SetLeverageAsync(string symbol, decimal leverage, bool? leverageOnly = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get user's profit and loss records - /// - /// - /// The symbol to get records for - /// Filter by startTime - /// Filter by endTime - /// Filter by type - /// Page - /// Page size - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetProfitAndLossHistoryAsync(string symbol, DateTime? startTime = null, DateTime? endTime = null, TradeType? type = null, int? page = null, int? pageSize = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Switch between full or partial Stop loss/Take profit mode - /// - /// - /// The symbol - /// New mode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> SetFullPartialPositionModeAsync(string symbol, StopLossTakeProfitMode mode, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Switch between cross and isolated mode. - /// - /// - /// The symbol - /// Is isolated - /// Buy leverage - /// Sell leverage - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task SetIsolatedPositionModeAsync(string symbol, bool isIsolated, decimal buyLeverage, decimal sellLeverage, long? receiveWindow = null, CancellationToken ct = default); - - #endregion - - #region Wallet - - /// - /// Get wallet balances - /// - /// - /// Filter by asset - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetBalancesAsync(string? asset = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get wallet fund endpoints - /// - /// - /// Filter by asset - /// Filter by start time - /// Filter by end time - /// Filter by type - /// Page size - /// Page - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetWalletFundHistoryAsync(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, WalletFundType? type = null, int? pageSize = null, int? page = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get withdrawal history - /// - /// - /// Filter by asset - /// Filter by start time - /// Filter by end time - /// Filter by status - /// Page size - /// Page - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetWithdrawalHistoryAsync(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, WithdrawStatus? status = null, int? pageSize = null, int? page = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get asset exchange history - /// - /// - /// Filter by id - /// Filter by direction - /// Max records - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetAssetExchangeHistoryAsync(long? fromId = null, SearchDirection? direction = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default); - - #endregion - - #region Funding - - /// - /// Get user last funding fee - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> GetLastUserFundingFeeAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get predicted next funding rate - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> GetPredictedUserFundingFeeAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - #endregion - - /// - /// Get Api key info - /// - /// - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetApiKeyInfoAsync(long? receiveWindow = null, CancellationToken ct = default); - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApiExchangeData.cs b/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApiExchangeData.cs deleted file mode 100644 index e08b233d..00000000 --- a/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApiExchangeData.cs +++ /dev/null @@ -1,159 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net.Objects; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.InversePerpetualApi -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 16 OCTOBER, USE V5 API INSTEAD] Bybit exchange data endpoints. Exchange data includes market data (tickers, order books, etc) and system status. - /// - public interface IBybitRestClientInversePerpetualApiExchangeData - { - /// - /// Get the server time - /// - /// - /// Cancellation token - /// - Task> GetServerTimeAsync(CancellationToken ct = default); - - /// - /// The API announcements for the last 30 days - /// - /// - /// Cancellation token - /// - Task>> GetAnnouncementsAsync(CancellationToken ct = default); - - /// - /// Get all supported symbols - /// - /// - /// Cancellation token - /// - Task>> GetSymbolsAsync(CancellationToken ct = default); - - /// - /// The ticker info for a symbol - /// - /// - /// The symbol - /// Cancellation token - /// - Task>> GetTickersAsync(string? symbol = null, CancellationToken ct = default); - - /// - /// Get public trade history - /// - /// - /// The symbol - /// Filter by records after this id - /// Max amount of results - /// Cancellation token - /// - Task>> GetTradeHistoryAsync(string symbol, long? fromId = null, int? limit = null, CancellationToken ct = default); - - /// - /// Get the current order book for a symbol - /// - /// - /// The symbol - /// Cancellation token - /// - Task>> GetOrderBookAsync(string symbol, CancellationToken ct = default); - - /// - /// Get price klines - /// - /// - /// Symbol of the klines - /// Interval of the kline data - /// Start time of the data - /// Max amount of candles - /// Cancellation token - /// - Task>> GetKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default); - - /// - /// Get index price klines - /// - /// - /// Symbol of the klines - /// Interval of the kline data - /// Start time of the data - /// Max amount of candles - /// Cancellation token - /// - Task>> GetIndexPriceKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default); - - /// - /// Get premium index klines - /// - /// - /// Symbol of the klines - /// Interval of the kline data - /// Start time of the data - /// Max amount of candles - /// Cancellation token - /// - Task>> GetPremiumIndexKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default); - - /// - /// Get mark price klines - /// - /// - /// Symbol of the klines - /// Interval of the kline data - /// Start time of the data - /// Max amount of candles - /// Cancellation token - /// - Task>> GetMarkPriceKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default); - - /// - /// Get long/short ratio - /// - /// - /// The symbol - /// The data period - /// Max amount of results - /// Cancellation token - /// - Task>> GetLongShortRatioAsync(string symbol, DataPeriod period, int? limit = null, CancellationToken ct = default); - - /// - /// Gets the total amount of unsettled contracts. In other words, the total number of contracts held in open positions. - /// - /// - /// The symbol - /// The period of data - /// Max amount of results - /// Cancellation token - /// - Task>> GetOpenInterestAsync(string symbol, DataPeriod period, int? limit = null, CancellationToken ct = default); - - /// - /// Obtain filled orders worth more than 500,000 USD within the last 24h. - /// - /// - /// The symbol - /// The max amount of results - /// Cancellation token - /// - Task>> GetRecentBigTradesAsync(string symbol, int? limit = null, CancellationToken ct = default); - - /// - /// Get last funding rate - /// - /// - /// The symbol - /// Cancellation token - /// - Task> GetLastFundingRateAsync(string symbol, CancellationToken ct = default); - - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApiTrading.cs b/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApiTrading.cs deleted file mode 100644 index 6a7c46d4..00000000 --- a/ByBit.Net/Interfaces/Clients/InversePerpetualApi/IBybitRestClientInversePerpetualApiTrading.cs +++ /dev/null @@ -1,264 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net.Objects; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.InversePerpetualApi -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 30 OCTOBER, USE V5 API INSTEAD] Bybit trading endpoints, placing and managing orders. - /// - public interface IBybitRestClientInversePerpetualApiTrading - { - #region Orders - /// - /// Place a new order - /// - /// - /// The symbol - /// Order side - /// Order type - /// Quantity - /// Time in force - /// Price - /// True means your position can only reduce in size if this order is triggered - /// For a closing order. It can only reduce your position, not increase it. If the account has insufficient available balance when the closing order is triggered, then other active orders of similar contracts will be cancelled or reduced. It can be used to ensure your stop loss reduces your position regardless of current available margin. - /// Client order id - /// Take profit price, only take effect upon opening the position - /// Stop loss price, only take effect upon opening the position - /// Take profit trigger price type, default: LastPrice - /// Stop loss trigger price type, default: LastPrice - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> PlaceOrderAsync(string symbol, OrderSide side, OrderType type, decimal quantity, TimeInForce timeInForce, decimal? price = null, bool? closeOnTrigger = null, string? clientOrderId = null, decimal? takeProfitPrice = null, decimal? stopLossPrice = null, TriggerType? takeProfitTriggerType = null, TriggerType? stopLossTriggerType = null, bool? reduceOnly = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Change an exising order. Either orderId or clientOrderId should be provided - /// - /// - /// The symbol - /// Stop order id - /// Client order id - /// New price to set - /// New quantity to set - /// New take profit price - /// New stop loss price - /// New take profit trigger type - /// New stop loss profit price - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> ModifyOrderAsync(string symbol, string? orderId = null, string? clientOrderId = null, decimal? newPrice = null, decimal? newQuantity = null, decimal? takeProfitPrice = null, decimal? stopLossPrice = null, TriggerType? takeProfitTriggerType = null, TriggerType? stopLossTriggerType = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get orders - /// - /// - /// The symbol - /// Filter by status - /// Filter by direction - /// Max amount of results - /// Page cursor - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetOrdersAsync(string symbol, OrderStatus? status = null, SearchDirection? direction = null, int? limit = null, string? cursor = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get order information. Either orderId or clientOrderId should be provided - /// - /// - /// The symbol - /// - /// - /// - /// - /// - Task> GetOpenOrderRealTimeAsync(string symbol, string? orderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get order information for up to 500 orders - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetOpenOrdersRealTimeAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Cancel an order, either orderId or clientOrderId should be provided - /// - /// - /// The symbol - /// The id of the order to cancel - /// The client order id of the conditional order to cancel - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> CancelOrderAsync(string symbol, string? orderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Cancel all active orders for a symbol - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> CancelAllOrdersAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - #endregion - - #region Conditional orders - /// - /// Place a new conditional order - /// - /// - /// The symbol - /// Order side - /// Order type - /// Position mode - /// Quantity - /// It will be used to compare with the value of trigger price, to decide whether your conditional order will be triggered by crossing trigger price from upper side or lower side. Mainly used to identify the expected direction of the current conditional order. - /// Trigger price - /// Time in force - /// Price - /// Trigger type - /// For a closing order. It can only reduce your position, not increase it. If the account has insufficient available balance when the closing order is triggered, then other active orders of similar contracts will be cancelled or reduced. It can be used to ensure your stop loss reduces your position regardless of current available margin. - /// Client order id - /// Take profit price, only take effect upon opening the position - /// Stop loss price, only take effect upon opening the position - /// Take profit trigger price type, default: LastPrice - /// Stop loss trigger price type, default: LastPrice - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> PlaceConditionalOrderAsync(string symbol, OrderSide side, OrderType type, PositionMode positionMode, decimal quantity, decimal basePrice, decimal triggerPrice, TimeInForce timeInForce, decimal? price = null, TriggerType? triggerType = null, bool? closeOnTrigger = null, string? clientOrderId = null, decimal? takeProfitPrice = null, decimal? stopLossPrice = null, TriggerType? takeProfitTriggerType = null, TriggerType? stopLossTriggerType = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Change an exising order. Either stopOrderId or clientOrderId should be provided - /// - /// - /// The symbol - /// Stop order id - /// Client order id - /// New price to set - /// New trigger price to set - /// New quantity to set - /// New take profit price - /// New stop loss price - /// New take profit trigger type - /// New stop loss profit price - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> ModifyConditionalOrderAsync(string symbol, string? stopOrderId = null, string? clientOrderId = null, decimal? newPrice = null, decimal? newTriggerPrice = null, decimal? newQuantity = null, decimal? takeProfitPrice = null, decimal? stopLossPrice = null, TriggerType? takeProfitTriggerType = null, TriggerType? stopLossTriggerType = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get a list of conditional orders - /// - /// - /// The symbol - /// Filter by status - /// Filter by direction - /// Max number of results - /// Page cursor - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetConditionalOrdersAsync(string symbol, StopOrderStatus? status = null, SearchDirection? direction = null, int? limit = null, string? cursor = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get order information for up to 10 conditional orders - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetOpenConditionalOrdersRealTimeAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get conditional order information. Either stopOrderId or clientOrderId should be provided - /// - /// - /// The symbol - /// The order id - /// The client order id - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> GetOpenConditionalOrderRealTimeAsync(string symbol, string? stopOrderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Cancel a conditional order, either stopOrderId or clientOrderId should be provided - /// - /// - /// The symbol - /// The id of the conditional order to cancel - /// The client order id of the conditional order to cancel - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> CancelConditionalOrderAsync(string symbol, string? stopOrderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Cancel all active conditional orders for a symbol - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> CancelAllConditionalOrdersAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - #endregion - - /// - /// Get executed user trades - /// - /// - /// The symbol - /// Filter by order id - /// Filter by start time - /// Page - /// Page size - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetUserTradesAsync(string symbol, string? orderId = null, DateTime? startTime = null, int? page = null, int? pageSize = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Set take profit, stop loss, and trailing stop for your open position - /// - /// - /// The symbol - /// The new take profit price. Setting it to null will not change the value, setting it to 0 will remove the current TakeProfit - /// The new stop loss price. Setting it to null will not change the value, setting it to 0 will remove the current StopLoss - /// Setting it to null will not change the value, setting it to 0 will remove the current TrailingStop - /// Take profit trigger type, defaults to LastPrice - /// Stop loss trigger type, defaults to LastPrice - /// Trailing stop trigger price. Trailing stops are triggered only when the price reaches the specified price. Trailing stops are triggered immediately by default. - /// Take profit quantity when in Partial mode - /// Stop loss quantity when in Partial mode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> SetTradingStopAsync( - string symbol, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - decimal? trailingStopPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - decimal? trailingStopTriggerPrice = null, - decimal? takeProfitQuantity = null, - decimal? stopLossQuantity = null, - long? receiveWindow = null, - CancellationToken ct = default); - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiAccountV1.cs b/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiAccountV1.cs deleted file mode 100644 index ab8c681b..00000000 --- a/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiAccountV1.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Bybit.Net.Objects.Models.Spot; -using CryptoExchange.Net.Objects; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.SpotApi.v1 -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 30 OCTOBER, USE V5 API INSTEAD] Bybit account endpoints. Account endpoints include balance info, withdraw/deposit info and requesting and account settings - /// - public interface IBybitRestClientSpotApiAccountV1 - { - /// - /// Get wallet balances - /// - /// - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetBalancesAsync(long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get margin account info - /// - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> GetMarginAccountInfoAsync(long? receiveWindow = null, CancellationToken ct = default); - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiExchangeDataV1.cs b/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiExchangeDataV1.cs deleted file mode 100644 index aab48a2e..00000000 --- a/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiExchangeDataV1.cs +++ /dev/null @@ -1,136 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Models.Spot; -using Bybit.Net.Objects.Models.Spot.v1; -using CryptoExchange.Net.Objects; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.SpotApi.v1 -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 16 OCTOBER, USE V5 API INSTEAD] Bybit exchange data endpoints. Exchange data includes market data (tickers, order books, etc) and system status. - /// - public interface IBybitRestClientSpotApiExchangeDataV1 - { - /// - /// Get the server time - /// - /// - /// Cancellation token - /// - Task> GetServerTimeAsync(CancellationToken ct = default); - - /// - /// Get all supported symbols - /// - /// - /// Cancellation token - /// - Task>> GetSymbolsAsync(CancellationToken ct = default); - - /// - /// Get the current order book for a symbol - /// - /// - /// The symbol - /// The number of rows - /// Cancellation token - /// - Task> GetOrderBookAsync(string symbol, int? limit = null, CancellationToken ct = default); - - /// - /// Get merged order book based on the scale - /// - /// - /// The symbol - /// The scale of the order book. 1 means 1 digit - /// The amount of rows - /// Cancellation token - /// - Task> GetMergedOrderBookAsync(string symbol, int? scale = null, int? limit = null, CancellationToken ct = default); - - /// - /// Get public trade history - /// - /// - /// The symbol - /// Max amount of results - /// Cancellation token - /// - Task>> GetTradeHistoryAsync(string symbol, int? limit = null, CancellationToken ct = default); - - /// - /// Get price klines - /// - /// - /// Symbol of the klines - /// Interval of the kline data - /// Start time of the data - /// End time of the data - /// Max amount of candles - /// Cancellation token - /// - Task>> GetKlinesAsync(string symbol, KlineInterval interval, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, CancellationToken ct = default); - - /// - /// The ticker info for a symbol - /// - /// - /// The symbol - /// Cancellation token - /// - Task> GetTickerAsync(string symbol, CancellationToken ct = default); - - /// - /// The ticker info for all symbols - /// - /// - /// Cancellation token - /// - Task>> GetTickersAsync(CancellationToken ct = default); - - /// - /// Get the last trade price of a symbol - /// - /// - /// The symbol - /// Cancellation token - /// - Task> GetPriceAsync(string symbol, CancellationToken ct = default); - - /// - /// Get the last trade price of all symbols - /// - /// - /// Cancellation token - /// - Task>> GetPricesAsync(CancellationToken ct = default); - - /// - /// Get the best ask/bid price for a symbol - /// - /// - /// The symbol - /// Cancellation token - /// - Task> GetBookPriceAsync(string symbol, CancellationToken ct = default); - - /// - /// Get the best ask/bid prices for all symbols - /// - /// - /// Cancellation token - /// - Task>> GetBookPricesAsync(CancellationToken ct = default); - - /// - /// Get borrow info - /// - /// The asset to retrieve info on - /// Cancellation token - /// - Task> GetBorrowInterestAndQuotaAsync(string asset, CancellationToken ct = default); - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiTradingV1.cs b/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiTradingV1.cs deleted file mode 100644 index 80cb0a55..00000000 --- a/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiTradingV1.cs +++ /dev/null @@ -1,152 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Models.Spot; -using Bybit.Net.Objects.Models.Spot.v1; -using CryptoExchange.Net.Objects; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.SpotApi.v1 -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 30 OCTOBER, USE V5 API INSTEAD] Bybit trading endpoints, placing and managing orders. - /// - public interface IBybitRestClientSpotApiTradingV1 - { - /// - /// Place a new order - /// - /// - /// The symbol - /// Order side - /// Order type - /// Quantity of the order. Note that for market buy orders this is the quantity of quote asset, otherwise it's in base asset - /// Price - /// Time in force - /// Client order id - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> PlaceOrderAsync(string symbol, OrderSide side, OrderType type, decimal quantity, decimal? price = null, TimeInForce? timeInForce = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get order, either orderId or clientOrderId should be provided - /// - /// - /// The id of the order - /// The client order id - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> GetOrderAsync(long? orderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get open orders - /// - /// - /// The symbol - /// Filter by order id, will only return orders with an orderId smaller than this - /// Max amount of results - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetOpenOrdersAsync(string? symbol = null, long? orderId = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get orders - /// - /// - /// Filter by symbol - /// Filter by order id, will only return orders with an orderId smaller than this - /// Max amount of results - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetOrdersAsync(string? symbol = null, long? orderId = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Cancel an active order. Either orderId or clientOrderId should be provided - /// - /// - /// The order id - /// The client order id - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> CancelOrderAsync(long? orderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Cancel multiple orders based on the provided parameters - /// - /// The symbol to cancel orders on - /// Only cancel buy or sell orders - /// Only cancel orders fitting the order types, default only cancels Limit orders (not LimitMaker orders) - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task CancelMultipleOrderAsync(string symbol, OrderSide? side = null, IEnumerable? orderTypes = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get user trade history - /// - /// - /// Filter by symbol - /// Filter by start id - /// Filter by end id - /// Max amount of results - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetUserTradesAsync(string? symbol = null, long? fromId = null, long? toId = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Place a new borrow order - /// - /// - /// The asset to borrow - /// The quantity to borrow - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> PlaceBorrowOrderAsync(string asset, decimal quantity, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Place a new borrow order - /// - /// - /// The asset to repay - /// The quantity to repay - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> PlaceRepayOrderAsync(string asset, decimal quantity, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get borrow records - /// - /// - /// Filter by borrow time - /// Filter by borrow time - /// Filter by asset - /// Filter by status - /// Max amount of results - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetBorrowRecordsAsync(DateTime? startTime = null, DateTime? endTime = null, string? asset = null, BorrowStatus? status = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get repayment records - /// - /// - /// Filter by borrow time - /// Filter by borrow time - /// Filter by asset - /// Max amount of results - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetRepayRecordsAsync(DateTime? startTime = null, DateTime? endTime = null, string? asset = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default); - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiV1.cs b/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiV1.cs deleted file mode 100644 index 66557e64..00000000 --- a/ByBit.Net/Interfaces/Clients/SpotApi/v1/IBybitRestClientSpotApiV1.cs +++ /dev/null @@ -1,33 +0,0 @@ -using CryptoExchange.Net.Interfaces; -using CryptoExchange.Net.Interfaces.CommonClients; -using System; - -namespace Bybit.Net.Interfaces.Clients.SpotApi.v1 -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 16/30 OCTOBER, USE V5 API INSTEAD] Bybit spot API endpoints (v1) - /// - public interface IBybitRestClientSpotApiV1 : IRestApiClient, IDisposable - { - /// - /// Endpoints related to account settings, info or actions - /// - IBybitRestClientSpotApiAccountV1 Account { get; } - - /// - /// Endpoints related to retrieving market and system data - /// - IBybitRestClientSpotApiExchangeDataV1 ExchangeData { get; } - - /// - /// Endpoints related to orders and trades - /// - IBybitRestClientSpotApiTradingV1 Trading { get; } - - /// - /// Get the ISpotClient for this client. This is a common interface which allows for some basic operations without knowing any details of the exchange. - /// - /// - public ISpotClient CommonSpotClient { get; } - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApi.cs b/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApi.cs deleted file mode 100644 index f17ff9a0..00000000 --- a/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApi.cs +++ /dev/null @@ -1,26 +0,0 @@ -using CryptoExchange.Net.Interfaces; -using System; - -namespace Bybit.Net.Interfaces.Clients.UsdPerpetualApi -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 16/30 OCTOBER, USE V5 API INSTEAD] Bybit USD perpetual API endpoints - /// - public interface IBybitRestClientUsdPerpetualApi : IRestApiClient, IDisposable - { - /// - /// Endpoints related to account settings, info or actions - /// - IBybitRestClientUsdPerpetualApiAccount Account { get; } - - /// - /// Endpoints related to retrieving market and system data - /// - IBybitRestClientUsdPerpetualApiExchangeData ExchangeData { get; } - - /// - /// Endpoints related to orders and trades - /// - IBybitRestClientUsdPerpetualApiTrading Trading { get; } - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApiAccount.cs b/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApiAccount.cs deleted file mode 100644 index e06f4628..00000000 --- a/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApiAccount.cs +++ /dev/null @@ -1,242 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net.Objects; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.UsdPerpetualApi -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 30 OCTOBER, USE V5 API INSTEAD] Bybit account endpoints. Account endpoints include balance info, withdraw/deposit info and requesting and changing account settings - /// - public interface IBybitRestClientUsdPerpetualApiAccount - { - #region Risk - /// - /// Get position risk limit - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetRiskLimitAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Set position risk - /// - /// - /// The symbol - /// The risk id to set - /// Side - /// Position mode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> SetRiskLimitAsync(string symbol, OrderSide side, long riskId, PositionMode? positionMode = null, long? receiveWindow = null, CancellationToken ct = default); - - #endregion - - #region Positions - /// - /// Get user positions - /// - /// - /// Filter by symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetPositionAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - /// - /// Get user positions - /// - /// - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetPositionsAsync(long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Set auto add margin switch - /// - /// - /// Symbol - /// Side - /// Auto add or not - /// Position mode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task SetAutoAddMarginAsync(string symbol, OrderSide side, bool autoAddMargin, PositionMode? positionMode = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Switch Cross/Isolated; must set leverage value when switching from Cross to Isolated - /// - /// - /// The symbol - /// True is Isolated; false is Cross - /// Buy leverage - /// Sell leverage - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task SetIsolatedPositionModeAsync(string symbol, bool isIsolated, decimal buyLeverage, decimal sellLeverage, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Switch position mode. If you are in One-Way Mode, you can only open one position on Buy or Sell side; - /// If you are in Hedge Mode, you can open both Buy and Sell side positions simultaneously. - /// - /// - /// Symbol. Required if not passing coin - /// Currency alias. Required if not passing symbol - /// True = HedgeMode, False = OneWayMode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task SetPositionModeAsync(string symbol, string asset, bool hedgeMode, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Switch between full or partial Stop loss/Take profit mode - /// - /// - /// The symbol - /// New mode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> SetFullPartialPositionModeAsync(string symbol, StopLossTakeProfitMode mode, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Add/reduce margin - /// - /// The symbol - /// The side - /// Margin to add (positive) or remove (negative) - /// Position mode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> AddReduceMarginAsync(string symbol, OrderSide side, decimal margin, PositionMode? positionMode = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Set leverage - /// - /// - /// The symbol - /// Buy leverage - /// Sell leverage - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task SetLeverageAsync(string symbol, decimal buyLeverage, decimal sellLeverage, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get user's profit and loss records - /// - /// - /// The symbol to get records for - /// Filter by startTime - /// Filter by endTime - /// Filter by type - /// Page - /// Page size - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetProfitAndLossHistoryAsync(string symbol, DateTime? startTime = null, DateTime? endTime = null, TradeType? type = null, int? page = null, int? pageSize = null, long? receiveWindow = null, CancellationToken ct = default); - #endregion - - #region Wallet - - /// - /// Get wallet fund endpoints - /// - /// - /// Filter by asset - /// Filter by start time - /// Filter by end time - /// Filter by type - /// Page size - /// Page - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetWalletFundHistoryAsync(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, WalletFundType? type = null, int? pageSize = null, int? page = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get asset exchange history - /// - /// - /// Filter by id - /// Filter by direction - /// Max records - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetAssetExchangeHistoryAsync(long? fromId = null, SearchDirection? direction = null, int? limit = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get wallet balances - /// - /// - /// Filter by asset - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetBalancesAsync(string? asset = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get withdrawal history - /// - /// - /// Filter by asset - /// Filter by start time - /// Filter by end time - /// Filter by status - /// Page size - /// Page - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetWithdrawalHistoryAsync(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, WithdrawStatus? status = null, int? pageSize = null, int? page = null, long? receiveWindow = null, CancellationToken ct = default); - - #endregion - - #region Funding - - /// - /// Get user last funding fee - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> GetUserLastFundingFeeAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get predicted next funding rate - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> GetUserPredictedFundingRateAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - #endregion - - /// - /// Get Api key info - /// - /// - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetApiKeyInfoAsync(long? receiveWindow = null, CancellationToken ct = default); - - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApiExchangeData.cs b/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApiExchangeData.cs deleted file mode 100644 index ae169a26..00000000 --- a/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApiExchangeData.cs +++ /dev/null @@ -1,157 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net.Objects; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.UsdPerpetualApi -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 16 OCTOBER, USE V5 API INSTEAD] Bybit exchange data endpoints. Exchange data includes market data (tickers, order books, etc) and system status. - /// - public interface IBybitRestClientUsdPerpetualApiExchangeData - { - /// - /// Get the server time - /// - /// - /// Cancellation token - /// - Task> GetServerTimeAsync(CancellationToken ct = default); - - /// - /// The API announcements for the last 30 days - /// - /// - /// Cancellation token - /// - Task>> GetAnnouncementsAsync(CancellationToken ct = default); - - /// - /// Get all supported symbols - /// - /// - /// Cancellation token - /// - Task>> GetSymbolsAsync(CancellationToken ct = default); - - /// - /// The ticker info for a symbol - /// - /// - /// The symbol - /// Cancellation token - /// - Task>> GetTickerAsync(string? symbol = null, CancellationToken ct = default); - - /// - /// Get the current order book for a symbol - /// - /// - /// The symbol - /// Cancellation token - /// - Task>> GetOrderBookAsync(string symbol, CancellationToken ct = default); - - /// - /// Get public trade history - /// - /// - /// The symbol - /// Max amount of results - /// Cancellation token - /// - Task>> GetTradeHistoryAsync(string symbol, int? limit = null, CancellationToken ct = default); - - /// - /// Get price klines - /// - /// - /// Symbol of the klines - /// Interval of the kline data - /// Start time of the data - /// Max amount of candles - /// Cancellation token - /// - Task>> GetKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default); - - /// - /// Get index price klines - /// - /// - /// Symbol of the klines - /// Interval of the kline data - /// Start time of the data - /// Max amount of candles - /// Cancellation token - /// - Task>> GetIndexPriceKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default); - - /// - /// Get mark price klines - /// - /// - /// Symbol of the klines - /// Interval of the kline data - /// Start time of the data - /// Max amount of candles - /// Cancellation token - /// - Task>> GetMarkPriceKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default); - - /// - /// Get premium index klines - /// - /// - /// Symbol of the klines - /// Interval of the kline data - /// Start time of the data - /// Max amount of candles - /// Cancellation token - /// - Task>> GetPremiumIndexKlinesAsync(string symbol, KlineInterval interval, DateTime from, int? limit = null, CancellationToken ct = default); - - /// - /// Get long/short ratio - /// - /// - /// The symbol - /// The data period - /// Max amount of results - /// Cancellation token - /// - Task>> GetLongShortRatioAsync(string symbol, DataPeriod period, int? limit = null, CancellationToken ct = default); - - /// - /// Gets the total amount of unsettled contracts. In other words, the total number of contracts held in open positions. - /// - /// - /// The symbol - /// The period of data - /// Max amount of results - /// Cancellation token - /// - Task>> GetOpenInterestAsync(string symbol, DataPeriod period, int? limit = null, CancellationToken ct = default); - - /// - /// Obtain filled orders worth more than 500,000 USD within the last 24h. - /// - /// - /// The symbol - /// The max amount of results - /// Cancellation token - /// - Task>> GetRecentBigTradesAsync(string symbol, int? limit = null, CancellationToken ct = default); - - /// - /// Get last funding rate - /// - /// - /// The symbol - /// Cancellation token - /// - Task> GetLastFundingRateAsync(string symbol, CancellationToken ct = default); - } -} \ No newline at end of file diff --git a/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApiTrading.cs b/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApiTrading.cs deleted file mode 100644 index c6c567c5..00000000 --- a/ByBit.Net/Interfaces/Clients/UsdPerpetualApi/IBybitRestClientUsdPerpetualApiTrading.cs +++ /dev/null @@ -1,274 +0,0 @@ -using Bybit.Net.Enums; -using Bybit.Net.Objects.Internal; -using Bybit.Net.Objects.Models; -using CryptoExchange.Net.Objects; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Bybit.Net.Interfaces.Clients.UsdPerpetualApi -{ - /// - /// [DEPRECATED, WILL STOP WORKING ON 30 OCTOBER, USE V5 API INSTEAD] Bybit trading endpoints, placing and managing orders. - /// - public interface IBybitRestClientUsdPerpetualApiTrading - { - #region Orders - /// - /// Place a new order - /// - /// - /// The symbol - /// Order side - /// Order type - /// Quantity - /// Time in force - /// Price - /// True means your position can only reduce in size if this order is triggered - /// For a closing order. It can only reduce your position, not increase it. If the account has insufficient available balance when the closing order is triggered, then other active orders of similar contracts will be cancelled or reduced. It can be used to ensure your stop loss reduces your position regardless of current available margin. - /// Client order id - /// Take profit price, only take effect upon opening the position - /// Stop loss price, only take effect upon opening the position - /// Take profit trigger price type, default: LastPrice - /// Stop loss trigger price type, default: LastPrice - /// Position mode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> PlaceOrderAsync(string symbol, OrderSide side, OrderType type, decimal quantity, TimeInForce timeInForce, bool reduceOnly, bool closeOnTrigger, decimal? price = null, string? clientOrderId = null, decimal? takeProfitPrice = null, decimal? stopLossPrice = null, TriggerType? takeProfitTriggerType = null, TriggerType? stopLossTriggerType = null, PositionMode? positionMode = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Change an exising order. Either orderId or clientOrderId should be provided - /// - /// - /// The symbol - /// Stop order id - /// Client order id - /// New price to set - /// New quantity to set - /// New take profit price - /// New stop loss price - /// New take profit trigger type - /// New stop loss profit price - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> ModifyOrderAsync(string symbol, string? orderId = null, string? clientOrderId = null, decimal? newPrice = null, decimal? newQuantity = null, decimal? takeProfitPrice = null, decimal? stopLossPrice = null, TriggerType? takeProfitTriggerType = null, TriggerType? stopLossTriggerType = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get orders - /// - /// - /// The symbol - /// Filter by order id - /// Filter by client order id - /// Filter by status - /// The result order - /// The page - /// The page size - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetOrdersAsync(string symbol, string? orderId = null, string? clientOrderId = null, OrderStatus? status = null, SortOrder? order = null, int? pageSize = null, int? page = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get order information for up to 500 orders - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetOpenOrdersRealTimeAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get order information. Either orderId or clientOrderId should be provided - /// - /// - /// The symbol - /// - /// - /// - /// - /// - Task> GetOpenOrderRealTimeAsync(string symbol, string? orderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Cancel an order, either orderId or clientOrderId should be provided - /// - /// - /// The symbol - /// The id of the order to cancel - /// The client order id of the conditional order to cancel - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> CancelOrderAsync(string symbol, string? orderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Cancel all active orders for a symbol - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> CancelAllOrdersAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - #endregion - - #region Conditional orders - /// - /// Place a new conditional order - /// - /// - /// The symbol - /// Order side - /// Order type - /// Quantity - /// It will be used to compare with the value of trigger price, to decide whether your conditional order will be triggered by crossing trigger price from upper side or lower side. Mainly used to identify the expected direction of the current conditional order. - /// Trigger price - /// Time in force - /// Price - /// Trigger type - /// True means your position can only reduce in size if this order is triggered. When reduce_only is true, take profit/stop loss cannot be set - /// For a closing order. It can only reduce your position, not increase it. If the account has insufficient available balance when the closing order is triggered, then other active orders of similar contracts will be cancelled or reduced. It can be used to ensure your stop loss reduces your position regardless of current available margin. - /// Client order id - /// Take profit price, only take effect upon opening the position - /// Stop loss price, only take effect upon opening the position - /// Take profit trigger price type, default: LastPrice - /// Stop loss trigger price type, default: LastPrice - /// Position mode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> PlaceConditionalOrderAsync(string symbol, OrderSide side, OrderType type, decimal quantity, decimal basePrice, decimal triggerPrice, TimeInForce timeInForce, bool closeOnTrigger, bool reduceOnly, decimal? price = null, TriggerType? triggerType = null, string? clientOrderId = null, decimal? takeProfitPrice = null, decimal? stopLossPrice = null, TriggerType? takeProfitTriggerType = null, TriggerType? stopLossTriggerType = null, PositionMode? positionMode = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Change an exising order. Either stopOrderId or clientOrderId should be provided - /// - /// - /// The symbol - /// Stop order id - /// Client order id - /// New price to set - /// New trigger price to set - /// New quantity to set - /// New take profit price - /// New stop loss price - /// New take profit trigger type - /// New stop loss profit price - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> ModifyConditionalOrderAsync(string symbol, string? stopOrderId = null, string? clientOrderId = null, decimal? newPrice = null, decimal? newTriggerPrice = null, decimal? newQuantity = null, decimal? takeProfitPrice = null, decimal? stopLossPrice = null, TriggerType? takeProfitTriggerType = null, TriggerType? stopLossTriggerType = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get order information for up to 10 conditional orders - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> GetOpenConditionalOrdersRealTimeAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get conditional order information. Either stopOrderId or clientOrderId should be provided - /// - /// - /// The symbol - /// The order id - /// The client order id - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> GetOpenConditionalOrderRealTimeAsync(string symbol, string? stopOrderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Get a list of conditional orders - /// - /// - /// The symbol - /// Filter by order id - /// Filter by client order id - /// Filter by status - /// Result order - /// Page size - /// Page - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetConditionalOrdersAsync(string symbol, string? stopOrderId = null, string? clientOrderId = null, OrderStatus? status = null, SortOrder? order = null, int? pageSize = null, int? page = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Cancel a conditional order, either stopOrderId or clientOrderId should be provided - /// - /// - /// The symbol - /// The id of the conditional order to cancel - /// The client order id of the conditional order to cancel - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task> CancelConditionalOrderAsync(string symbol, string? stopOrderId = null, string? clientOrderId = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Cancel all active conditional orders for a symbol - /// - /// - /// The symbol - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>> CancelAllConditionalOrdersAsync(string symbol, long? receiveWindow = null, CancellationToken ct = default); - - #endregion - - /// - /// Get executed user trades - /// - /// - /// The symbol - /// Filter by start time - /// Filter by end time - /// Filter by type - /// Page - /// Page size - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task>>> GetUserTradesAsync(string symbol, DateTime? startTime = null, DateTime? endTime = null, int? page = null, int? pageSize = null, TradeType? type = null, long? receiveWindow = null, CancellationToken ct = default); - - /// - /// Set take profit, stop loss, and trailing stop for your open position - /// - /// - /// The symbol - /// The position side - /// The new take profit price. Setting it to null will not change the value, setting it to 0 will remove the current TakeProfit - /// The new stop loss price. Setting it to null will not change the value, setting it to 0 will remove the current StopLoss - /// Setting it to null will not change the value, setting it to 0 will remove the current TrailingStop - /// Take profit trigger type, defaults to LastPrice - /// Stop loss trigger type, defaults to LastPrice - /// Take profit quantity when in Partial mode - /// Stop loss quantity when in Partial mode - /// Position mode - /// The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request - /// Cancellation token - /// - Task SetTradingStopAsync( - string symbol, - PositionSide side, - decimal? takeProfitPrice = null, - decimal? stopLossPrice = null, - decimal? trailingStopPrice = null, - TriggerType? takeProfitTriggerType = null, - TriggerType? stopLossTriggerType = null, - decimal? takeProfitQuantity = null, - decimal? stopLossQuantity = null, - PositionMode? positionMode = null, - long? receiveWindow = null, - CancellationToken ct = default); - } -} \ No newline at end of file diff --git a/ByBit.Net/Objects/Models/Spot/v3/BybitSpotOrderV3.cs b/ByBit.Net/Objects/Models/Spot/v3/BybitSpotOrderV3.cs index 9be12de1..aaaff097 100644 --- a/ByBit.Net/Objects/Models/Spot/v3/BybitSpotOrderV3.cs +++ b/ByBit.Net/Objects/Models/Spot/v3/BybitSpotOrderV3.cs @@ -33,7 +33,7 @@ public class BybitSpotOrderV3 /// Order id /// [JsonProperty("orderId")] - public string OrderId { get; set; } = string.Empty; + public string Id { get; set; } = string.Empty; /// /// Order price @@ -84,14 +84,14 @@ public class BybitSpotOrderV3 /// [JsonProperty("orderType")] [JsonConverter(typeof(OrderTypeSpotConverter))] - public OrderType OrderType { get; set; } + public OrderType Type { get; set; } /// /// Order side /// [JsonProperty("side")] [JsonConverter(typeof(OrderSideConverter))] - public OrderSide OrderSide { get; set; } + public OrderSide Side { get; set; } /// /// Stop price @@ -109,7 +109,7 @@ public class BybitSpotOrderV3 /// Create time /// [JsonProperty("createTime"), JsonConverter(typeof(DateTimeConverter))] - public DateTime? CreateTime { get; set; } + public DateTime CreateTime { get; set; } /// /// Update time diff --git a/ByBit.Net/Objects/Options/BybitRestOptions.cs b/ByBit.Net/Objects/Options/BybitRestOptions.cs index 964882d7..c6a79e63 100644 --- a/ByBit.Net/Objects/Options/BybitRestOptions.cs +++ b/ByBit.Net/Objects/Options/BybitRestOptions.cs @@ -27,21 +27,6 @@ public class BybitRestOptions : RestExchangeOptions public TimeSpan ReceiveWindow { get; set; } = TimeSpan.FromSeconds(5); - /// - /// Options for the Inverse Futures API - /// - public RestApiOptions InverseFuturesOptions { get; private set; } = new RestApiOptions(); - - /// - /// Options for the Inverse Perpetual API - /// - public RestApiOptions InversePerpetualOptions { get; private set; } = new RestApiOptions(); - - /// - /// Options for the Usd Perpetual API - /// - public RestApiOptions UsdPerpetualOptions { get; private set; } = new RestApiOptions(); - /// /// Options for the Spot API /// @@ -67,9 +52,6 @@ internal BybitRestOptions Copy() var options = Copy(); options.Referer = Referer; options.ReceiveWindow = ReceiveWindow; - options.InverseFuturesOptions = InverseFuturesOptions.Copy(); - options.InversePerpetualOptions = InversePerpetualOptions.Copy(); - options.UsdPerpetualOptions = UsdPerpetualOptions.Copy(); options.SpotOptions = SpotOptions.Copy(); options.CopyTradingOptions = CopyTradingOptions.Copy(); options.DerivativesOptions = DerivativesOptions.Copy(); diff --git a/ByBit.Net/Objects/Options/BybitSocketOptions.cs b/ByBit.Net/Objects/Options/BybitSocketOptions.cs index 5c99bb29..9ed651b5 100644 --- a/ByBit.Net/Objects/Options/BybitSocketOptions.cs +++ b/ByBit.Net/Objects/Options/BybitSocketOptions.cs @@ -18,35 +18,11 @@ public class BybitSocketOptions : SocketExchangeOptions SocketNoDataTimeout = TimeSpan.FromSeconds(30) }; - /// - /// Options for the Inverse Futures API - /// - public BybitSocketApiOptions InverseFuturesOptions { get; private set; } = new BybitSocketApiOptions(); - /// - /// Options for the Inverse Perpetual API - /// - public BybitSocketApiOptions InversePerpetualOptions { get; private set; } = new BybitSocketApiOptions(); - /// - /// Options for the Usd Perpetual API - /// - public BybitSocketApiOptions UsdPerpetualOptions { get; private set; } = new BybitSocketApiOptions(); - /// - /// Options for the Spot V1 API - /// - public BybitSocketApiOptions SpotV1Options { get; private set; } = new BybitSocketApiOptions(); - /// - /// Options for the Spot V2 API - /// - public BybitSocketApiOptions SpotV2Options { get; private set; } = new BybitSocketApiOptions(); /// /// Options for the Spot V3 API /// public BybitSocketApiOptions SpotV3Options { get; private set; } = new BybitSocketApiOptions(); /// - /// Options for the Copy Trading API - /// - public BybitSocketApiOptions CopyTradingOptions { get; private set; } = new BybitSocketApiOptions(); - /// /// Options for the Public Derivatives API /// public BybitSocketApiOptions DerivativesPublicOptions { get; private set; } = new BybitSocketApiOptions(); @@ -66,13 +42,7 @@ public class BybitSocketOptions : SocketExchangeOptions internal BybitSocketOptions Copy() { var options = Copy(); - options.InverseFuturesOptions = InverseFuturesOptions.Copy(); - options.InversePerpetualOptions = InversePerpetualOptions.Copy(); - options.UsdPerpetualOptions = UsdPerpetualOptions.Copy(); - options.SpotV1Options = SpotV1Options.Copy(); - options.SpotV2Options = SpotV2Options.Copy(); options.SpotV3Options = SpotV3Options.Copy(); - options.CopyTradingOptions = CopyTradingOptions.Copy(); options.DerivativesPublicOptions = DerivativesPublicOptions.Copy(); options.UnifiedMarginOptions = UnifiedMarginOptions.Copy(); options.ContractOptions = ContractOptions.Copy(); diff --git a/Bybit.UnitTests/JsonTests.cs b/Bybit.UnitTests/JsonTests.cs index 19ae88a1..682e0e15 100644 --- a/Bybit.UnitTests/JsonTests.cs +++ b/Bybit.UnitTests/JsonTests.cs @@ -17,12 +17,6 @@ public class JsonTests x.ApiCredentials = new CryptoExchange.Net.Authentication.ApiCredentials("123", "123"); x.SpotOptions.RateLimiters = new List(); x.SpotOptions.OutputOriginalData = true; - x.InverseFuturesOptions.RateLimiters = new List(); - x.InverseFuturesOptions.OutputOriginalData = true; - x.InversePerpetualOptions.RateLimiters = new List(); - x.InversePerpetualOptions.OutputOriginalData = true; - x.UsdPerpetualOptions.RateLimiters = new List(); - x.UsdPerpetualOptions.OutputOriginalData = true; x.DerivativesOptions.RateLimiters = new List(); x.DerivativesOptions.OutputOriginalData = true; x.V5Options.RateLimiters = new List(); @@ -30,193 +24,6 @@ public class JsonTests }, System.Net.HttpStatusCode.OK)); - [Test] - public async Task ValidateFuturesAccountCalls() - { - await _comparer.ProcessSubject("InversePerpetual/Account", c => c.InversePerpetualApi.Account, - useNestedJsonPropertyForCompare: new Dictionary - { - { "GetWalletFundHistoryAsync", "data" }, - { "GetWithdrawalHistoryAsync", "data" } - }, - ignoreProperties: new Dictionary> - { - { "GetWithdrawalHistoryAsync", new List { "current_page", "last_page" } }, - { "GetPositionAsync", new List { "oc_calc_data" } } - }, - useNestedJsonPropertyForAllCompare: new List { "result" }, - parametersToSetNull: new string[] { } - ); - } - - [Test] - public async Task ValidateFuturesExchangeDataCalls() - { - await _comparer.ProcessSubject("InversePerpetual/ExchangeData", c => c.InversePerpetualApi.ExchangeData, - useNestedJsonPropertyForCompare: new Dictionary - { - - }, - ignoreProperties: new Dictionary> - { - }, - useNestedJsonPropertyForAllCompare: new List { "result" }, - parametersToSetNull: new string[] { } - ); - } - - [Test] - public async Task ValidateFuturesTradingCalls() - { - await _comparer.ProcessSubject("InversePerpetual/Trading", c => c.InversePerpetualApi.Trading, - useNestedJsonPropertyForCompare: new Dictionary - { - { "GetUserTradesAsync", "trade_list" } - }, - ignoreProperties: new Dictionary> - { - { "GetOpenOrderRealTimeAsync", new List { "ext_fields" } }, - { "GetOpenOrdersRealTimeAsync", new List { "ext_fields" } }, - { "GetOpenConditionalOrderRealTimeAsync", new List { "ext_fields" } }, - { "GetOpenConditionalOrdersRealTimeAsync", new List { "ext_fields" } }, - { "SetTradingStopAsync", new List { "oc_calc_data", "ext_fields" } } - }, - useNestedJsonPropertyForAllCompare: new List { "result" }, - parametersToSetNull: new string[] { "clientOrderId" } - ); - } - - [Test] - public async Task ValidateSpotAccountCalls() - { - await _comparer.ProcessSubject("Spot/Account", c => c.SpotApiV1.Account, - useNestedJsonPropertyForCompare: new Dictionary - { - { "GetBalancesAsync", "balances" } - }, - ignoreProperties: new Dictionary> - { - }, - useNestedJsonPropertyForAllCompare: new List { "result" }, - parametersToSetNull: new string[] { } - ); - } - - [Test] - public async Task ValidateSpotTradingCalls() - { - await _comparer.ProcessSubject("Spot/Trading", c => c.SpotApiV1.Trading, - useNestedJsonPropertyForCompare: new Dictionary - { - }, - ignoreProperties: new Dictionary> - { - { "PlaceOrderAsync", new List{ "executedQty" } }, - { "CancelOrderAsync", new List{ "executedQty" } } - }, - useNestedJsonPropertyForAllCompare: new List { "result" }, - parametersToSetNull: new string[] { "clientOrderId" } - - ); - } - - [Test] - public async Task ValidateSpotExchangeDataCalls() - { - await _comparer.ProcessSubject("Spot/ExchangeData", c => c.SpotApiV1.ExchangeData, - useNestedJsonPropertyForCompare: new Dictionary - { - }, - ignoreProperties: new Dictionary> - { - { "GetKlinesAsync", new List() { "CloseTime" } } - }, - useNestedJsonPropertyForAllCompare: new List { "result" } - - ); - } - - [Test] - public async Task ValidateGeneralTransferCalls() - { - await _comparer.ProcessSubject("General/Transfer", c => c.GeneralApi.Transfer, - useNestedJsonPropertyForCompare: new Dictionary - { - }, - ignoreProperties: new Dictionary> - { - }, - useNestedJsonPropertyForAllCompare: new List { "result" } - - ); - } - - [Test] - public async Task ValidateGeneralDepositWithdrawalCalls() - { - await _comparer.ProcessSubject("General/DepositWithdraw", c => c.GeneralApi.WithdrawDeposit, - useNestedJsonPropertyForCompare: new Dictionary - { - { "GetSupportedDepositMethodsAsync", "config_list" }, - { "GetAssetInfoAsync", "rows" }, - }, - ignoreProperties: new Dictionary> - { - }, - useNestedJsonPropertyForAllCompare: new List { "result" } - - ); - } - - [Test] - public async Task ValidateUsdPerpetualAccountCalls() - { - await _comparer.ProcessSubject("UsdPerpetual/Account", c => c.UsdPerpetualApi.Account, - useNestedJsonPropertyForCompare: new Dictionary - { - }, - ignoreProperties: new Dictionary> - { - }, - useNestedJsonPropertyForAllCompare: new List { "result" } - - ); - } - - [Test] - public async Task ValidateUsdPerpetualExchangeDataCalls() - { - await _comparer.ProcessSubject("UsdPerpetual/ExchangeData", c => c.UsdPerpetualApi.ExchangeData, - useNestedJsonPropertyForCompare: new Dictionary - { - }, - ignoreProperties: new Dictionary> - { - { "GetKlinesAsync", new List{ "id", "period", "start_at" } } - }, - useNestedJsonPropertyForAllCompare: new List { "result" } - - ); - } - - [Test] - public async Task ValidateUsdPerpetualTradingCalls() - { - await _comparer.ProcessSubject("UsdPerpetual/Trading", c => c.UsdPerpetualApi.Trading, - useNestedJsonPropertyForCompare: new Dictionary - { - }, - ignoreProperties: new Dictionary> - { - { "GetUserTradesAsync", new List { "trade_time" } }, - { "GetOpenConditionalOrdersRealTimeAsync", new List { "ext_fields" } }, - { "GetOpenConditionalOrderRealTimeAsync", new List { "ext_fields" } } - }, - useNestedJsonPropertyForAllCompare: new List { "result" }, - parametersToSetNull: new string[] { "clientOrderId" } - ); - } - [Test] public async Task ValidateCopyTradingAccountCalls() { diff --git a/Bybit.UnitTests/TestHelpers.cs b/Bybit.UnitTests/TestHelpers.cs index cc6a80d9..83127b6e 100644 --- a/Bybit.UnitTests/TestHelpers.cs +++ b/Bybit.UnitTests/TestHelpers.cs @@ -62,13 +62,8 @@ public static BybitRestClient CreateClient(Action options = nu { BybitRestClient client; client = options != null ? new BybitRestClient(options) : new BybitRestClient(); - client.SpotApiV1.RequestFactory = Mock.Of(); client.SpotApiV3.RequestFactory = Mock.Of(); client.CopyTradingApi.RequestFactory = Mock.Of(); - client.GeneralApi.RequestFactory = Mock.Of(); - client.InverseFuturesApi.RequestFactory = Mock.Of(); - client.InversePerpetualApi.RequestFactory = Mock.Of(); - client.UsdPerpetualApi.RequestFactory = Mock.Of(); client.DerivativesApi.RequestFactory = Mock.Of(); client.V5Api.RequestFactory = Mock.Of(); return client; @@ -98,25 +93,10 @@ public static Mock SetResponse(BybitRestClient client, string response request.Setup(c => c.GetResponseAsync(It.IsAny())).Returns(Task.FromResult(response.Object)); request.Setup(c => c.GetHeaders()).Returns(new Dictionary>()); - var factory = Mock.Get(client.SpotApiV1.RequestFactory); - factory.Setup(c => c.Create(It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(request.Object); - factory = Mock.Get(client.SpotApiV3.RequestFactory); + var factory = Mock.Get(client.SpotApiV3.RequestFactory); factory.Setup(c => c.Create(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(request.Object); factory = Mock.Get(client.CopyTradingApi.RequestFactory); - factory.Setup(c => c.Create(It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(request.Object); - factory = Mock.Get(client.GeneralApi.RequestFactory); - factory.Setup(c => c.Create(It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(request.Object); - factory = Mock.Get(client.InverseFuturesApi.RequestFactory); - factory.Setup(c => c.Create(It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(request.Object); - factory = Mock.Get(client.InversePerpetualApi.RequestFactory); - factory.Setup(c => c.Create(It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(request.Object); - factory = Mock.Get(client.UsdPerpetualApi.RequestFactory); factory.Setup(c => c.Create(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(request.Object); factory = Mock.Get(client.DerivativesApi.RequestFactory); From 5c7ff79d0a11b11c1cde1d06e4365066fe1dba00 Mon Sep 17 00:00:00 2001 From: JKorf Date: Mon, 26 Feb 2024 20:09:39 +0100 Subject: [PATCH 09/17] Removed unused models and tests --- ByBit.Net/Objects/Internal/BybitData.cs | 26 - .../Objects/Internal/BybitTradeWrapper.cs | 14 - ByBit.Net/Objects/Models/ByBitApiKeyInfo.cs | 75 -- ByBit.Net/Objects/Models/BybitAccountRatio.cs | 32 - ByBit.Net/Objects/Models/BybitAnnouncement.cs | 33 - ByBit.Net/Objects/Models/BybitAssetInfo.cs | 69 - ByBit.Net/Objects/Models/BybitBalance.cs | 75 -- ByBit.Net/Objects/Models/BybitBigTrade.cs | 33 - .../Models/BybitCanceledConditionalOrder.cs | 58 - .../Objects/Models/BybitCanceledOrder.cs | 38 - .../Objects/Models/BybitConditionalOrder.cs | 116 -- .../Models/BybitConditionalOrderUsd.cs | 73 -- ByBit.Net/Objects/Models/BybitDeposit.cs | 73 -- .../Objects/Models/BybitDepositAddress.cs | 50 - .../Objects/Models/BybitDepositConfig.cs | 50 - .../Models/BybitExchangeHistoryEntry.cs | 51 - ByBit.Net/Objects/Models/BybitFundingRate.cs | 27 - .../Objects/Models/BybitFundingSettlement.cs | 47 - .../Models/BybitGeneralAccountStatus.cs | 45 - ByBit.Net/Objects/Models/BybitId.cs | 13 - .../Objects/Models/BybitIndexPriceKline.cs | 27 - ByBit.Net/Objects/Models/BybitMarginResult.cs | 101 -- .../Objects/Models/BybitMarkPriceKline.cs | 30 - ByBit.Net/Objects/Models/BybitOpenInterest.cs | 27 - ByBit.Net/Objects/Models/BybitOrder.cs | 113 -- ByBit.Net/Objects/Models/BybitOrderBase.cs | 86 -- .../Objects/Models/BybitOrderBookEntry.cs | 32 - ByBit.Net/Objects/Models/BybitOrderId.cs | 16 - ByBit.Net/Objects/Models/BybitPnlEntry.cs | 105 -- ByBit.Net/Objects/Models/BybitPosition.cs | 92 -- ByBit.Net/Objects/Models/BybitPositionBase.cs | 109 -- ByBit.Net/Objects/Models/BybitPositionUsd.cs | 49 - .../Objects/Models/BybitPredictedFunding.cs | 21 - ByBit.Net/Objects/Models/BybitRiskId.cs | 16 - ByBit.Net/Objects/Models/BybitRiskLimit.cs | 59 - ByBit.Net/Objects/Models/BybitStopOrderId.cs | 16 - .../Objects/Models/BybitSubAccountList.cs | 18 - ByBit.Net/Objects/Models/BybitSymbol.cs | 132 -- ByBit.Net/Objects/Models/BybitTicker.cs | 143 --- ByBit.Net/Objects/Models/BybitTpSlMode.cs | 18 - ByBit.Net/Objects/Models/BybitTrade.cs | 45 - ByBit.Net/Objects/Models/BybitTransfer.cs | 16 - .../Objects/Models/BybitTransferDetails.cs | 76 -- ByBit.Net/Objects/Models/BybitTransferId.cs | 16 - .../Objects/Models/BybitUniversalTransfer.cs | 57 - ByBit.Net/Objects/Models/BybitUserTrade.cs | 119 -- .../Objects/Models/BybitWalletFundRecord.cs | 64 - ByBit.Net/Objects/Models/BybitWithdraw.cs | 68 - ByBit.Net/Objects/Models/BybitWithdrawal.cs | 61 - ByBit.Net/Objects/Models/CoinBalanceQuery.cs | 71 -- .../Models/Socket/BybitBalanceUpdate.cs | 26 - .../Objects/Models/Socket/BybitDeltaUpdate.cs | 25 - .../Models/Socket/BybitInsuranceUpdate.cs | 26 - .../Models/Socket/BybitLiquidationUpdate.cs | 37 - .../Objects/Models/Socket/BybitOrderUpdate.cs | 120 -- .../Models/Socket/BybitPositionUpdate.cs | 93 -- .../Models/Socket/BybitStopOrderUpdate.cs | 81 -- .../Models/Socket/BybitTickerUpdate.cs | 172 --- .../Objects/Models/Socket/BybitTradeUpdate.cs | 59 - .../Models/Socket/BybitUserTradeUpdate.cs | 75 -- .../Socket/Spot/BybitSpotLeverageUpdate.cs | 55 - .../Objects/Models/Spot/BybitSpotBalance.cs | 13 - .../Objects/Models/Spot/v1/BybitLoanInfoV1.cs | 30 - .../Models/Spot/v1/BybitSpotBookPriceV1.cs | 49 - .../Models/Spot/v1/BybitSpotKlineV1.cs | 69 - .../Models/Spot/v1/BybitSpotOrderV1.cs | 57 - .../Models/Spot/v1/BybitSpotSymbolV1.cs | 83 -- .../Models/Spot/v1/BybitSpotTickerV1.cs | 56 - .../Models/Spot/v1/BybitSpotTradeV1.cs | 31 - .../Models/Spot/v1/BybitSpotUserTradeV1.cs | 101 -- .../Account/ChangeMarginAsync.txt | 11 - .../Account/GetApiKeyInfoAsync.txt | 29 - .../Account/GetAssetExchangeHistoryAsync.txt | 32 - .../Account/GetBalancesAsync.txt | 38 - .../Account/GetPositionAsync.txt | 45 - .../Account/GetProfitAndLossHistoryAsync.txt | 35 - .../Account/GetUserLastFundingFeeAsync.txt | 18 - .../GetUserPredictedFundingRateAsync.txt | 14 - .../Account/GetWalletFundHistoryAsync.txt | 40 - .../Account/GetWithdrawalHistoryAsync.txt | 26 - .../SetFullPartialPositionModeAsync.txt | 13 - .../Account/SetLeverageAsync.txt | 11 - .../Account/SetPositionModeAsync.txt | 11 - .../ExchangeData/GetAnnouncementsAsync.txt | 16 - .../ExchangeData/GetIndexPriceKlinesAsync.txt | 18 - .../ExchangeData/GetKlinesAsync.txt | 28 - .../ExchangeData/GetLastFundingRateAsync.txt | 15 - .../ExchangeData/GetLongShortRatioAsync.txt | 21 - .../ExchangeData/GetMarkPriceKlinesAsync.txt | 20 - .../ExchangeData/GetOpenInterestAsync.txt | 19 - .../ExchangeData/GetOrderBookAsync.txt | 21 - .../GetPremiumIndexKlinesAsync.txt | 18 - .../ExchangeData/GetRecentBigTradesAsync.txt | 21 - .../ExchangeData/GetSymbolsAsync.txt | 109 -- .../ExchangeData/GetTickerAsync.txt | 65 - .../ExchangeData/GetTradeHistoryAsync.txt | 17 - .../InversePerpetual/Socket/BalanceUpdate.txt | 7 - .../Socket/InsuranceUpdate.txt | 7 - .../InversePerpetual/Socket/KlineUpdate.txt | 13 - .../Socket/LiquidationUpdate.txt | 7 - .../InversePerpetual/Socket/OrderUpdate.txt | 28 - .../Socket/PositionUpdate.txt | 32 - .../Socket/StopOrderUpdate.txt | 21 - .../InversePerpetual/Socket/TickerUpdate.txt | 1 - .../InversePerpetual/Socket/TradeUpdate.txt | 13 - .../Socket/UserTradeUpdate.txt | 17 - .../CancelAllConditionalOrdersAsync.txt | 58 - .../Trading/CancelAllOrdersAsync.txt | 31 - .../Trading/CancelConditionalOrderAsync.txt | 13 - .../Trading/CancelOrderAsync.txt | 31 - .../Trading/GetConditionalOrdersAsync.txt | 32 - .../GetOpenConditionalOrderRealTimeAsync.txt | 31 - .../GetOpenConditionalOrdersRealTimeAsync.txt | 62 - .../Trading/GetOpenOrderRealTimeAsync.txt | 37 - .../Trading/GetOpenOrdersRealTimeAsync.txt | 64 - .../Trading/GetOrdersAsync.txt | 35 - .../Trading/GetUserTradesAsync.txt | 38 - .../Trading/ModifyConditionalOrderAsync.txt | 13 - .../Trading/ModifyOrderAsync.txt | 12 - .../Trading/PlaceConditionalOrderAsync.txt | 24 - .../Trading/PlaceOrderAsync.txt | 31 - .../Trading/SetTradingStopAsync.txt | 48 - .../Spot/Socket/BookPriceUpdateV1.txt | 8 - .../Account/AddReduceMarginAsync.txt | 30 - .../UsdPerpetual/Account/GetPositionAsync.txt | 62 - .../Account/GetProfitAndLossHistoryAsync.txt | 36 - .../Account/GetUserLastFundingFeeAsync.txt | 18 - .../GetUserPredictedFundingRateAsync.txt | 14 - .../SetFullPartialPositionModeAsync.txt | 13 - .../ExchangeData/GetAnnouncementsAsync.txt | 16 - .../ExchangeData/GetIndexPriceKlinesAsync.txt | 16 - .../ExchangeData/GetKlinesAsync.txt | 22 - .../ExchangeData/GetLastFundingRateAsync.txt | 12 - .../ExchangeData/GetMarkPriceKlinesAsync.txt | 27 - .../GetPremiumIndexKlinesAsync.txt | 16 - .../ExchangeData/GetTradeHistoryAsync.txt | 18 - .../UsdPerpetual/Socket/BalanceUpdate.txt | 6 - .../UsdPerpetual/Socket/KlineUpdate.txt | 15 - .../UsdPerpetual/Socket/LiquidationUpdate.txt | 7 - .../UsdPerpetual/Socket/OrderUpdate1.txt | 26 - .../UsdPerpetual/Socket/OrderUpdate2.txt | 28 - .../UsdPerpetual/Socket/PositionUpdate1.txt | 27 - .../UsdPerpetual/Socket/PositionUpdate2.txt | 66 - .../UsdPerpetual/Socket/StopOrderUpdate.txt | 22 - .../UsdPerpetual/Socket/TickerUpdate.txt | 39 - .../UsdPerpetual/Socket/TradeUpdate.txt | 12 - .../UsdPerpetual/Socket/UserTradeUpdate.txt | 17 - .../GetOpenConditionalOrderRealTimeAsync.txt | 39 - .../GetOpenConditionalOrdersRealTimeAsync.txt | 70 -- .../Trading/GetUserTradesAsync.txt | 1115 ----------------- Bybit.UnitTests/JsonSocketTests.cs | 155 --- 151 files changed, 7428 deletions(-) delete mode 100644 ByBit.Net/Objects/Internal/BybitTradeWrapper.cs delete mode 100644 ByBit.Net/Objects/Models/ByBitApiKeyInfo.cs delete mode 100644 ByBit.Net/Objects/Models/BybitAccountRatio.cs delete mode 100644 ByBit.Net/Objects/Models/BybitAnnouncement.cs delete mode 100644 ByBit.Net/Objects/Models/BybitAssetInfo.cs delete mode 100644 ByBit.Net/Objects/Models/BybitBalance.cs delete mode 100644 ByBit.Net/Objects/Models/BybitBigTrade.cs delete mode 100644 ByBit.Net/Objects/Models/BybitCanceledConditionalOrder.cs delete mode 100644 ByBit.Net/Objects/Models/BybitCanceledOrder.cs delete mode 100644 ByBit.Net/Objects/Models/BybitConditionalOrder.cs delete mode 100644 ByBit.Net/Objects/Models/BybitConditionalOrderUsd.cs delete mode 100644 ByBit.Net/Objects/Models/BybitDeposit.cs delete mode 100644 ByBit.Net/Objects/Models/BybitDepositAddress.cs delete mode 100644 ByBit.Net/Objects/Models/BybitDepositConfig.cs delete mode 100644 ByBit.Net/Objects/Models/BybitExchangeHistoryEntry.cs delete mode 100644 ByBit.Net/Objects/Models/BybitFundingRate.cs delete mode 100644 ByBit.Net/Objects/Models/BybitFundingSettlement.cs delete mode 100644 ByBit.Net/Objects/Models/BybitGeneralAccountStatus.cs delete mode 100644 ByBit.Net/Objects/Models/BybitId.cs delete mode 100644 ByBit.Net/Objects/Models/BybitIndexPriceKline.cs delete mode 100644 ByBit.Net/Objects/Models/BybitMarginResult.cs delete mode 100644 ByBit.Net/Objects/Models/BybitMarkPriceKline.cs delete mode 100644 ByBit.Net/Objects/Models/BybitOpenInterest.cs delete mode 100644 ByBit.Net/Objects/Models/BybitOrder.cs delete mode 100644 ByBit.Net/Objects/Models/BybitOrderBase.cs delete mode 100644 ByBit.Net/Objects/Models/BybitOrderBookEntry.cs delete mode 100644 ByBit.Net/Objects/Models/BybitOrderId.cs delete mode 100644 ByBit.Net/Objects/Models/BybitPnlEntry.cs delete mode 100644 ByBit.Net/Objects/Models/BybitPosition.cs delete mode 100644 ByBit.Net/Objects/Models/BybitPositionBase.cs delete mode 100644 ByBit.Net/Objects/Models/BybitPositionUsd.cs delete mode 100644 ByBit.Net/Objects/Models/BybitPredictedFunding.cs delete mode 100644 ByBit.Net/Objects/Models/BybitRiskId.cs delete mode 100644 ByBit.Net/Objects/Models/BybitRiskLimit.cs delete mode 100644 ByBit.Net/Objects/Models/BybitStopOrderId.cs delete mode 100644 ByBit.Net/Objects/Models/BybitSubAccountList.cs delete mode 100644 ByBit.Net/Objects/Models/BybitSymbol.cs delete mode 100644 ByBit.Net/Objects/Models/BybitTicker.cs delete mode 100644 ByBit.Net/Objects/Models/BybitTpSlMode.cs delete mode 100644 ByBit.Net/Objects/Models/BybitTrade.cs delete mode 100644 ByBit.Net/Objects/Models/BybitTransfer.cs delete mode 100644 ByBit.Net/Objects/Models/BybitTransferDetails.cs delete mode 100644 ByBit.Net/Objects/Models/BybitTransferId.cs delete mode 100644 ByBit.Net/Objects/Models/BybitUniversalTransfer.cs delete mode 100644 ByBit.Net/Objects/Models/BybitUserTrade.cs delete mode 100644 ByBit.Net/Objects/Models/BybitWalletFundRecord.cs delete mode 100644 ByBit.Net/Objects/Models/BybitWithdraw.cs delete mode 100644 ByBit.Net/Objects/Models/BybitWithdrawal.cs delete mode 100755 ByBit.Net/Objects/Models/CoinBalanceQuery.cs delete mode 100644 ByBit.Net/Objects/Models/Socket/BybitBalanceUpdate.cs delete mode 100644 ByBit.Net/Objects/Models/Socket/BybitDeltaUpdate.cs delete mode 100644 ByBit.Net/Objects/Models/Socket/BybitInsuranceUpdate.cs delete mode 100644 ByBit.Net/Objects/Models/Socket/BybitLiquidationUpdate.cs delete mode 100644 ByBit.Net/Objects/Models/Socket/BybitOrderUpdate.cs delete mode 100644 ByBit.Net/Objects/Models/Socket/BybitPositionUpdate.cs delete mode 100644 ByBit.Net/Objects/Models/Socket/BybitStopOrderUpdate.cs delete mode 100644 ByBit.Net/Objects/Models/Socket/BybitTickerUpdate.cs delete mode 100644 ByBit.Net/Objects/Models/Socket/BybitTradeUpdate.cs delete mode 100644 ByBit.Net/Objects/Models/Socket/BybitUserTradeUpdate.cs delete mode 100644 ByBit.Net/Objects/Models/Socket/Spot/BybitSpotLeverageUpdate.cs delete mode 100644 ByBit.Net/Objects/Models/Spot/v1/BybitLoanInfoV1.cs delete mode 100644 ByBit.Net/Objects/Models/Spot/v1/BybitSpotBookPriceV1.cs delete mode 100644 ByBit.Net/Objects/Models/Spot/v1/BybitSpotKlineV1.cs delete mode 100644 ByBit.Net/Objects/Models/Spot/v1/BybitSpotOrderV1.cs delete mode 100644 ByBit.Net/Objects/Models/Spot/v1/BybitSpotSymbolV1.cs delete mode 100644 ByBit.Net/Objects/Models/Spot/v1/BybitSpotTickerV1.cs delete mode 100644 ByBit.Net/Objects/Models/Spot/v1/BybitSpotTradeV1.cs delete mode 100644 ByBit.Net/Objects/Models/Spot/v1/BybitSpotUserTradeV1.cs delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Account/ChangeMarginAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetApiKeyInfoAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetAssetExchangeHistoryAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetBalancesAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetPositionAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetProfitAndLossHistoryAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetUserLastFundingFeeAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetUserPredictedFundingRateAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetWalletFundHistoryAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetWithdrawalHistoryAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Account/SetFullPartialPositionModeAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Account/SetLeverageAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Account/SetPositionModeAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetAnnouncementsAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetIndexPriceKlinesAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetKlinesAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetLastFundingRateAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetLongShortRatioAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetMarkPriceKlinesAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetOpenInterestAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetOrderBookAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetPremiumIndexKlinesAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetRecentBigTradesAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetSymbolsAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetTickerAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetTradeHistoryAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/BalanceUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/InsuranceUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/KlineUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/LiquidationUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/OrderUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/PositionUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/StopOrderUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/TickerUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/TradeUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/UserTradeUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelAllConditionalOrdersAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelAllOrdersAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelConditionalOrderAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelOrderAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetConditionalOrdersAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenConditionalOrderRealTimeAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenConditionalOrdersRealTimeAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenOrderRealTimeAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenOrdersRealTimeAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOrdersAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetUserTradesAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/ModifyConditionalOrderAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/ModifyOrderAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/PlaceConditionalOrderAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/PlaceOrderAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/SetTradingStopAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/Spot/Socket/BookPriceUpdateV1.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/AddReduceMarginAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetPositionAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetProfitAndLossHistoryAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetUserLastFundingFeeAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetUserPredictedFundingRateAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/SetFullPartialPositionModeAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetAnnouncementsAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetIndexPriceKlinesAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetKlinesAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetLastFundingRateAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetMarkPriceKlinesAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetPremiumIndexKlinesAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetTradeHistoryAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/BalanceUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/KlineUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/LiquidationUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/OrderUpdate1.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/OrderUpdate2.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/PositionUpdate1.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/PositionUpdate2.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/StopOrderUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/TickerUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/TradeUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/UserTradeUpdate.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Trading/GetOpenConditionalOrderRealTimeAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Trading/GetOpenConditionalOrdersRealTimeAsync.txt delete mode 100644 Bybit.UnitTests/JsonResponses/UsdPerpetual/Trading/GetUserTradesAsync.txt diff --git a/ByBit.Net/Objects/Internal/BybitData.cs b/ByBit.Net/Objects/Internal/BybitData.cs index 7c188906..824c337b 100644 --- a/ByBit.Net/Objects/Internal/BybitData.cs +++ b/ByBit.Net/Objects/Internal/BybitData.cs @@ -63,30 +63,4 @@ public class BybitDerivativesCursorPage : BybitCursorPage [JsonProperty("category"), JsonConverter(typeof(EnumConverter))] public Category Category { get; set; } = Category.Undefined; } - - /// - /// Cursor paged data wrapper - /// - /// - public class BybitPage : BybitData - { - /// - /// Current page - /// - [JsonProperty("current_page")] - public int CurrentPage { get; set; } - } - - internal class BybitPositionData : BybitData - { - [JsonProperty("is_valid")] - public bool IsValid { get; set; } - } - - internal class BybitPositionUsdData : BybitData - { - [JsonProperty("is_valid")] - public bool IsValid { get; set; } - } - } diff --git a/ByBit.Net/Objects/Internal/BybitTradeWrapper.cs b/ByBit.Net/Objects/Internal/BybitTradeWrapper.cs deleted file mode 100644 index 631ce0e0..00000000 --- a/ByBit.Net/Objects/Internal/BybitTradeWrapper.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Bybit.Net.Objects.Models; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; - -namespace Bybit.Net.Objects.Internal -{ - internal class BybitTradeWrapper - { - [JsonProperty("trade_list")] - public IEnumerable Trades { get; set; } = Array.Empty(); - } - -} diff --git a/ByBit.Net/Objects/Models/ByBitApiKeyInfo.cs b/ByBit.Net/Objects/Models/ByBitApiKeyInfo.cs deleted file mode 100644 index 056938e3..00000000 --- a/ByBit.Net/Objects/Models/ByBitApiKeyInfo.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Api key info - /// - public class ByBitApiKeyInfo - { - /// - /// The api key - /// - [JsonProperty("api_key")] - public string Apikey { get; set; } = string.Empty; - /// - /// Type of key - /// - public string Type { get; set; } = string.Empty; - /// - /// User id - /// - [JsonProperty("user_id")] - public long UserId { get; set; } - /// - /// Inviter id - /// - [JsonProperty("inviter_id")] - public long InviterId { get; set; } - /// - /// IP whitelist - /// - [JsonProperty("ips")] - public IEnumerable IpWhitelist { get; set; } = Array.Empty(); - /// - /// Notes - /// - public string Note { get; set; } = string.Empty; - /// - /// Key permissions - /// - public IEnumerable Permissions { get; set; } = Array.Empty(); - /// - /// Creation time - /// - [JsonProperty("created_at")] - public DateTime CreateTime { get; set; } - /// - /// Expiry time - /// - [JsonProperty("expired_at")] - public DateTime? ExpireTime { get; set; } - /// - /// Is readonly key - /// - [JsonProperty("read_only")] - public bool Readonly { get; set; } - /// - /// Vip Level - /// - [JsonProperty("vip_level")] - public string VipLevel { get; set; } = string.Empty; - /// - /// Market Maker Level - /// - [JsonProperty("mkt_maker_level")] - public int MarketMakerLevel { get; set; } - /// - /// Affiliate Id - /// - [JsonProperty("affiliate_id")] - public long AffiliateId { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitAccountRatio.cs b/ByBit.Net/Objects/Models/BybitAccountRatio.cs deleted file mode 100644 index 7842a760..00000000 --- a/ByBit.Net/Objects/Models/BybitAccountRatio.cs +++ /dev/null @@ -1,32 +0,0 @@ -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Long/short account ratio - /// - public class BybitAccountRatio - { - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Buy ratio - /// - [JsonProperty("buy_ratio")] - public decimal BuyRatio { get; set; } - /// - /// Sell ratio - /// - [JsonProperty("sell_ratio")] - public decimal SellRatio { get; set; } - /// - /// Data timestamp - /// - [JsonConverter(typeof(DateTimeConverter))] - public DateTime Timestamp { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitAnnouncement.cs b/ByBit.Net/Objects/Models/BybitAnnouncement.cs deleted file mode 100644 index 09660955..00000000 --- a/ByBit.Net/Objects/Models/BybitAnnouncement.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Announcement - /// - public class BybitAnnouncement - { - /// - /// Announcement id - /// - public long Id { get; set; } - /// - /// Title - /// - public string Title { get; set; } = string.Empty; - /// - /// Link - /// - public string Link { get; set; } = string.Empty; - /// - /// Summary - /// - public string Summary { get; set; } = string.Empty; - /// - /// Create time - /// - [JsonProperty("created_at")] - public DateTime CreateTime { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitAssetInfo.cs b/ByBit.Net/Objects/Models/BybitAssetInfo.cs deleted file mode 100644 index 40caa964..00000000 --- a/ByBit.Net/Objects/Models/BybitAssetInfo.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Asset information - /// - public class BybitAssetInfo - { - /// - /// Name - /// - public string Name { get; set; } = string.Empty; - /// - /// Asset - /// - [JsonProperty("coin")] - public string Asset { get; set; } = string.Empty; - /// - /// Withdrawable quantity remaining - /// - [JsonProperty("remain_amount")] - public decimal? RemainingWithdrawableQuantity { get; set; } - /// - /// Networks info - /// - [JsonProperty("chains")] - public IEnumerable Networks { get; set; } = Array.Empty(); - } - - /// - /// Network info - /// - public class BybitAssetNetwork - { - /// - /// Network type - /// - [JsonProperty("chain_type")] - public string NetworkType { get; set; } = string.Empty; - /// - /// Number of confirmations needed for deposit - /// - [JsonProperty("confirmation")] - public int ConfirmationsNeeded { get; set; } - /// - /// Withdrawal fee - /// - [JsonProperty("withdraw_fee")] - public decimal? WithdrawFee { get; set; } - /// - /// Deposit fee - /// - [JsonProperty("deposit_min")] - public decimal? MinimalDeposit { get; set; } - /// - /// Minimal withdrawal amount - /// - [JsonProperty("withdraw_min")] - public decimal? MinimalWithdrawal { get; set; } - /// - /// Network name - /// - [JsonProperty("chain")] - public string Network { get; set; } = string.Empty; - } -} diff --git a/ByBit.Net/Objects/Models/BybitBalance.cs b/ByBit.Net/Objects/Models/BybitBalance.cs deleted file mode 100644 index f10c2785..00000000 --- a/ByBit.Net/Objects/Models/BybitBalance.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Balance info - /// - public class BybitBalance - { - /// - /// Equity, wallet balance + unrealized pnl - /// - public decimal Equity { get; set; } - /// - /// Available balance - /// - [JsonProperty("available_balance")] - public decimal AvailableBalance { get; set; } - /// - /// Used margin, wallet balance - available balance - /// - [JsonProperty("used_margin")] - public decimal UsedMargin { get; set; } - /// - /// Used margin by order - /// - [JsonProperty("order_margin")] - public decimal OrderMargin { get; set; } - /// - /// Position margin - /// - [JsonProperty("position_margin")] - public decimal PositionMargin { get; set; } - /// - /// Position closing fee - /// - [JsonProperty("occ_closing_fee")] - public decimal PositionClosingFee { get; set; } - /// - /// Funding fee - /// - [JsonProperty("occ_funding_fee")] - public decimal FundingFee { get; set; } - /// - /// Wallet balance - /// - [JsonProperty("wallet_balance")] - public decimal WalletBalance { get; set; } - /// - /// Daily realized profit and loss - /// - [JsonProperty("realised_pnl")] - public decimal RealizedPnl { get; set; } - /// - /// Unrealized profit and loss - /// - [JsonProperty("unrealised_pnl")] - public decimal UnrealizedPnl { get; set; } - /// - /// Total realized profit and loss - /// - [JsonProperty("cum_realised_pnl")] - public decimal TotalRealizedPnl { get; set; } - /// - /// Given cash - /// - [JsonProperty("given_cash")] - public decimal GivenCash { get; set; } - /// - /// Service cash - /// - [JsonProperty("service_cash")] - public decimal ServiceCash { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitBigTrade.cs b/ByBit.Net/Objects/Models/BybitBigTrade.cs deleted file mode 100644 index 6d169cbc..00000000 --- a/ByBit.Net/Objects/Models/BybitBigTrade.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Big trade info - /// - public class BybitBigTrade - { - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Trade value - /// - public decimal Value { get; set; } - /// - /// Side of the trade - /// - [JsonConverter(typeof(OrderSideConverter))] - public OrderSide Side { get; set; } - /// - /// Timestamp of the trade - /// - [JsonConverter(typeof(DateTimeConverter))] - public DateTime Timestamp { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitCanceledConditionalOrder.cs b/ByBit.Net/Objects/Models/BybitCanceledConditionalOrder.cs deleted file mode 100644 index cc1a44e1..00000000 --- a/ByBit.Net/Objects/Models/BybitCanceledConditionalOrder.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Canceled order info - /// - public class BybitCanceledConditionalOrder : BybitOrderBase - { - /// - /// Cancel order id - /// - [JsonProperty("clOrdID")] - public override string Id { get; set; } = string.Empty; - /// - /// Order status - /// - [JsonProperty("order_status"), JsonConverter(typeof(OrderStatusConverter))] - public OrderStatus? Status { get; set; } - /// - /// The state of initiating a matchmaking request - /// - [JsonProperty("cross_status"), JsonConverter(typeof(StopOrderStatusConverter))] - public StopOrderStatus CrossStatus { get; set; } - /// - /// Trigger scenario for single action - /// - [JsonProperty("create_type")] - public string? CreateType { get; set; } - /// - /// Cross sequence - /// - [JsonProperty("cross_seq")] - public decimal CrossSequence { get; set; } - /// - /// Stop order type - /// - [JsonProperty("stop_order_type"), JsonConverter(typeof(StopOrderTypeConverter))] - public StopOrderType StopOrderType { get; set; } - /// - /// Trigger type - /// - [JsonProperty("trigger_by"), JsonConverter(typeof(TriggerTypeConverter))] - public TriggerType? TriggerType { get; set; } - /// - /// Base price - /// - [JsonProperty("base_price")] - public decimal BasePrice { get; set; } - /// - /// Expected direction - /// - [JsonProperty("expected_direction")] - public string? ExpectedDirection { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitCanceledOrder.cs b/ByBit.Net/Objects/Models/BybitCanceledOrder.cs deleted file mode 100644 index 9a2da756..00000000 --- a/ByBit.Net/Objects/Models/BybitCanceledOrder.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Canceled order info - /// - public class BybitCanceledOrder: BybitOrderBase - { - /// - /// Cancel order id - /// - [JsonProperty("clOrdID")] - public override string Id { get; set; } = string.Empty; - /// - /// Order status - /// - [JsonProperty("order_status"), JsonConverter(typeof(OrderStatusConverter))] - public OrderStatus? Status { get; set; } - /// - /// The state of initiating a matchmaking request - /// - [JsonProperty("cross_status"), JsonConverter(typeof(OrderStatusConverter))] - public OrderStatus CrossStatus { get; set; } - /// - /// Trigger scenario for single action - /// - [JsonProperty("create_type")] - public string? CreateType { get; set; } - /// - /// Cross sequence - /// - [JsonProperty("cross_seq")] - public decimal CrossSequence { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitConditionalOrder.cs b/ByBit.Net/Objects/Models/BybitConditionalOrder.cs deleted file mode 100644 index e6b9cf23..00000000 --- a/ByBit.Net/Objects/Models/BybitConditionalOrder.cs +++ /dev/null @@ -1,116 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Conditional order info - /// - public class BybitConditionalOrder: BybitOrderBase - { - /// - /// Stop order id - /// - [JsonProperty("stop_order_id")] - public override string Id { get; set; } = string.Empty; - [JsonProperty("order_id")] - internal string? _stopId { get => Id; set { if (value != null) Id = value; } } - /// - /// Client order id - /// - [JsonProperty("order_link_id")] - public string? ClientOrderId { get; set; } - /// - /// Remark - /// - public string? Remark { get; set; } - /// - /// Stop price - /// - [JsonProperty("stop_px")] - public decimal StopPrice { get; set; } - /// - /// Base price - /// - [JsonProperty("base_price")] - public decimal BasePrice { get; set; } - /// - /// Reason for reject - /// - [JsonProperty("reject_reason")] - public string? RejectReason { get; set; } - /// - /// Type of the stop order - /// - [JsonProperty("stop_order_type"), JsonConverter(typeof(StopOrderTypeConverter))] - public StopOrderType? StopOrderType { get; set; } - - /// - /// Stop order status - /// - [JsonProperty("stop_order_status"), JsonConverter(typeof(StopOrderStatusConverter))] - public StopOrderStatus Status { get; set; } - [JsonProperty("order_status"), JsonConverter(typeof(StopOrderStatusConverter))] - internal StopOrderStatus? _status { get => Status; set { if (value != null) Status = value.Value; } } - - /// - /// Quote quantity filled - /// - [JsonProperty("cum_exec_qty")] - public decimal QuoteQuantityFilled { get; set; } - /// - /// Base quantity filled - /// - [JsonProperty("cum_exec_value")] - public decimal? BaseQuantityFilled { get; set; } - /// - /// Fee paid - /// - [JsonProperty("cum_exec_fee")] - public decimal? Fee { get; set; } - - /// - /// Trigger type - /// - [JsonProperty("trigger_by"), JsonConverter(typeof(TriggerTypeConverter))] - public TriggerType? TriggerType { get; set; } - /// - /// Trigger type for take profit - /// - [JsonProperty("tp_trigger_by"), JsonConverter(typeof(TriggerTypeConverter))] - public TriggerType? TakeProfitTriggerType { get; set; } - /// - /// Trigger type for stop loss - /// - [JsonProperty("sl_trigger_by"), JsonConverter(typeof(TriggerTypeConverter))] - public TriggerType? StopLossTriggerType { get; set; } - - /// - /// Take profit price - /// - [JsonProperty("take_profit")] - public decimal? TakeProfitPrice { get; set; } - /// - /// Stop loss price - /// - [JsonProperty("stop_loss")] - public decimal? StopLossPrice { get; set; } - /// - /// Trigger price - /// - [JsonProperty("trigger_price")] - public decimal? TriggerPrice { get; set; } - /// - /// Reduce only - /// - [JsonProperty("reduce_only")] - public bool ReduceOnly { get; set; } - /// - /// Position mode - /// - [JsonProperty("position_idx")] - [JsonConverter(typeof(PositionModeConverter))] - public PositionMode? PositionMode { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitConditionalOrderUsd.cs b/ByBit.Net/Objects/Models/BybitConditionalOrderUsd.cs deleted file mode 100644 index 561b4511..00000000 --- a/ByBit.Net/Objects/Models/BybitConditionalOrderUsd.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Conditional order info - /// - public class BybitConditionalOrderUsd: BybitOrderBase - { - /// - /// Stop order id - /// - [JsonProperty("stop_order_id")] - public override string Id { get; set; } = string.Empty; - /// - /// Client order id - /// - [JsonProperty("order_link_id")] - public string? ClientOrderId { get; set; } - /// - /// Base price - /// - [JsonProperty("base_price")] - public decimal BasePrice { get; set; } - /// - /// Stop order status - /// - [JsonProperty("order_status"), JsonConverter(typeof(StopOrderStatusConverter))] - public StopOrderStatus Status { get; set; } - /// - /// Trigger type - /// - [JsonProperty("trigger_by"), JsonConverter(typeof(TriggerTypeConverter))] - public TriggerType? TriggerType { get; set; } - /// - /// Take profit trigger type - /// - [JsonProperty("tp_trigger_by"), JsonConverter(typeof(TriggerTypeConverter))] - public TriggerType? TakeProfitTriggerType { get; set; } - /// - /// Stop loss trigger type - /// - [JsonProperty("sl_trigger_by"), JsonConverter(typeof(TriggerTypeConverter))] - public TriggerType? StopLossTriggerType { get; set; } - /// - /// True means close order, false means open position - /// - [JsonProperty("reduce_only")] - public bool ReduceOnly { get; set; } - /// - /// Is close on trigger order - /// - [JsonProperty("close_on_trigger")] - public bool CloseOnTrigger { get; set; } - /// - /// Take profit price - /// - [JsonProperty("take_profit")] - public decimal? TakeProfitPrice { get; set; } - /// - /// Stop loss price - /// - [JsonProperty("stop_loss")] - public decimal? StopLossPrice { get; set; } - /// - /// Trigger price - /// - [JsonProperty("trigger_price")] - public decimal? TriggerPrice { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitDeposit.cs b/ByBit.Net/Objects/Models/BybitDeposit.cs deleted file mode 100644 index b3d31b89..00000000 --- a/ByBit.Net/Objects/Models/BybitDeposit.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Deposit info - /// - public class BybitDeposit - { - /// - /// Asset - /// - [JsonProperty("coin")] - public string Asset { get; set; } = string.Empty; - /// - /// Network - /// - [JsonProperty("chain")] - public string Network { get; set; } = string.Empty; - /// - /// Quantity - /// - [JsonProperty("amount")] - public decimal Quantity { get; set; } - /// - /// Transaction id - /// - [JsonProperty("tx_id")] - public string TransactionId { get; set; } = string.Empty; - /// - /// Status - /// - [JsonConverter(typeof(EnumConverter))] - public DepositStatus Status { get; set; } - /// - /// Address - /// - [JsonProperty("to_address")] - public string ToAddress { get; set; } = string.Empty; - /// - /// Tag - /// - public string Tag { get; set; } = string.Empty; - /// - /// Deposit fee - /// - [JsonProperty("deposit_fee")] - public decimal? DepositFee { get; set; } - /// - /// Success time - /// - [JsonConverter(typeof(DateTimeConverter))] - [JsonProperty("success_at")] - public DateTime SuccessTime { get; set; } - /// - /// Number of confirmations - /// - public int Confirmations { get; set; } - /// - /// Transaction sequence number - /// - [JsonProperty("tx_index")] - public string TransactionIndex { get; set; } = string.Empty; - /// - /// Hash number on the chain - /// - [JsonProperty("block_hash")] - public string BlockHash { get; set; } = string.Empty; - } -} diff --git a/ByBit.Net/Objects/Models/BybitDepositAddress.cs b/ByBit.Net/Objects/Models/BybitDepositAddress.cs deleted file mode 100644 index 04663898..00000000 --- a/ByBit.Net/Objects/Models/BybitDepositAddress.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Deposit address info - /// - public class BybitDepositAddress - { - /// - /// The asset - /// - [JsonProperty("coin")] - public string Asset { get; set; } = string.Empty; - /// - /// Available network adresses - /// - [JsonProperty("chains")] - public IEnumerable Networks { get; set; } = Array.Empty(); - } - - /// - /// Deposit address on a network - /// - public class BybitNetworkDepositAddress - { - /// - /// Network type - /// - [JsonProperty("chain_type")] - public string NetworkType { get; set; } = string.Empty; - /// - /// Deposit address - /// - [JsonProperty("address_deposit")] - public string Address { get; set; } = string.Empty; - /// - /// Tag to use for deposit - /// - [JsonProperty("tag_deposit")] - public string DepositTag { get; set; } = string.Empty; - /// - /// Network - /// - [JsonProperty("chain")] - public string Network { get; set; } = string.Empty; - } -} diff --git a/ByBit.Net/Objects/Models/BybitDepositConfig.cs b/ByBit.Net/Objects/Models/BybitDepositConfig.cs deleted file mode 100644 index 73f9dfb7..00000000 --- a/ByBit.Net/Objects/Models/BybitDepositConfig.cs +++ /dev/null @@ -1,50 +0,0 @@ - -using Newtonsoft.Json; -using System; -using System.Collections.Generic; - -namespace Bybit.Net.Objects.Models -{ - internal class BybitDepositConfigWrapper - { - [JsonProperty("config_list")] - public IEnumerable ConfigList { get; set; } = Array.Empty(); - } - - /// - /// Deposit config - /// - public class BybitDepositConfig - { - /// - /// Asset name - /// - [JsonProperty("coin")] - public string Asset { get; set; } = string.Empty; - /// - /// Chain - /// - [JsonProperty("chain")] - public string Network { get; set; } = string.Empty; - /// - /// Asset name - /// - [JsonProperty("coin_show_name")] - public string AssetName { get; set; } = string.Empty; - /// - /// Chain type - /// - [JsonProperty("chain_type")] - public string NetworkType { get; set; } = string.Empty; - /// - /// Number of confirmations needed - /// - [JsonProperty("block_confirm_number")] - public int ConfirmationsNeeded { get; set; } - /// - /// Min deposit quantity - /// - [JsonProperty("min_deposit_amount")] - public decimal MinDepositQuantity { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitExchangeHistoryEntry.cs b/ByBit.Net/Objects/Models/BybitExchangeHistoryEntry.cs deleted file mode 100644 index bf511324..00000000 --- a/ByBit.Net/Objects/Models/BybitExchangeHistoryEntry.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Asset exchange history info - /// - public class BybitExchangeHistoryEntry - { - /// - /// Exchange id - /// - public long Id { get; set; } - /// - /// Exchange rate - /// - [JsonProperty("exchange_rate")] - public decimal ExchangeRate { get; set; } - /// - /// From asset - /// - [JsonProperty("from_coin")] - public string FromAsset { get; set; } = string.Empty; - /// - /// From quantity - /// - [JsonProperty("from_amount")] - public decimal FromQuantity { get; set; } - /// - /// From fee - /// - [JsonProperty("from_fee")] - public decimal FromFee { get; set; } - /// - /// To asset - /// - [JsonProperty("to_coin")] - public string ToAsset { get; set; } = string.Empty; - /// - /// To quantity - /// - [JsonProperty("to_amount")] - public decimal ToQuantity { get; set; } - /// - /// Timestamp - /// - [JsonProperty("created_at")] - public DateTime CreateTime { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitFundingRate.cs b/ByBit.Net/Objects/Models/BybitFundingRate.cs deleted file mode 100644 index 5d7969d1..00000000 --- a/ByBit.Net/Objects/Models/BybitFundingRate.cs +++ /dev/null @@ -1,27 +0,0 @@ -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Funding rate info - /// - public class BybitFundingRate - { - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Funding rate - /// - [JsonProperty("funding_rate")] - public decimal FundingRate { get; set; } - /// - /// Timestamp - /// - [JsonProperty("funding_rate_timestamp"), JsonConverter(typeof(DateTimeConverter))] - public DateTime Timestamp { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitFundingSettlement.cs b/ByBit.Net/Objects/Models/BybitFundingSettlement.cs deleted file mode 100644 index 6bcc525c..00000000 --- a/ByBit.Net/Objects/Models/BybitFundingSettlement.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Funding settlement info - /// - public class BybitFundingSettlement - { - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Position side at the time of settlement - /// - [JsonConverter(typeof(OrderSideConverter))] - public OrderSide Side { get; set; } - /// - /// Position size at the time of settlement - /// - [JsonProperty("size")] - public decimal Quantity { get; set; } - /// - /// Funding rate for settlement - /// - [JsonProperty("funding_rate")] - public decimal FundingRate { get; set; } - /// - /// Funding fee - /// - [JsonProperty("exec_fee")] - public decimal FundingFee { get; set; } - /// - /// Funding settlement time - /// - [JsonProperty("exec_timestamp")] - [JsonConverter(typeof(DateTimeConverter))] - public DateTime? Timestamp { get; set; } - [JsonProperty("exec_time")] - internal DateTime? _time { set => Timestamp = value; get => Timestamp; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitGeneralAccountStatus.cs b/ByBit.Net/Objects/Models/BybitGeneralAccountStatus.cs deleted file mode 100644 index 02102214..00000000 --- a/ByBit.Net/Objects/Models/BybitGeneralAccountStatus.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Account status - /// - public class BybitGeneralAccountStatus - { - /// - /// Account status - /// - public string Status { get; set; } = string.Empty; - /// - /// Asset infos - /// - public IEnumerable Assets { get; set; } = Array.Empty(); - } - - /// - /// Asset info - /// - public class BybitGeneralAssetInfo - { - /// - /// Asset name - /// - [JsonProperty("coin")] - public string Asset { get; set; } = string.Empty; - /// - /// Free amount - /// - public decimal Free { get; set; } - /// - /// Frozen amount - /// - public decimal Frozen { get; set; } - /// - /// temporarily "" - /// - public string? Withdraw { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitId.cs b/ByBit.Net/Objects/Models/BybitId.cs deleted file mode 100644 index f40a08a8..00000000 --- a/ByBit.Net/Objects/Models/BybitId.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Bybit.Net.Objects.Models -{ - /// - /// Id - /// - public class BybitId - { - /// - /// Id - /// - public string Id { get; set; } = string.Empty; - } -} diff --git a/ByBit.Net/Objects/Models/BybitIndexPriceKline.cs b/ByBit.Net/Objects/Models/BybitIndexPriceKline.cs deleted file mode 100644 index 6de573fd..00000000 --- a/ByBit.Net/Objects/Models/BybitIndexPriceKline.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Kline info - /// - public class BybitIndexPriceKline : BybitKlineBase - { - /// - /// Open time - /// - [JsonProperty("open_time"), JsonConverter(typeof(DateTimeConverter))] - public DateTime OpenTime { get; set; } - - /// - /// Data recording period - /// - [JsonConverter(typeof(KlineIntervalConverter))] - public KlineInterval Period { get; set; } - - } -} diff --git a/ByBit.Net/Objects/Models/BybitMarginResult.cs b/ByBit.Net/Objects/Models/BybitMarginResult.cs deleted file mode 100644 index 6979ed72..00000000 --- a/ByBit.Net/Objects/Models/BybitMarginResult.cs +++ /dev/null @@ -1,101 +0,0 @@ -using Bybit.Net.Enums; -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Margin result - /// - public class BybitMarginResult - { - /// - /// Position info - /// - [JsonProperty("PositionListResult")] - public BybitMarginPositionInfo Position { get; set; } = null!; - /// - /// Wallet balance - /// - [JsonProperty("wallet_balance")] - public decimal WalletBalance { get; set; } - /// - /// Available balance = wallet balance - used margin - /// - [JsonProperty("available_balance")] - public decimal AvailableBalance { get; set; } - } - - /// - /// Position info - /// - public class BybitMarginPositionInfo - { - /// - /// User id - /// - [JsonProperty("user_id")] - public long UserId { get; set; } - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Side - /// - public PositionSide Side { get; set; } - /// - /// Position quantity - /// - [JsonProperty("size")] - public decimal Quantity { get; set; } - /// - /// Current position value - /// - [JsonProperty("position_value")] - public decimal PositionValue { get; set; } - /// - /// Average opening price - /// - [JsonProperty("entry_price")] - public decimal EntryPrice { get; set; } - /// - /// Liquidation price - /// - [JsonProperty("liq_price")] - public decimal LiquidationPrice { get; set; } - /// - /// Bust price - /// - [JsonProperty("bust_price")] - public decimal BankruptcyPrice { get; set; } - /// - /// In Isolated Margin mode, the value is set by user. In Cross Margin mode, the value is the max leverage at current risk level - /// - public int Leverage { get; set; } - /// - /// Position margin - /// - [JsonProperty("position_margin")] - public decimal PositionMargin { get; set; } - /// - /// Pre-occupancy closing fee - /// - [JsonProperty("occ_closing_fee")] - public decimal ClosingFee { get; set; } - /// - /// Today's realized Profit and Loss - /// - [JsonProperty("realised_pnl")] - public decimal RealizedPnl { get; set; } - /// - /// Cumulative realized Profit and Loss - /// - [JsonProperty("cum_realised_pnl")] - public decimal TotalRealizedPnl { get; set; } - /// - /// Quantity which can be closed - /// - [JsonProperty("free_qty")] - public decimal FreeQuantity { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitMarkPriceKline.cs b/ByBit.Net/Objects/Models/BybitMarkPriceKline.cs deleted file mode 100644 index a020cee0..00000000 --- a/ByBit.Net/Objects/Models/BybitMarkPriceKline.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Kline info - /// - public class BybitMarkPriceKline : BybitKlineBase - { - /// - /// Id - /// - public long? Id { get; set; } - /// - /// Open time - /// - [JsonProperty("start_at"), JsonConverter(typeof(DateTimeConverter))] - public DateTime OpenTime { get; set; } - /// - /// Data recording period - /// - [JsonConverter(typeof(KlineIntervalConverter))] - public KlineInterval Period { get; set; } - - } -} diff --git a/ByBit.Net/Objects/Models/BybitOpenInterest.cs b/ByBit.Net/Objects/Models/BybitOpenInterest.cs deleted file mode 100644 index af41c290..00000000 --- a/ByBit.Net/Objects/Models/BybitOpenInterest.cs +++ /dev/null @@ -1,27 +0,0 @@ -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Open interest info - /// - public class BybitOpenInterest - { - /// - /// Open interest value - /// - [JsonProperty("open_interest")] - public decimal OpenInterest { get; set; } - /// - /// Date timestamp - /// - [JsonConverter(typeof(DateTimeConverter))] - public DateTime Timestamp { get; set; } - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - } -} diff --git a/ByBit.Net/Objects/Models/BybitOrder.cs b/ByBit.Net/Objects/Models/BybitOrder.cs deleted file mode 100644 index b13c97ba..00000000 --- a/ByBit.Net/Objects/Models/BybitOrder.cs +++ /dev/null @@ -1,113 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Order info - /// - public abstract class BybitOrder: BybitOrderBase - { - /// - /// Order id - /// - [JsonProperty("order_id")] - public override string Id { get; set; } = string.Empty; - /// - /// Order status - /// - [JsonProperty("order_status"), JsonConverter(typeof(OrderStatusConverter))] - public OrderStatus? Status { get; set; } - /// - /// Time of last fill - /// - [JsonProperty("last_exec_time"), JsonConverter(typeof(DateTimeConverter))] - public DateTime? LastTradeTime { get; set; } - /// - /// Price of last fill - /// - [JsonProperty("last_exec_price")] - public decimal? LastTradePrice { get; set; } - /// - /// Quote quantity filled - /// - public abstract decimal? QuoteQuantityFilled { get; set; } - /// - /// Base quantity filled - /// - public abstract decimal? BaseQuantityFilled { get; set; } - /// - /// Fee paid - /// - [JsonProperty("cum_exec_fee")] - public decimal? Fee { get; set; } - /// - /// Reason for reject - /// - [JsonProperty("reject_reason")] - public string? RejectReason { get; set; } - /// - /// Client order id - /// - [JsonProperty("order_link_id")] - public string? ClientOrderId { get; set; } - /// - /// Take profit price - /// - [JsonProperty("take_profit")] - public decimal? TakeProfit { get; set; } - /// - /// Stop loss price - /// - [JsonProperty("stop_loss")] - public decimal? StopLoss { get; set; } - /// - /// Take profit trigger type - /// - [JsonProperty("tp_trigger_by"), JsonConverter(typeof(TriggerTypeConverter))] - public TriggerType? TakeProfitTriggerType { get; set; } - /// - /// Stop loss trigger type - /// - [JsonProperty("sl_trigger_by"), JsonConverter(typeof(TriggerTypeConverter))] - public TriggerType? StopLossTriggerType { get; set; } - /// - /// True means close order, false means open position - /// - [JsonProperty("reduce_only")] - public bool? ReduceOnly { get; set; } - /// - /// Is close on trigger order - /// - [JsonProperty("close_on_trigger")] - public bool? CloseOnTrigger { get; set; } - } - - /// - public class BybitUsdPerpetualOrder : BybitOrder - { - /// - [JsonProperty("cum_exec_value")] - public override decimal? QuoteQuantityFilled { get; set; } - - /// - [JsonProperty("cum_exec_qty")] - public override decimal? BaseQuantityFilled { get; set; } - } - - /// - public class BybitInverseOrder : BybitOrder - { - /// - [JsonProperty("cum_exec_qty")] - public override decimal? QuoteQuantityFilled { get; set; } - - /// - [JsonProperty("cum_exec_value")] - public override decimal? BaseQuantityFilled { get; set; } - } - -} diff --git a/ByBit.Net/Objects/Models/BybitOrderBase.cs b/ByBit.Net/Objects/Models/BybitOrderBase.cs deleted file mode 100644 index 1d99e341..00000000 --- a/ByBit.Net/Objects/Models/BybitOrderBase.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Order data - /// - public abstract class BybitOrderBase - { - /// - /// Id - /// - public abstract string Id { get; set; } - /// - /// User id - /// - [JsonProperty("user_id")] - public long UserId { get; set; } - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Order side - /// - [JsonConverter(typeof(OrderSideConverter))] - public OrderSide Side { get; set; } - /// - /// Order type - /// - [JsonProperty("order_type"), JsonConverter(typeof(OrderTypeConverter))] - public OrderType Type { get; set; } - /// - /// Order price - /// - public decimal Price { get; set; } - /// - /// Order quantity - /// - [JsonProperty("qty")] - public decimal Quantity { get; set; } - /// - /// Time in force - /// - [JsonProperty("time_in_force"), JsonConverter(typeof(TimeInForceConverter))] - public TimeInForce TimeInForce { get; set; } - - /// - /// The estimated value corresponding to the number of remaining orders - /// - [JsonProperty("leaves_value")] - public decimal? LeavesValue { get; set; } - /// - /// Number of unfilled contracts from the order's size - /// - [JsonProperty("leaves_qty")] - public decimal? LeavesQuantity { get; set; } - /// - /// Creation time - /// - [JsonProperty("created_at")] - public DateTime? CreateTime { get; set; } - [JsonProperty("created_time"), JsonConverter(typeof(DateTimeConverter))] - internal DateTime? _createTime { get => CreateTime; set => CreateTime = value; } - [JsonProperty("create_time"), JsonConverter(typeof(DateTimeConverter))] - internal DateTime? _createTime2 { get => CreateTime; set => CreateTime = value; } - /// - /// Update time - /// - [JsonProperty("updated_at")] - public DateTime? UpdateTime { get; set; } - [JsonProperty("updated_time"), JsonConverter(typeof(DateTimeConverter))] - internal DateTime? _updateTime { get => UpdateTime; set => UpdateTime = value; } - [JsonProperty("update_time"), JsonConverter(typeof(DateTimeConverter))] - internal DateTime? _updateTime2 { get => UpdateTime; set => UpdateTime = value; } - /// - /// Trigger scenario for cancel operation - /// - [JsonProperty("cancel_type")] - public string? CancelType { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitOrderBookEntry.cs b/ByBit.Net/Objects/Models/BybitOrderBookEntry.cs deleted file mode 100644 index c15bc9cf..00000000 --- a/ByBit.Net/Objects/Models/BybitOrderBookEntry.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net.Interfaces; -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Order book entry - /// - public class BybitOrderBookEntry: ISymbolOrderBookEntry - { - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Price of the entry - /// - public decimal Price { get; set; } - /// - /// Quantity of the entry - /// - [JsonProperty("size")] - public decimal Quantity { get; set; } - /// - /// Side of the entry - /// - [JsonConverter(typeof(OrderSideConverter))] - public OrderSide Side { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitOrderId.cs b/ByBit.Net/Objects/Models/BybitOrderId.cs deleted file mode 100644 index 8f24aea8..00000000 --- a/ByBit.Net/Objects/Models/BybitOrderId.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Order id - /// - public class BybitOrderId - { - /// - /// Order id - /// - [JsonProperty("order_id")] - public string OrderId { get; set; } = string.Empty; - } -} diff --git a/ByBit.Net/Objects/Models/BybitPnlEntry.cs b/ByBit.Net/Objects/Models/BybitPnlEntry.cs deleted file mode 100644 index 2fb1bbf9..00000000 --- a/ByBit.Net/Objects/Models/BybitPnlEntry.cs +++ /dev/null @@ -1,105 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Profit and loss entry - /// - public class BybitPnlEntry - { - /// - /// Position id - /// - public long Id { get; set; } - /// - /// User id - /// - [JsonProperty("user_id")] - public long UserId { get; set; } - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Order id - /// - [JsonProperty("order_id")] - public string OrderId { get; set; } = string.Empty; - /// - /// Order side - /// - [JsonConverter(typeof(OrderSideConverter))] - public OrderSide Side { get; set; } - /// - /// Order quantity - /// - [JsonProperty("qty")] - public decimal Quantity { get; set; } - /// - /// Order price - /// - [JsonProperty("order_price")] - public decimal OrderPrice { get; set; } - /// - /// Order type - /// - [JsonProperty("order_type")] - [JsonConverter(typeof(OrderTypeConverter))] - public OrderType OrderType { get; set; } - /// - /// Trade type - /// - [JsonProperty("exec_type")] - [JsonConverter(typeof(TradeTypeConverter))] - public TradeType Type { get; set; } - /// - /// The corresponding closing size of the closing order - /// - [JsonProperty("closed_size")] - public decimal ClosedQuantity { get; set; } - /// - /// Closed position value - /// - [JsonProperty("cum_entry_value")] - public decimal TotalEntryValue { get; set; } - /// - /// Average entry price - /// - [JsonProperty("avg_entry_price")] - public decimal AverageEntryPrice { get; set; } - /// - /// Cumulative trading value of position closing orders - /// - [JsonProperty("cum_exit_value")] - public decimal TotalExitValue { get; set; } - /// - /// Average exit price - /// - [JsonProperty("avg_exit_price")] - public decimal AverageExitPrice { get; set; } - /// - /// Closed Profit and Loss - /// - [JsonProperty("closed_pnl")] - public decimal ClosedPnl { get; set; } - /// - /// The number of fills in a single order - /// - [JsonProperty("fill_count")] - public int Fills { get; set; } - /// - /// In Isolated Margin mode, the value is set by user. In Cross Margin mode, the value is the max leverage at current risk level - /// - public decimal Leverage { get; set; } - /// - /// Creation time - /// - [JsonProperty("created_at")] - [JsonConverter(typeof(DateTimeConverter))] - public DateTime CreateTime { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitPosition.cs b/ByBit.Net/Objects/Models/BybitPosition.cs deleted file mode 100644 index 1c7d4e81..00000000 --- a/ByBit.Net/Objects/Models/BybitPosition.cs +++ /dev/null @@ -1,92 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Position info - /// - public class BybitPosition: BybitPositionBase - { - /// - /// Id - /// - public string Id { get; set; } = string.Empty; - /// - /// Whether the current data is valid. Only use data when IsValid is true - /// - public bool IsValid { get; set; } - /// - /// Isolated margin mode - /// - [JsonProperty("is_isolated")] - public bool IsIsolated { get; set; } - /// - /// Effective leverage - /// - [JsonProperty("effective_leverage")] - public decimal EffectiveLeverage { get; set; } - /// - /// Deleverage indicator level (1,2,3,4,5) - /// - [JsonProperty("deleverage_indicator")] - public int DeleverageIndicator { get; set; } - /// - /// Position status - /// - [JsonProperty("position_status"), JsonConverter(typeof(PositionStatusConverter))] - public PositionStatus PositionStatus { get; set; } - /// - /// Unrealized pnl - /// - [JsonProperty("unrealised_pnl")] - public decimal UnrealizedPnl { get; set; } - /// - /// Cross sequence - /// - [JsonProperty("cross_seq")] - public long CrossSequence { get; set; } - /// - /// The account creation time - /// - [JsonProperty("created_at")] - public DateTime CreateTime { get; set; } - /// - /// Update time - /// - [JsonProperty("updated_at")] - public DateTime UpdateTime { get; set; } - /// - /// Stop loss and take profit mode - /// - [JsonProperty("tp_sl_mode"), JsonConverter(typeof(StopLossTakeProfitModeConverter))] - public StopLossTakeProfitMode StopMode { get; set; } - /// - /// Position closing fee occupied (your opening fee + expected maximum closing fee) - /// - [JsonProperty("occ_closing_fee")] - public decimal ClosingFee { get; set; } - /// - /// Pre-occupied order margin - /// - [JsonProperty("order_margin")] - public decimal OrderMargin { get; set; } - /// - /// Wallet balance - /// - [JsonProperty("wallet_balance")] - public decimal WalletBalance { get; set; } - /// - /// Position sequence - /// - [JsonProperty("position_seq")] - public long PositionSequence { get; set; } - /// - /// Accumelated fee - /// - [JsonProperty("cum_commission")] - public decimal? AccumulatedFee { get; set; } -} -} diff --git a/ByBit.Net/Objects/Models/BybitPositionBase.cs b/ByBit.Net/Objects/Models/BybitPositionBase.cs deleted file mode 100644 index 0be1b36e..00000000 --- a/ByBit.Net/Objects/Models/BybitPositionBase.cs +++ /dev/null @@ -1,109 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Position info - /// - public class BybitPositionBase - { - /// - /// User id - /// - [JsonProperty("user_id")] - public long UserId { get; set; } - /// - /// Risk id - /// - [JsonProperty("risk_id")] - public long RiskId { get; set; } - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Side - /// - [JsonConverter(typeof(PositionSideConverter))] - public PositionSide Side { get; set; } - /// - /// Quantity - /// - [JsonProperty("size")] - public decimal Quantity { get; set; } - /// - /// Value - /// - [JsonProperty("position_value")] - public decimal PositionValue { get; set; } - /// - /// Average entry price - /// - [JsonProperty("entry_price")] - public decimal EntryPrice { get; set; } - /// - /// In Isolated Margin mode, the value is set by user. In Cross Margin mode, the value is the max leverage at current risk level - /// - public decimal Leverage { get; set; } - /// - /// Position margin - /// - [JsonProperty("position_margin")] - public decimal PositionMargin { get; set; } - /// - /// Liquidation price - /// - [JsonProperty("liq_price")] - public decimal? LiquidationPrice { get; set; } - /// - /// Bankruptcy price - /// - [JsonProperty("bust_price")] - public decimal BankruptcyPrice { get; set; } - - /// - /// Pre-occupied funding fee: calculated from position qty and current funding fee - /// - [JsonProperty("occ_funding_fee")] - public decimal FundingFee { get; set; } - /// - /// Take profit price - /// - [JsonProperty("take_profit")] - public decimal TakeProfit { get; set; } - /// - /// Stop loss price - /// - [JsonProperty("stop_loss")] - public decimal StopLoss { get; set; } - /// - /// Trailing stop - /// - [JsonProperty("trailing_stop")] - public decimal TrailingStop { get; set; } - /// - /// Whether to add margin automatically - /// - [JsonProperty("auto_add_margin")] - [JsonConverter(typeof(BoolConverter))] - public bool AutoAddMargin { get; set; } - /// - /// Today's realized pnl - /// - [JsonProperty("realised_pnl")] - public decimal RealizedPnl { get; set; } - /// - /// Accumulated realized pnl (all-time total) - /// - [JsonProperty("cum_realised_pnl")] - public decimal TotalRealizedPnl { get; set; } - /// - /// Position mode - /// - [JsonProperty("position_idx"), JsonConverter(typeof(PositionModeConverter))] - public PositionMode PositionMode { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitPositionUsd.cs b/ByBit.Net/Objects/Models/BybitPositionUsd.cs deleted file mode 100644 index f0cf964f..00000000 --- a/ByBit.Net/Objects/Models/BybitPositionUsd.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Position info - /// - public class BybitPositionUsd: BybitPositionBase - { - /// - /// Whether the current data is valid. Only use data when IsValid is true - /// - [JsonProperty("is_valid")] - public bool IsValid { get; set; } - /// - /// Is isolated margin mode - /// - [JsonProperty("is_isolated")] - public bool IsIsolated { get; set; } - /// - /// Quantity which can be closed - /// - [JsonProperty("free_qty")] - public decimal FreeQuantity { get; set; } - /// - /// Stop loss and take profit mode - /// - [JsonProperty("tp_sl_mode"), JsonConverter(typeof(StopLossTakeProfitModeConverter))] - public StopLossTakeProfitMode StopLossTakeProfitMode { get; set; } - /// - /// Unrealized profit and loss - /// - [JsonProperty("unrealised_pnl")] - public decimal UnrealizedPnl { get; set; } - - /// - /// Deleverage indicator level (1,2,3,4,5) - /// - [JsonProperty("deleverage_indicator")] - public int DeleverageIndicator { get; set; } - /// - /// Pre-occupancy closing fee - /// - [JsonProperty("occ_closing_fee")] - public decimal ClosingFee { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitPredictedFunding.cs b/ByBit.Net/Objects/Models/BybitPredictedFunding.cs deleted file mode 100644 index fa34c445..00000000 --- a/ByBit.Net/Objects/Models/BybitPredictedFunding.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Predicted funding rate and fee - /// - public class BybitPredictedFunding - { - /// - /// Predicted funding rate - /// - [JsonProperty("predicted_funding_rate")] - public decimal PredictedFundingRate { get; set; } - /// - /// Predicted funding fee - /// - [JsonProperty("predicted_funding_fee")] - public decimal PredictedFundingFee { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitRiskId.cs b/ByBit.Net/Objects/Models/BybitRiskId.cs deleted file mode 100644 index 8184cca9..00000000 --- a/ByBit.Net/Objects/Models/BybitRiskId.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Risk id - /// - public class BybitRiskId - { - /// - /// Risk id - /// - [JsonProperty("risk_id")] - public long RiskId { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitRiskLimit.cs b/ByBit.Net/Objects/Models/BybitRiskLimit.cs deleted file mode 100644 index acb2b85c..00000000 --- a/ByBit.Net/Objects/Models/BybitRiskLimit.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Risk limit info - /// - public class BybitRiskLimit - { - /// - /// Risk id - /// - public long Id { get; set; } - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Risk limit - /// - public decimal Limit { get; set; } - /// - /// Maintain margin - /// - [JsonProperty("maintain_margin")] - public decimal MaintainMargin { get; set; } - /// - /// Starting margin - /// - [JsonProperty("starting_margin")] - public decimal StartingMargin { get; set; } - /// - /// Section - /// - public IEnumerable Section { get; set; } = Array.Empty(); - /// - /// Is lowest risk - /// - [JsonProperty("is_lowest_risk")] - public bool IsLowestRisk { get; set; } - /// - /// Create time - /// - [JsonProperty("created_at")] - public DateTime CreateTime { get; set; } - /// - /// Update time - /// - [JsonProperty("updated_at")] - public DateTime UpdateTime { get; set; } - /// - /// Max leverage - /// - [JsonProperty("max_leverage")] - public decimal MaxLeverage { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitStopOrderId.cs b/ByBit.Net/Objects/Models/BybitStopOrderId.cs deleted file mode 100644 index bfc5348d..00000000 --- a/ByBit.Net/Objects/Models/BybitStopOrderId.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Stop order id - /// - public class BybitStopOrderId - { - /// - /// Stop order id - /// - [JsonProperty("stop_order_id")] - public string StopOrderId { get; set; } = string.Empty; - } -} diff --git a/ByBit.Net/Objects/Models/BybitSubAccountList.cs b/ByBit.Net/Objects/Models/BybitSubAccountList.cs deleted file mode 100644 index fbbfa9f5..00000000 --- a/ByBit.Net/Objects/Models/BybitSubAccountList.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Sub account list - /// - public class BybitSubAccountList - { - /// - /// Sub account ids - /// - [JsonProperty("sub_user_id")] - public IEnumerable SubAccountIds { get; set; } = Array.Empty(); - } -} diff --git a/ByBit.Net/Objects/Models/BybitSymbol.cs b/ByBit.Net/Objects/Models/BybitSymbol.cs deleted file mode 100644 index c8e4064a..00000000 --- a/ByBit.Net/Objects/Models/BybitSymbol.cs +++ /dev/null @@ -1,132 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Symbol info - /// - public class BybitSymbol - { - /// - /// Symbol name - /// - public string Name { get; set; } = string.Empty; - /// - /// Alias - /// - public string Alias { get; set; } = string.Empty; - /// - /// Symbol status - /// - [JsonConverter(typeof(SymbolStatusConverter))] - public SymbolStatus Status { get; set; } - /// - /// Base currency of the symbol - /// - [JsonProperty("base_currency")] - public string BaseCurrency { get; set; } = string.Empty; - /// - /// Quote currency of the symbol - /// - [JsonProperty("quote_currency")] - public string QuoteCurrency { get; set; } = string.Empty; - /// - /// Price precision (amount of decimals) - /// - [JsonProperty("price_scale")] - public int PricePrecision { get; set; } - /// - /// Taker fee rate - /// - [JsonProperty("taker_fee")] - public decimal TakerFee { get; set; } - /// - /// Maker fee rate - /// - [JsonProperty("maker_fee")] - public decimal MakerFee { get; set; } - /// - /// Leverage filter - /// - [JsonProperty("leverage_filter")] - public BybitLeverageFilter LeverageFilter { get; set; } = default!; - /// - /// Price filter - /// - [JsonProperty("price_filter")] - public BybitPriceFilter PriceFilter { get; set; } = default!; - /// - /// Lot size filter - /// - [JsonProperty("lot_size_filter")] - public BybitLotSizeFilter LotSizeFilter { get; set; } = default!; - } - - /// - /// Leverage rules - /// - public class BybitLeverageFilter - { - /// - /// Minimal leverage - /// - [JsonProperty("min_leverage")] - public decimal MinLeverage { get; set; } - /// - /// Maximum leverage - /// - [JsonProperty("max_leverage")] - public decimal MaxLeverage { get; set; } - /// - /// Leverage step - /// - [JsonProperty("leverage_step")] - public decimal LeverageStep { get; set; } - } - - /// - /// Price rules - /// - public class BybitPriceFilter - { - /// - /// Minimal price - /// - [JsonProperty("min_price")] - public decimal MinPrice { get; set; } - /// - /// Maximum price - /// - [JsonProperty("max_price")] - public decimal MaxPrice { get; set; } - /// - /// Tick size - /// - [JsonProperty("tick_size")] - public decimal TickSize { get; set; } - } - - /// - /// Lot size rules - /// - public class BybitLotSizeFilter - { - /// - /// Minimal quantity - /// - [JsonProperty("min_trading_qty")] - public decimal MinQuantity { get; set; } - /// - /// Maximum quantity - /// - [JsonProperty("max_trading_qty")] - public decimal MaxQuantity { get; set; } - /// - /// Quantity step - /// - [JsonProperty("qty_step")] - public decimal QuantityStep { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitTicker.cs b/ByBit.Net/Objects/Models/BybitTicker.cs deleted file mode 100644 index 0747a379..00000000 --- a/ByBit.Net/Objects/Models/BybitTicker.cs +++ /dev/null @@ -1,143 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Ticker - /// - public class BybitTicker - { - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Best bid price available - /// - [JsonProperty("bid_price")] - public decimal BestBidPrice { get; set; } - /// - /// Best ask price available - /// - [JsonProperty("ask_price")] - public decimal BestAskPrice { get; set; } - /// - /// Last trade price - /// - [JsonProperty("last_price")] - public decimal LastPrice { get; set; } - /// - /// Price change direction - /// - [JsonProperty("last_tick_direction"), JsonConverter(typeof(TickDirectionConverter))] - public TickDirection LastTickDirection { get; set; } - /// - /// Price 24 hours ago - /// - [JsonProperty("prev_price_24h")] - public decimal? Price24H { get; set; } - /// - /// Price change percentage since 24 hours ago - /// - [JsonProperty("price_24h_pcnt")] - public decimal? PriceChangePercentage24H { get; set; } - /// - /// High price in the last 24 hours - /// - [JsonProperty("high_price_24h")] - public decimal? HighPrice24H { get; set; } - /// - /// Low price in the last 24 hours - /// - [JsonProperty("low_price_24h")] - public decimal? LowPrice24H { get; set; } - /// - /// Pirce 1 hour ago - /// - [JsonProperty("prev_price_1h")] - public decimal? Price1H { get; set; } - /// - /// Price change percentage since 1 hour ago - /// - [JsonProperty("price_1h_pcnt")] - public decimal? PriceChangePercentage1H { get; set; } - /// - /// Mark price - /// - [JsonProperty("mark_price")] - public decimal? MarkPrice { get; set; } - /// - /// Index price - /// - [JsonProperty("index_price")] - public decimal? IndexPrice { get; set; } - /// - /// Open interest - /// - [JsonProperty("open_interest")] - public decimal? OpenInterest { get; set; } - /// - /// Open position value - /// - [JsonProperty("open_value")] - public decimal? OpenValue { get; set; } - /// - /// Total turnover - /// - [JsonProperty("total_turnover")] - public decimal? TotalTurnover { get; set; } - /// - /// Turnover in the last 24 hours - /// - [JsonProperty("turnover_24h")] - public decimal? Turnover24H { get; set; } - /// - /// Total volume - /// - [JsonProperty("total_volume")] - public decimal? TotalVolume { get; set; } - /// - /// Volume in the last 24 hours - /// - [JsonProperty("volume_24h")] - public decimal? Volume24H { get; set; } - /// - /// Funding rate - /// - [JsonProperty("funding_rate")] - public decimal? FundingRate { get; set; } - /// - /// Predicted funding rate - /// - [JsonProperty("predicted_funding_rate")] - public decimal? PredictedFundingRate { get; set; } - /// - /// Next settlement time of capital cost - /// - [JsonProperty("next_funding_time")] - public DateTime? NextFundingTime { get; set; } - /// - /// Countdown of settlemnt capital cost - /// - [JsonProperty("countdown_hour")] - public int CountdownHour { get; set; } - /// - /// Delivery fee rate of futures contract - /// - [JsonProperty("delivery_fee_rate")] - public decimal? DeliveryFeeRate { get; set; } - /// - /// Predicted delivery price of futures contract - /// - [JsonProperty("predicted_delivery_price")] - public decimal? PredictedDeliveryPrice { get; set; } - /// - /// Delivery time of futures contract - /// - [JsonProperty("delivery_time")] - public DateTime? DeliveryTime { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitTpSlMode.cs b/ByBit.Net/Objects/Models/BybitTpSlMode.cs deleted file mode 100644 index 16b23380..00000000 --- a/ByBit.Net/Objects/Models/BybitTpSlMode.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Mode info - /// - public class BybitTpSlMode - { - /// - /// New mode - /// - [JsonProperty("tp_sl_mode"), JsonConverter(typeof(StopLossTakeProfitModeConverter))] - public StopLossTakeProfitMode Mode { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitTrade.cs b/ByBit.Net/Objects/Models/BybitTrade.cs deleted file mode 100644 index e61cb955..00000000 --- a/ByBit.Net/Objects/Models/BybitTrade.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Trade info - /// - public class BybitTrade - { - /// - /// Trade id - /// - public long Id { get; set; } - - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Trade price - /// - public decimal Price { get; set; } - /// - /// Trade quantity - /// - [JsonProperty("qty")] - public decimal Quantity { get; set; } - /// - /// Side of the trade - /// - [JsonConverter(typeof(OrderSideConverter))] - public OrderSide Side { get; set; } - /// - /// Timestamp of the trade - /// - [JsonProperty("time")] - public DateTime? Timestamp { get; set; } - [JsonProperty("trade_time_ms"), JsonConverter(typeof(DateTimeConverter))] - internal DateTime Time { set => Timestamp = value; get => Timestamp ?? default; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitTransfer.cs b/ByBit.Net/Objects/Models/BybitTransfer.cs deleted file mode 100644 index 9ecbb6c0..00000000 --- a/ByBit.Net/Objects/Models/BybitTransfer.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Transfer id - /// - public class BybitTransfer - { - /// - /// Transfer id - /// - [JsonProperty("transfer_id")] - public string TransferId { get; set; } = string.Empty; - } -} diff --git a/ByBit.Net/Objects/Models/BybitTransferDetails.cs b/ByBit.Net/Objects/Models/BybitTransferDetails.cs deleted file mode 100644 index 69210e9b..00000000 --- a/ByBit.Net/Objects/Models/BybitTransferDetails.cs +++ /dev/null @@ -1,76 +0,0 @@ -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Transfer details - /// - public class BybitTransferDetails - { - /// - /// Transfer id - /// - [JsonProperty("transfer_id")] - public string TransferId { get; set; } = string.Empty; - /// - /// Asset - /// - [JsonProperty("coin")] - public string Asset { get; set; } = string.Empty; - /// - /// Quantity - /// - [JsonProperty("amount")] - public decimal Quantity { get; set; } - /// - /// Timestamp - /// - [JsonConverter(typeof(DateTimeConverter))] - public DateTime Timestamp { get; set; } - /// - /// Status - /// - public TransferStatus Status { get; set; } - } - - /// - /// Transfer details - /// - public class BybitInternalTransferDetails: BybitTransferDetails - { - /// - /// From account type - /// - [JsonProperty("from_account_type")] - public AccountType FromAccountType { get; set; } - /// - /// To account type - /// - [JsonProperty("to_account_type")] - public AccountType ToAccountType { get; set; } - } - - /// - /// Sub account transfer details - /// - public class BybitSubAccountTransferDetails: BybitTransferDetails - { - /// - /// User id - /// - [JsonProperty("user_id")] - public long UserId { get; set; } - /// - /// Sub account id - /// - [JsonProperty("sub_user_id")] - public long SubAccountId { get; set; } - /// - /// Type - /// - public TransferType Type { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitTransferId.cs b/ByBit.Net/Objects/Models/BybitTransferId.cs deleted file mode 100644 index c4688824..00000000 --- a/ByBit.Net/Objects/Models/BybitTransferId.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Transfer id - /// - public class BybitTransferId - { - /// - /// Transfer id - /// - [JsonProperty("transfer_id")] - public string TransferId { get; set; } = string.Empty; - } -} diff --git a/ByBit.Net/Objects/Models/BybitUniversalTransfer.cs b/ByBit.Net/Objects/Models/BybitUniversalTransfer.cs deleted file mode 100644 index 0458fdb2..00000000 --- a/ByBit.Net/Objects/Models/BybitUniversalTransfer.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Universal transfer info - /// - public class BybitUniversalTransfer - { - /// - /// Tranfer id - /// - [JsonProperty("transfer_id")] - public string TransferId { get; set; } = string.Empty; - /// - /// Asset - /// - [JsonProperty("coin")] - public string Asset { get; set; } = string.Empty; - /// - /// Quantity - /// - [JsonProperty("amount")] - public decimal Quantity { get; set; } - /// - /// Status - /// - [JsonConverter(typeof(EnumConverter))] - public UniversalTransferStatus Status { get; set; } - /// - /// From account type - /// - [JsonConverter(typeof(EnumConverter))] - public AccountType FromAccountType { get; set; } - /// - /// To account type - /// - [JsonConverter(typeof(EnumConverter))] - public AccountType ToAccountType { get; set; } - /// - /// From member id - /// - public string FromMemberId { get; set; } = string.Empty; - /// - /// To member id - /// - public string ToMemberId { get; set; } = string.Empty; - /// - /// Timestamp - /// - [JsonConverter(typeof(DateTimeConverter))] - public DateTime Timestamp { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitUserTrade.cs b/ByBit.Net/Objects/Models/BybitUserTrade.cs deleted file mode 100644 index 8f0fb0af..00000000 --- a/ByBit.Net/Objects/Models/BybitUserTrade.cs +++ /dev/null @@ -1,119 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// User trade info - /// - public class BybitUserTrade - { - /// - /// The corresponding closing size of the closing order - /// - [JsonProperty("closed_size")] - public decimal ClosedQuantity { get; set; } - /// - /// Cross sequence - /// - [JsonProperty("cross_seq")] - public long CrossSequence { get; set; } - /// - /// Transaction fee - /// - [JsonProperty("exec_fee")] - public decimal Fee { get; set; } - /// - /// Trade id - /// - [JsonProperty("exec_id")] - public string Id { get; set; } = string.Empty; - /// - /// Price - /// - [JsonProperty("exec_price")] - public decimal Price { get; set; } - /// - /// Quantity - /// - [JsonProperty("exec_qty")] - public decimal Quantity { get; set; } - /// - /// Trade type - /// - [JsonProperty("exec_type"), JsonConverter(typeof(TradeTypeConverter))] - public TradeType Type { get; set; } - /// - /// Value of trade - /// - [JsonProperty("exec_value")] - public decimal Value { get; set; } - /// - /// Maker or taker fee rate - /// - [JsonProperty("fee_rate")] - public decimal FeeRate { get; set; } - /// - /// Liquiditry, only valid while Type is Trade, AdlTrade, BustTrade - /// - [JsonProperty("last_liquidity_ind"), JsonConverter(typeof(TradeLiquidityConverter))] - public TradeLiquidity Liquidity { get; set; } - /// - /// Remaining quantity - /// - [JsonProperty("leaves_qty")] - public decimal QuantityRemaining { get; set; } - /// - /// The sequence of the transaction in this cross sequence data package - /// - [JsonProperty("nth_fill")] - public decimal FillNumber { get; set; } - /// - /// Order id - /// - [JsonProperty("order_id")] - public string OrderId { get; set; } = string.Empty; - /// - /// Client order id - /// - [JsonProperty("order_link_id")] - public string ClientOrderId { get; set; } = string.Empty; - /// - /// Price of the order - /// - [JsonProperty("order_price")] - public decimal OrderPrice { get; set; } - /// - /// Quantity of the order - /// - [JsonProperty("order_qty")] - public decimal OrderQuantity { get; set; } - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Type of the order - /// - [JsonProperty("order_type"), JsonConverter(typeof(OrderTypeConverter))] - public OrderType? OrderType { get; set; } - /// - /// Side of the order - /// - [JsonProperty("side"), JsonConverter(typeof(OrderSideConverter))] - public OrderSide OrderSide { get; set; } - /// - /// User id - /// - [JsonProperty("user_id")] - public long UserId { get; set; } - /// - /// Trade time - /// - [JsonProperty("trade_time_ms"), JsonConverter(typeof(DateTimeConverter))] - public DateTime Timestamp { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitWalletFundRecord.cs b/ByBit.Net/Objects/Models/BybitWalletFundRecord.cs deleted file mode 100644 index fa52b2b2..00000000 --- a/ByBit.Net/Objects/Models/BybitWalletFundRecord.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Wallet fund record - /// - public class BybitWalletFundRecord - { - /// - /// Record id - /// - public long Id { get; set; } - /// - /// User id - /// - [JsonProperty("user_id")] - public long UserId { get; set; } - /// - /// Asset - /// - [JsonProperty("coin")] - public string Asset { get; set; } = string.Empty; - /// - /// Wallet id - /// - [JsonProperty("wallet_id")] - public long WalletId { get; set; } - /// - /// Transfer type - /// - public string Type { get; set; } = string.Empty; - /// - /// Quantity - /// - [JsonProperty("amount")] - public decimal Quantity { get; set; } - /// - /// Transaction id - /// - [JsonProperty("tx_id")] - public string? TransactionId { get; set; } - /// - /// Address - /// - public string? Address { get; set; } - /// - /// Wallet balance - /// - [JsonProperty("wallet_balance")] - public decimal WalletBalance { get; set; } - /// - /// Execution time - /// - [JsonProperty("exec_time")] - public DateTime Timestamp { get; set; } - /// - /// Cross sequence - /// - [JsonProperty("cross_seq")] - public decimal CrossSequence { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/BybitWithdraw.cs b/ByBit.Net/Objects/Models/BybitWithdraw.cs deleted file mode 100644 index a4d04cfa..00000000 --- a/ByBit.Net/Objects/Models/BybitWithdraw.cs +++ /dev/null @@ -1,68 +0,0 @@ -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Withdraw info - /// - public class BybitWithdraw - { - /// - /// Asset - /// - [JsonProperty("coin")] - public string Asset { get; set; } = string.Empty; - /// - /// Network - /// - [JsonProperty("chain")] - public string Network { get; set; } = string.Empty; - /// - /// Quantity - /// - [JsonProperty("amount")] - public decimal Quantity { get; set; } - /// - /// Trasaction id - /// - [JsonProperty("tx_id")] - public string TransactionId { get; set; } = string.Empty; - /// - /// Status - /// - public string Status { get; set; } = string.Empty; - /// - /// To address - /// - [JsonProperty("to_address")] - public string ToAddress { get; set; } = string.Empty; - /// - /// Tag - /// - public string Tag { get; set; } = string.Empty; - /// - /// Withdrawal fee - /// - [JsonProperty("withdraw_fee")] - public decimal? WithdrawFee { get; set; } - /// - /// Creation time - /// - [JsonProperty("create_time")] - [JsonConverter(typeof(DateTimeConverter))] - public DateTime CreateTime { get; set; } - /// - /// Last update time - /// - [JsonProperty("update_time")] - [JsonConverter(typeof(DateTimeConverter))] - public DateTime UpdateTime { get; set; } - /// - /// Withdrawal id - /// - [JsonProperty("withdraw_id")] - public string WithdrawId { get; set; } = string.Empty; - } -} diff --git a/ByBit.Net/Objects/Models/BybitWithdrawal.cs b/ByBit.Net/Objects/Models/BybitWithdrawal.cs deleted file mode 100644 index d6884a16..00000000 --- a/ByBit.Net/Objects/Models/BybitWithdrawal.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Withdrawal info - /// - public class BybitWithdrawal - { - /// - /// Withdrawal id - /// - public long Id { get; set; } - /// - /// User id - /// - [JsonProperty("user_id")] - public long UserId { get; set; } - /// - /// The asset - /// - [JsonProperty("coin")] - public string Asset { get; set; } = string.Empty; - /// - /// Status - /// - [JsonConverter(typeof(WithdrawStatusConverter))] - public WithdrawStatus Status { get; set; } - /// - /// Quantity - /// - [JsonProperty("amount")] - public decimal Quantity { get; set; } - /// - /// Fee paid - /// - public decimal Fee { get; set; } - /// - /// Withdrawal address - /// - public string Address { get; set; } = string.Empty; - /// - /// Transaction id - /// - [JsonProperty("tx_id")] - public string? TransactionId { get; set; } - /// - /// Time submitted - /// - [JsonProperty("submited_at")] - public DateTime SubmitTime { get; set; } - /// - /// Time last updated - /// - [JsonProperty("updated_at")] - public DateTime UpdateTime { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/CoinBalanceQuery.cs b/ByBit.Net/Objects/Models/CoinBalanceQuery.cs deleted file mode 100755 index bcb14c34..00000000 --- a/ByBit.Net/Objects/Models/CoinBalanceQuery.cs +++ /dev/null @@ -1,71 +0,0 @@ -using Bybit.Net.Enums; -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models -{ - /// - /// Transfer coin balance - /// - public class CoinBalanceQuery - { - /// - /// Account type - /// - [JsonProperty("accountType")] - public AccountType AccountType { get; set; } - - /// - /// Account business subtype - /// - [JsonProperty("bizType")] - public int BizType { get; set; } - - /// - /// AccountID - /// - [JsonProperty("accountId")] - public int AccountId { get; set; } - - /// - /// UserID - /// - [JsonProperty("memberId")] - public int UserId { get; set; } - - /// - /// Balance info - /// - [JsonProperty("balance")] - public QueryBalance Balance { get; set; } = null!; - } - - /// - /// Transfer balance info - /// - public class QueryBalance - { - /// - /// The asset - /// - [JsonProperty("coin")] - public string? Asset { get; set; } - - /// - /// Wallet balance - /// - [JsonProperty("walletBalance")] - public decimal WalletBalance { get; set; } - - /// - /// Transferable balance = available balance - bonus - /// - [JsonProperty("transferBalance")] - public decimal TransferBalance { get; set; } - - /// - /// The bonus - /// - [JsonProperty("bonus")] - public string BonusAmount { get; set; } = string.Empty; - } -} diff --git a/ByBit.Net/Objects/Models/Socket/BybitBalanceUpdate.cs b/ByBit.Net/Objects/Models/Socket/BybitBalanceUpdate.cs deleted file mode 100644 index 7b08a278..00000000 --- a/ByBit.Net/Objects/Models/Socket/BybitBalanceUpdate.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models.Socket -{ - /// - /// Balance update - /// - public class BybitBalanceUpdate - { - /// - /// The asset - /// - [JsonProperty("coin")] - public string? Asset { get; set; } - /// - /// Wallet balance - /// - [JsonProperty("wallet_balance")] - public decimal WalletBalance { get; set; } - /// - /// Available balance = wallet balance - used margin - /// - [JsonProperty("available_balance")] - public decimal AvailableBalance { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Socket/BybitDeltaUpdate.cs b/ByBit.Net/Objects/Models/Socket/BybitDeltaUpdate.cs deleted file mode 100644 index a6b51b05..00000000 --- a/ByBit.Net/Objects/Models/Socket/BybitDeltaUpdate.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Bybit.Net.Objects.Models.Socket -{ - /// - /// Delta update - /// - /// Data type - public class BybitDeltaUpdate - { - /// - /// Delete entries - /// - public IEnumerable Delete { get; set; } = Array.Empty(); - /// - /// Update entries - /// - public IEnumerable Update { get; set; } = Array.Empty(); - /// - /// Insert entries - /// - public IEnumerable Insert { get; set; } = Array.Empty(); - } -} diff --git a/ByBit.Net/Objects/Models/Socket/BybitInsuranceUpdate.cs b/ByBit.Net/Objects/Models/Socket/BybitInsuranceUpdate.cs deleted file mode 100644 index a5e83043..00000000 --- a/ByBit.Net/Objects/Models/Socket/BybitInsuranceUpdate.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models.Socket -{ - /// - /// Insurance update - /// - public class BybitInsuranceUpdate - { - /// - /// Asset - /// - [JsonProperty("currency")] - public string Asset { get; set; } = string.Empty; - /// - /// Timestamp - /// - public DateTime Timestamp { get; set; } - /// - /// Wallet balance - /// - [JsonProperty("wallet_balance")] - public decimal WalletBalance { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Socket/BybitLiquidationUpdate.cs b/ByBit.Net/Objects/Models/Socket/BybitLiquidationUpdate.cs deleted file mode 100644 index 25a1783d..00000000 --- a/ByBit.Net/Objects/Models/Socket/BybitLiquidationUpdate.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models.Socket -{ - /// - /// Liquidation update - /// - public class BybitLiquidationUpdate - { - /// - /// The symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Side - /// - public OrderSide Side { get; set; } - /// - /// Price - /// - public decimal Price { get; set; } - /// - /// Quantity - /// - [JsonProperty("qty")] - public decimal Quantity { get; set; } - /// - /// Timestamp - /// - [JsonConverter(typeof(DateTimeConverter))] - [JsonProperty("time")] - public DateTime Timestamp { get; set;} - } -} diff --git a/ByBit.Net/Objects/Models/Socket/BybitOrderUpdate.cs b/ByBit.Net/Objects/Models/Socket/BybitOrderUpdate.cs deleted file mode 100644 index 1f9119b1..00000000 --- a/ByBit.Net/Objects/Models/Socket/BybitOrderUpdate.cs +++ /dev/null @@ -1,120 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models.Socket -{ - /// - /// Order info - /// - public abstract class BybitOrderUpdate: BybitOrderBase - { - /// - /// Order id - /// - [JsonProperty("order_id")] - public override string Id { get; set; } = string.Empty; - /// - /// Client order id - /// - [JsonProperty("order_link_id")] - public string? ClientOrderId { get; set; } - /// - /// Create type - /// - [JsonProperty("create_type")] - public string CreateType { get; set; } = string.Empty; - /// - /// Order status - /// - [JsonProperty("order_status"), JsonConverter(typeof(OrderStatusConverter))] - public OrderStatus? Status { get; set; } - /// - /// Quote quantity filled - /// - [JsonProperty("cum_exec_value")] - public abstract decimal? QuoteQuantityFilled { get; set; } - /// - /// Base quantity filled - /// - [JsonProperty("cum_exec_qty")] - public abstract decimal? BaseQuantityFilled { get; set; } - /// - /// Fee paid - /// - [JsonProperty("cum_exec_fee")] - public decimal Fee { get; set; } - /// - /// Timestamp - /// - public DateTime Timestamp { get; set; } - /// - /// Take profit price - /// - [JsonProperty("take_profit")] - public decimal? TakeProfit { get; set; } - /// - /// Stop loss price - /// - [JsonProperty("stop_loss")] - public decimal? StopLoss { get; set; } - /// - /// Trailing stop - /// - [JsonProperty("trailing_stop")] - public decimal? TrailingStop { get; set; } - - /// - /// Trailing stop active price - /// - [JsonProperty("trailing_active")] - public decimal? TrailingActive { get; set; } - /// - /// Price of last fill - /// - [JsonProperty("last_exec_price")] - public decimal LastTradePrice { get; set; } - /// - /// True means your position can only reduce in size if this order is triggered - /// - [JsonProperty("reduce_only")] - public bool ReduceOnly { get; set; } - /// - /// For a closing order. It can only reduce your position, not increase it. If the account has insufficient available balance when the closing order is triggered, then other active orders of similar contracts will be cancelled or reduced. It can be used to ensure your stop loss reduces your position regardless of current available margin. - /// - [JsonProperty("close_on_trigger")] - public bool CloseOnTrigger { get; set; } - - /// - /// Position mode (only availaable on USD perpetual) - /// - [JsonConverter(typeof(PositionModeConverter))] - [JsonProperty("position_idx")] - public PositionMode? PositionMode { get; set; } - } - - /// - public class BybitUsdPerpetualOrderUpdate : BybitOrderUpdate - { - /// - [JsonProperty("cum_exec_value")] - public override decimal? QuoteQuantityFilled { get; set; } - - /// - [JsonProperty("cum_exec_qty")] - public override decimal? BaseQuantityFilled { get; set; } - } - - /// - public class BybitInverseOrderUpdate : BybitOrderUpdate - { - /// - [JsonProperty("cum_exec_qty")] - public override decimal? QuoteQuantityFilled { get; set; } - - /// - [JsonProperty("cum_exec_value")] - public override decimal? BaseQuantityFilled { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Socket/BybitPositionUpdate.cs b/ByBit.Net/Objects/Models/Socket/BybitPositionUpdate.cs deleted file mode 100644 index 374a7421..00000000 --- a/ByBit.Net/Objects/Models/Socket/BybitPositionUpdate.cs +++ /dev/null @@ -1,93 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models.Socket -{ - /// - /// Position update - /// - public class BybitPositionUpdate: BybitPositionBase - { - /// - /// Take profit trigger - /// - [JsonProperty("tp_trigger_by"), JsonConverter(typeof(TriggerTypeConverter))] - public TriggerType TakeProfitTriggerBy { get; set; } - /// - /// Stop loss trigger - /// - [JsonProperty("sl_trigger_by"), JsonConverter(typeof(TriggerTypeConverter))] - public TriggerType StopLossTriggeredBy { get; set; } - /// - /// Trailing stop trigger - /// - [JsonProperty("trailing_active")] - public decimal? TrailingActive { get; set; } - /// - /// Position status - /// - [JsonProperty("position_status"), JsonConverter(typeof(PositionStatusConverter))] - public PositionStatus PositionStatus { get; set; } - /// - /// Position closing fee occupied (your opening fee + expected maximum closing fee) - /// - [JsonProperty("occ_closing_fee")] - public decimal ClosingFee { get; set; } - /// - /// Pre-occupied order margin - /// - [JsonProperty("order_margin")] - public decimal OrderMargin { get; set; } - /// - /// Wallet balance - /// - [JsonProperty("wallet_balance")] - public decimal WalletBalance { get; set; } - /// - /// Wallet balance - /// - [JsonProperty("available_balance")] - public decimal AvailableBalance { get; set; } - /// - /// Position sequence - /// - [JsonProperty("position_seq")] - public long PositionSequence { get; set; } - } - - /// - /// Uds perpetual position update - /// - public class BybitPositionUsdPerpetualUpdate: BybitPositionUpdate - { - /// - /// Take profit trigger - /// - [JsonProperty("tp_sl_mode"), JsonConverter(typeof(StopLossTakeProfitModeConverter))] - public StopLossTakeProfitMode? TakeProfitStopLossMode { get; set; } - /// - /// Mode - /// - public string? Mode { get; set; } - /// - /// Is isolated - /// - public bool Isolated { get; set; } - /// - /// Position id - /// - [JsonProperty("position_id")] - public string? PositionId { get; set; } - /// - /// Adl indicator - /// - [JsonProperty("adl_rank_indicator")] - public int? AdlRankIndicator { get; set; } - /// - /// Fee quantity - /// - [JsonProperty("free_qty")] - public decimal? FeeQuantity { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Socket/BybitStopOrderUpdate.cs b/ByBit.Net/Objects/Models/Socket/BybitStopOrderUpdate.cs deleted file mode 100644 index 2fdc9181..00000000 --- a/ByBit.Net/Objects/Models/Socket/BybitStopOrderUpdate.cs +++ /dev/null @@ -1,81 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models.Socket -{ - /// - /// Stop order update - /// - public class BybitStopOrderUpdate: BybitOrderBase - { - /// - /// Order id - /// - [JsonProperty("order_id")] - public override string Id { get; set; } = string.Empty; - [JsonProperty("stop_order_id")] - internal string StopId { get => Id; set => Id = value; } - /// - /// Client order id - /// - [JsonProperty("order_link_id")] - public string? ClientOrderId { get; set; } - - /// - /// Stop order status - /// - [JsonProperty("order_status"), JsonConverter(typeof(StopOrderStatusConverter))] - public StopOrderStatus Status { get; set; } - - /// - /// Stop order type - /// - [JsonProperty("stop_order_type"), JsonConverter(typeof(StopOrderTypeConverter))] - public StopOrderType StopOrderType { get; set; } - - /// - /// Create type - /// - [JsonProperty("create_type")] - public string CreateType { get; set; } = string.Empty; - - /// - /// Trigger price type - /// - [JsonProperty("trigger_by")] - public TriggerType TriggerBy { get; set; } - /// - /// Trigger rpice. If stop_order_type is TrailingProfit, this field is the trailing stop active price - /// - [JsonProperty("trigger_price")] - public decimal TriggerPrice { get; set; } - /// - /// For a closing order. It can only reduce your position, not increase it. If the account has insufficient available balance when the closing order is triggered, then other active orders of similar contracts will be cancelled or reduced. It can be used to ensure your stop loss reduces your position regardless of current available margin. - /// - [JsonProperty("close_on_trigger")] - public bool CloseOnTrigger { get; set; } - /// - /// Timestamp - /// - public DateTime Timestamp { get; set; } - } - - /// - /// Usd perpetual order update - /// - public class BybitUsdPerpetualStopOrderUpdate: BybitStopOrderUpdate - { - /// - /// Reduce only - /// - [JsonProperty("reduce_only")] - public bool? ReduceOnly { get; set; } - /// - /// Position mode - /// - [JsonProperty("position_idx"), JsonConverter(typeof(PositionModeConverter))] - public PositionMode? PositionMode { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Socket/BybitTickerUpdate.cs b/ByBit.Net/Objects/Models/Socket/BybitTickerUpdate.cs deleted file mode 100644 index 2e1d907b..00000000 --- a/ByBit.Net/Objects/Models/Socket/BybitTickerUpdate.cs +++ /dev/null @@ -1,172 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models.Socket -{ - /// - /// Ticker update - /// - public class BybitTickerUpdate - { - /// - /// Id - /// - public long Id { get; set; } - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Direction of price change - /// - [JsonConverter(typeof(TickDirectionConverter))] - [JsonProperty("last_tick_direction")] - public TickDirection? LastTickDirection { get; set; } - /// - /// 24 hour price change percentage - /// - [JsonConverter(typeof(ExponentDivConverter), 6)] - [JsonProperty("price_24h_pcnt_e6")] - public decimal? PriceChangePercentage24H { get; set; } - /// - /// 1 hour price change percentage - /// - [JsonConverter(typeof(ExponentDivConverter), 6)] - [JsonProperty("price_1h_pcnt_e6")] - public decimal? PriceChangePercentage1H { get; set; } - /// - /// Last trade price - /// - [JsonProperty("last_price")] - public decimal? LastPrice { get; set; } - /// - /// Price 24 hours ago - /// - [JsonProperty("prev_price_24h")] - public decimal? Price24H { get; set; } - /// - /// High price in the last 24 hours - /// - [JsonProperty("high_price_24h")] - public decimal? HighPrice24H { get; set; } - /// - /// Low price in the last 24 hours - /// - [JsonProperty("low_price_24h")] - public decimal? LowPrice24H { get; set; } - /// - /// Price 1 hour ago - /// - [JsonProperty("prev_price_1h")] - public decimal? Price1H { get; set; } - /// - /// Mark price - /// - [JsonProperty("mark_price")] - public decimal? MarkPrice { get; set; } - /// - /// Index price - /// - [JsonProperty("index_price")] - public decimal? IndexPrice { get; set; } - /// - /// Open interest - /// - [JsonProperty("open_interest")] - public decimal? OpenInterest { get; set; } - [JsonConverter(typeof(ExponentDivConverter), 7)] - [JsonProperty("open_interest_e8")] - private decimal? OpenInterestE8 { get => OpenInterest; set => OpenInterest = value; } - /// - /// Open value - /// - [JsonConverter(typeof(ExponentDivConverter), 8)] - [JsonProperty("open_value_e8")] - public decimal? OpenValue { get; set; } - /// - /// Total turnover - /// - [JsonConverter(typeof(ExponentDivConverter), 8)] - [JsonProperty("total_turnover_e8")] - public decimal? TotalTurnover { get; set; } - /// - /// 24 hour turnover - /// - [JsonConverter(typeof(ExponentDivConverter), 8)] - [JsonProperty("turnover_24h_e8")] - public decimal? Turnover24H { get; set; } - /// - /// Total volume - /// - [JsonProperty("total_volume")] - public decimal? TotalVolume { get; set; } - [JsonConverter(typeof(ExponentDivConverter), 8)] - [JsonProperty("total_volume_e8")] - private decimal? TotalVolumeE8 { get => TotalVolume; set => TotalVolume = value; } - /// - /// 24 hour volume - /// - [JsonProperty("volume_24h")] - public decimal? Volume24H { get; set; } - [JsonConverter(typeof(ExponentDivConverter), 8)] - [JsonProperty("volume_24h_e8")] - private decimal? Volume24HE8 { get => Volume24H; set => Volume24H = value; } - /// - /// Predicted funding rate - /// - [JsonConverter(typeof(ExponentDivConverter), 6)] - [JsonProperty("predicted_funding_rate_e6")] - public decimal? PredictedFundingRate { get; set; } - /// - /// Cross sequence - /// - [JsonProperty("cross_seq")] - public long? CrossSequence { get; set; } - /// - /// Creation time - /// - [JsonProperty("created_at")] - public DateTime? CreateTime { get; set; } - /// - /// Update time - /// - [JsonProperty("updated_at")] - public DateTime? UpdateTime { get; set; } - /// - /// Next funding time - /// - [JsonProperty("next_funding_time")] - public DateTime? NextFundingTime { get; set; } - /// - /// Countdown hour - /// - [JsonProperty("countdown_hour")] - public int? CountdownHour { get; set; } - [JsonProperty("count_down_hour")] - private int? CountdownHourInternal { get => CountdownHour; set => CountdownHour = value; } - /// - /// Best ask price - /// - [JsonProperty("ask1_price")] - public decimal? BestAskPrice { get; set; } - /// - /// Best bid price - /// - [JsonProperty("bid1_price")] - public decimal? BestBidPrice { get; set; } - - /// - /// Funding rate - /// - [JsonConverter(typeof(ExponentDivConverter), 6)] - [JsonProperty("funding_rate_e6")] - public decimal? FundingRate { get; set; } - /// - /// Funding rate interval in hours - /// - [JsonProperty("funding_rate_interval")] - public int? FundingRateInterval { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Socket/BybitTradeUpdate.cs b/ByBit.Net/Objects/Models/Socket/BybitTradeUpdate.cs deleted file mode 100644 index 5846cb90..00000000 --- a/ByBit.Net/Objects/Models/Socket/BybitTradeUpdate.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Bybit.Net.Converters; -using Bybit.Net.Enums; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models.Socket -{ - /// - /// Trade update - /// - public class BybitTradeUpdate - { - /// - /// Update timestamp - /// - public DateTime Timestamp { get; set; } - /// - /// Trade time - /// - [JsonConverter(typeof(DateTimeConverter))] - [JsonProperty("trade_time_ms")] - public DateTime TradeTime { get; set; } - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Side - /// - [JsonConverter(typeof(OrderSideConverter))] - public OrderSide Side { get; set; } - /// - /// Quantity - /// - [JsonProperty("size")] - public decimal Quantity { get; set; } - /// - /// Price - /// - public decimal Price { get; set; } - /// - /// Tick direction - /// - [JsonConverter(typeof(TickDirectionConverter))] - [JsonProperty("tick_direction")] - public TickDirection TickDirection { get; set; } - /// - /// Id - /// - [JsonProperty("trade_id")] - public string Id { get; set; } = string.Empty; - /// - /// Cross sequence - /// - [JsonProperty("cross_seq")] - public long? CrossSequence { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Socket/BybitUserTradeUpdate.cs b/ByBit.Net/Objects/Models/Socket/BybitUserTradeUpdate.cs deleted file mode 100644 index e0568fa4..00000000 --- a/ByBit.Net/Objects/Models/Socket/BybitUserTradeUpdate.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Bybit.Net.Enums; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models.Socket -{ - /// - /// User trade info - /// - public class BybitUserTradeUpdate - { - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Side - /// - public OrderSide Side { get; set; } - /// - /// The order id the trade was for - /// - [JsonProperty("order_id")] - public string OrderId { get; set; } = string.Empty; - /// - /// The trade id - /// - [JsonProperty("exec_id")] - public string Id { get; set; } = string.Empty; - /// - /// The client order id the trade was for - /// - [JsonProperty("order_link_id")] - public string ClientOrderId { get; set; } = string.Empty; - /// - /// The trade price - /// - public decimal Price { get; set; } - /// - /// Quantity of the order the trade was for - /// - [JsonProperty("order_qty")] - public decimal OrderQuantity { get; set; } - /// - /// The traded quantity - /// - [JsonProperty("exec_qty")] - public decimal Quantity { get; set; } - /// - /// Trade type - /// - [JsonProperty("exec_type")] - public TradeType Type { get; set; } - /// - /// Fee paid for the trade - /// - [JsonProperty("exec_fee")] - public decimal Fee { get; set; } - /// - /// Remaining quantity in order - /// - [JsonProperty("leaves_qty")] - public decimal QuantityRemaining { get; set; } - /// - /// Is maker - /// - [JsonProperty("is_maker")] - public bool IsMaker { get; set; } - /// - /// Timestamp - /// - [JsonProperty("trade_time")] - public DateTime TradeTime { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Socket/Spot/BybitSpotLeverageUpdate.cs b/ByBit.Net/Objects/Models/Socket/Spot/BybitSpotLeverageUpdate.cs deleted file mode 100644 index 0569bc68..00000000 --- a/ByBit.Net/Objects/Models/Socket/Spot/BybitSpotLeverageUpdate.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models.Socket.Spot -{ - /// - /// Leverage Token Net value update - /// - public class BybitSpotLeverageUpdate - { - /// - /// Timestamp - /// - [JsonConverter(typeof(DateTimeConverter))] - [JsonProperty("t")] - public DateTime Timestamp { get; set; } - /// - /// Symbol - /// - /// Please make sure to add "NAV" as a suffix to the name of the pair you're querying - [JsonProperty("s")] - public string Symbol { get; set; } = string.Empty; - /// - /// Net asset value - /// - [JsonProperty("nav")] - public decimal NetAssetValue { get; set; } - /// - /// Basket value - /// - [JsonProperty("b")] - public decimal BasketValue { get; set; } - /// - /// Real Leverage calculated by last traded price. - /// - [JsonProperty("l")] - public decimal RealLeverage { get; set; } - /// - /// Basket loan - /// - [JsonProperty("loan")] - public decimal BasketLoan { get; set; } - /// - /// Circulating supply in the secondary market - /// - [JsonProperty("ti")] - public decimal CirculatingSupply { get; set; } - /// - /// Total position value = basket value * total circulation - /// - [JsonProperty("n")] - public decimal TotalPositionValue { get; set; } - } -} \ No newline at end of file diff --git a/ByBit.Net/Objects/Models/Spot/BybitSpotBalance.cs b/ByBit.Net/Objects/Models/Spot/BybitSpotBalance.cs index d8689ec6..dd9fda5f 100644 --- a/ByBit.Net/Objects/Models/Spot/BybitSpotBalance.cs +++ b/ByBit.Net/Objects/Models/Spot/BybitSpotBalance.cs @@ -1,20 +1,7 @@ using Newtonsoft.Json; -using System; -using System.Collections.Generic; namespace Bybit.Net.Objects.Models.Spot { - /// - /// Wrapper for balances deserialization - /// - internal class BybitSpotBalanceWrapper - { - /// - /// List of spot balances - /// - public IEnumerable Balances { get; set; } = Array.Empty(); - } - /// /// Balance info /// diff --git a/ByBit.Net/Objects/Models/Spot/v1/BybitLoanInfoV1.cs b/ByBit.Net/Objects/Models/Spot/v1/BybitLoanInfoV1.cs deleted file mode 100644 index 0e1d9e67..00000000 --- a/ByBit.Net/Objects/Models/Spot/v1/BybitLoanInfoV1.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models.Spot.v1 -{ - /// - /// Borrow info - /// - public class BybitBorrowInfoV1 - { - /// - /// Asset - /// - [JsonProperty("currency")] - public string Asset { get; set; } = string.Empty; - /// - /// Interest rate - /// - public decimal InterestRate { get; set; } - /// - /// Max loan quantity - /// - [JsonProperty("maxLoanAmount")] - public decimal MaxBorrowQuantity { get; set; } - /// - /// Borrowable quantity - /// - [JsonProperty("loanAbleAmount")] - public decimal BorrowableQuantity { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Spot/v1/BybitSpotBookPriceV1.cs b/ByBit.Net/Objects/Models/Spot/v1/BybitSpotBookPriceV1.cs deleted file mode 100644 index cb7f9263..00000000 --- a/ByBit.Net/Objects/Models/Spot/v1/BybitSpotBookPriceV1.cs +++ /dev/null @@ -1,49 +0,0 @@ -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models.Spot.v1 -{ - /// - /// Book price info - /// - public class BybitSpotBookPriceV1 - { - /// - /// The symbol - /// - [JsonProperty("symbol")] - public string Symbol { get; set; } = string.Empty; - - /// - /// Best bid price - /// - /// In some methods they changed naming, in some they changed type. Not very logic, but.. - [JsonProperty("bidPrice")] - public decimal BestBidPrice { get; set; } - - /// - /// Quantity of the best bid price - /// - [JsonProperty("bidQty")] - public decimal BestBidQuantity { get; set; } - - /// - /// Best ask price - /// - [JsonProperty("askPrice")] - public decimal BestAskPrice { get; set; } - - /// - /// Quantity of the best ask price - /// - [JsonProperty("askQty")] - public decimal BestAskQuantity { get; set; } - - /// - /// Timestamp of the data - /// - [JsonProperty("time"), JsonConverter(typeof(DateTimeConverter))] - public DateTime Timestamp { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Spot/v1/BybitSpotKlineV1.cs b/ByBit.Net/Objects/Models/Spot/v1/BybitSpotKlineV1.cs deleted file mode 100644 index 6b31fb69..00000000 --- a/ByBit.Net/Objects/Models/Spot/v1/BybitSpotKlineV1.cs +++ /dev/null @@ -1,69 +0,0 @@ -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models.Spot.v1 -{ - /// - /// Kline data - /// - [JsonConverter(typeof(ArrayConverter))] - public class BybitSpotKlineV1 - { - /// - /// Candle open time - /// - [ArrayProperty(0), JsonConverter(typeof(DateTimeConverter))] - public DateTime OpenTime { get; set; } - /// - /// Open price - /// - [ArrayProperty(1)] - public decimal OpenPrice { get; set; } - /// - /// High price - /// - [ArrayProperty(2)] - public decimal HighPrice { get; set; } - /// - /// Low price - /// - [ArrayProperty(3)] - public decimal LowPrice { get; set; } - /// - /// Close price - /// - [ArrayProperty(4)] - public decimal ClosePrice { get; set; } - /// - /// Volume - /// - [ArrayProperty(5)] - public decimal Volume { get; set; } - /// - /// Close time - /// - [ArrayProperty(6), JsonConverter(typeof(DateTimeConverter))] - public DateTime? CloseTime { get; set; } - /// - /// Quote volume - /// - [ArrayProperty(7)] - public decimal QuoteVolume { get; set; } - /// - /// Number of trades - /// - [ArrayProperty(8)] - public int Trades { get; set; } - /// - /// Take volume - /// - [ArrayProperty(9)] - public decimal TakerVolume { get; set; } - /// - /// Taker quote volume - /// - [ArrayProperty(10)] - public decimal TakerQuoteVolume { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Spot/v1/BybitSpotOrderV1.cs b/ByBit.Net/Objects/Models/Spot/v1/BybitSpotOrderV1.cs deleted file mode 100644 index 3bf967d4..00000000 --- a/ByBit.Net/Objects/Models/Spot/v1/BybitSpotOrderV1.cs +++ /dev/null @@ -1,57 +0,0 @@ -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models.Spot.v1 -{ - /// - /// Spot order info - /// - public class BybitSpotOrderV1 : BybitSpotOrderBase - { - /// - /// Exchange id - /// - public long ExchangeId { get; set; } - /// - /// Quantity executed - /// - [JsonProperty("executedQty")] - public decimal QuantityFilled { get; set; } - /// - /// Quote quantity - /// - [JsonProperty("cummulativeQuoteQty")] - public decimal QuoteQuantity { get; set; } - /// - /// Average execution price - /// - [JsonProperty("avgPrice")] - public decimal AveragePrice { get; set; } - /// - /// Stop price - /// - public decimal? StopPrice { get; set; } - /// - /// Ice berg quantity - /// - [JsonProperty("icebergQty")] - public decimal? IcebergQuantity { get; set; } - /// - /// Creation time - /// - [JsonConverter(typeof(DateTimeConverter))] - [JsonProperty("time")] - public DateTime CreateTime { get; set; } - /// - /// Last update time - /// - [JsonConverter(typeof(DateTimeConverter))] - [JsonProperty("updateTime")] - public DateTime UpdateTime { get; set; } - /// - /// Is working - /// - public bool IsWorking { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Spot/v1/BybitSpotSymbolV1.cs b/ByBit.Net/Objects/Models/Spot/v1/BybitSpotSymbolV1.cs deleted file mode 100644 index 54a94ebc..00000000 --- a/ByBit.Net/Objects/Models/Spot/v1/BybitSpotSymbolV1.cs +++ /dev/null @@ -1,83 +0,0 @@ -using Newtonsoft.Json; - -namespace Bybit.Net.Objects.Models.Spot.v1 -{ - /// - /// Symbol info - /// - public class BybitSpotSymbolV1 - { - /// - /// Name of the symbol - /// - public string Name { get; set; } = string.Empty; - /// - /// Alias - /// - public string Alias { get; set; } = string.Empty; - /// - /// Base asset - /// - [JsonProperty("baseCurrency")] - public string BaseAsset { get; set; } = string.Empty; - - /// - /// Quote asset - /// - [JsonProperty("quoteCurrency")] - public string QuoteAsset { get; set; } = string.Empty; - - /// - /// Precision of the base asset - /// - public decimal BasePrecision { get; set; } - /// - /// Precision of the quote asset - /// - public decimal QuotePrecision { get; set; } - /// - /// Minimal order quantity - /// - [JsonProperty("minTradeQuantity")] - public decimal MinOrderQuantity { get; set; } - - /// - /// Minimal order value (quantity * price) - /// - [JsonProperty("minTradeAmount")] - public decimal MinOrderValue { get; set; } - - /// - /// Price precision - /// - [JsonProperty("minPricePrecision")] - public decimal PricePrecision { get; set; } - /// - /// Max order quantity - /// - [JsonProperty("maxTradeQuantity")] - public decimal MaxOrderQuantity { get; set; } - - /// - /// Max order value (quantity * price) - /// - [JsonProperty("maxTradeAmount")] - public decimal MaxOrderValue { get; set; } - - /// - /// Category - /// - public int Category { get; set; } - - - /// - /// True indicates that the price of this currency is relatively volatile - /// - public bool Innovation { get; set; } - - /// - /// True indicates that the symbol open for trading - /// - public bool ShowStatus { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Spot/v1/BybitSpotTickerV1.cs b/ByBit.Net/Objects/Models/Spot/v1/BybitSpotTickerV1.cs deleted file mode 100644 index e5c86412..00000000 --- a/ByBit.Net/Objects/Models/Spot/v1/BybitSpotTickerV1.cs +++ /dev/null @@ -1,56 +0,0 @@ -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models.Spot.v1 -{ - /// - /// Ticker info - /// - public class BybitSpotTickerV1 - { - /// - /// Timestamp of the data - /// - [JsonConverter(typeof(DateTimeConverter))] - [JsonProperty("time")] - public DateTime Timestamp { get; set; } - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Current best bid price - /// - public decimal BestBidPrice { get; set; } - /// - /// Current best ask price - /// - public decimal BestAskPrice { get; set; } - /// - /// Volume - /// - public decimal Volume { get; set; } - /// - /// Quote volume - /// - public decimal QuoteVolume { get; set; } - /// - /// Last trade price - /// - [JsonProperty("lastPrice")] - public decimal LastPrice { get; set; } - /// - /// 24 hour high price - /// - public decimal HighPrice { get; set; } - /// - /// 24 hour low price - /// - public decimal LowPrice { get; set; } - /// - /// Price 24 hours ago - /// - public decimal OpenPrice { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Spot/v1/BybitSpotTradeV1.cs b/ByBit.Net/Objects/Models/Spot/v1/BybitSpotTradeV1.cs deleted file mode 100644 index 96c6f427..00000000 --- a/ByBit.Net/Objects/Models/Spot/v1/BybitSpotTradeV1.cs +++ /dev/null @@ -1,31 +0,0 @@ -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models.Spot.v1 -{ - /// - /// Spot trade info - /// - public class BybitSpotTradeV1 - { - /// - /// Trade price - /// - public decimal Price { get; set; } - /// - /// Timestamp of the trade - /// - [JsonProperty("time"), JsonConverter(typeof(DateTimeConverter))] - public DateTime TradeTime { get; set; } - /// - /// Quantity - /// - [JsonProperty("qty")] - public decimal Quantity { get; set; } - /// - /// Is the buyer the maker - /// - public bool IsBuyerMaker { get; set; } - } -} diff --git a/ByBit.Net/Objects/Models/Spot/v1/BybitSpotUserTradeV1.cs b/ByBit.Net/Objects/Models/Spot/v1/BybitSpotUserTradeV1.cs deleted file mode 100644 index 6c8b49cc..00000000 --- a/ByBit.Net/Objects/Models/Spot/v1/BybitSpotUserTradeV1.cs +++ /dev/null @@ -1,101 +0,0 @@ -using CryptoExchange.Net.Converters; -using Newtonsoft.Json; -using System; - -namespace Bybit.Net.Objects.Models.Spot -{ - /// - /// User trade info - /// - public class BybitSpotUserTradeV1 - { - /// - /// Trade id - /// - public long Id { get; set; } - /// - /// Symbol - /// - public string Symbol { get; set; } = string.Empty; - /// - /// Symbol name - /// - public string SymbolName { get; set; } = string.Empty; - /// - /// Order id - /// - public long OrderId { get; set; } - /// - /// Matching order id - /// - public long MatchOrderId { get; set; } - /// - /// Trade price - /// - public decimal Price { get; set; } - /// - /// Trade quantity - /// - [JsonProperty("qty")] - public decimal Quantity { get; set; } - /// - /// Fee - /// - [JsonProperty("commission")] - public decimal Fee { get; set; } - /// - /// Fee asset - /// - [JsonProperty("commissionAsset")] - public string FeeAsset { get; set; } = string.Empty; - /// - /// Trade time - /// - [JsonProperty("time"), JsonConverter(typeof(DateTimeConverter))] - public DateTime TradeTime { get; set; } - /// - /// Is buyer - /// - public bool IsBuyer { get; set; } - /// - /// Is maker - /// - public bool IsMaker { get; set; } - /// - /// Fee details - /// - [JsonProperty("fee")] - public BybitTradeFee FeeDetails { get; set; } = default!; - /// - /// Fee otken id - /// - public string FeeTokenId { get; set; } = string.Empty; - /// - /// Trading fee - /// - public decimal FeeAmount { get; set; } - /// - /// Maker rebate - /// - public decimal MakerRebate { get; set; } - } - - /// - /// Fee info - /// - public class BybitTradeFee - { - /// - /// Fee token id - /// - public string FeeTokenId { get; set; } = string.Empty; - /// - /// Fee token name - /// - public string FeeTokenName { get; set; } = string.Empty; - /// - /// Fee - /// - public decimal Fee { get; set; } - } -} diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/ChangeMarginAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/ChangeMarginAsync.txt deleted file mode 100644 index 726d6fef..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/ChangeMarginAsync.txt +++ /dev/null @@ -1,11 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "ok", - "ext_code": "", - "result": 0.00000997, - "ext_info": null, - "time_now": "1577480720.003444", - "rate_limit_status": 74, - "rate_limit_reset_ms": 1577480720011, - "rate_limit": 75 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetApiKeyInfoAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetApiKeyInfoAsync.txt deleted file mode 100644 index ca6116b0..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetApiKeyInfoAsync.txt +++ /dev/null @@ -1,29 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "ok", - "ext_code": "", - "result": [ - { - "api_key": "7GkMBBLTbGRfa0Nuh1", - "type": "personal", - "user_id": 1, - "inviter_id": 3, - "ips": [ - "*" - ], - "note": "scalping_bot", - "permissions": [ - "Order", - "Position" - ], - "created_at": "2019-10-28T13:22:39.000Z", - "expired_at": "2020-01-28T13:22:39.000Z", - "read_only": false - } - ], - "ext_info": null, - "time_now": "1577445138.790150", - "rate_limit_status": 99, - "rate_limit_reset_ms": 1577445138812, - "rate_limit": 100 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetAssetExchangeHistoryAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetAssetExchangeHistoryAsync.txt deleted file mode 100644 index 50350976..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetAssetExchangeHistoryAsync.txt +++ /dev/null @@ -1,32 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": [ - { - "id": 31, - "exchange_rate": 40.57202774, - "from_coin": "BTC", - "to_coin": "ETH", - "to_amount": 4.05720277, - "from_fee": 0.0005, - "from_amount": 0.1, - "created_at": "2020-06-15 03:32:52" - }, - { - "id": 30, - "exchange_rate": 39.92359901, - "from_coin": "BTC", - "to_coin": "ETH", - "to_amount": 39.923599, - "from_fee": 0.0005, - "from_amount": 1, - "created_at": "2020-06-12 08:27:51" - } - ], - "time_now": "1592554785.486414", - "rate_limit_status": 119, - "rate_limit_reset_ms": 1592554785484, - "rate_limit": 120 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetBalancesAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetBalancesAsync.txt deleted file mode 100644 index cbc86772..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetBalancesAsync.txt +++ /dev/null @@ -1,38 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "BTC": { - "equity": 1002, //equity = wallet_balance + unrealised_pnl - "available_balance": 999.99987471, //available_balance - //In Isolated Margin Mode: - // available_balance = wallet_balance - (position_margin + occ_closing_fee + occ_funding_fee + order_margin) - //In Cross Margin Mode: - //if unrealised_pnl > 0: - //available_balance = wallet_balance - (position_margin + occ_closing_fee + occ_funding_fee + order_margin); - //if unrealised_pnl < 0: - //available_balance = wallet_balance - (position_margin + occ_closing_fee + occ_funding_fee + order_margin) + unrealised_pnl - "used_margin": 0.00012529, //used_margin = wallet_balance - available_balance - "order_margin": 0.00012529, //Used margin by order - "position_margin": 0, //position margin - "occ_closing_fee": 0, //position closing fee - "occ_funding_fee": 0, //funding fee - "wallet_balance": 1000, //wallet balance. When in Cross Margin mod, the number minus your unclosed loss is your real wallet balance. - "realised_pnl": 0, //daily realized profit and loss - "unrealised_pnl": 2, //unrealised profit and loss - //when side is sell: - // unrealised_pnl = size * (1.0 / mark_price - 1.0 / entry_price) - //when side is buy: - // unrealised_pnl = size * (1.0 / entry_price - 1.0 / mark_price) - "cum_realised_pnl": 0, //total relised profit and loss - "given_cash": 0, //given_cash - "service_cash": 0 //service_cash - } - }, - "time_now": "1578284274.816029", - "rate_limit_status": 98, - "rate_limit_reset_ms": 1580885703683, - "rate_limit": 100 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetPositionAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetPositionAsync.txt deleted file mode 100644 index 343e207f..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetPositionAsync.txt +++ /dev/null @@ -1,45 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "id": 27913, - "user_id": 1, - "risk_id": 1, - "symbol": "BTCUSD", - "side": "Buy", - "size": 5, - "position_value": "0.0006947", - "entry_price": "7197.35137469", - "is_isolated":true, - "auto_add_margin": 0, - "leverage": "1", //In Isolated Margin mode, the value is set by user. In Cross Margin mode, the value is the max leverage at current risk level - "effective_leverage": "1", - "position_margin": "0.0006947", - "liq_price": "3608", - "bust_price": "3599", - "occ_closing_fee": "0.00000105", - "occ_funding_fee": "0", - "take_profit": "0", - "stop_loss": "0", - "trailing_stop": "0", - "position_status": "Normal", - "deleverage_indicator": 4, - "oc_calc_data": "{\"blq\":2,\"blv\":\"0.0002941\",\"slq\":0,\"bmp\":6800.408,\"smp\":0,\"fq\":-5,\"fc\":-0.00029477,\"bv2c\":1.00225,\"sv2c\":1.0007575}", - "order_margin": "0.00029477", - "wallet_balance": "0.03000227", - "realised_pnl": "-0.00000126", - "unrealised_pnl": 0, - "cum_realised_pnl": "-0.00001306", - "cross_seq": 444081383, - "position_seq": 287141589, - "created_at": "2019-10-19T17:04:55Z", - "updated_at": "2019-12-27T20:25:45.158767Z", - "tp_sl_mode": "Partial" - }, - "time_now": "1577480599.097287", - "rate_limit_status": 119, - "rate_limit_reset_ms": 1580885703683, - "rate_limit": 120 -} diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetProfitAndLossHistoryAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetProfitAndLossHistoryAsync.txt deleted file mode 100644 index 79c10ec9..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetProfitAndLossHistoryAsync.txt +++ /dev/null @@ -1,35 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "current_page": 1, - "data": [ - { - "id": 9982, - "user_id": 160320, - "symbol": "BTCUSD", - "order_id": "e976ac13-10e7-4883-a7ba-13b0e93659f1", - "side": "Sell", - "qty": 226, - "order_price": 1600, - "order_type": "Limit", - "exec_type": "Trade", - "closed_size": 113, - "cum_entry_value": 0.07062500000000001, - "avg_entry_price": 1600, - "cum_exit_value": 0.066198, - "avg_exit_price": 1707, - "closed_pnl": 0.0043950000000000005, - "fill_count": 1, - "leverage": 100, - "created_at": 1591155741 - } - ] - }, - "time_now": "1591173153.876047", - "rate_limit_status": 119, - "rate_limit_reset_ms": 1591173153852, - "rate_limit": 120 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetUserLastFundingFeeAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetUserLastFundingFeeAsync.txt deleted file mode 100644 index cb1e74a1..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetUserLastFundingFeeAsync.txt +++ /dev/null @@ -1,18 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "ok", - "ext_code": "", - "result": { - "symbol": "BTCUSD", - "side": "Buy", // Your position side at the time of settlement - "size": 1, // Your position size at the time of settlement - "funding_rate": 0.0001, // Funding rate for settlement. When the funding rate is positive, longs pay shorts. When it is negative, shorts pay longs. - "exec_fee": 0.00000002, // Funding fee. - "exec_timestamp": 1575907200 // The time of funding settlement occurred, UTC timestamp - }, - "ext_info": null, - "time_now": "1577446900.717204", - "rate_limit_status": 119, - "rate_limit_reset_ms": 1577446900724, - "rate_limit": 120 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetUserPredictedFundingRateAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetUserPredictedFundingRateAsync.txt deleted file mode 100644 index 0edc0d96..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetUserPredictedFundingRateAsync.txt +++ /dev/null @@ -1,14 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "ok", - "ext_code": "", - "result": { - "predicted_funding_rate": 0.0001, - "predicted_funding_fee": 0 - }, - "ext_info": null, - "time_now": "1577447415.583259", - "rate_limit_status": 118, - "rate_limit_reset_ms": 1577447415590, - "rate_limit": 120 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetWalletFundHistoryAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetWalletFundHistoryAsync.txt deleted file mode 100644 index e236eb75..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetWalletFundHistoryAsync.txt +++ /dev/null @@ -1,40 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "ok", - "ext_code": "", - "result": { - "data": [ - { - "id": 235853, - "user_id": 1, - "coin": "BTC", - "wallet_id": 27913, - "type": "Realized P&L", - "amount": "0.00000023", - "tx_id": "", - "address": "BTCUSD", - "wallet_balance": "0.03000353", - "exec_time": "2019-12-10T00:00:29.000Z", - "cross_seq": 0 - }, - { - "id": 234467, - "user_id": 1, - "coin": "BTC", - "wallet_id": 27913, - "type": "Realized P&L", - "amount": "-0.00000006", - "tx_id": "", - "address": "BTCUSD", - "wallet_balance": "0.03000330", - "exec_time": "2019-12-09T00:00:25.000Z", - "cross_seq": 0 - } - ] - }, - "ext_info": null, - "time_now": "1577481867.115552", - "rate_limit_status": 119, - "rate_limit_reset_ms": 1577481867122, - "rate_limit": 120 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetWithdrawalHistoryAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetWithdrawalHistoryAsync.txt deleted file mode 100644 index 6c612ae9..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/GetWithdrawalHistoryAsync.txt +++ /dev/null @@ -1,26 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "ok", - "ext_code": "", - "result": { - "data": [{ - "id": 137, - "user_id": 1, - "coin": "XRP", //Coin Enum - "status": "Pending", //Withdraw Status Enum - "amount": "20.00000000", - "fee": "0.25000000", - "address": "rH7H595XYEVTEHU2FySYsWnmfACBnZS9zM", - "tx_id": "", - "submited_at": "2019-06-11T02:20:24.000Z", - "updated_at": "2019-06-11T02:20:24.000Z" - }], - "current_page": 1, - "last_page": 1 - }, - "ext_info": null, - "time_now": "1577482295.125488", - "rate_limit_status": 119, - "rate_limit_reset_ms": 1577482295132, - "rate_limit": 120 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/SetFullPartialPositionModeAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/SetFullPartialPositionModeAsync.txt deleted file mode 100644 index e708613a..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/SetFullPartialPositionModeAsync.txt +++ /dev/null @@ -1,13 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "tp_sl_mode": "Partial" - }, - "time_now": "1598266294.610276", - "rate_limit_status": 72, - "rate_limit_reset_ms": 1598266294607, - "rate_limit": 75 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/SetLeverageAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/SetLeverageAsync.txt deleted file mode 100644 index a47096c7..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/SetLeverageAsync.txt +++ /dev/null @@ -1,11 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "ok", - "ext_code": "", - "result": 2, - "ext_info": null, - "time_now": "1577477968.175013", - "rate_limit_status": 74, - "rate_limit_reset_ms": 1577477968183, - "rate_limit": 75 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/SetPositionModeAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/SetPositionModeAsync.txt deleted file mode 100644 index bdc7d207..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Account/SetPositionModeAsync.txt +++ /dev/null @@ -1,11 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "ok", - "ext_code": "", - "result": null, - "ext_info": null, - "time_now": "1577477968.175013", - "rate_limit_status": 74, - "rate_limit_reset_ms": 1577477968183, - "rate_limit": 75 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetAnnouncementsAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetAnnouncementsAsync.txt deleted file mode 100644 index abb1c660..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetAnnouncementsAsync.txt +++ /dev/null @@ -1,16 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": [ - { - "id": 2, - "title": "2019-12-02 RELEASE", - "link": "https://github.com/bybit-exchange/bybit-official-api-docs/blob/master/en/CHANGELOG.md", - "summary": "

New `cancel all` endpoint is here now!

Additionally, we strongly recommend that you use the new released place and cancel active V2 endpoints, which are more stable and efficient.The old ones are deprecated (although still working for the time be", - "created_at": "2019-12-02T11:33:42Z" - } - ], - "time_now": "1577444818.227082" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetIndexPriceKlinesAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetIndexPriceKlinesAsync.txt deleted file mode 100644 index d4fec648..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetIndexPriceKlinesAsync.txt +++ /dev/null @@ -1,18 +0,0 @@ -{ - "ret_code":0, - "ret_msg":"OK", - "ext_code":"", - "ext_info":"", - "result":[ - { - "symbol":"BTCUSD", - "period":"1", - "open_time":1582231260, - "open":"10106.09", - "high":"10108.75", - "low":"10104.66", - "close":"10108.73" - } - ], - "time_now":"1591263582.601795" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetKlinesAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetKlinesAsync.txt deleted file mode 100644 index a47cd29f..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetKlinesAsync.txt +++ /dev/null @@ -1,28 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": [{ - "symbol": "BTCUSD", - "interval": "1", - "open_time": 1581231300, - "open": "10112.5", - "high": "10112.5", - "low": "10112", - "close": "10112", - "volume": "75981", - "turnover": "7.51394369" - }, { - "symbol": "BTCUSD", - "interval": "1", - "open_time": 1581231360, - "open": "10112", - "high": "10112.5", - "low": "10112", - "close": "10112", - "volume": "24616", - "turnover": "2.4343353100000003" - }], - "time_now": "1581928016.558522" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetLastFundingRateAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetLastFundingRateAsync.txt deleted file mode 100644 index 1b40afc1..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetLastFundingRateAsync.txt +++ /dev/null @@ -1,15 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "ok", - "ext_code": "", - "result": { - "symbol": "BTCUSD", - "funding_rate": "0.00010000", - "funding_rate_timestamp": 1577433600 - }, - "ext_info": null, - "time_now": "1577445586.446797", - "rate_limit_status": 119, - "rate_limit_reset_ms": 1577445586454, - "rate_limit": 120 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetLongShortRatioAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetLongShortRatioAsync.txt deleted file mode 100644 index effe8400..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetLongShortRatioAsync.txt +++ /dev/null @@ -1,21 +0,0 @@ -{ - "ret_code":0, - "ret_msg":"OK", - "ext_code":"", - "ext_info":"", - "result":[ - { - "symbol":"BTCUSD", - "buy_ratio":0.6538, - "sell_ratio":0.3462, - "timestamp":1597659000 - }, - { - "symbol":"BTCUSD", - "buy_ratio":0.6533, - "sell_ratio":0.3467, - "timestamp":1597658700 - } - ], - "time_now":"1597659230.743313" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetMarkPriceKlinesAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetMarkPriceKlinesAsync.txt deleted file mode 100644 index afa570f5..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetMarkPriceKlinesAsync.txt +++ /dev/null @@ -1,20 +0,0 @@ - -{ - "ret_code":0, - "ret_msg":"OK", - "ext_code":"", - "ext_info":"", - "result":[ - { - "id":2, - "symbol":"BTCUSD", - "period":"1", - "start_at":1582231260, - "open":100, - "high":120, - "low":88, - "close":115 - } - ], - "time_now":"1591263582.601795" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetOpenInterestAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetOpenInterestAsync.txt deleted file mode 100644 index c1892ad1..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetOpenInterestAsync.txt +++ /dev/null @@ -1,19 +0,0 @@ -{ - "ret_code":0, - "ret_msg":"OK", - "ext_code":"", - "ext_info":"", - "result":[ - { - "open_interest":371491978, - "timestamp":1597658100, - "symbol":"BTCUSD" - }, - { - "open_interest":370696076, - "timestamp":1597657800, - "symbol":"BTCUSD" - } - ], - "time_now":"1597658304.938839" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetOrderBookAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetOrderBookAsync.txt deleted file mode 100644 index b6507d1b..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetOrderBookAsync.txt +++ /dev/null @@ -1,21 +0,0 @@ -{ - "ret_code": 0, // return code - "ret_msg": "OK", // error message - "ext_code": "", // additional error code - "ext_info": "", // additional error info - "result": [ - { - "symbol": "BTCUSD", // symbol - "price": "9487", // price - "size": 336241, // size (in USD contracts) - "side": "Buy" // side - }, - { - "symbol": "BTCUSD", // symbol - "price": "9487.5", // price - "size": 522147, // size (in USD contracts) - "side": "Sell" // side - } - ], - "time_now": "1567108756.834357" // UTC timestamp -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetPremiumIndexKlinesAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetPremiumIndexKlinesAsync.txt deleted file mode 100644 index 14537c2b..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetPremiumIndexKlinesAsync.txt +++ /dev/null @@ -1,18 +0,0 @@ -{ - "ret_code":0, - "ret_msg":"OK", - "ext_code":"", - "ext_info":"", - "result":[ - { - "symbol":"BTCUSD", - "period":"1", - "open_time":1582231260, - "open":"0.000588", - "high":"0.000618", - "low":"0.000588", - "close":"0.000618" - } - ], - "time_now":"1591263582.601795" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetRecentBigTradesAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetRecentBigTradesAsync.txt deleted file mode 100644 index 0633fdba..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetRecentBigTradesAsync.txt +++ /dev/null @@ -1,21 +0,0 @@ -{ - "ret_code":0, - "ret_msg":"OK", - "ext_code":"", - "ext_info":"", - "result":[ - { - "symbol":"BTCUSD", - "side":"Sell", - "timestamp":1597623362, - "value":1242368 - }, - { - "symbol":"BTCUSD", - "side":"Buy", - "timestamp":1597623363, - "value":1242368 - } - ], - "time_now":"1597658434.219859" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetSymbolsAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetSymbolsAsync.txt deleted file mode 100644 index 8d9840c5..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetSymbolsAsync.txt +++ /dev/null @@ -1,109 +0,0 @@ -{ - "ret_code":0, - "ret_msg":"OK", - "ext_code":"", - "ext_info":"", - "result":[ - { - "name":"BTCUSD", - "alias":"BTCUSD", - "status":"Trading", - "base_currency":"BTC", - "quote_currency":"USD", - "price_scale":2, - "taker_fee":"0.00075", - "maker_fee":"-0.00025", - "leverage_filter":{ - "min_leverage":1, - "max_leverage":100, - "leverage_step":"0.01" - }, - "price_filter":{ - "min_price":"0.5", - "max_price":"999999.5", - "tick_size":"0.5" - }, - "lot_size_filter":{ - "max_trading_qty":1000000, - "min_trading_qty":1, - "qty_step":1 - } - }, - { - "name":"EOSUSD", - "alias":"EOSUSD", - "status":"Trading", - "base_currency":"EOS", - "quote_currency":"USD", - "price_scale":3, - "taker_fee":"0.00075", - "maker_fee":"-0.00025", - "leverage_filter":{ - "min_leverage":1, - "max_leverage":50, - "leverage_step":"0.01" - }, - "price_filter":{ - "min_price":"0.001", - "max_price":"1999.999", - "tick_size":"0.001" - }, - "lot_size_filter":{ - "max_trading_qty":1000000, - "min_trading_qty":1, - "qty_step":1 - } - }, - { - "name":"BTCUSDT", - "alias":"BTCUSDT", - "status":"Trading", - "base_currency":"BTC", - "quote_currency":"USDT", - "price_scale":2, - "taker_fee":"0.00075", - "maker_fee":"-0.00025", - "leverage_filter":{ - "min_leverage":1, - "max_leverage":100, - "leverage_step":"0.01" - }, - "price_filter":{ - "min_price":"0.5", - "max_price":"999999.5", - "tick_size":"0.5" - }, - "lot_size_filter":{ - "max_trading_qty":100, - "min_trading_qty":0.001, - "qty_step":0.001 - } - }, - { - "name":"BTCUSDM21", - "alias":"BTCUSD0625", - "status":"Trading", - "base_currency":"BTC", - "quote_currency":"USD", - "price_scale":2, - "taker_fee":"0.00075", - "maker_fee":"-0.00025", - "leverage_filter":{ - "min_leverage":1, - "max_leverage":100, - "leverage_step":"0.01" - }, - "price_filter":{ - "min_price":"0.5", - "max_price":"999999.5", - "tick_size":"0.5" - }, - "lot_size_filter":{ - "max_trading_qty":1000000, - "min_trading_qty":1, - "qty_step":1 - } - } - ], - "time_now":"1615801223.589808" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetTickerAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetTickerAsync.txt deleted file mode 100644 index 82a79550..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetTickerAsync.txt +++ /dev/null @@ -1,65 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": [ - { - "symbol": "BTCUSD", - "bid_price": "7230", - "ask_price": "7230.5", - "last_price": "7230.00", - "last_tick_direction": "ZeroMinusTick", - "prev_price_24h": "7163.00", - "price_24h_pcnt": "0.009353", - "high_price_24h": "7267.50", - "low_price_24h": "7067.00", - "prev_price_1h": "7209.50", - "price_1h_pcnt": "0.002843", - "mark_price": "7230.31", - "index_price": "7230.14", - "open_interest": 117860186, - "open_value": "16157.26", - "total_turnover": "3412874.21", - "turnover_24h": "10864.63", - "total_volume": 28291403954, - "volume_24h": 78053288, - "funding_rate": "0.0001", - "predicted_funding_rate": "0.0001", - "next_funding_time": "2019-12-28T00:00:00Z", - "countdown_hour": 2, - "delivery_fee_rate": "0", - "predicted_delivery_price": "0.00", - "delivery_time": "" - }, - { - "symbol": "BTCUSDM21", - "bid_price": "67895", - "ask_price": "67895.5", - "last_price": "67895.50", - "last_tick_direction": "ZeroPlusTick", - "prev_price_24h": "68073.00", - "price_24h_pcnt": "-0.002607", - "high_price_24h": "69286.50", - "low_price_24h": "66156.00", - "prev_price_1h": "68028.50", - "price_1h_pcnt": "-0.001955", - "mark_price": "67883.88", - "index_price": "62687.89", - "open_interest": 531821673, - "open_value": "0.00", - "total_turnover": "85713.36", - "turnover_24h": "2371.47", - "total_volume": 5352251354, - "volume_24h": 160716002, - "funding_rate": "0", - "predicted_funding_rate": "0", - "next_funding_time": "", - "countdown_hour": 0, - "delivery_fee_rate": "0.0005", - "predicted_delivery_price": "0.00", - "delivery_time": "2021-06-25T08:00:00Z" - } - ], - "time_now": "1577484619.817968" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetTradeHistoryAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetTradeHistoryAsync.txt deleted file mode 100644 index 42af53a9..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/ExchangeData/GetTradeHistoryAsync.txt +++ /dev/null @@ -1,17 +0,0 @@ -{ - "ret_code": 0, // error code 0 means success - "ret_msg": "OK", // error message - "ext_code": "", - "ext_info": "", - "result": [ - { - "id": 7724919, // ID - "symbol": "BTCUSD", // contract type - "price": 9499.5, // execution price - "qty": 9500, // execution quantity - "side": "Buy", // side - "time": "2019-11-19T08:03:04.077Z" // UTC time - } - ], - "time_now": "1567109419.049271" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/BalanceUpdate.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/BalanceUpdate.txt deleted file mode 100644 index 6e05c147..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/BalanceUpdate.txt +++ /dev/null @@ -1,7 +0,0 @@ -[ - { - "coin": "BTC", - "available_balance": "1.50121026", - "wallet_balance": "1.50121261" - } - ] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/InsuranceUpdate.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/InsuranceUpdate.txt deleted file mode 100644 index 7d92323d..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/InsuranceUpdate.txt +++ /dev/null @@ -1,7 +0,0 @@ -[ - { - "currency": "BTC", - "timestamp": "2020-01-11T20:00:00Z", - "wallet_balance": 98786916569 - } - ] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/KlineUpdate.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/KlineUpdate.txt deleted file mode 100644 index b567ecf4..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/KlineUpdate.txt +++ /dev/null @@ -1,13 +0,0 @@ -[{ - "start": 1572425640, //start time of the candle - "end": 1572425700, //end time of the candle - "open": 9200, //open price - "close": 9202.5, //close price - "high": 9202.5, //max price - "low": 9196, //min price - "volume": 81790, //volume - "turnover": 8.889247899999999, //turnover - "confirm": false, //snapshot flag - "cross_seq": 297503466, - "timestamp": 1572425676958323 //cross time - }] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/LiquidationUpdate.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/LiquidationUpdate.txt deleted file mode 100644 index de8531ee..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/LiquidationUpdate.txt +++ /dev/null @@ -1,7 +0,0 @@ -{ - "symbol":"ETHUSD", - "side":"Sell", - "price":"3384.15", - "qty":"3655", - "time":1631608881954 - } \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/OrderUpdate.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/OrderUpdate.txt deleted file mode 100644 index aae5fc9b..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/OrderUpdate.txt +++ /dev/null @@ -1,28 +0,0 @@ -[ - { -"order_id": "19bffe79-de68-4c53-9515-4f91b0c70112", -"order_link_id": "", -"symbol": "BTCUSDT", -"side": "Buy", -"order_type": "Market", -"price": 38262, -"qty": 0.01, -"leaves_qty": 0, -"last_exec_price": 36442, -"cum_exec_qty": 0.01, -"cum_exec_value": 364.411, -"cum_exec_fee": 0.0273315, -"time_in_force": "ImmediateOrCancel", -"create_type": "CreateByUser", -"cancel_type": "UNKNOWN", -"order_status": "Filled", -"take_profit": 0, -"stop_loss": 0, -"trailing_stop": 0, -"create_time": "2022-01-25T10:32:34.519268798Z", -"update_time": "2022-01-25T10:32:34.519369Z", -"reduce_only": false, -"close_on_trigger": false, -"position_idx": "1" -} - ] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/PositionUpdate.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/PositionUpdate.txt deleted file mode 100644 index f61b26b2..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/PositionUpdate.txt +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "user_id": 1, // user ID - "symbol": "BTCUSD", // the contract for this position - "size": 11, // the current position amount - "side": "Sell", // side - "position_value": "0.00159252", // positional value - "entry_price": "6907.291588174717", // entry price - "liq_price": "7100.234", // liquidation price - "bust_price": "7088.1234", // bankruptcy price - "leverage": "1", // leverage - "order_margin": "1", // order margin - "position_margin": "1", // position margin - "available_balance": "2", // available balance - "take_profit": "0", // take profit price - "tp_trigger_by": "LastPrice", // take profit trigger price, eg: LastPrice, IndexPrice. Conditional order only - "stop_loss": "0", // stop loss price - "sl_trigger_by": "", // stop loss trigger price, eg: LastPrice, IndexPrice. Conditional order only - "realised_pnl": "0.10", // realised PNL - "trailing_stop": "0", // trailing stop points - "trailing_active": "0", // trailing stop trigger price - "wallet_balance": "4.12", // wallet balance - "risk_id": 1, - "occ_closing_fee": "0.1", // position closing - "occ_funding_fee": "0.1", // funding fee - "auto_add_margin": 0, // auto margin replenishment switch - "cum_realised_pnl": "0.12", // Total realized profit and loss - "position_status": "Normal", // status of position (Normal: normal Liq: in the process of liquidation Adl: in the process of Auto-Deleveraging) - // Auto margin replenishment enabled (0: no 1: yes) - "position_seq": 14 // position version number - } - ] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/StopOrderUpdate.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/StopOrderUpdate.txt deleted file mode 100644 index 941e642a..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/StopOrderUpdate.txt +++ /dev/null @@ -1,21 +0,0 @@ -[ - { - "order_id": "xxxxxxxx-xxxx-xxxx-98fb-335aaa6c613b", - "order_link_id": "", - "user_id": 1, - "symbol": "BTCUSD", - "side": "Buy", - "order_type": "Limit", - "price": "8584.5", - "qty": 1, - "time_in_force": "ImmediateOrCancel", - "create_type": "CreateByStopOrder", - "cancel_type": "", - "order_status": "Untriggered", //Stop Order Status - "stop_order_type": "Stop", - "trigger_by": "LastPrice", - "trigger_price": "8584.5", //If stop_order_type is TrailingProfit, this field is the trailing stop active price. - "close_on_trigger": false, - "timestamp": "2020-01-14T14:11:22.062Z" - } - ] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/TickerUpdate.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/TickerUpdate.txt deleted file mode 100644 index e457adce..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/TickerUpdate.txt +++ /dev/null @@ -1 +0,0 @@ -{"id":92,"symbol":"BITUSD","last_price_e4":19080,"last_price":"1.908","bid1_price_e4":19070,"bid1_price":"1.907","ask1_price_e4":19080,"ask1_price":"1.908","last_tick_direction":"ZeroMinusTick","prev_price_24h_e4":19740,"prev_price_24h":"1.974","price_24h_pcnt_e6":-33434,"high_price_24h_e4":20260,"high_price_24h":"2.026","low_price_24h_e4":18600,"low_price_24h":"1.860","prev_price_1h_e4":19140,"prev_price_1h":"1.914","price_1h_pcnt_e6":-3134,"mark_price_e4":19070,"mark_price":"1.907","index_price_e4":19060,"index_price":"1.906","open_interest":54392640,"open_value_e8":0,"total_turnover_e8":89893008673429363,"turnover_24h_e8":2955232844926929,"total_volume":1801762781,"volume_24h":57130366,"funding_rate_e6":548,"predicted_funding_rate_e6":100,"cross_seq":98763156,"created_at":"2021-11-04T13:32:53Z","updated_at":"2022-01-21T10:14:18Z","next_funding_time":"2022-01-21T16:00:00Z","countdown_hour":6,"funding_rate_interval":8} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/TradeUpdate.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/TradeUpdate.txt deleted file mode 100644 index 62bcdf38..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/TradeUpdate.txt +++ /dev/null @@ -1,13 +0,0 @@ - [ - { - "timestamp": "2020-01-12T16:59:59.000Z", - "trade_time_ms": 1582793344685, // trade time in millisecond - "symbol": "BTCUSD", - "side": "Sell", - "size": 328, - "price": 8098, - "tick_direction": "MinusTick", - "trade_id": "00c706e1-ba52-5bb0-98d0-bf694bdc69f7", - "cross_seq": 1052816407 - } - ] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/UserTradeUpdate.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/UserTradeUpdate.txt deleted file mode 100644 index f97cbd59..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Socket/UserTradeUpdate.txt +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "symbol": "BTCUSD", - "side": "Buy", - "order_id": "xxxxxxxx-xxxx-xxxx-9a8f-4a973eb5c418", - "exec_id": "xxxxxxxx-xxxx-xxxx-8b66-c3d2fcd352f6", - "order_link_id": "", - "price": "8300", - "order_qty": 1, - "exec_type": "Trade", - "exec_qty": 1, - "exec_fee": "0.00000009", - "leaves_qty": 0, - "is_maker": false, - "trade_time": "2020-01-14T14:07:23.629Z" // trade time - } - ] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelAllConditionalOrdersAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelAllConditionalOrdersAsync.txt deleted file mode 100644 index f2bf2e76..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelAllConditionalOrdersAsync.txt +++ /dev/null @@ -1,58 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": [ - { - "clOrdID": "dea89649-9492-459d-a8c4-c298b87b3d26", - "user_id": 1, - "symbol": "BTCUSD", - "side": "Sell", - "order_type": "Limit", - "price": "999999", - "qty": 1, - "time_in_force": "PostOnly", - "create_type": "CreateByUser", - "cancel_type": "CancelByUser", - "order_status": "", - "leaves_qty": 1, - "leaves_value": "0", - "created_at": "2019-12-17T12:13:20Z", - "updated_at": "2019-12-27T13:56:33.793799Z", - "cross_status": "Deactivated", - "cross_seq": -1, - "stop_order_type": "Stop", - "trigger_by": "LastPrice", - "base_price": "6910.5", - "expected_direction": "Rising" - }, - { - "clOrdID": "a85cd1c0-a9a4-49d3-a1bd-bab5ebe946d5", - "user_id": 1, - "symbol": "BTCUSD", - "side": "Buy", - "order_type": "Limit", - "price": "8000", - "qty": 1, - "time_in_force": "GoodTillCancel", - "create_type": "CreateByStopOrder", - "cancel_type": "CancelByUser", - "order_status": "", - "leaves_qty": 1, - "leaves_value": "0", - "created_at": "2019-12-27T12:48:24.339323Z", - "updated_at": "2019-12-27T13:56:33.793802Z", - "cross_status": "Deactivated", - "cross_seq": -1, - "stop_order_type": "Stop", - "trigger_by": "LastPrice", - "base_price": "7000", - "expected_direction": "Rising" - } - ], - "time_now": "1577454993.799912", - "rate_limit_status": 90, - "rate_limit_reset_ms": 1580885703683, - "rate_limit": 100 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelAllOrdersAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelAllOrdersAsync.txt deleted file mode 100644 index 3e54db55..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelAllOrdersAsync.txt +++ /dev/null @@ -1,31 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": [ - { - "clOrdID": "89a38056-80f1-45b2-89d3-4d8e3a203a79", - "user_id": 1, - "symbol": "BTCUSD", - "side": "Buy", - "order_type": "Limit", - "price": "7693.5", - "qty": 1, - "time_in_force": "GoodTillCancel", - "create_type": "CreateByUser", - "cancel_type": "CancelByUser", - "order_status": "", - "leaves_qty": 1, - "leaves_value": "0", - "created_at": "2019-11-30T10:38:53.564428Z", - "updated_at": "2019-11-30T10:38:59.102589Z", - "cross_status": "PendingCancel", // `PendingCancel` means the matching engine received the cancellation but there is no guarantee that the cancellation will be successful. - "cross_seq": 387734027 - } - ], - "time_now": "1575110339.105675", - "rate_limit_status": 98, - "rate_limit_reset_ms": 1580885703683, - "rate_limit": 100 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelConditionalOrderAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelConditionalOrderAsync.txt deleted file mode 100644 index 60fa78fb..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelConditionalOrderAsync.txt +++ /dev/null @@ -1,13 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "ok", - "ext_code": "", - "result": { - "stop_order_id": "c1025629-e85b-4c26-b4f3-76e86ad9f8cb" - }, - "ext_info": null, - "time_now": "1577452218.567120", - "rate_limit_status": 97, - "rate_limit_reset_ms": 1577452218573, - "rate_limit": "100" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelOrderAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelOrderAsync.txt deleted file mode 100644 index 2b68227c..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/CancelOrderAsync.txt +++ /dev/null @@ -1,31 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "user_id": 1, - "order_id": "3bd1844f-f3c0-4e10-8c25-10fea03763f6", - "symbol": "BTCUSD", - "side": "Buy", - "order_type": "Limit", - "price": 8800, - "qty": 1, - "time_in_force": "GoodTillCancel", - "order_status": "New", - "last_exec_time": "2019-11-30T11:17:18.396Z", - "last_exec_price": 0, - "leaves_qty": 1, - "cum_exec_qty": 0, - "cum_exec_value": 0, - "cum_exec_fee": 0, - "reject_reason": "", - "order_link_id": "", - "created_at": "2019-11-30T11:17:18.396Z", - "updated_at": "2019-11-30T11:18:01.811Z" - }, - "time_now": "1575112681.814760", - "rate_limit_status": 98, - "rate_limit_reset_ms": 1580885703683, - "rate_limit": 100 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetConditionalOrdersAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetConditionalOrdersAsync.txt deleted file mode 100644 index dc9d3c63..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetConditionalOrdersAsync.txt +++ /dev/null @@ -1,32 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "data": [ - { - "user_id": 160861, - "stop_order_status": "Active", - "symbol": "ETHUSD", - "side": "Buy", - "order_type": "Market", - "stop_order_type": "TakeProfit", - "price": "220", - "qty": "120", - "time_in_force": "ImmediateOrCancel", - "base_price": "258", - "order_link_id": "", - "created_at": "2019-08-02T07:37:24Z", - "updated_at": "2019-08-02T07:38:40Z", - "stop_px": "224.3", - "stop_order_id": "6d0dec74-f516-4d95-81f1-c85e60c9a331" - } - ], - "cursor": "zZtvOJ0gc3UOxZOwotsJSZyMTOgyC9tj1DmFyUU6eNHUL0X4NLwZvo8iqI6ltPIc" - }, - "time_now": "1604653512.292878", - "rate_limit_status": 599, - "rate_limit_reset_ms": 1604653512287, - "rate_limit": 600 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenConditionalOrderRealTimeAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenConditionalOrderRealTimeAsync.txt deleted file mode 100644 index e9cea343..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenConditionalOrderRealTimeAsync.txt +++ /dev/null @@ -1,31 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "user_id": 1, - "symbol": "BTCUSD", - "side": "Buy", - "order_type": "Limit", - "price": "8000", - "qty": 1, - "time_in_force": "GoodTillCancel", - "order_status": "Untriggered", - "ext_fields": {}, - "leaves_qty": 1, - "leaves_value": "0.00013333", - "cum_exec_qty": 0, - "cum_exec_value": null, - "cum_exec_fee": null, - "reject_reason": "", - "order_link_id": "", - "created_at": "2019-12-27T19:56:24.052194Z", - "updated_at": "2019-12-27T19:56:24.052194Z", - "order_id": "378a1bbc-a93a-4e75-87f4-502ea754ba36" - }, - "time_now": "1577476584.386958", - "rate_limit_status": 99, - "rate_limit_reset_ms": 1580885703683, - "rate_limit": 100 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenConditionalOrdersRealTimeAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenConditionalOrdersRealTimeAsync.txt deleted file mode 100644 index c3f2b0c2..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenConditionalOrdersRealTimeAsync.txt +++ /dev/null @@ -1,62 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": [ - { - "user_id": 100328, - "symbol": "EOSUSD", - "side": "Sell", - "order_type": "Limit", - "price": "2.7", - "qty": 1, - "stop_px": "2.0000", - "base_price": "2.7000", - "time_in_force": "GoodTillCancel", - "order_status": "Untriggered", - "ext_fields": {}, - "leaves_qty": 1, - "leaves_value": "0.37037037", - "cum_exec_qty": 0, - "cum_exec_value": null, - "cum_exec_fee": null, - "reject_reason": "EC_NoError", - "cancel_type": "UNKNOWN", - "order_link_id": "", - "created_at": "2020-12-17T08:21:15.246331281Z", - "updated_at": "2020-12-17T08:21:15.246331281Z", - "order_id": "a0dee45e-ae2a-4eb4-8205-9739075a7a81", - "trigger_by": "MarkPrice" - }, - { - "user_id": 100328, - "symbol": "EOSUSD", - "side": "Sell", - "order_type": "Limit", - "price": "2.6", - "qty": 1, - "stop_px": "2.0000", - "base_price": "2.7000", - "time_in_force": "GoodTillCancel", - "order_status": "Untriggered", - "ext_fields": {}, - "leaves_qty": 1, - "leaves_value": "0.38461538", - "cum_exec_qty": 0, - "cum_exec_value": null, - "cum_exec_fee": null, - "reject_reason": "EC_NoError", - "cancel_type": "UNKNOWN", - "order_link_id": "", - "created_at": "2020-12-17T08:21:10.924193413Z", - "updated_at": "2020-12-17T08:21:10.924193413Z", - "order_id": "51d048ba-a71f-40ef-b4c4-897e94590b80", - "trigger_by": "MarkPrice" - } - ], - "time_now": "1608193281.690286", - "rate_limit_status": 599, - "rate_limit_reset_ms": 1608193281687, - "rate_limit": 600 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenOrderRealTimeAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenOrderRealTimeAsync.txt deleted file mode 100644 index e7f39b2e..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenOrderRealTimeAsync.txt +++ /dev/null @@ -1,37 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "user_id": 106958, - "symbol": "BTCUSD", - "side": "Buy", - "order_type": "Limit", - "price": "11756.5", - "qty": 1, - "time_in_force": "PostOnly", - "order_status": "Filled", - "ext_fields": { - "o_req_num": -68948112492, - "xreq_type": "x_create" - }, - "last_exec_time": "1596304897.847944", - "last_exec_price": "11756.5", - "leaves_qty": 0, - "leaves_value": "0", - "cum_exec_qty": 1, - "cum_exec_value": "0.00008505", - "cum_exec_fee": "-0.00000002", - "reject_reason": "", - "cancel_type": "", - "order_link_id": "", - "created_at": "2020-08-01T18:00:26Z", - "updated_at": "2020-08-01T18:01:37Z", - "order_id": "e66b101a-ef3f-4647-83b5-28e0f38dcae0" - }, - "time_now": "1597171013.867068", - "rate_limit_status": 599, - "rate_limit_reset_ms": 1597171013861, - "rate_limit": 600 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenOrdersRealTimeAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenOrdersRealTimeAsync.txt deleted file mode 100644 index afe44cf1..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOpenOrdersRealTimeAsync.txt +++ /dev/null @@ -1,64 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": [ - { - "user_id": 100228, - "symbol": "BTCUSD", - "side": "Sell", - "order_type": "Limit", - "price": "17740", - "qty": 10, - "time_in_force": "GoodTillCancel", - "order_status": "New", - "ext_fields": { - "o_req_num": 434743, - "xreq_type": "x_create" - }, - "last_exec_time": "1608193181.827761", - "leaves_qty": 10, - "leaves_value": "0.00056369", - "cum_exec_qty": 0, - "cum_exec_value": "0.00008505", - "cum_exec_fee": "-0.00000002", - "reject_reason": "EC_NoError", - "cancel_type": "UNKNOWN", - "order_link_id": "", - "created_at": "2020-12-17T08:19:41.827637283Z", - "updated_at": "2020-12-17T08:19:41.827761Z", - "order_id": "d570d931-771e-4911-a24e-cdeddedb5b0e" - }, - { - "user_id": 100228, - "symbol": "BTCUSD", - "side": "Sell", - "order_type": "Limit", - "price": "17740", - "qty": 10, - "time_in_force": "GoodTillCancel", - "order_status": "New", - "ext_fields": { - "o_req_num": 434728, - "xreq_type": "x_create" - }, - "last_exec_time": "1608193178.955412", - "leaves_qty": 10, - "leaves_value": "0.00056369", - "cum_exec_qty": 0, - "cum_exec_value": "0.00008505", - "cum_exec_fee": "-0.00000002", - "reject_reason": "EC_NoError", - "cancel_type": "UNKNOWN", - "order_link_id": "", - "created_at": "2020-12-17T08:19:38.955297869Z", - "updated_at": "2020-12-17T08:19:38.955412Z", - "order_id": "88b91101-7ac1-40af-90b8-72d53fe23622" - } - ], - "time_now": "1608193190.911073", - "rate_limit_status": 599, - "rate_limit_reset_ms": 1608193190909, - "rate_limit": 600 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOrdersAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOrdersAsync.txt deleted file mode 100644 index 7e7bb948..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetOrdersAsync.txt +++ /dev/null @@ -1,35 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "data": [ - { - "user_id": 160861, - "order_status": "Cancelled", - "symbol": "BTCUSD", - "side": "Buy", - "order_type": "Market", - "price": "9800", - "qty": "16737", - "time_in_force": "ImmediateOrCancel", - "order_link_id": "", - "order_id": "fead08d7-47c0-4d6a-b9e7-5c71d5df8ba1", - "created_at": "2020-07-24T08:22:30Z", - "updated_at": "2020-07-24T08:22:30Z", - "leaves_qty": "0", - "leaves_value": "0", - "cum_exec_qty": "0", - "cum_exec_value": "0", - "cum_exec_fee": "0", - "reject_reason": "EC_NoImmediateQtyToFill" - } - ], - "cursor": "w01XFyyZc8lhtCLl6NgAaYBRfsN9Qtpp1f2AUy3AS4+fFDzNSlVKa0od8DKCqgAn" - }, - "time_now": "1604653633.173848", - "rate_limit_status": 599, - "rate_limit_reset_ms": 1604653633171, - "rate_limit": 600 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetUserTradesAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetUserTradesAsync.txt deleted file mode 100644 index 6a826852..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/GetUserTradesAsync.txt +++ /dev/null @@ -1,38 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "order_id": "Abandoned!!", // Abandoned!! - "trade_list": [ - { - "closed_size": 0, // The corresponding closing size of the closing order - "cross_seq": 277136382, - "exec_fee": "0.0000001", - "exec_id": "256e5ef8-abfe-5772-971b-f944e15e0d68", - "exec_price": "8178.5", - "exec_qty": 1, - "exec_type": "Trade", //Exec Type Enum - "exec_value": "0.00012227", - "fee_rate": "0.00075", - "last_liquidity_ind": "RemovedLiquidity", //Liquidity Enum, only valid while exec_type is Trade, AdlTrade, BustTrade - "leaves_qty": 0, - "nth_fill": 2, - "order_id": "7ad50cb1-9ad0-4f74-804b-d82a516e1029", - "order_link_id": "", - "order_price": "8178", - "order_qty": 1, - "order_type": "Market", //Order Type Enum - "side": "Buy", //Side Enum - "symbol": "BTCUSD", //Symbol Enum - "user_id": 1, - "trade_time_ms": 1577480599000 - } - ] - }, - "time_now": "1577483699.281488", - "rate_limit_status": 118, - "rate_limit_reset_ms": 1577477968183, - "rate_limit": 120 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/ModifyConditionalOrderAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/ModifyConditionalOrderAsync.txt deleted file mode 100644 index 1fea2c59..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/ModifyConditionalOrderAsync.txt +++ /dev/null @@ -1,13 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "ok", - "ext_code": "", - "result": { - "stop_order_id": "378a1bbc-a93a-4e75-87f4-502ea754ba36" - }, - "ext_info": null, - "time_now": "1577475760.604942", - "rate_limit_status": 96, - "rate_limit_reset_ms": 1577475760612, - "rate_limit": "100" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/ModifyOrderAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/ModifyOrderAsync.txt deleted file mode 100644 index e85de53d..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/ModifyOrderAsync.txt +++ /dev/null @@ -1,12 +0,0 @@ -{ - "ret_code": 0, //Error code, - "ret_msg": "ok", //Error message, - "ext_code": "", - "result": { - "order_id": "efa44157-c355-4a98-b6d6-1d846a936b93" - }, - "time_now": "1539778407.210858", // UTC timestamp - "rate_limit_status": 99, // The remaining number of accesses in one minute - "rate_limit_reset_ms": 1580885703683, - "rate_limit": 100 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/PlaceConditionalOrderAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/PlaceConditionalOrderAsync.txt deleted file mode 100644 index 64b030dc..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/PlaceConditionalOrderAsync.txt +++ /dev/null @@ -1,24 +0,0 @@ -{ - "ret_code":0, - "ret_msg":"OK", - "ext_code":"", - "ext_info":"", - "result":{ - "user_id":160880, - "symbol":"BTCUSD", - "side":"Buy", - "order_type":"Limit", - "price":"9003", - "qty":"2", - "time_in_force":"GoodTillCancel", - "remark":"127.0.0.1", - "leaves_qty":"2", - "leaves_value":"0", - "stop_px":"8232", - "reject_reason":"EC_NoError", - "stop_order_id":"eaf205ac-9dcc-44f6-8731-734e2101e61b", - "created_at":"2020-11-06T07:48:43.940Z", - "updated_at":"2020-11-06T07:48:43.940Z" - }, - "time_now":"1604648923.942177" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/PlaceOrderAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/PlaceOrderAsync.txt deleted file mode 100644 index f396575a..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/PlaceOrderAsync.txt +++ /dev/null @@ -1,31 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "user_id": 1, - "order_id": "335fd977-e5a5-4781-b6d0-c772d5bfb95b", - "symbol": "BTCUSD", - "side": "Buy", - "order_type": "Market", - "price": 8800, - "qty": 1, - "time_in_force": "GoodTillCancel", - "order_status": "Created", - "last_exec_time": 0, - "last_exec_price": 0, - "leaves_qty": 1, - "cum_exec_qty": 0, - "cum_exec_value": 0, - "cum_exec_fee": 0, - "reject_reason": "", - "order_link_id": "", - "created_at": "2019-11-30T11:03:43.452Z", - "updated_at": "2019-11-30T11:03:43.455Z" - }, - "time_now": "1575111823.458705", - "rate_limit_status": 98, - "rate_limit_reset_ms": 1580885703683, - "rate_limit": 100 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/SetTradingStopAsync.txt b/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/SetTradingStopAsync.txt deleted file mode 100644 index ff5e9b98..00000000 --- a/Bybit.UnitTests/JsonResponses/InversePerpetual/Trading/SetTradingStopAsync.txt +++ /dev/null @@ -1,48 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "ok", - "ext_code": "", - "result": { - "id": 27913, - "user_id": 1, - "symbol": "BTCUSD", - "side": "Buy", - "size": 5, - "position_value": 0.0006947, - "entry_price": 7197.35137469, - "risk_id": 1, - "auto_add_margin": 0, - "leverage": 6.95, - "position_margin": 9.996e-05, - "liq_price": 6320, - "bust_price": 6292.5, - "occ_closing_fee": 6e-07, - "occ_funding_fee": 0, - "take_profit": 0, - "stop_loss": 7000, - "trailing_stop": 0, - "position_status": "Normal", - "deleverage_indicator": 5, - "oc_calc_data": "{\"blq\":2,\"blv\":\"0.0002941\",\"slq\":0,\"bmp\":6800.408,\"smp\":0,\"fq\":-5,\"fc\":-0.00004279,\"bv2c\":0.14549282,\"sv2c\":0.14527699}", - "order_margin": 4.279e-05, - "wallet_balance": 0.03000227, - "realised_pnl": -1.26e-06, - "cum_realised_pnl": -1.306e-05, - "cum_commission": 0, - "cross_seq": 444081383, - "position_seq": 287176872, - "created_at": "2019-10-19T17:04:55.000Z", - "updated_at": "2019-12-27T21:17:27.000Z", - "ext_fields": { - "trailing_active":"9000", - "sl_trigger_by": "LastPrice", - "v": 221, - "mm": 0 - } - }, - "ext_info": null, - "time_now": "1577481447.436689", - "rate_limit_status": 73, - "rate_limit_reset_ms": 1577481447443, - "rate_limit": 75 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/Spot/Socket/BookPriceUpdateV1.txt b/Bybit.UnitTests/JsonResponses/Spot/Socket/BookPriceUpdateV1.txt deleted file mode 100644 index 7f8c9449..00000000 --- a/Bybit.UnitTests/JsonResponses/Spot/Socket/BookPriceUpdateV1.txt +++ /dev/null @@ -1,8 +0,0 @@ -{ - "symbol": "BTCUSDT", - "bidPrice": "9797.79", - "bidQty": "0.177976", - "askPrice": "9799", - "askQty": "0.65", - "time": 1582001830346 - } \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/AddReduceMarginAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/AddReduceMarginAsync.txt deleted file mode 100644 index 1bcb1d69..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/AddReduceMarginAsync.txt +++ /dev/null @@ -1,30 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "PositionListResult": { - "user_id": 160815, - "symbol": "BTCUSDT", - "side": "Buy", - "size": 3.14, - "position_value": 18843.14, - "entry_price": 6001, - "liq_price": 5428, - "bust_price": 5398, - "leverage": 10, - "position_margin": 1907.0331195, - "occ_closing_fee": 12.71229, - "realised_pnl": 3052.20905294, - "cum_realised_pnl": 75628.40815795, - "free_qty": 0 - }, - "wallet_balance": 68738.01696765, - "available_balance": 66830.98384815 - }, - "time_now": "1577480599.097287", - "rate_limit_status": 119, - "rate_limit_reset_ms": 1580885703683, - "rate_limit": 120 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetPositionAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetPositionAsync.txt deleted file mode 100644 index 14940516..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetPositionAsync.txt +++ /dev/null @@ -1,62 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": [ - { - "user_id":100004, - "symbol":"BTCUSDT", - "side":"Buy", - "size":0, - "position_value":0, //Current position value - "entry_price":0, //Average opening price - "liq_price":1, //Liquidation price - "bust_price":100, //Bust price - "leverage":0, - "is_isolated":true, - "auto_add_margin": 0, - "position_margin":0, //Position margin - "occ_closing_fee":0, //Pre-occupancy closing fee - "realised_pnl":0, //Today's realised Profit and Loss - "cum_realised_pnl":0, //Cumulative realised Profit and Loss - "free_qty": 30, //Qty which can be closed - "tp_sl_mode": "Full", - "unrealised_pnl": 0, - "deleverage_indicator": 0, - "risk_id": 0, - "stop_loss": 0, - "take_profit": 0, - "trailing_stop": 0 - }, - { - "user_id":100004, - "symbol":"BTCUSDT", - "side":"Sell", - "size":0, - "position_value":0, - "entry_price":0, - "liq_price":1, - "bust_price":100, - "leverage":0, - "is_isolated":true, - "auto_add_margin": 0, - "position_margin":0, - "occ_closing_fee":0, - "realised_pnl":0, - "cum_realised_pnl":0, - "free_qty": 30, - "tp_sl_mode": "Full", - "unrealised_pnl": 0, - "deleverage_indicator": 0, - "risk_id": 0, - "stop_loss": 0, - "take_profit": 0, - "trailing_stop": 0 - } - ], - "time_now": "1577480599.097287", - "rate_limit_status": 119, - "rate_limit_reset_ms": 1580885703683, - "rate_limit": 120 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetProfitAndLossHistoryAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetProfitAndLossHistoryAsync.txt deleted file mode 100644 index 99885448..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetProfitAndLossHistoryAsync.txt +++ /dev/null @@ -1,36 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "current_page": 1, - "data": [ - { - "id": 1710, - "user_id": 160815, - "symbol": "BTCUSDT", - "order_id": "e6a11e08-6dd0-404e-bea7-dc22b7ab0228", - "side": "Buy", - "qty": 0.5, - "order_price": 999999, - "order_type": "Market", - "exec_type": "Trade", - "closed_size": 0.5, //Closed size - "cum_entry_value": 3000, //Closed position value - "avg_entry_price": 6000, //Average entry price - "cum_exit_value": 3000.5, //Cumulative trading value of position closing orders - "avg_exit_price": 6001, //Average exit price - "closed_pnl": -5.000375, //Closed Profit and Loss - "fill_count": 1, //The number of fills in a single order - "leverage": 100, - "created_at": 1577480599 - } - ] - }, - "time_now": "1577480599.097287", - "rate_limit_status": 119, - "rate_limit_reset_ms": 1580885703683, - "rate_limit": 120 - -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetUserLastFundingFeeAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetUserLastFundingFeeAsync.txt deleted file mode 100644 index 4adb8e37..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetUserLastFundingFeeAsync.txt +++ /dev/null @@ -1,18 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "symbol": "BTCUSDT", - "side": "Buy", - "size": 3.13, - "funding_rate": 0.0001, - "exec_fee": 1.868923, - "exec_time": "2020-04-13T08:00:00.000Z" - }, - "time_now": "1586780352.867171", - "rate_limit_status": 119, - "rate_limit_reset_ms": 1586780352864, - "rate_limit": 120 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetUserPredictedFundingRateAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetUserPredictedFundingRateAsync.txt deleted file mode 100644 index 0ea8e03f..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/GetUserPredictedFundingRateAsync.txt +++ /dev/null @@ -1,14 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "predicted_funding_rate": -0.00375, - "predicted_funding_fee": 0.13081256 - }, - "time_now": "1587035697.424492", - "rate_limit_status": 119, - "rate_limit_reset_ms": 1587035697422, - "rate_limit": 120 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/SetFullPartialPositionModeAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/SetFullPartialPositionModeAsync.txt deleted file mode 100644 index e708613a..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Account/SetFullPartialPositionModeAsync.txt +++ /dev/null @@ -1,13 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "tp_sl_mode": "Partial" - }, - "time_now": "1598266294.610276", - "rate_limit_status": 72, - "rate_limit_reset_ms": 1598266294607, - "rate_limit": 75 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetAnnouncementsAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetAnnouncementsAsync.txt deleted file mode 100644 index abb1c660..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetAnnouncementsAsync.txt +++ /dev/null @@ -1,16 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": [ - { - "id": 2, - "title": "2019-12-02 RELEASE", - "link": "https://github.com/bybit-exchange/bybit-official-api-docs/blob/master/en/CHANGELOG.md", - "summary": "

New `cancel all` endpoint is here now!

Additionally, we strongly recommend that you use the new released place and cancel active V2 endpoints, which are more stable and efficient.The old ones are deprecated (although still working for the time be", - "created_at": "2019-12-02T11:33:42Z" - } - ], - "time_now": "1577444818.227082" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetIndexPriceKlinesAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetIndexPriceKlinesAsync.txt deleted file mode 100644 index 5f36887d..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetIndexPriceKlinesAsync.txt +++ /dev/null @@ -1,16 +0,0 @@ -{ - "ret_code":0, - "ret_msg":"OK", - "ext_code":"", - "ext_info":"", - "result":[{ - "symbol":"BTCUSDT", - "period":"1", - "open_time":1582231260, - "open":"10106.09", - "high":"10108.75", - "low":"10104.66", - "close":"10108.73" - }], - "time_now":"1591263582.601795" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetKlinesAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetKlinesAsync.txt deleted file mode 100644 index 25f247cd..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetKlinesAsync.txt +++ /dev/null @@ -1,22 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": [ - { - "id": 3866948, - "symbol": "BTCUSDT", - "period": "1", - "start_at": 1577836800, // Abandoned!! - "volume": 1451.59, - "open": 7700, // Abandoned!! - "high": 999999, - "low": 0.5, - "close": 6000, - "interval": 1, - "open_time": 1577836800, - "turnover": 2.4343353100000003, - }], - "time_now": "1581928016.558522" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetLastFundingRateAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetLastFundingRateAsync.txt deleted file mode 100644 index 1298e944..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetLastFundingRateAsync.txt +++ /dev/null @@ -1,12 +0,0 @@ -{ - "ret_code":0, - "ret_msg":"OK", - "ext_code":"", - "ext_info":"", - "result":{ - "symbol":"BTCUSDT", - "funding_rate":-0.00005965, - "funding_rate_timestamp":"2020-04-07T08:00:00.000Z" - }, - "time_now":"1586251109.454281" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetMarkPriceKlinesAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetMarkPriceKlinesAsync.txt deleted file mode 100644 index f025730c..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetMarkPriceKlinesAsync.txt +++ /dev/null @@ -1,27 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": [{ - "id": 3866948, - "symbol": "BTCUSDT", - "period": "1", - "start_at": 1577836800, - "open": 7700, - "high": 999999, - "low": 0.5, - "close": 6000 - }, - { - "id": 3866948, - "symbol": "BTCUSDT", - "period": "1", - "start_at": 1577836800, - "open": 7700, - "high": 999999, - "low": 0.5, - "close": 6000 - }], - "time_now": "1581928016.558522" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetPremiumIndexKlinesAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetPremiumIndexKlinesAsync.txt deleted file mode 100644 index 64b8a451..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetPremiumIndexKlinesAsync.txt +++ /dev/null @@ -1,16 +0,0 @@ -{ - "ret_code":0, - "ret_msg":"OK", - "ext_code":"", - "ext_info":"", - "result":[{ - "symbol":"BTCUSDT", - "period":"1", - "open_time":1582231260, - "open":"0.000588", - "high":"0.000618", - "low":"0.000588", - "close":"0.000618" - }], - "time_now":"1591263582.601795" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetTradeHistoryAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetTradeHistoryAsync.txt deleted file mode 100644 index b7b4fdee..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/ExchangeData/GetTradeHistoryAsync.txt +++ /dev/null @@ -1,18 +0,0 @@ -{ - "ret_code": 0, // error code 0 means success - "ret_msg": "OK", // error message - "ext_code": "", - "ext_info": "", - "result": [ - { - "id": "18368131384", // ID, string type, all ids are in descending order globally - "symbol": "BTCUSDT", // contract type - "price": 9499.5, // execution price - "qty": 9500, // execution quantity - "side": "Buy", // side - "time": "2019-11-19T08:03:04.077Z", // Abandoned!! - "trade_time_ms":1587638305175 - } - ], - "time_now": "1567109419.049271" -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/BalanceUpdate.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/BalanceUpdate.txt deleted file mode 100644 index 36b97fac..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/BalanceUpdate.txt +++ /dev/null @@ -1,6 +0,0 @@ -[ - { - "wallet_balance":429.80713, - "available_balance":429.67322 - } - ] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/KlineUpdate.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/KlineUpdate.txt deleted file mode 100644 index e4b35863..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/KlineUpdate.txt +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "start":1588071660, - "end":1588071720, - "open":7744.5, - "close":7745, - "high":7745, - "low":7744, - "volume":"33.051", - "turnover":"255979.995", - "confirm":true, - "cross_seq":71947372, - "timestamp":1588071717325846 - } - ] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/LiquidationUpdate.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/LiquidationUpdate.txt deleted file mode 100644 index b184b81d..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/LiquidationUpdate.txt +++ /dev/null @@ -1,7 +0,0 @@ -{ - "symbol":"XRPUSDT", - "side":"Sell", - "price":"3384.15", - "qty":"0.057", - "time":1631608881954 - } \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/OrderUpdate1.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/OrderUpdate1.txt deleted file mode 100644 index 9353ca2b..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/OrderUpdate1.txt +++ /dev/null @@ -1,26 +0,0 @@ -[ - { - "order_id": "xxxxxxxx-xxxx-xxxx-9a8f-4a973eb5c418", - "order_link_id": "", - "symbol": "BTCUSDT", - "side": "Buy", - "order_type": "Limit", - "price": 11000, - "qty": 0.001, - "leaves_qty": 0.001, - "last_exec_price": 0, - "cum_exec_qty": 0, - "cum_exec_value": 0, - "cum_exec_fee": 0, - "time_in_force": "GoodTillCancel", - "create_type": "CreateByUser", - "cancel_type": "UNKNOWN", - "order_status": "New", - "take_profit": 0, - "stop_loss": 0, - "trailing_stop": 0, - "reduce_only": false, - "close_on_trigger": false, - "position_idx": 1 - } - ] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/OrderUpdate2.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/OrderUpdate2.txt deleted file mode 100644 index 4fe9fc84..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/OrderUpdate2.txt +++ /dev/null @@ -1,28 +0,0 @@ -[ -{ -"order_id": "19bffe79-de68-4c53-9515-4f91b0c70112", -"order_link_id": "", -"symbol": "BTCUSDT", -"side": "Buy", -"order_type": "Market", -"price": 38262, -"qty": 0.01, -"leaves_qty": 0, -"last_exec_price": 36442, -"cum_exec_qty": 0.01, -"cum_exec_value": 364.411, -"cum_exec_fee": 0.0273315, -"time_in_force": "ImmediateOrCancel", -"create_type": "CreateByUser", -"cancel_type": "UNKNOWN", -"order_status": "Filled", -"take_profit": 0, -"stop_loss": 0, -"trailing_stop": 0, -"create_time": "2022-01-25T10:32:34.519268798Z", -"update_time": "2022-01-25T10:32:34.519369Z", -"reduce_only": false, -"close_on_trigger": false, -"position_idx": "1" -} -] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/PositionUpdate1.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/PositionUpdate1.txt deleted file mode 100644 index c6252fcb..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/PositionUpdate1.txt +++ /dev/null @@ -1,27 +0,0 @@ -[ - { - "user_id": 1, - "symbol": "BTCUSD", - "size": 11, - "side": "Sell", - "position_value": "0.00159252", - "entry_price": "6907.291588174717", - "liq_price": "7100.234", - "bust_price": "7088.1234", - "leverage": "1", - "order_margin": "1", - "position_margin": "1", - "occ_closing_fee": "0.1", - "take_profit": "0.1", - "tp_trigger_by": 0, - "stop_loss": "0.12", - "realised_pnl": "0", - "cum_realised_pnl": "0.1", - "position_seq": 14, - "tp_sl_mode": "Full", - "position_idx": 1, - "mode": "MergedSingle", - "isolated": true, - "risk_id": 0 - } - ] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/PositionUpdate2.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/PositionUpdate2.txt deleted file mode 100644 index 22b5ee7d..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/PositionUpdate2.txt +++ /dev/null @@ -1,66 +0,0 @@ -[ -{ -"user_id": "443745", -"symbol": "BTCUSDT", -"size": 0.01, -"side": "Buy", -"position_value": 364.411, -"entry_price": 36441.098, -"liq_price": 32979.5, -"bust_price": 32797, -"leverage": 10, -"order_margin": 0, -"position_margin": 36.68708, -"occ_closing_fee": 0.2459775, -"take_profit": 0, -"tp_trigger_by": "UNKNOWN", -"stop_loss": 0, -"sl_trigger_by": "UNKNOWN", -"trailing_stop": 0, -"realised_pnl": -3.9626534, -"auto_add_margin": "0", -"cum_realised_pnl": -4.0535393, -"position_status": "Normal", -"position_id": "0", -"position_seq": "10383", -"adl_rank_indicator": "2", -"free_qty": 0.01, -"tp_sl_mode": "Full", -"risk_id": "1", -"isolated": true, -"mode": "BothSide", -"position_idx": "1" -}, -{ -"user_id": "443745", -"symbol": "BTCUSDT", -"size": 0, -"side": "Sell", -"position_value": 0, -"entry_price": 0, -"liq_price": 0, -"bust_price": 0, -"leverage": 10, -"order_margin": 0, -"position_margin": 0, -"occ_closing_fee": 0, -"take_profit": 0, -"tp_trigger_by": "UNKNOWN", -"stop_loss": 0, -"sl_trigger_by": "UNKNOWN", -"trailing_stop": 0, -"realised_pnl": -0.9992362, -"auto_add_margin": "0", -"cum_realised_pnl": -0.9992362, -"position_status": "Normal", -"position_id": "0", -"position_seq": "10380", -"adl_rank_indicator": "0", -"free_qty": 0, -"tp_sl_mode": "Full", -"risk_id": "1", -"isolated": true, -"mode": "BothSide", -"position_idx": "2" -} -] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/StopOrderUpdate.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/StopOrderUpdate.txt deleted file mode 100644 index 49a66840..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/StopOrderUpdate.txt +++ /dev/null @@ -1,22 +0,0 @@ - [ - { - "stop_order_id": "xxxxxxxx-xxxx-xxxx-98fb-335aaa6c613b", - "order_link_id": "", - "user_id": 1, - "symbol": "BTCUSD", - "side": "Buy", - "order_type": "Limit", - "price": "8584.5", - "qty": 1, - "time_in_force": "ImmediateOrCancel", - "order_status": "Untriggered", //Stop Order Status - "stop_order_type": "Stop", - "trigger_by": "LastPrice", - "trigger_price": "8584.5", - "reduce_only": false, - "close_on_trigger": false, - "position_idx": 1, - "create_time": "2020-01-14T14:11:22.062Z", - "update_time": "2020-01-14T14:11:22.062Z" - } - ] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/TickerUpdate.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/TickerUpdate.txt deleted file mode 100644 index 9a7fb131..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/TickerUpdate.txt +++ /dev/null @@ -1,39 +0,0 @@ -{ - "id": 1, - "symbol": "BTCUSDT", - "last_price_e4": "322955000", - "last_price": "322955000", - "last_tick_direction": "ZeroPlusTick", - "prev_price_24h_e4": "331960000", - "prev_price_24h": "331960000", - "price_24h_pcnt_e6": "-27126", - "high_price_24h_e4": "333120000", - "high_price_24h": "333120000", - "low_price_24h_e4": "315940000", - "low_price_24h": "315940000", - "prev_price_1h_e4": "319490000", - "prev_price_1h": "319490000", - "price_1h_pcnt_e6": "10845", - "mark_price_e4": "323133000", - "mark_price": "323133000", - "index_price_e4": "323106800", - "index_price": "323106800", - "open_interest_e8": "1430451600000", - "total_turnover_e8": "5297934997553700000", - "turnover_24h_e8": "243143978993099700", - "total_volume_e8": "1184936057899924", - "volume_24h_e8": "7511238100000", - "funding_rate_e6": "100", - "predicted_funding_rate_e6": "-15", - "cross_seq": "6501157651", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "2021-07-14T09:32:10.000Z", - "next_funding_time": "2021-07-14T16:00:00Z", - "count_down_hour": 7, - "funding_rate_interval": 8, - "bid1_price_e4": "322950000", - "ask1_price_e4": "322955000", - "bid1_price": "322950000", - "ask1_price_e4": "322955000", - "ask1_price": "322955000", - } \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/TradeUpdate.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/TradeUpdate.txt deleted file mode 100644 index 47dc4deb..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/TradeUpdate.txt +++ /dev/null @@ -1,12 +0,0 @@ - [ - { - "symbol": "BTCUSDT", - "tick_direction": "PlusTick", - "price": 8098, - "size": 328, - "timestamp":"2020-03-30T02:21:06.000Z", - "trade_time_ms":"1585534866418", - "side":"Sell", - "trade_id":"01e79e28-d1f4-59ac-b079-ca909606d91a" - } - ] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/UserTradeUpdate.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/UserTradeUpdate.txt deleted file mode 100644 index 1044154e..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Socket/UserTradeUpdate.txt +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "symbol": "BTCUSDT", - "side": "Sell", - "order_id": "xxxxxxxx-xxxx-xxxx-9a8f-4a973eb5c418", - "exec_id": "xxxxxxxx-xxxx-xxxx-8b66-c3d2fcd352f6", - "order_link_id": "", - "price": 11527.5, - "order_qty": 0.001, - "exec_type": "Trade", - "exec_qty": 0.001, - "exec_fee": 0.00864563, - "leaves_qty": 0, - "is_maker": false, - "trade_time": "2020-08-12T21:16:18.142746Z" - } - ] \ No newline at end of file diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Trading/GetOpenConditionalOrderRealTimeAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Trading/GetOpenConditionalOrderRealTimeAsync.txt deleted file mode 100644 index daf1db5d..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Trading/GetOpenConditionalOrderRealTimeAsync.txt +++ /dev/null @@ -1,39 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": { - "stop_order_id": "", - "order_link_id": "", - "base_price": 20000, - "trigger_by": "MarkPrice", - "tp_trigger_by": "LastPrice", - "sl_trigger_by": "LastPrice", - "reduce_only": false, - "close_on_trigger": false, - "take_profit": 16500, - "stop_loss": 22000, - "trigger_price": null, - "user_id": 533285, - "Symbol": "BTCUSDM22", - "Side": "Sell", - "order_type": "Market", - "Price": 0, - "qty": 130, - "time_in_force": "ImmediateOrCancel", - "leaves_value": 0, - "leaves_qty": 130, - "created_at": "2022-06-23T07:15:46.8037185Z", - "created_time": 1655968546804, - "create_time": 1655968546804, - "updated_at": "2022-06-23T07:15:46.8037185Z", - "updated_time": 1655968546804, - "update_time": 1655968546804, - "cancel_type": "UNKNOWN" - }, - "time_now": "1655969170.027184", - "rate_limit_status": 599, - "rate_limit_reset_ms": 1655969170024, - "rate_limit": 600 -} diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Trading/GetOpenConditionalOrdersRealTimeAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Trading/GetOpenConditionalOrdersRealTimeAsync.txt deleted file mode 100644 index c843aedf..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Trading/GetOpenConditionalOrdersRealTimeAsync.txt +++ /dev/null @@ -1,70 +0,0 @@ -{ - "ret_code": 0, - "ret_msg": "OK", - "ext_code": "", - "ext_info": "", - "result": [ - { - "stop_order_id": "", - "order_link_id": "", - "base_price": 2.7, - "trigger_by": "MarkPrice", - "tp_trigger_by": null, - "sl_trigger_by": null, - "reduce_only": false, - "close_on_trigger": false, - "take_profit": null, - "stop_loss": null, - "trigger_price": null, - "user_id": 100328, - "Symbol": "EOSUSD", - "Side": "Sell", - "order_type": "Limit", - "Price": 2.7, - "qty": 1, - "time_in_force": "GoodTillCancel", - "leaves_value": 0.37037037, - "leaves_qty": 1, - "created_at": "2020-12-17T08:21:15.2463313Z", - "created_time": 1608193275246, - "create_time": 1608193275246, - "updated_at": "2020-12-17T08:21:15.2463313Z", - "updated_time": 1608193275246, - "update_time": 1608193275246, - "cancel_type": "UNKNOWN" - }, - { - "stop_order_id": "", - "order_link_id": "", - "base_price": 2.7, - "trigger_by": "MarkPrice", - "tp_trigger_by": null, - "sl_trigger_by": null, - "reduce_only": false, - "close_on_trigger": false, - "take_profit": null, - "stop_loss": null, - "trigger_price": null, - "user_id": 100328, - "Symbol": "EOSUSD", - "Side": "Sell", - "order_type": "Limit", - "Price": 2.6, - "qty": 1, - "time_in_force": "GoodTillCancel", - "leaves_value": 0.38461538, - "leaves_qty": 1, - "created_at": "2020-12-17T08:21:10.9241934Z", - "created_time": 1608193270924, - "create_time": 1608193270924, - "updated_at": "2020-12-17T08:21:10.9241934Z", - "updated_time": 1608193270924, - "update_time": 1608193270924, - "cancel_type": "UNKNOWN" - } - ], - "time_now": "1608193281.690286", - "rate_limit_status": 599, - "rate_limit_reset_ms": 1608193281687, - "rate_limit": 600 -} diff --git a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Trading/GetUserTradesAsync.txt b/Bybit.UnitTests/JsonResponses/UsdPerpetual/Trading/GetUserTradesAsync.txt deleted file mode 100644 index 344ce523..00000000 --- a/Bybit.UnitTests/JsonResponses/UsdPerpetual/Trading/GetUserTradesAsync.txt +++ /dev/null @@ -1,1115 +0,0 @@ -{ -"ret_code": 0, -"ret_msg": "OK", -"ext_code": "", -"ext_info": "", -"result": { -"current_page": 1, -"data": [ -{ -"order_id": "f32133d7-66d8-4ad7-99d2-5267e2dc5d4f", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "f32133d7-66d8-4ad7-99d2-5267e2dc5d4f", -"price": 0.00733, -"order_price": 0.00733, -"order_qty": 940, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00718, -"exec_type": "BustTrade", -"exec_qty": 940, -"exec_fee": 0.00404952, -"exec_value": 6.7492, -"leaves_qty": 0, -"closed_size": 940, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652253746, -"trade_time_ms": 1652253746981 -}, -{ -"order_id": "085a39f1-d948-455e-b033-415196f6aa38", -"order_link_id": "", -"side": "Buy", -"symbol": "SLPUSDT", -"exec_id": "9df92d3f-8c7c-56f0-9238-c679a13c3b75", -"price": 0.00778, -"order_price": 0.00778, -"order_qty": 940, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00755, -"exec_type": "Trade", -"exec_qty": 940, -"exec_fee": 0.0042582, -"exec_value": 7.097, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652253494, -"trade_time_ms": 1652253494616 -}, -{ -"order_id": "e911c04f-a768-421c-ac09-841746c23a8b", -"order_link_id": "", -"side": "Buy", -"symbol": "SLPUSDT", -"exec_id": "379284fa-4322-566a-a407-317818468bdc", -"price": 0.00767, -"order_price": 0.00767, -"order_qty": 480, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00732, -"exec_type": "Trade", -"exec_qty": 480, -"exec_fee": 0.00210816, -"exec_value": 3.5136, -"leaves_qty": 0, -"closed_size": 480, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652253198, -"trade_time_ms": 1652253198309 -}, -{ -"order_id": "f4d4675d-f3f5-4eed-a5de-115fa084e273", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "7c0cd568-241f-55fe-a8ae-010d52391848", -"price": 0.00719, -"order_price": 0.00719, -"order_qty": 480, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00736, -"exec_type": "Trade", -"exec_qty": 480, -"exec_fee": 0.00211968, -"exec_value": 3.5328, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652253163, -"trade_time_ms": 1652253163020 -}, -{ -"order_id": "7fbfa24c-f2ab-4717-be97-16e5ee586ecf", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "5b5f1c7b-467d-51b7-87c3-d035e02d26b8", -"price": 0.00729, -"order_price": 0.00729, -"order_qty": 460, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00767, -"exec_type": "Trade", -"exec_qty": 460, -"exec_fee": 0.00211692, -"exec_value": 3.5282, -"leaves_qty": 0, -"closed_size": 460, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652252703, -"trade_time_ms": 1652252703074 -}, -{ -"order_id": "1652252400-SLPUSDT-24638417-Buy", -"order_link_id": "", -"side": "Buy", -"symbol": "SLPUSDT", -"exec_id": "5a01cfa0-fe92-4edf-9f1b-3adcbfa5fe9f", -"price": 0, -"order_price": 0, -"order_qty": 0, -"order_type": "", -"fee_rate": 1.25E-05, -"exec_price": 0.00758, -"exec_type": "Funding", -"exec_qty": 460, -"exec_fee": 4.359E-05, -"exec_value": 3.4868, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "LiquidityIndNA", -"trade_time": 1652252400, -"trade_time_ms": 1652252400000 -}, -{ -"order_id": "85902a57-f353-4c08-a4df-76cc6e10befe", -"order_link_id": "", -"side": "Buy", -"symbol": "SLPUSDT", -"exec_id": "028136a5-de65-5349-8609-065827a2ae82", -"price": 0.00798, -"order_price": 0.00798, -"order_qty": 460, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.0076, -"exec_type": "Trade", -"exec_qty": 460, -"exec_fee": 0.0020976, -"exec_value": 3.496, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652252279, -"trade_time_ms": 1652252279729 -}, -{ -"order_id": "1a43798e-8759-4bb4-b998-9ad2a8ee1ce0", -"order_link_id": "", -"side": "Buy", -"symbol": "SLPUSDT", -"exec_id": "56531fd0-5c4a-5b8f-a50d-f39e54293963", -"price": 0.00841, -"order_price": 0.00841, -"order_qty": 440, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00802, -"exec_type": "Trade", -"exec_qty": 440, -"exec_fee": 0.00211728, -"exec_value": 3.5288, -"leaves_qty": 0, -"closed_size": 440, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652250429, -"trade_time_ms": 1652250429905 -}, -{ -"order_id": "216f2226-0b1a-4dbf-b94c-0d5e88ea574f", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "ff53a28a-c1dd-5ad9-b6df-4caf9d893152", -"price": 0.00799, -"order_price": 0.00799, -"order_qty": 440, -"order_type": "Limit", -"fee_rate": 0.0006, -"exec_price": 0.00799, -"exec_type": "Trade", -"exec_qty": 190, -"exec_fee": 0.00091086, -"exec_value": 1.5181, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652250278, -"trade_time_ms": 1652250278138 -}, -{ -"order_id": "216f2226-0b1a-4dbf-b94c-0d5e88ea574f", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "980101d9-c770-5b38-8f5e-183cad70f73d", -"price": 0.00799, -"order_price": 0.00799, -"order_qty": 440, -"order_type": "Limit", -"fee_rate": 0.0006, -"exec_price": 0.00799, -"exec_type": "Trade", -"exec_qty": 250, -"exec_fee": 0.0011985, -"exec_value": 1.9975, -"leaves_qty": 190, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652250278, -"trade_time_ms": 1652250278138 -}, -{ -"order_id": "f20efb77-1079-45be-bb2e-5f4dae3d8191", -"order_link_id": "", -"side": "Buy", -"symbol": "SLPUSDT", -"exec_id": "ef8ca6f2-e507-58c0-9eee-a08d6c905e98", -"price": 0.0089, -"order_price": 0.0089, -"order_qty": 240, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 240, -"exec_fee": 0.00122256, -"exec_value": 2.0376, -"leaves_qty": 0, -"closed_size": 240, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247766, -"trade_time_ms": 1652247766520 -}, -{ -"order_id": "d776e172-71c4-4c7e-a2ab-7c7b7ffd1121", -"order_link_id": "", -"side": "Buy", -"symbol": "SLPUSDT", -"exec_id": "c64a11b2-cc62-5d25-8153-0038890cff33", -"price": 0.00891, -"order_price": 0.00891, -"order_qty": 1730, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.0085, -"exec_type": "Trade", -"exec_qty": 1730, -"exec_fee": 0.008823, -"exec_value": 14.705, -"leaves_qty": 0, -"closed_size": 1730, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247758, -"trade_time_ms": 1652247758539 -}, -{ -"order_id": "c50902df-476f-4ebc-9802-e251853ceacc", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "16faf138-af70-52a2-a806-eba958a3f443", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 240, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 240, -"exec_fee": 0.00122256, -"exec_value": 2.0376, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247756, -"trade_time_ms": 1652247756708 -}, -{ -"order_id": "d7098f48-ce27-4fbe-bc56-7fce3d60af1a", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "4c0b4bb3-c879-5d7c-89a2-d7b2b5c96c00", -"price": 0.00808, -"order_price": 0.00808, -"order_qty": 300, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.0085, -"exec_type": "Trade", -"exec_qty": 300, -"exec_fee": 0.00153, -"exec_value": 2.55, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247750, -"trade_time_ms": 1652247750434 -}, -{ -"order_id": "3e179f1d-e656-4ca6-b828-86b8428d6a15", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "535730f2-692c-5ba3-873d-6a79c4c9a6d0", -"price": 0.00808, -"order_price": 0.00808, -"order_qty": 300, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00851, -"exec_type": "Trade", -"exec_qty": 300, -"exec_fee": 0.0015318, -"exec_value": 2.553, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247744, -"trade_time_ms": 1652247744081 -}, -{ -"order_id": "ee754562-2a31-4f88-bb4e-e3c5a4eae21c", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "f6bd2db8-3b20-592b-b409-8c9dd8b6f35f", -"price": 0.00807, -"order_price": 0.00807, -"order_qty": 340, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 340, -"exec_fee": 0.00173196, -"exec_value": 2.8866, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247737, -"trade_time_ms": 1652247737242 -}, -{ -"order_id": "93a9bcac-fd02-46ce-8893-67a7102be334", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "12d970fa-eccf-510b-b34a-067c99645cfa", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 370, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 50, -"exec_fee": 0.0002547, -"exec_value": 0.4245, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247730, -"trade_time_ms": 1652247730899 -}, -{ -"order_id": "93a9bcac-fd02-46ce-8893-67a7102be334", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "9eea7de8-79fa-546b-abb2-f4a6bdba12ff", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 370, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.0085, -"exec_type": "Trade", -"exec_qty": 320, -"exec_fee": 0.001632, -"exec_value": 2.72, -"leaves_qty": 50, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247730, -"trade_time_ms": 1652247730899 -}, -{ -"order_id": "ead6aec6-b697-44d6-8cb2-c24ec00d629e", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "7755ed3f-f240-5115-ab55-c970ea51daa5", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 410, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 410, -"exec_fee": 0.00208854, -"exec_value": 3.4809, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247724, -"trade_time_ms": 1652247724425 -}, -{ -"order_id": "f9a93f97-14ad-4f6c-9039-06692558642f", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "58961ed3-edc7-5d71-9564-4cf4a954377e", -"price": 0.00808, -"order_price": 0.00808, -"order_qty": 10, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 10, -"exec_fee": 5.094E-05, -"exec_value": 0.0849, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247718, -"trade_time_ms": 1652247718172 -}, -{ -"order_id": "bdd777d2-20e1-46cb-8059-2d8a60e2c239", -"order_link_id": "", -"side": "Buy", -"symbol": "SLPUSDT", -"exec_id": "608c5bb3-ecf1-56aa-8d8e-613f593cd642", -"price": 0.00892, -"order_price": 0.00892, -"order_qty": 4080, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00851, -"exec_type": "Trade", -"exec_qty": 4080, -"exec_fee": 0.02083248, -"exec_value": 34.7208, -"leaves_qty": 0, -"closed_size": 4080, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247716, -"trade_time_ms": 1652247716716 -}, -{ -"order_id": "00d749f9-82b1-4e18-ae55-968a0715ab56", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "6e6d2e31-9d24-5feb-b9c6-0d976625b71b", -"price": 0.00807, -"order_price": 0.00807, -"order_qty": 10, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.0085, -"exec_type": "Trade", -"exec_qty": 10, -"exec_fee": 5.1E-05, -"exec_value": 0.085, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247711, -"trade_time_ms": 1652247711815 -}, -{ -"order_id": "ada2fd10-db3b-4809-8e47-43de5f39370e", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "b43c7626-0bc5-5432-bea2-3496f95c2388", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 10, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 10, -"exec_fee": 5.094E-05, -"exec_value": 0.0849, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247705, -"trade_time_ms": 1652247705546 -}, -{ -"order_id": "8023c368-956f-41ee-9ef8-299d42815783", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "a11c1c4f-a1c3-5dc0-9419-0428f6c6853c", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 10, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 10, -"exec_fee": 5.094E-05, -"exec_value": 0.0849, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247699, -"trade_time_ms": 1652247699197 -}, -{ -"order_id": "280f7faf-041a-4e47-a932-66968ac62e30", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "75c98ec3-4970-5e4e-b80e-472c96bc7657", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 10, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 10, -"exec_fee": 5.094E-05, -"exec_value": 0.0849, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247692, -"trade_time_ms": 1652247692967 -}, -{ -"order_id": "382a6d66-9bd4-492b-89d3-79d5a008b3ee", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "a7a2af35-6da0-5103-8fc7-81db766e2388", -"price": 0.00805, -"order_price": 0.00805, -"order_qty": 10, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 10, -"exec_fee": 5.094E-05, -"exec_value": 0.0849, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247686, -"trade_time_ms": 1652247686688 -}, -{ -"order_id": "11ff4b3e-e659-4ef0-adc1-6c57f558b532", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "da2d8447-1a61-5f23-abea-0cd397c765fe", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 10, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00848, -"exec_type": "Trade", -"exec_qty": 10, -"exec_fee": 5.088E-05, -"exec_value": 0.0848, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247680, -"trade_time_ms": 1652247680433 -}, -{ -"order_id": "319573bf-46b8-44e4-8457-febbb46b32b2", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "eec2a817-f309-5220-bf53-a38c221efdda", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 10, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00848, -"exec_type": "Trade", -"exec_qty": 10, -"exec_fee": 5.088E-05, -"exec_value": 0.0848, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247674, -"trade_time_ms": 1652247674072 -}, -{ -"order_id": "92ec6efe-d74f-4b99-a64a-b171885ed43e", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "14598aca-d7c2-57f3-988c-42be2d787f20", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 20, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 20, -"exec_fee": 0.00010188, -"exec_value": 0.1698, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247667, -"trade_time_ms": 1652247667724 -}, -{ -"order_id": "c065d797-c7b6-46e3-86d6-80116a94969d", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "458dee9f-92b7-5e24-81dd-14bc7a5530eb", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 20, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 20, -"exec_fee": 0.00010188, -"exec_value": 0.1698, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247661, -"trade_time_ms": 1652247661442 -}, -{ -"order_id": "ff7c682b-6dd9-4e7e-b1fa-8c5ecfe31a7f", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "8a742877-3828-5356-b387-af07e82a912c", -"price": 0.00805, -"order_price": 0.00805, -"order_qty": 20, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00848, -"exec_type": "Trade", -"exec_qty": 20, -"exec_fee": 0.00010176, -"exec_value": 0.1696, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247655, -"trade_time_ms": 1652247655083 -}, -{ -"order_id": "87e1de31-f802-4947-b330-e65c90d99726", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "7edcdd01-ba1f-52f9-b1b0-ee36a6a1a90f", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 20, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00848, -"exec_type": "Trade", -"exec_qty": 20, -"exec_fee": 0.00010176, -"exec_value": 0.1696, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247648, -"trade_time_ms": 1652247648724 -}, -{ -"order_id": "d3e4146d-8eb4-4a62-8ff9-0f1b3b39e8b4", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "4c3907d7-36c4-5c05-898c-da18b9bf37e8", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 20, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 20, -"exec_fee": 0.00010188, -"exec_value": 0.1698, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247642, -"trade_time_ms": 1652247642508 -}, -{ -"order_id": "9ecb8314-fee6-4113-bd21-cc8447735a5a", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "06c55ab3-a115-539e-8bf1-a64dc36cfa9f", -"price": 0.00807, -"order_price": 0.00807, -"order_qty": 30, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 30, -"exec_fee": 0.00015282, -"exec_value": 0.2547, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247636, -"trade_time_ms": 1652247636198 -}, -{ -"order_id": "211d5c64-8ef2-45b2-9673-78e77db765b0", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "4f6127a7-9cc2-533f-b8cd-8557147c3cd0", -"price": 0.00805, -"order_price": 0.00805, -"order_qty": 30, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00848, -"exec_type": "Trade", -"exec_qty": 30, -"exec_fee": 0.00015264, -"exec_value": 0.2544, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247629, -"trade_time_ms": 1652247629964 -}, -{ -"order_id": "7a0ae1ab-2c41-4159-a5ed-3e9b656743da", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "af2ddbf3-8500-5426-84d3-f32d78419121", -"price": 0.00808, -"order_price": 0.00808, -"order_qty": 30, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00851, -"exec_type": "Trade", -"exec_qty": 30, -"exec_fee": 0.00015318, -"exec_value": 0.2553, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247623, -"trade_time_ms": 1652247623716 -}, -{ -"order_id": "4dc6ff6c-a662-4d53-9e70-8cf5e177c32b", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "9a8dbeb2-81fe-5bd3-b8a2-cfc24a194ebb", -"price": 0.00808, -"order_price": 0.00808, -"order_qty": 40, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00851, -"exec_type": "Trade", -"exec_qty": 40, -"exec_fee": 0.00020424, -"exec_value": 0.3404, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247617, -"trade_time_ms": 1652247617414 -}, -{ -"order_id": "243f1957-f127-49d7-87ff-62f8ce882cf3", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "cbbcf94c-b4b7-55b2-800d-d1ad5b175e65", -"price": 0.0081, -"order_price": 0.0081, -"order_qty": 40, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00852, -"exec_type": "Trade", -"exec_qty": 40, -"exec_fee": 0.00020448, -"exec_value": 0.3408, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247611, -"trade_time_ms": 1652247611031 -}, -{ -"order_id": "95a2a92c-0de9-4276-93af-ecd4c30f6d77", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "656718c1-1031-551b-b3a6-7a7e43ceea58", -"price": 0.00809, -"order_price": 0.00809, -"order_qty": 40, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00851, -"exec_type": "Trade", -"exec_qty": 40, -"exec_fee": 0.00020424, -"exec_value": 0.3404, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247604, -"trade_time_ms": 1652247604726 -}, -{ -"order_id": "044348ca-0c91-4dc0-8222-0f7fa63ae757", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "e959cd1c-2cd5-5cff-8812-4258d8a8fc13", -"price": 0.00809, -"order_price": 0.00809, -"order_qty": 50, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00851, -"exec_type": "Trade", -"exec_qty": 50, -"exec_fee": 0.0002553, -"exec_value": 0.4255, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247598, -"trade_time_ms": 1652247598475 -}, -{ -"order_id": "68f67bca-e3a6-487b-a4d0-0ac2e7975f60", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "e2cf419f-9ee9-512c-875f-9ed62d90c333", -"price": 0.00807, -"order_price": 0.00807, -"order_qty": 60, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 60, -"exec_fee": 0.00030564, -"exec_value": 0.5094, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247591, -"trade_time_ms": 1652247591998 -}, -{ -"order_id": "54794915-27b9-405b-9000-434a3e18010d", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "deee175b-202f-5b52-8897-cddac9a8a5d1", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 60, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 60, -"exec_fee": 0.00030564, -"exec_value": 0.5094, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247585, -"trade_time_ms": 1652247585675 -}, -{ -"order_id": "b4725338-e0e8-4a71-a489-07c46058eda2", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "411aa17d-eb36-5ebb-b976-871d76fadf8b", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 70, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 70, -"exec_fee": 0.00035658, -"exec_value": 0.5943, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247579, -"trade_time_ms": 1652247579465 -}, -{ -"order_id": "7284f53e-78b2-4149-b994-ac949de415b1", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "403eedb5-c61f-52bf-970e-f9bb78977315", -"price": 0.00807, -"order_price": 0.00807, -"order_qty": 80, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 80, -"exec_fee": 0.00040752, -"exec_value": 0.6792, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247573, -"trade_time_ms": 1652247573258 -}, -{ -"order_id": "0459fd1d-413e-4068-a083-499f90278790", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "c0f5dc55-086c-54d0-b201-3462ab604af6", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 80, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 80, -"exec_fee": 0.00040752, -"exec_value": 0.6792, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247566, -"trade_time_ms": 1652247566899 -}, -{ -"order_id": "ec55e01a-387e-4570-a576-1225aa917aad", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "7e99d2f2-effd-523d-ab04-77e883239e9e", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 90, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 90, -"exec_fee": 0.00045846, -"exec_value": 0.7641, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247560, -"trade_time_ms": 1652247560648 -}, -{ -"order_id": "34c649c2-21d0-4089-9018-f5c058b62967", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "79fb55e1-9dab-535e-8443-b857b1530d27", -"price": 0.00806, -"order_price": 0.00806, -"order_qty": 100, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 100, -"exec_fee": 0.0005094, -"exec_value": 0.849, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247554, -"trade_time_ms": 1652247554308 -}, -{ -"order_id": "055eabc7-6e9b-4461-91e0-2808fc724a92", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "af72c249-a8ff-521a-aeca-5d13a0aa8ded", -"price": 0.00807, -"order_price": 0.00807, -"order_qty": 120, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 120, -"exec_fee": 0.00061128, -"exec_value": 1.0188, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247548, -"trade_time_ms": 1652247548001 -}, -{ -"order_id": "2e450222-1a13-490d-953a-5e928f8218b0", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "c84f4e11-9bba-53b2-90e5-106fcd03df15", -"price": 0.00807, -"order_price": 0.00807, -"order_qty": 130, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.0085, -"exec_type": "Trade", -"exec_qty": 130, -"exec_fee": 0.000663, -"exec_value": 1.105, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247541, -"trade_time_ms": 1652247541699 -}, -{ -"order_id": "9dbadad8-e139-417c-9f77-4fe7e809a74c", -"order_link_id": "", -"side": "Sell", -"symbol": "SLPUSDT", -"exec_id": "174e651d-bdbe-5575-a9c3-6b5f04564ea9", -"price": 0.00807, -"order_price": 0.00807, -"order_qty": 140, -"order_type": "Market", -"fee_rate": 0.0006, -"exec_price": 0.00849, -"exec_type": "Trade", -"exec_qty": 140, -"exec_fee": 0.00071316, -"exec_value": 1.1886, -"leaves_qty": 0, -"closed_size": 0, -"last_liquidity_ind": "RemovedLiquidity", -"trade_time": 1652247535, -"trade_time_ms": 1652247535086 -} -] -}, -"time_now": "1652257599.243318", -"rate_limit_status": 118, -"rate_limit_reset_ms": 1652257599237, -"rate_limit": 120 -} \ No newline at end of file diff --git a/Bybit.UnitTests/JsonSocketTests.cs b/Bybit.UnitTests/JsonSocketTests.cs index e634523d..44dab86d 100644 --- a/Bybit.UnitTests/JsonSocketTests.cs +++ b/Bybit.UnitTests/JsonSocketTests.cs @@ -13,7 +13,6 @@ using Bybit.Net.Objects.Models.Socket.Derivatives.Contract; using Bybit.Net.Objects.Models.Socket.Derivatives.UnifiedMargin; using Bybit.Net.Objects.Models.Socket.Spot; -using Bybit.Net.Objects.Models.Spot.v1; using Bybit.Net.Objects.Models.Spot.v3; using Bybit.Net.UnitTests; using Newtonsoft.Json; @@ -23,12 +22,6 @@ namespace Bybit.UnitTests { internal class JsonSocketTests { - [Test] - public async Task ValidateTradeUpdateStreamJson() - { - await TestFileToObject(@"JsonResponses/Spot/Socket/TradeUpdate.txt"); - } - [Test] public async Task ValidateKlineUpdateStreamJson() { @@ -41,12 +34,6 @@ public async Task ValidateOrderBookUpdateStreamJson() await TestFileToObject(@"JsonResponses/Spot/Socket/OrderBookUpdate.txt", new List { "v" }); } - [Test] - public async Task ValidateBookPriceV1UpdateStreamJson() - { - await TestFileToObject(@"JsonResponses/Spot/Socket/BookPriceUpdateV1.txt"); - } - [Test] public async Task ValidateBookPriceV3UpdateStreamJson() { @@ -77,148 +64,6 @@ public async Task ValidateUserTradeUpdateStreamJson() await TestFileToObject(@"JsonResponses/Spot/Socket/UserTradeUpdate.txt"); } - [Test] - public async Task ValidateIPTradeUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/InversePerpetual/Socket/TradeUpdate.txt"); - } - - [Test] - public async Task ValidateIPTickerUpdateStreamJson() - { - await TestFileToObject(@"JsonResponses/InversePerpetual/Socket/TickerUpdate.txt", - new List - { - // Deprecated - "last_price_e4", - "prev_price_24h_e4", - "high_price_24h_e4", - "low_price_24h_e4", - "prev_price_1h_e4", - "mark_price_e4", - "index_price_e4", - "ask1_price_e4", - "bid1_price_e4", - }); - } - - [Test] - public async Task ValidateIPInsuranceUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/InversePerpetual/Socket/InsuranceUpdate.txt"); - } - - [Test] - public async Task ValidateIPKlineUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/InversePerpetual/Socket/KlineUpdate.txt"); - } - - [Test] - public async Task ValidateIPLiquidationUpdateStreamJson() - { - await TestFileToObject(@"JsonResponses/InversePerpetual/Socket/LiquidationUpdate.txt"); - } - - [Test] - public async Task ValidateIPPositionUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/InversePerpetual/Socket/PositionUpdate.txt"); - } - - [Test] - public async Task ValidateIPUserTradeUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/InversePerpetual/Socket/UserTradeUpdate.txt"); - } - - [Test] - public async Task ValidateIPOrderUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/InversePerpetual/Socket/OrderUpdate.txt"); - } - - [Test] - public async Task ValidateIPStopOrderUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/InversePerpetual/Socket/StopOrderUpdate.txt"); - } - - [Test] - public async Task ValidateIPBalanceUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/InversePerpetual/Socket/BalanceUpdate.txt"); - } - - [Test] - public async Task ValidateUPTradeUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/UsdPerpetual/Socket/TradeUpdate.txt"); - } - - [Test] - public async Task ValidateUPTickerUpdateStreamJson() - { - await TestFileToObject(@"JsonResponses/UsdPerpetual/Socket/TickerUpdate.txt", - new List - { - // Deprecated - "last_price_e4", - "prev_price_24h_e4", - "high_price_24h_e4", - "low_price_24h_e4", - "prev_price_1h_e4", - "mark_price_e4", - "index_price_e4", - "ask1_price_e4", - "bid1_price_e4", - }); - } - - [Test] - public async Task ValidateUPKlineUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/UsdPerpetual/Socket/KlineUpdate.txt"); - } - - [Test] - public async Task ValidateUPLiquidationUpdateStreamJson() - { - await TestFileToObject(@"JsonResponses/UsdPerpetual/Socket/LiquidationUpdate.txt"); - } - - [Test] - public async Task ValidateUPPositionUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/UsdPerpetual/Socket/PositionUpdate1.txt"); - await TestFileToObject>(@"JsonResponses/UsdPerpetual/Socket/PositionUpdate2.txt"); - } - - [Test] - public async Task ValidateUPUserTradeUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/UsdPerpetual/Socket/UserTradeUpdate.txt"); - } - - [Test] - public async Task ValidateUPOrderUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/UsdPerpetual/Socket/OrderUpdate1.txt"); - await TestFileToObject>(@"JsonResponses/UsdPerpetual/Socket/OrderUpdate2.txt"); - } - - [Test] - public async Task ValidateUPStopOrderUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/UsdPerpetual/Socket/StopOrderUpdate.txt"); - } - - [Test] - public async Task ValidateUPBalanceUpdateStreamJson() - { - await TestFileToObject>(@"JsonResponses/UsdPerpetual/Socket/BalanceUpdate.txt"); - } - [Test] public async Task ValidateCopyBalanceUpdateStreamJson() { From a54e05d7072f0c510936779dc24a4699dc57572c Mon Sep 17 00:00:00 2001 From: JKorf Date: Mon, 26 Feb 2024 20:12:46 +0100 Subject: [PATCH 10/17] Updated version --- ByBit.Net/Bybit.Net.csproj | 8 ++++---- README.md | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ByBit.Net/Bybit.Net.csproj b/ByBit.Net/Bybit.Net.csproj index 253f6987..a6958443 100644 --- a/ByBit.Net/Bybit.Net.csproj +++ b/ByBit.Net/Bybit.Net.csproj @@ -1,4 +1,4 @@ - + netstandard2.0;netstandard2.1 enable @@ -7,9 +7,9 @@ Bybit.Net JKorf - 3.4.0 - 3.4.0 - 3.4.0 + 3.5.0 + 3.5.0 + 3.5.0 Bybit.Net is a client library for accessing the Bybit REST and Websocket API. All data is mapped to readable models and enum values. Additional features include an implementation for maintaining a client side order book, easy integration with other exchange client libraries and more. false Bybit;Bybit.Net;Bybit Client;Bybit API;CryptoCurrency;CryptoCurrency Exchange diff --git a/README.md b/README.md index d518e971..1ff87cbf 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,13 @@ Make a one time donation in a crypto currency of your choice. If you prefer to d Alternatively, sponsor me on Github using [Github Sponsors](https://github.com/sponsors/JKorf). ## Release notes +* Version 3.5.0 - 26 Feb 2024 + * Fixed BybitSpotUserTradeV3 model mapping + * Added Id to BybitTransactionLog model + * Updated BybitPosition model + * Updated Spot V3 and V5 order models + * Removed deprecated endpoints and models + * Version 3.4.0 - 25 Feb 2024 * Updated CryptoExchange.Net and implemented reworked websocket message handling. For release notes for the CryptoExchange.Net base library see: https://github.com/JKorf/CryptoExchange.Net?tab=readme-ov-file#release-notes * Fixed issue in DI registration causing http client to not be correctly injected From 1829801947a9c78b1024fc52edf4c35505d2c036 Mon Sep 17 00:00:00 2001 From: JKorf Date: Tue, 27 Feb 2024 21:25:24 +0100 Subject: [PATCH 11/17] Updated Linear/Inverse symbol model --- ByBit.Net/Enums/CopyTradeType.cs | 31 +++++++++++++++++++ .../Models/V5/BybitLinearInverseSymbol.cs | 25 ++++++++++++--- 2 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 ByBit.Net/Enums/CopyTradeType.cs diff --git a/ByBit.Net/Enums/CopyTradeType.cs b/ByBit.Net/Enums/CopyTradeType.cs new file mode 100644 index 00000000..81b038f3 --- /dev/null +++ b/ByBit.Net/Enums/CopyTradeType.cs @@ -0,0 +1,31 @@ +using CryptoExchange.Net.Attributes; + +namespace Bybit.Net.Enums +{ + ///

+ /// Copy trading type + /// + public enum CopyTradeType + { + /// + /// Regardless of normal account or UTA account, this trading pair does not support copy trading + /// + [Map("none")] + None, + /// + /// For both normal account and UTA account, this trading pair supports copy trading + /// + [Map("both")] + Both, + /// + /// Only for UTA account,this trading pair supports copy trading + /// + [Map("utaOnly")] + UtaOnly, + /// + /// Only for normal account, this trading pair supports copy trading + /// + [Map("normalOnly")] + NormalOnly + } +} diff --git a/ByBit.Net/Objects/Models/V5/BybitLinearInverseSymbol.cs b/ByBit.Net/Objects/Models/V5/BybitLinearInverseSymbol.cs index 53e8fedb..c1b7e7af 100644 --- a/ByBit.Net/Objects/Models/V5/BybitLinearInverseSymbol.cs +++ b/ByBit.Net/Objects/Models/V5/BybitLinearInverseSymbol.cs @@ -67,6 +67,21 @@ public class BybitLinearInverseSymbol /// Funding interval in minutes ///
public int FundingInterval { get; set; } + /// + /// Copy trading support + /// + [JsonProperty("copyTrading"), JsonConverter(typeof(EnumConverter))] + public CopyTradeType CopyTrading { get; set; } + /// + /// Upper limit of funding date + /// + [JsonProperty("upperFundingRate")] + public decimal UpperFundingRate { get; set; } + /// + /// Lower limit of funding data + /// + [JsonProperty("lowerFundingRate")] + public decimal LowerFundingRate { get; set; } /// /// Lot size order filter @@ -106,11 +121,6 @@ public class BybitLinearInverseLeveragefilter /// public class BybitLinearInverseLotSizeFilter { - /// - /// Post only max order quantity - /// - [JsonProperty("postOnlyMaxOrderQty")] - public decimal PostOnlyMaxOrderQuantity { get; set; } /// /// Quantity step /// @@ -126,6 +136,11 @@ public class BybitLinearInverseLotSizeFilter /// [JsonProperty("maxOrderQty")] public decimal MaxOrderQuantity { get; set; } + /// + /// Max market order quantity + /// + [JsonProperty("maxMktOrderQty")] + public decimal MaxMarketOrderQuantity { get; set; } } /// From 83838b46fd0724fe39659ab392f4b4dc2393fa60 Mon Sep 17 00:00:00 2001 From: JKorf Date: Tue, 27 Feb 2024 21:26:54 +0100 Subject: [PATCH 12/17] Fixed PositionIdx property order updates --- ByBit.Net/Objects/Models/V5/BybitOrder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ByBit.Net/Objects/Models/V5/BybitOrder.cs b/ByBit.Net/Objects/Models/V5/BybitOrder.cs index ff8977a5..9509e488 100644 --- a/ByBit.Net/Objects/Models/V5/BybitOrder.cs +++ b/ByBit.Net/Objects/Models/V5/BybitOrder.cs @@ -51,7 +51,7 @@ public class BybitOrder /// Position mode /// [JsonProperty("positionIdx")] - public Enums.V5.PositionMode? PositionMode { get; set; } + public PositionIdx? PositionIdx { get; set; } /// /// Order status /// From 3a8048b8b8ba7290b8a0e1db1e37fd2aae448e71 Mon Sep 17 00:00:00 2001 From: JKorf Date: Tue, 27 Feb 2024 21:27:49 +0100 Subject: [PATCH 13/17] Updated version --- ByBit.Net/Bybit.Net.csproj | 6 +++--- README.md | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ByBit.Net/Bybit.Net.csproj b/ByBit.Net/Bybit.Net.csproj index a6958443..0422d9e7 100644 --- a/ByBit.Net/Bybit.Net.csproj +++ b/ByBit.Net/Bybit.Net.csproj @@ -7,9 +7,9 @@ Bybit.Net JKorf - 3.5.0 - 3.5.0 - 3.5.0 + 3.5.1 + 3.5.1 + 3.5.1 Bybit.Net is a client library for accessing the Bybit REST and Websocket API. All data is mapped to readable models and enum values. Additional features include an implementation for maintaining a client side order book, easy integration with other exchange client libraries and more. false Bybit;Bybit.Net;Bybit Client;Bybit API;CryptoCurrency;CryptoCurrency Exchange diff --git a/README.md b/README.md index 1ff87cbf..fd321f6a 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,10 @@ Make a one time donation in a crypto currency of your choice. If you prefer to d Alternatively, sponsor me on Github using [Github Sponsors](https://github.com/sponsors/JKorf). ## Release notes +* Version 3.5.1 - 27 Feb 2024 + * Updated V5 Linear/Inverse Symbol model + * Fixed PositionIdx property in V5 order updates + * Version 3.5.0 - 26 Feb 2024 * Fixed BybitSpotUserTradeV3 model mapping * Added Id to BybitTransactionLog model From f643cca65f212f3a4ccfa98e09dc22d6ad45d679 Mon Sep 17 00:00:00 2001 From: JKorf Date: Wed, 28 Feb 2024 22:22:49 +0100 Subject: [PATCH 14/17] Fixed position deserialization --- ByBit.Net/Objects/Models/V5/BybitPosition.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ByBit.Net/Objects/Models/V5/BybitPosition.cs b/ByBit.Net/Objects/Models/V5/BybitPosition.cs index 0cdaea3e..10aa3644 100644 --- a/ByBit.Net/Objects/Models/V5/BybitPosition.cs +++ b/ByBit.Net/Objects/Models/V5/BybitPosition.cs @@ -158,11 +158,13 @@ private decimal? EntryPrice /// When IsReduceOnly = true: the timestamp when the MMR will be forcibly adjusted by the system. When IsReduceOnly = false: the timestamp when the MMR had been adjusted by system /// [JsonProperty("mmrSysUpdatedTime")] + [JsonConverter(typeof(DateTimeConverter))] public DateTime? MaintenanceMarginUpdateTime { get; set; } /// /// When IsReduceOnly = true: the timestamp when the leverage will be forcibly adjusted by the system. When IsReduceOnly = false: the timestamp when the leverage had been adjusted by system /// [JsonProperty("leverageSysUpdatedTime")] + [JsonConverter(typeof(DateTimeConverter))] public DateTime? LeverageUpdateTime { get; set; } /// /// Cross sequence, used to associate each fill and each position update From bf1707fe091cbe5703350093463db703c002a90a Mon Sep 17 00:00:00 2001 From: JKorf Date: Wed, 28 Feb 2024 22:23:30 +0100 Subject: [PATCH 15/17] Updated version --- ByBit.Net/Bybit.Net.csproj | 6 +++--- README.md | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ByBit.Net/Bybit.Net.csproj b/ByBit.Net/Bybit.Net.csproj index 0422d9e7..30b94f70 100644 --- a/ByBit.Net/Bybit.Net.csproj +++ b/ByBit.Net/Bybit.Net.csproj @@ -7,9 +7,9 @@ Bybit.Net JKorf - 3.5.1 - 3.5.1 - 3.5.1 + 3.5.2 + 3.5.2 + 3.5.2 Bybit.Net is a client library for accessing the Bybit REST and Websocket API. All data is mapped to readable models and enum values. Additional features include an implementation for maintaining a client side order book, easy integration with other exchange client libraries and more. false Bybit;Bybit.Net;Bybit Client;Bybit API;CryptoCurrency;CryptoCurrency Exchange diff --git a/README.md b/README.md index fd321f6a..c2901c1c 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,9 @@ Make a one time donation in a crypto currency of your choice. If you prefer to d Alternatively, sponsor me on Github using [Github Sponsors](https://github.com/sponsors/JKorf). ## Release notes +* Version 3.5.2 - 28 Feb 2024 + * Fixed V5Api.Trading.GetPositionAsync model deserialization + * Version 3.5.1 - 27 Feb 2024 * Updated V5 Linear/Inverse Symbol model * Fixed PositionIdx property in V5 order updates From 88dfa99dbf7393bf6009989ce063a7315d33d998 Mon Sep 17 00:00:00 2001 From: JKorf Date: Fri, 1 Mar 2024 14:26:47 +0100 Subject: [PATCH 16/17] Examples --- Examples/Bybit.Api/Bybit.Examples.Api.csproj | 16 +++++++ Examples/Bybit.Api/Program.cs | 45 +++++++++++++++++++ .../Bybit.Api/Properties/launchSettings.json | 41 +++++++++++++++++ .../Bybit.Api/appsettings.Development.json | 8 ++++ Examples/Bybit.Api/appsettings.json | 9 ++++ .../Bybit.Examples.Console.csproj | 14 ++++++ Examples/Bybit.Console/Program.cs | 20 +++++++++ .../Bybit.Examples.Authentication.csproj | 10 +++++ .../Bybit.Examples.Authentication/Program.cs | 2 + Examples/Examples.sln | 31 +++++++++++++ README.md | 2 +- 11 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 Examples/Bybit.Api/Bybit.Examples.Api.csproj create mode 100644 Examples/Bybit.Api/Program.cs create mode 100644 Examples/Bybit.Api/Properties/launchSettings.json create mode 100644 Examples/Bybit.Api/appsettings.Development.json create mode 100644 Examples/Bybit.Api/appsettings.json create mode 100644 Examples/Bybit.Console/Bybit.Examples.Console.csproj create mode 100644 Examples/Bybit.Console/Program.cs create mode 100644 Examples/Bybit.Examples.Authentication/Bybit.Examples.Authentication.csproj create mode 100644 Examples/Bybit.Examples.Authentication/Program.cs create mode 100644 Examples/Examples.sln diff --git a/Examples/Bybit.Api/Bybit.Examples.Api.csproj b/Examples/Bybit.Api/Bybit.Examples.Api.csproj new file mode 100644 index 00000000..6a1612f0 --- /dev/null +++ b/Examples/Bybit.Api/Bybit.Examples.Api.csproj @@ -0,0 +1,16 @@ + + + + net8.0 + enable + enable + true + + + + + + + + + diff --git a/Examples/Bybit.Api/Program.cs b/Examples/Bybit.Api/Program.cs new file mode 100644 index 00000000..503619bb --- /dev/null +++ b/Examples/Bybit.Api/Program.cs @@ -0,0 +1,45 @@ +using Bybit.Net.Interfaces.Clients; +using CryptoExchange.Net.Authentication; +using Microsoft.AspNetCore.Mvc; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +// Add the Bybit services +builder.Services.AddBybit(); + +// OR to provide API credentials for accessing private endpoints, or setting other options: +/* +builder.Services.AddBybit(restOptions => +{ + restOptions.ApiCredentials = new ApiCredentials("", ""); + restOptions.RequestTimeout = TimeSpan.FromSeconds(5); +}, socketOptions => +{ + socketOptions.ApiCredentials = new ApiCredentials("", ""); +}); +*/ + +var app = builder.Build(); +app.UseSwagger(); +app.UseSwaggerUI(); +app.UseHttpsRedirection(); + +// Map the endpoints and inject the bybit rest client +app.MapGet("/{Symbol}", async ([FromServices] IBybitRestClient client, string symbol) => +{ + var result = await client.V5Api.ExchangeData.GetSpotTickersAsync(symbol); + return (object)(result.Success ? result.Data : result.Error!); +}) +.WithOpenApi(); + +app.MapGet("/Balances", async ([FromServices] IBybitRestClient client) => +{ + var result = await client.V5Api.Account.GetBalancesAsync(Bybit.Net.Enums.AccountType.Spot); + return (object)(result.Success ? result.Data : result.Error!); +}) +.WithOpenApi(); + +app.Run(); \ No newline at end of file diff --git a/Examples/Bybit.Api/Properties/launchSettings.json b/Examples/Bybit.Api/Properties/launchSettings.json new file mode 100644 index 00000000..066e9d1f --- /dev/null +++ b/Examples/Bybit.Api/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:23442", + "sslPort": 44376 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5114", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7266;http://localhost:5114", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Examples/Bybit.Api/appsettings.Development.json b/Examples/Bybit.Api/appsettings.Development.json new file mode 100644 index 00000000..0c208ae9 --- /dev/null +++ b/Examples/Bybit.Api/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/Examples/Bybit.Api/appsettings.json b/Examples/Bybit.Api/appsettings.json new file mode 100644 index 00000000..10f68b8c --- /dev/null +++ b/Examples/Bybit.Api/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Examples/Bybit.Console/Bybit.Examples.Console.csproj b/Examples/Bybit.Console/Bybit.Examples.Console.csproj new file mode 100644 index 00000000..a9c02642 --- /dev/null +++ b/Examples/Bybit.Console/Bybit.Examples.Console.csproj @@ -0,0 +1,14 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + diff --git a/Examples/Bybit.Console/Program.cs b/Examples/Bybit.Console/Program.cs new file mode 100644 index 00000000..16cb0597 --- /dev/null +++ b/Examples/Bybit.Console/Program.cs @@ -0,0 +1,20 @@ + +using Bybit.Net.Clients; + +// REST +var restClient = new BybitRestClient(); +var ticker = await restClient.V5Api.ExchangeData.GetSpotTickersAsync("ETHUSDT"); +Console.WriteLine($"Rest client ticker price for ETHUSDT: {ticker.Data.List.First().LastPrice}"); + +Console.WriteLine(); +Console.WriteLine("Press enter to start websocket subscription"); +Console.ReadLine(); + +// Websocket +var socketClient = new BybitSocketClient(); +var subscription = await socketClient.V5SpotApi.SubscribeToTickerUpdatesAsync("ETHUSDT", update => +{ + Console.WriteLine($"Websocket client ticker price for ETHUSDT: {update.Data.LastPrice}"); +}); + +Console.ReadLine(); diff --git a/Examples/Bybit.Examples.Authentication/Bybit.Examples.Authentication.csproj b/Examples/Bybit.Examples.Authentication/Bybit.Examples.Authentication.csproj new file mode 100644 index 00000000..2150e379 --- /dev/null +++ b/Examples/Bybit.Examples.Authentication/Bybit.Examples.Authentication.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/Examples/Bybit.Examples.Authentication/Program.cs b/Examples/Bybit.Examples.Authentication/Program.cs new file mode 100644 index 00000000..3751555c --- /dev/null +++ b/Examples/Bybit.Examples.Authentication/Program.cs @@ -0,0 +1,2 @@ +// See https://aka.ms/new-console-template for more information +Console.WriteLine("Hello, World!"); diff --git a/Examples/Examples.sln b/Examples/Examples.sln new file mode 100644 index 00000000..151b79d2 --- /dev/null +++ b/Examples/Examples.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bybit.Examples.Console", "Bybit.Console\Bybit.Examples.Console.csproj", "{72F29164-3C3E-4EB1-9C2B-BC9BA5FCD5AA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bybit.Examples.Api", "Bybit.Api\Bybit.Examples.Api.csproj", "{2E6BB5F7-6F04-4122-8CB6-6B89E822040A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {72F29164-3C3E-4EB1-9C2B-BC9BA5FCD5AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72F29164-3C3E-4EB1-9C2B-BC9BA5FCD5AA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72F29164-3C3E-4EB1-9C2B-BC9BA5FCD5AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72F29164-3C3E-4EB1-9C2B-BC9BA5FCD5AA}.Release|Any CPU.Build.0 = Release|Any CPU + {2E6BB5F7-6F04-4122-8CB6-6B89E822040A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E6BB5F7-6F04-4122-8CB6-6B89E822040A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E6BB5F7-6F04-4122-8CB6-6B89E822040A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E6BB5F7-6F04-4122-8CB6-6B89E822040A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {84A4E6CE-9D3A-43FF-97B1-D91CE93B7E8F} + EndGlobalSection +EndGlobal diff --git a/README.md b/README.md index c2901c1c..7706cd8b 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ The library is targeting both `.NET Standard 2.0` and `.NET Standard 2.1` for op }); ``` -For information on the clients, dependency injection, response processing and more see the [documentation](https://jkorf.github.io/CryptoExchange.Net), or have a look at the examples [here](https://github.com/JKorf/CryptoExchange.Net/tree/master/Examples). +For information on the clients, dependency injection, response processing and more see the [documentation](https://jkorf.github.io/CryptoExchange.Net), or have a look at the examples [here(https://github.com/JKorf/Bybit.Net/tree/main/Examples)] and [here](https://github.com/JKorf/CryptoExchange.Net/tree/master/Examples). ## CryptoExchange.Net Bybit.Net is based on the [CryptoExchange.Net](https://github.com/JKorf/CryptoExchange.Net) base library. Other exchange API implementations based on the CryptoExchange.Net base library are available and follow the same logic. From fa9ed5804a09f48d599b9f0449f1dab3917b7607 Mon Sep 17 00:00:00 2001 From: JKorf Date: Fri, 1 Mar 2024 14:34:47 +0100 Subject: [PATCH 17/17] Examples/docs --- .../Bybit.Examples.Authentication.csproj | 10 ---------- Examples/Bybit.Examples.Authentication/Program.cs | 2 -- .../Bybit.Examples.Console.csproj | 0 .../Program.cs | 0 Examples/README.md | 7 +++++++ README.md | 2 +- 6 files changed, 8 insertions(+), 13 deletions(-) delete mode 100644 Examples/Bybit.Examples.Authentication/Bybit.Examples.Authentication.csproj delete mode 100644 Examples/Bybit.Examples.Authentication/Program.cs rename Examples/{Bybit.Console => Bybit.Examples.Console}/Bybit.Examples.Console.csproj (100%) rename Examples/{Bybit.Console => Bybit.Examples.Console}/Program.cs (100%) create mode 100644 Examples/README.md diff --git a/Examples/Bybit.Examples.Authentication/Bybit.Examples.Authentication.csproj b/Examples/Bybit.Examples.Authentication/Bybit.Examples.Authentication.csproj deleted file mode 100644 index 2150e379..00000000 --- a/Examples/Bybit.Examples.Authentication/Bybit.Examples.Authentication.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - diff --git a/Examples/Bybit.Examples.Authentication/Program.cs b/Examples/Bybit.Examples.Authentication/Program.cs deleted file mode 100644 index 3751555c..00000000 --- a/Examples/Bybit.Examples.Authentication/Program.cs +++ /dev/null @@ -1,2 +0,0 @@ -// See https://aka.ms/new-console-template for more information -Console.WriteLine("Hello, World!"); diff --git a/Examples/Bybit.Console/Bybit.Examples.Console.csproj b/Examples/Bybit.Examples.Console/Bybit.Examples.Console.csproj similarity index 100% rename from Examples/Bybit.Console/Bybit.Examples.Console.csproj rename to Examples/Bybit.Examples.Console/Bybit.Examples.Console.csproj diff --git a/Examples/Bybit.Console/Program.cs b/Examples/Bybit.Examples.Console/Program.cs similarity index 100% rename from Examples/Bybit.Console/Program.cs rename to Examples/Bybit.Examples.Console/Program.cs diff --git a/Examples/README.md b/Examples/README.md new file mode 100644 index 00000000..d6cb5068 --- /dev/null +++ b/Examples/README.md @@ -0,0 +1,7 @@ +# Examples + +### Bybit.Examples.Api +A minimal API showing how to integrate Bybit.Net in a web API project + +### Bybit.Examples.Console +A simple console client demonstrating basic usage \ No newline at end of file diff --git a/README.md b/README.md index 7706cd8b..66289ccc 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ The library is targeting both `.NET Standard 2.0` and `.NET Standard 2.1` for op }); ``` -For information on the clients, dependency injection, response processing and more see the [documentation](https://jkorf.github.io/CryptoExchange.Net), or have a look at the examples [here(https://github.com/JKorf/Bybit.Net/tree/main/Examples)] and [here](https://github.com/JKorf/CryptoExchange.Net/tree/master/Examples). +For information on the clients, dependency injection, response processing and more see the [documentation](https://jkorf.github.io/CryptoExchange.Net), or have a look at the examples [here](https://github.com/JKorf/Bybit.Net/tree/main/Examples) and [here](https://github.com/JKorf/CryptoExchange.Net/tree/master/Examples). ## CryptoExchange.Net Bybit.Net is based on the [CryptoExchange.Net](https://github.com/JKorf/CryptoExchange.Net) base library. Other exchange API implementations based on the CryptoExchange.Net base library are available and follow the same logic.