diff --git a/CryptoExchange.Net.UnitTests/TestImplementations/TestBaseClient.cs b/CryptoExchange.Net.UnitTests/TestImplementations/TestBaseClient.cs index 9269cf80..e32a4680 100644 --- a/CryptoExchange.Net.UnitTests/TestImplementations/TestBaseClient.cs +++ b/CryptoExchange.Net.UnitTests/TestImplementations/TestBaseClient.cs @@ -8,6 +8,7 @@ using CryptoExchange.Net.Clients; using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects.Options; +using CryptoExchange.Net.SharedApis; using CryptoExchange.Net.UnitTests.TestImplementations; using Microsoft.Extensions.Logging; @@ -55,7 +56,7 @@ public CallResult Deserialize(string data) } /// - public override string FormatSymbol(string baseAsset, string quoteAsset) => $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}"; + public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode futuresType, DateTime? deliverDate = null) => $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}"; public override TimeSpan? GetTimeOffset() => null; public override TimeSyncInfo GetTimeSyncInfo() => null; protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => throw new NotImplementedException(); diff --git a/CryptoExchange.Net.UnitTests/TestImplementations/TestRestClient.cs b/CryptoExchange.Net.UnitTests/TestImplementations/TestRestClient.cs index 1ad9c9f3..d739e579 100644 --- a/CryptoExchange.Net.UnitTests/TestImplementations/TestRestClient.cs +++ b/CryptoExchange.Net.UnitTests/TestImplementations/TestRestClient.cs @@ -15,6 +15,7 @@ using CryptoExchange.Net.Objects.Options; using Microsoft.Extensions.Logging; using CryptoExchange.Net.Clients; +using CryptoExchange.Net.SharedApis; namespace CryptoExchange.Net.UnitTests.TestImplementations { @@ -138,7 +139,7 @@ public TestRestApi1Client(TestClientOptions options) : base(new TraceLogger(), n } /// - public override string FormatSymbol(string baseAsset, string quoteAsset) => $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}"; + public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode futuresType, DateTime? deliverDate = null) => $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}"; public async Task> Request(CancellationToken ct = default) where T : class { @@ -182,7 +183,7 @@ public TestRestApi2Client(TestClientOptions options) : base(new TraceLogger(), n } /// - public override string FormatSymbol(string baseAsset, string quoteAsset) => $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}"; + public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode futuresType, DateTime? deliverDate = null) => $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}"; public async Task> Request(CancellationToken ct = default) where T : class { diff --git a/CryptoExchange.Net.UnitTests/TestImplementations/TestSocketClient.cs b/CryptoExchange.Net.UnitTests/TestImplementations/TestSocketClient.cs index 661f6d76..e2646110 100644 --- a/CryptoExchange.Net.UnitTests/TestImplementations/TestSocketClient.cs +++ b/CryptoExchange.Net.UnitTests/TestImplementations/TestSocketClient.cs @@ -14,6 +14,7 @@ using Microsoft.Extensions.Logging; using Moq; using CryptoExchange.Net.Testing.Implementations; +using CryptoExchange.Net.SharedApis; namespace CryptoExchange.Net.UnitTests.TestImplementations { @@ -86,7 +87,7 @@ public TestSubSocketClient(TestSocketOptions options, SocketApiOptions apiOption } /// - public override string FormatSymbol(string baseAsset, string quoteAsset) => $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}"; + public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode futuresType, DateTime? deliverDate = null) => $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}"; internal IWebsocket CreateSocketInternal(string address) { diff --git a/CryptoExchange.Net/Clients/BaseApiClient.cs b/CryptoExchange.Net/Clients/BaseApiClient.cs index 8ac98d01..9046faa2 100644 --- a/CryptoExchange.Net/Clients/BaseApiClient.cs +++ b/CryptoExchange.Net/Clients/BaseApiClient.cs @@ -1,7 +1,9 @@ using System; using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Interfaces; +using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects.Options; +using CryptoExchange.Net.SharedApis; using Microsoft.Extensions.Logging; namespace CryptoExchange.Net.Clients @@ -76,7 +78,7 @@ protected BaseApiClient(ILogger logger, bool outputOriginalData, ApiCredentials? protected abstract AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials); /// - public abstract string FormatSymbol(string baseAsset, string quoteAsset); + public abstract string FormatSymbol(string baseAsset, string quoteAsset, TradingMode tradingMode, DateTime? deliverDate = null); /// public void SetApiCredentials(T credentials) where T : ApiCredentials diff --git a/CryptoExchange.Net/Clients/RestApiClient.cs b/CryptoExchange.Net/Clients/RestApiClient.cs index 60916b02..41e22d16 100644 --- a/CryptoExchange.Net/Clients/RestApiClient.cs +++ b/CryptoExchange.Net/Clients/RestApiClient.cs @@ -18,7 +18,6 @@ using CryptoExchange.Net.RateLimiting.Interfaces; using CryptoExchange.Net.Requests; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; namespace CryptoExchange.Net.Clients { diff --git a/CryptoExchange.Net/Clients/SocketApiClient.cs b/CryptoExchange.Net/Clients/SocketApiClient.cs index e92572ca..74c3f220 100644 --- a/CryptoExchange.Net/Clients/SocketApiClient.cs +++ b/CryptoExchange.Net/Clients/SocketApiClient.cs @@ -8,7 +8,6 @@ using CryptoExchange.Net.Sockets; using Microsoft.Extensions.Logging; using System; -using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; diff --git a/CryptoExchange.Net/Converters/JsonNet/DateTimeConverter.cs b/CryptoExchange.Net/Converters/JsonNet/DateTimeConverter.cs index 2540d369..e2f686a9 100644 --- a/CryptoExchange.Net/Converters/JsonNet/DateTimeConverter.cs +++ b/CryptoExchange.Net/Converters/JsonNet/DateTimeConverter.cs @@ -1,5 +1,4 @@ -using Microsoft.Extensions.Primitives; -using Newtonsoft.Json; +using Newtonsoft.Json; using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/CryptoExchange.Net/Converters/SystemTextJson/DateTimeConverter.cs b/CryptoExchange.Net/Converters/SystemTextJson/DateTimeConverter.cs index 5d480a12..14005601 100644 --- a/CryptoExchange.Net/Converters/SystemTextJson/DateTimeConverter.cs +++ b/CryptoExchange.Net/Converters/SystemTextJson/DateTimeConverter.cs @@ -1,5 +1,4 @@ -using Microsoft.Extensions.Primitives; -using System; +using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; diff --git a/CryptoExchange.Net/Converters/SystemTextJson/NumberStringConverter.cs b/CryptoExchange.Net/Converters/SystemTextJson/NumberStringConverter.cs index 7beafd9d..e38c95cc 100644 --- a/CryptoExchange.Net/Converters/SystemTextJson/NumberStringConverter.cs +++ b/CryptoExchange.Net/Converters/SystemTextJson/NumberStringConverter.cs @@ -1,5 +1,4 @@ using System; -using System.Globalization; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/CryptoExchange.Net/Converters/SystemTextJson/ObjectStringConverter.cs b/CryptoExchange.Net/Converters/SystemTextJson/ObjectStringConverter.cs index f2747cdc..542defaf 100644 --- a/CryptoExchange.Net/Converters/SystemTextJson/ObjectStringConverter.cs +++ b/CryptoExchange.Net/Converters/SystemTextJson/ObjectStringConverter.cs @@ -1,11 +1,6 @@ using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.Serialization; -using System.Text; using System.Text.Json.Serialization; using System.Text.Json; -using System.Globalization; namespace CryptoExchange.Net.Converters.SystemTextJson { diff --git a/CryptoExchange.Net/CryptoExchange.Net.csproj b/CryptoExchange.Net/CryptoExchange.Net.csproj index b5e53189..689cc98a 100644 --- a/CryptoExchange.Net/CryptoExchange.Net.csproj +++ b/CryptoExchange.Net/CryptoExchange.Net.csproj @@ -35,7 +35,7 @@ true - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CryptoExchange.Net/ExchangeHelpers.cs b/CryptoExchange.Net/ExchangeHelpers.cs index 20049e22..d5f55473 100644 --- a/CryptoExchange.Net/ExchangeHelpers.cs +++ b/CryptoExchange.Net/ExchangeHelpers.cs @@ -1,7 +1,11 @@ using CryptoExchange.Net.Objects; +using CryptoExchange.Net.SharedApis; using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Threading; +using System.Threading.Tasks; namespace CryptoExchange.Net { @@ -12,6 +16,22 @@ public static class ExchangeHelpers { private const string _allowedRandomChars = "ABCDEFGHIJKLMONOPQRSTUVWXYZabcdefghijklmonopqrstuvwxyz0123456789"; + private static readonly Dictionary _monthSymbols = new Dictionary() + { + { 1, "F" }, + { 2, "G" }, + { 3, "H" }, + { 4, "J" }, + { 5, "K" }, + { 6, "M" }, + { 7, "N" }, + { 8, "Q" }, + { 9, "U" }, + { 10, "V" }, + { 11, "X" }, + { 12, "Z" }, + }; + /// /// The last used id, use NextId() to get the next id and up this /// @@ -55,6 +75,11 @@ public static decimal AdjustValueStep(decimal min, decimal max, decimal? step, R { value -= offset; } + else if(roundingType == RoundingType.Up) + { + if (offset != 0) + value += (step.Value - offset); + } else { if (offset < step / 2) @@ -107,17 +132,23 @@ public static decimal RoundToSignificantDigits(decimal value, int digits, Roundi } /// - /// Rounds a value down to + /// Rounds a value down /// - /// - /// - /// public static decimal RoundDown(decimal i, double decimalPlaces) { var power = Convert.ToDecimal(Math.Pow(10, decimalPlaces)); return Math.Floor(i * power) / power; } + /// + /// Rounds a value up + /// + public static decimal RoundUp(decimal i, double decimalPlaces) + { + var power = Convert.ToDecimal(Math.Pow(10, decimalPlaces)); + return Math.Ceiling(i * power) / power; + } + /// /// Strips any trailing zero's of a decimal value, useful when converting the value to string. /// @@ -177,5 +208,70 @@ public static string AppendRandomString(string source, int totalLength) return source + RandomString(totalLength - source.Length); } + + /// + /// Get the month representation for futures symbol based on the delivery month + /// + /// Delivery time + /// + public static string GetDeliveryMonthSymbol(DateTime time) => _monthSymbols[time.Month]; + + /// + /// Execute multiple requests to retrieve multiple pages of the result set + /// + /// Type of the client + /// Type of the request + /// The func to execute with each request + /// The request parameters + /// Cancellation token + /// + public static async IAsyncEnumerable>> ExecutePages(Func>>> paginatedFunc, U request, [EnumeratorCancellation]CancellationToken ct = default) + { + var result = new List(); + ExchangeWebResult> batch; + INextPageToken? nextPageToken = null; + while (true) + { + batch = await paginatedFunc(request, nextPageToken, ct).ConfigureAwait(false); + yield return batch; + if (!batch || ct.IsCancellationRequested) + break; + + result.AddRange(batch.Data); + nextPageToken = batch.NextPageToken; + if (nextPageToken == null) + break; + } + } + + /// + /// Apply the rules (price and quantity step size and decimals precision, min/max quantity) from the symbol to the quantity and price + /// + /// The symbol as retrieved from the exchange + /// Quantity to trade + /// Price to trade at + /// Quantity adjusted to match all trading rules + /// Price adjusted to match all trading rules + public static void ApplySymbolRules(SharedSpotSymbol symbol, decimal quantity, decimal? price, out decimal adjustedQuantity, out decimal? adjustedPrice) + { + adjustedPrice = price; + adjustedQuantity = quantity; + var minNotionalAdjust = false; + + if (price != null) + { + adjustedPrice = AdjustValueStep(0, decimal.MaxValue, symbol.PriceStep, RoundingType.Down, price.Value); + adjustedPrice = symbol.PriceDecimals.HasValue ? RoundDown(price.Value, symbol.PriceDecimals.Value) : adjustedPrice; + if (adjustedPrice != 0 && adjustedPrice * quantity < symbol.MinNotionalValue) + { + adjustedQuantity = symbol.MinNotionalValue.Value / adjustedPrice.Value; + minNotionalAdjust = true; + } + } + + adjustedQuantity = AdjustValueStep(symbol.MinTradeQuantity ?? 0, symbol.MaxTradeQuantity ?? decimal.MaxValue, symbol.QuantityStep, minNotionalAdjust ? RoundingType.Up : RoundingType.Down, adjustedQuantity); + adjustedQuantity = symbol.QuantityDecimals.HasValue ? (minNotionalAdjust ? RoundUp(adjustedQuantity, symbol.QuantityDecimals.Value) : RoundDown(adjustedQuantity, symbol.QuantityDecimals.Value)) : adjustedQuantity; + + } } } diff --git a/CryptoExchange.Net/ExtensionMethods.cs b/CryptoExchange.Net/ExtensionMethods.cs index c9e026be..a649050f 100644 --- a/CryptoExchange.Net/ExtensionMethods.cs +++ b/CryptoExchange.Net/ExtensionMethods.cs @@ -4,11 +4,12 @@ using System.IO; using System.Linq; using System.Runtime.InteropServices; -using System.Security; using System.Text; using System.Web; using CryptoExchange.Net.Objects; using System.Globalization; +using Microsoft.Extensions.DependencyInjection; +using CryptoExchange.Net.SharedApis; namespace CryptoExchange.Net { @@ -378,6 +379,116 @@ public static ReadOnlyMemory Decompress(this ReadOnlyMemory input) output.Position = 0; return new ReadOnlyMemory(output.GetBuffer(), 0, (int)output.Length); } + + /// + /// Whether the trading mode is linear + /// + public static bool IsLinear(this TradingMode type) => type == TradingMode.PerpetualLinear || type == TradingMode.DeliveryLinear; + + /// + /// Whether the trading mode is inverse + /// + public static bool IsInverse(this TradingMode type) => type == TradingMode.PerpetualInverse || type == TradingMode.DeliveryInverse; + + /// + /// Whether the trading mode is perpetual + /// + public static bool IsPerpetual(this TradingMode type) => type == TradingMode.PerpetualInverse || type == TradingMode.PerpetualLinear; + + /// + /// Whether the trading mode is delivery + /// + public static bool IsDelivery(this TradingMode type) => type == TradingMode.DeliveryInverse || type == TradingMode.DeliveryLinear; + + /// + /// Register rest client interfaces + /// + public static IServiceCollection RegisterSharedRestInterfaces(this IServiceCollection services, Func client) + { + if (typeof(IAssetsRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IAssetsRestClient)client(x)!); + if (typeof(IBalanceRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IBalanceRestClient)client(x)!); + if (typeof(IDepositRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IDepositRestClient)client(x)!); + if (typeof(IKlineRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IKlineRestClient)client(x)!); + if (typeof(IListenKeyRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IListenKeyRestClient)client(x)!); + if (typeof(IOrderBookRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IOrderBookRestClient)client(x)!); + if (typeof(IRecentTradeRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IRecentTradeRestClient)client(x)!); + if (typeof(ITradeHistoryRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (ITradeHistoryRestClient)client(x)!); + if (typeof(IWithdrawalRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IWithdrawalRestClient)client(x)!); + if (typeof(IWithdrawRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IWithdrawRestClient)client(x)!); + + if (typeof(ISpotOrderRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (ISpotOrderRestClient)client(x)!); + if (typeof(ISpotSymbolRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (ISpotSymbolRestClient)client(x)!); + if (typeof(ISpotTickerRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (ISpotTickerRestClient)client(x)!); + + if (typeof(IFundingRateRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IFundingRateRestClient)client(x)!); + if (typeof(IFuturesOrderRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IFuturesOrderRestClient)client(x)!); + if (typeof(IFuturesSymbolRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IFuturesSymbolRestClient)client(x)!); + if (typeof(IFuturesTickerRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IFuturesTickerRestClient)client(x)!); + if (typeof(IIndexPriceKlineRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IIndexPriceKlineRestClient)client(x)!); + if (typeof(ILeverageRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (ILeverageRestClient)client(x)!); + if (typeof(IMarkPriceKlineRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IMarkPriceKlineRestClient)client(x)!); + if (typeof(IOpenInterestRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IOpenInterestRestClient)client(x)!); + if (typeof(IPositionHistoryRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IPositionHistoryRestClient)client(x)!); + if (typeof(IPositionModeRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IPositionModeRestClient)client(x)!); + + return services; + } + + /// + /// Register socket client interfaces + /// + public static IServiceCollection RegisterSharedSocketInterfaces(this IServiceCollection services, Func client) + { + if (typeof(IBalanceSocketClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IBalanceSocketClient)client(x)!); + if (typeof(IBookTickerSocketClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IBookTickerSocketClient)client(x)!); + if (typeof(IKlineSocketClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IKlineSocketClient)client(x)!); + if (typeof(IOrderBookRestClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IOrderBookRestClient)client(x)!); + if (typeof(ITickerSocketClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (ITickerSocketClient)client(x)!); + if (typeof(ITickersSocketClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (ITickersSocketClient)client(x)!); + if (typeof(ITradeSocketClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (ITradeSocketClient)client(x)!); + if (typeof(IUserTradeSocketClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IUserTradeSocketClient)client(x)!); + + if (typeof(ISpotOrderSocketClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (ISpotOrderSocketClient)client(x)!); + + if (typeof(IFuturesOrderSocketClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IFuturesOrderSocketClient)client(x)!); + if (typeof(IPositionSocketClient).IsAssignableFrom(typeof(T))) + services.AddTransient(x => (IPositionSocketClient)client(x)!); + + return services; + } } } diff --git a/CryptoExchange.Net/Interfaces/CommonClients/IBaseRestClient.cs b/CryptoExchange.Net/Interfaces/CommonClients/IBaseRestClient.cs index 4624edf8..ebd2bdba 100644 --- a/CryptoExchange.Net/Interfaces/CommonClients/IBaseRestClient.cs +++ b/CryptoExchange.Net/Interfaces/CommonClients/IBaseRestClient.cs @@ -8,131 +8,87 @@ namespace CryptoExchange.Net.Interfaces.CommonClients { /// - /// Common rest client endpoints + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// public interface IBaseRestClient { /// - /// The name of the exchange + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// string ExchangeName { get; } /// - /// Should be triggered on order placing + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// event Action OnOrderPlaced; /// - /// Should be triggered on order cancelling + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// event Action OnOrderCanceled; /// - /// Get the symbol name based on a base and quote asset + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// The base asset - /// The quote asset - /// string GetSymbolName(string baseAsset, string quoteAsset); /// - /// Get a list of symbols for the exchange + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// [Optional] Cancellation token for cancelling the request - /// Task>> GetSymbolsAsync(CancellationToken ct = default); /// - /// Get a ticker for the exchange + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// The symbol to get klines for - /// [Optional] Cancellation token for cancelling the request - /// Task> GetTickerAsync(string symbol, CancellationToken ct = default); /// - /// Get a list of tickers for the exchange + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// [Optional] Cancellation token for cancelling the request - /// Task>> GetTickersAsync(CancellationToken ct = default); /// - /// Get a list of candles for a given symbol on the exchange + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// The symbol to retrieve the candles for - /// The timespan to retrieve the candles for. The supported value are dependent on the exchange - /// [Optional] Start time to retrieve klines for - /// [Optional] End time to retrieve klines for - /// [Optional] Max number of results - /// [Optional] Cancellation token for cancelling the request - /// Task>> GetKlinesAsync(string symbol, TimeSpan timespan, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, CancellationToken ct = default); /// - /// Get the order book for a symbol + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// The symbol to get the book for - /// [Optional] Cancellation token for cancelling the request - /// Task> GetOrderBookAsync(string symbol, CancellationToken ct = default); /// - /// The recent trades for a symbol + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// The symbol to get the trades for - /// [Optional] Cancellation token for cancelling the request - /// Task>> GetRecentTradesAsync(string symbol, CancellationToken ct = default); /// - /// Get balances + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// [Optional] The account id to retrieve balances for, required for some exchanges, ignored otherwise - /// [Optional] Cancellation token for cancelling the request - /// Task>> GetBalancesAsync(string? accountId = null, CancellationToken ct = default); /// - /// Get an order by id + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// The id - /// [Optional] The symbol the order is on, required for some exchanges, ignored otherwise - /// [Optional] Cancellation token for cancelling the request - /// Task> GetOrderAsync(string orderId, string? symbol = null, CancellationToken ct = default); /// - /// Get trades for an order by id + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// The id - /// [Optional] The symbol the order is on, required for some exchanges, ignored otherwise - /// [Optional] Cancellation token for cancelling the request - /// Task>> GetOrderTradesAsync(string orderId, string? symbol = null, CancellationToken ct = default); /// - /// Get a list of open orders + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// [Optional] The symbol to get open orders for, required for some exchanges, ignored otherwise - /// [Optional] Cancellation token for cancelling the request - /// Task>> GetOpenOrdersAsync(string? symbol = null, CancellationToken ct = default); /// - /// Get a list of closed orders + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// [Optional] The symbol to get closed orders for, required for some exchanges, ignored otherwise - /// [Optional] Cancellation token for cancelling the request - /// Task>> GetClosedOrdersAsync(string? symbol = null, CancellationToken ct = default); /// - /// Cancel an order by id + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// The id - /// [Optional] The symbol the order is on, required for some exchanges, ignored otherwise - /// [Optional] Cancellation token for cancelling the request - /// Task> CancelOrderAsync(string orderId, string? symbol = null, CancellationToken ct = default); } } diff --git a/CryptoExchange.Net/Interfaces/CommonClients/IFuturesClient.cs b/CryptoExchange.Net/Interfaces/CommonClients/IFuturesClient.cs index 48c99752..8a6feb3e 100644 --- a/CryptoExchange.Net/Interfaces/CommonClients/IFuturesClient.cs +++ b/CryptoExchange.Net/Interfaces/CommonClients/IFuturesClient.cs @@ -7,30 +7,18 @@ namespace CryptoExchange.Net.Interfaces.CommonClients { /// - /// Common futures endpoints + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// public interface IFuturesClient : IBaseRestClient { /// - /// Place an order + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// The symbol the order is for - /// The side of the order - /// The type of the order - /// The quantity of the order - /// The price of the order, only for limit orders - /// [Optional] The account id to place the order on, required for some exchanges, ignored otherwise - /// [Optional] Leverage for this order. This is needed for some exchanges. For exchanges where this is not needed this parameter is ignored (and should be set before hand) - /// [Optional] Client specified id for this order - /// [Optional] Cancellation token for cancelling the request - /// The id of the resulting order Task> PlaceOrderAsync(string symbol, CommonOrderSide side, CommonOrderType type, decimal quantity, decimal? price = null, int? leverage = null, string? accountId = null, string? clientOrderId = null, CancellationToken ct = default); /// - /// Get position + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// [Optional] Cancellation token for cancelling the request - /// Task>> GetPositionsAsync(CancellationToken ct = default); } } diff --git a/CryptoExchange.Net/Interfaces/CommonClients/ISpotClient.cs b/CryptoExchange.Net/Interfaces/CommonClients/ISpotClient.cs index 15c2fd18..8ca7ec4b 100644 --- a/CryptoExchange.Net/Interfaces/CommonClients/ISpotClient.cs +++ b/CryptoExchange.Net/Interfaces/CommonClients/ISpotClient.cs @@ -6,22 +6,13 @@ namespace CryptoExchange.Net.Interfaces.CommonClients { /// - /// Common spot endpoints + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// public interface ISpotClient: IBaseRestClient { /// - /// Place an order + /// DEPRECATED; use instead for common/shared functionality. See for more info. /// - /// The symbol the order is for - /// The side of the order - /// The type of the order - /// The quantity of the order - /// The price of the order, only for limit orders - /// [Optional] The account id to place the order on, required for some exchanges, ignored otherwise - /// [Optional] Client specified id for this order - /// [Optional] Cancellation token for cancelling the request - /// The id of the resulting order Task> PlaceOrderAsync(string symbol, CommonOrderSide side, CommonOrderType type, decimal quantity, decimal? price = null, string? accountId = null, string? clientOrderId = null, CancellationToken ct = default); } } diff --git a/CryptoExchange.Net/Interfaces/IBaseApiClient.cs b/CryptoExchange.Net/Interfaces/IBaseApiClient.cs index 88bbd73a..548a196c 100644 --- a/CryptoExchange.Net/Interfaces/IBaseApiClient.cs +++ b/CryptoExchange.Net/Interfaces/IBaseApiClient.cs @@ -1,4 +1,7 @@ using CryptoExchange.Net.Authentication; +using CryptoExchange.Net.Objects; +using CryptoExchange.Net.SharedApis; +using System; namespace CryptoExchange.Net.Interfaces { @@ -17,8 +20,10 @@ public interface IBaseApiClient /// /// The base asset /// The quote asset + /// The trading mode + /// The deliver date for a delivery futures symbol /// - string FormatSymbol(string baseAsset, string quoteAsset); + string FormatSymbol(string baseAsset, string quoteAsset, TradingMode tradingMode, DateTime? deliverDate = null); /// /// Set the API credentials for this API client diff --git a/CryptoExchange.Net/Interfaces/IRateLimiter.cs b/CryptoExchange.Net/Interfaces/IRateLimiter.cs index eee90da4..ec8a4223 100644 --- a/CryptoExchange.Net/Interfaces/IRateLimiter.cs +++ b/CryptoExchange.Net/Interfaces/IRateLimiter.cs @@ -1,7 +1,6 @@ using CryptoExchange.Net.Objects; using Microsoft.Extensions.Logging; using System.Net.Http; -using System.Security; using System.Threading; using System.Threading.Tasks; diff --git a/CryptoExchange.Net/Objects/ApiProxy.cs b/CryptoExchange.Net/Objects/ApiProxy.cs index 08fc51eb..3ba14c52 100644 --- a/CryptoExchange.Net/Objects/ApiProxy.cs +++ b/CryptoExchange.Net/Objects/ApiProxy.cs @@ -1,6 +1,4 @@ -using System.Security; - -namespace CryptoExchange.Net.Objects +namespace CryptoExchange.Net.Objects { /// /// Proxy info diff --git a/CryptoExchange.Net/Objects/CallResult.cs b/CryptoExchange.Net/Objects/CallResult.cs index c3218905..0cfa78d0 100644 --- a/CryptoExchange.Net/Objects/CallResult.cs +++ b/CryptoExchange.Net/Objects/CallResult.cs @@ -1,4 +1,5 @@ -using System; +using CryptoExchange.Net.SharedApis; +using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Net; @@ -284,6 +285,32 @@ public WebCallResult As([AllowNull] K data) return new WebCallResult(ResponseStatusCode, ResponseHeaders, ResponseTime, 0, null, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, ResultDataSource.Server, data, Error); } + /// + /// Copy the WebCallResult to an ExchangeWebResult of a new data type + /// + /// The new type + /// The exchange + /// Trade mode the result applies to + /// The data + /// + public ExchangeWebResult AsExchangeResult(string exchange, TradingMode tradeMode, [AllowNull] K data) + { + return new ExchangeWebResult(exchange, tradeMode, this.As(data)); + } + + /// + /// Copy the WebCallResult to an ExchangeWebResult of a new data type + /// + /// The new type + /// The exchange + /// Trade modes the result applies to + /// The data + /// + public ExchangeWebResult AsExchangeResult(string exchange, TradingMode[]? tradeModes, [AllowNull] K data) + { + return new ExchangeWebResult(exchange, tradeModes, this.As(data)); + } + /// /// Copy the WebCallResult to a new data type /// @@ -447,6 +474,68 @@ public WebCallResult(Error? error) : this(null, null, null, null, null, null, nu return new WebCallResult(ResponseStatusCode, ResponseHeaders, ResponseTime, ResponseLength, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, DataSource, default, error); } + /// + /// Copy the WebCallResult to an ExchangeWebResult of a new data type + /// + /// The exchange + /// Trade mode the result applies to + /// + public ExchangeWebResult AsExchangeResult(string exchange, TradingMode tradeMode) + { + return new ExchangeWebResult(exchange, tradeMode, this); + } + + /// + /// Copy the WebCallResult to an ExchangeWebResult of a new data type + /// + /// The exchange + /// Trade modes the result applies to + /// + public ExchangeWebResult AsExchangeResult(string exchange, TradingMode[] tradeModes) + { + return new ExchangeWebResult(exchange, tradeModes, this); + } + + /// + /// Copy the WebCallResult to an ExchangeWebResult of a new data type + /// + /// The new type + /// The exchange + /// Trade mode the result applies to + /// Data + /// Next page token + /// + public ExchangeWebResult AsExchangeResult(string exchange, TradingMode tradeMode, [AllowNull] K data, INextPageToken? nextPageToken = null) + { + return new ExchangeWebResult(exchange, tradeMode, As(data), nextPageToken); + } + + /// + /// Copy the WebCallResult to an ExchangeWebResult of a new data type + /// + /// The new type + /// The exchange + /// Trade modes the result applies to + /// Data + /// Next page token + /// + public ExchangeWebResult AsExchangeResult(string exchange, TradingMode[]? tradeModes, [AllowNull] K data, INextPageToken? nextPageToken = null) + { + return new ExchangeWebResult(exchange, tradeModes, As(data), nextPageToken); + } + + /// + /// Copy the WebCallResult to an ExchangeWebResult with a specific error + /// + /// The new type + /// The exchange + /// The error returned + /// + public ExchangeWebResult AsExchangeError(string exchange, Error error) + { + return new ExchangeWebResult(exchange, null, AsError(error)); + } + /// /// Return a copy of this result with data source set to cache /// diff --git a/CryptoExchange.Net/Objects/Enums.cs b/CryptoExchange.Net/Objects/Enums.cs index 2af12e0a..56783d80 100644 --- a/CryptoExchange.Net/Objects/Enums.cs +++ b/CryptoExchange.Net/Objects/Enums.cs @@ -152,7 +152,11 @@ public enum RoundingType /// /// Round to closest value /// - Closest + Closest, + /// + /// Round up (ceil) + /// + Up } /// @@ -203,4 +207,5 @@ public enum ResultDataSource /// Cache } + } diff --git a/CryptoExchange.Net/Objects/Options/SocketExchangeOptions.cs b/CryptoExchange.Net/Objects/Options/SocketExchangeOptions.cs index 5588bea6..63c6a5a6 100644 --- a/CryptoExchange.Net/Objects/Options/SocketExchangeOptions.cs +++ b/CryptoExchange.Net/Objects/Options/SocketExchangeOptions.cs @@ -1,5 +1,4 @@ using CryptoExchange.Net.Authentication; -using CryptoExchange.Net.Objects.Sockets; using System; namespace CryptoExchange.Net.Objects.Options diff --git a/CryptoExchange.Net/Objects/RequestDefinition.cs b/CryptoExchange.Net/Objects/RequestDefinition.cs index a28f5b85..1dd05673 100644 --- a/CryptoExchange.Net/Objects/RequestDefinition.cs +++ b/CryptoExchange.Net/Objects/RequestDefinition.cs @@ -1,5 +1,4 @@ using CryptoExchange.Net.RateLimiting.Interfaces; -using System; using System.Net.Http; namespace CryptoExchange.Net.Objects diff --git a/CryptoExchange.Net/Objects/RequestDefinitionCache.cs b/CryptoExchange.Net/Objects/RequestDefinitionCache.cs index 45dde1bb..acd469fd 100644 --- a/CryptoExchange.Net/Objects/RequestDefinitionCache.cs +++ b/CryptoExchange.Net/Objects/RequestDefinitionCache.cs @@ -1,7 +1,5 @@ using CryptoExchange.Net.RateLimiting.Interfaces; -using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Net.Http; namespace CryptoExchange.Net.Objects diff --git a/CryptoExchange.Net/Objects/Sockets/DataEvent.cs b/CryptoExchange.Net/Objects/Sockets/DataEvent.cs index 2b49131e..e486f37d 100644 --- a/CryptoExchange.Net/Objects/Sockets/DataEvent.cs +++ b/CryptoExchange.Net/Objects/Sockets/DataEvent.cs @@ -1,4 +1,5 @@ -using System; +using CryptoExchange.Net.SharedApis; +using System; namespace CryptoExchange.Net.Objects.Sockets { @@ -38,7 +39,10 @@ public class DataEvent /// public T Data { get; set; } - internal DataEvent(T data, string? streamId, string? symbol, string? originalData, DateTime timestamp, SocketUpdateType? updateType) + /// + /// ctor + /// + public DataEvent(T data, string? streamId, string? symbol, string? originalData, DateTime timestamp, SocketUpdateType? updateType) { Data = data; StreamId = streamId; @@ -85,6 +89,19 @@ public DataEvent As(K data, string streamId, string? symbol, SocketUpdateT return new DataEvent(data, streamId, symbol, OriginalData, Timestamp, updateType); } + /// + /// Copy the WebCallResult to a new data type + /// + /// The new type + /// The exchange the result is for + /// The data + /// + public ExchangeEvent AsExchangeEvent(string exchange, K data) + { + return new ExchangeEvent(exchange, this.As(data)); + } + + /// /// Specify the symbol /// diff --git a/CryptoExchange.Net/Objects/Sockets/UpdateSubscription.cs b/CryptoExchange.Net/Objects/Sockets/UpdateSubscription.cs index 9f43e94f..f75268bd 100644 --- a/CryptoExchange.Net/Objects/Sockets/UpdateSubscription.cs +++ b/CryptoExchange.Net/Objects/Sockets/UpdateSubscription.cs @@ -30,6 +30,15 @@ public event Action ConnectionClosed remove => _connection.ConnectionClosed -= value; } + /// + /// Event when a lost connection is restored, but the resubscribing of update subscriptions failed + /// + public event Action ResubscribingFailed + { + add => _connection.ResubscribingFailed += value; + remove => _connection.ResubscribingFailed -= value; + } + /// /// Event when the connection is restored. Timespan parameter indicates the time the socket has been offline for before reconnecting. /// Note that when the executing code is suspended and resumed at a later period (for example, a laptop going to sleep) the disconnect time will be incorrect as the diconnect diff --git a/CryptoExchange.Net/RateLimiting/Filters/AuthenticatedEndpointFilter.cs b/CryptoExchange.Net/RateLimiting/Filters/AuthenticatedEndpointFilter.cs index 22808d97..b40b36f3 100644 --- a/CryptoExchange.Net/RateLimiting/Filters/AuthenticatedEndpointFilter.cs +++ b/CryptoExchange.Net/RateLimiting/Filters/AuthenticatedEndpointFilter.cs @@ -1,6 +1,5 @@ using CryptoExchange.Net.Objects; using CryptoExchange.Net.RateLimiting.Interfaces; -using System.Security; namespace CryptoExchange.Net.RateLimiting.Filters { diff --git a/CryptoExchange.Net/RateLimiting/Filters/ExactPathFilter.cs b/CryptoExchange.Net/RateLimiting/Filters/ExactPathFilter.cs index 855a5897..bf8681ed 100644 --- a/CryptoExchange.Net/RateLimiting/Filters/ExactPathFilter.cs +++ b/CryptoExchange.Net/RateLimiting/Filters/ExactPathFilter.cs @@ -1,9 +1,6 @@ using CryptoExchange.Net.Objects; using CryptoExchange.Net.RateLimiting.Interfaces; using System; -using System.Collections.Generic; -using System.Security; -using System.Text; namespace CryptoExchange.Net.RateLimiting.Filters { diff --git a/CryptoExchange.Net/RateLimiting/Filters/ExactPathsFilter.cs b/CryptoExchange.Net/RateLimiting/Filters/ExactPathsFilter.cs index 6d17663d..6f663775 100644 --- a/CryptoExchange.Net/RateLimiting/Filters/ExactPathsFilter.cs +++ b/CryptoExchange.Net/RateLimiting/Filters/ExactPathsFilter.cs @@ -1,7 +1,6 @@ using CryptoExchange.Net.Objects; using CryptoExchange.Net.RateLimiting.Interfaces; using System.Collections.Generic; -using System.Security; namespace CryptoExchange.Net.RateLimiting.Filters { diff --git a/CryptoExchange.Net/RateLimiting/Filters/HostFilter.cs b/CryptoExchange.Net/RateLimiting/Filters/HostFilter.cs index 3079297b..65b47df5 100644 --- a/CryptoExchange.Net/RateLimiting/Filters/HostFilter.cs +++ b/CryptoExchange.Net/RateLimiting/Filters/HostFilter.cs @@ -1,6 +1,5 @@ using CryptoExchange.Net.Objects; using CryptoExchange.Net.RateLimiting.Interfaces; -using System.Security; namespace CryptoExchange.Net.RateLimiting.Filters { diff --git a/CryptoExchange.Net/RateLimiting/Filters/LimitItemTypeFilter.cs b/CryptoExchange.Net/RateLimiting/Filters/LimitItemTypeFilter.cs index 8d9d4bf5..93137a54 100644 --- a/CryptoExchange.Net/RateLimiting/Filters/LimitItemTypeFilter.cs +++ b/CryptoExchange.Net/RateLimiting/Filters/LimitItemTypeFilter.cs @@ -1,6 +1,5 @@ using CryptoExchange.Net.Objects; using CryptoExchange.Net.RateLimiting.Interfaces; -using System.Security; namespace CryptoExchange.Net.RateLimiting.Filters { diff --git a/CryptoExchange.Net/RateLimiting/Filters/PathStartFilter.cs b/CryptoExchange.Net/RateLimiting/Filters/PathStartFilter.cs index 449ac721..ba68b8b6 100644 --- a/CryptoExchange.Net/RateLimiting/Filters/PathStartFilter.cs +++ b/CryptoExchange.Net/RateLimiting/Filters/PathStartFilter.cs @@ -1,7 +1,6 @@ using CryptoExchange.Net.Objects; using CryptoExchange.Net.RateLimiting.Interfaces; using System; -using System.Security; namespace CryptoExchange.Net.RateLimiting.Filters { diff --git a/CryptoExchange.Net/RateLimiting/Guards/RateLimitGuard.cs b/CryptoExchange.Net/RateLimiting/Guards/RateLimitGuard.cs index 0f02b4ea..9501360e 100644 --- a/CryptoExchange.Net/RateLimiting/Guards/RateLimitGuard.cs +++ b/CryptoExchange.Net/RateLimiting/Guards/RateLimitGuard.cs @@ -3,8 +3,6 @@ using CryptoExchange.Net.RateLimiting.Trackers; using System; using System.Collections.Generic; -using System.Security; -using System.Text; namespace CryptoExchange.Net.RateLimiting.Guards { diff --git a/CryptoExchange.Net/RateLimiting/Guards/RetryAfterGuard.cs b/CryptoExchange.Net/RateLimiting/Guards/RetryAfterGuard.cs index 23a9fdcb..9383d541 100644 --- a/CryptoExchange.Net/RateLimiting/Guards/RetryAfterGuard.cs +++ b/CryptoExchange.Net/RateLimiting/Guards/RetryAfterGuard.cs @@ -1,9 +1,6 @@ using CryptoExchange.Net.Objects; using CryptoExchange.Net.RateLimiting.Interfaces; using System; -using System.Collections.Generic; -using System.Security; -using System.Text; namespace CryptoExchange.Net.RateLimiting.Guards { diff --git a/CryptoExchange.Net/RateLimiting/Guards/SingleLimitGuard.cs b/CryptoExchange.Net/RateLimiting/Guards/SingleLimitGuard.cs index 5b174ebf..1b53963e 100644 --- a/CryptoExchange.Net/RateLimiting/Guards/SingleLimitGuard.cs +++ b/CryptoExchange.Net/RateLimiting/Guards/SingleLimitGuard.cs @@ -3,7 +3,6 @@ using CryptoExchange.Net.RateLimiting.Trackers; using System; using System.Collections.Generic; -using System.Security; namespace CryptoExchange.Net.RateLimiting.Guards { diff --git a/CryptoExchange.Net/RateLimiting/Interfaces/IGuardFilter.cs b/CryptoExchange.Net/RateLimiting/Interfaces/IGuardFilter.cs index 7599db8d..8a75999e 100644 --- a/CryptoExchange.Net/RateLimiting/Interfaces/IGuardFilter.cs +++ b/CryptoExchange.Net/RateLimiting/Interfaces/IGuardFilter.cs @@ -1,5 +1,4 @@ using CryptoExchange.Net.Objects; -using System.Security; namespace CryptoExchange.Net.RateLimiting.Interfaces { diff --git a/CryptoExchange.Net/RateLimiting/Interfaces/IRateLimitGate.cs b/CryptoExchange.Net/RateLimiting/Interfaces/IRateLimitGate.cs index 536ebd62..a9078604 100644 --- a/CryptoExchange.Net/RateLimiting/Interfaces/IRateLimitGate.cs +++ b/CryptoExchange.Net/RateLimiting/Interfaces/IRateLimitGate.cs @@ -1,8 +1,6 @@ using CryptoExchange.Net.Objects; -using CryptoExchange.Net.RateLimiting.Guards; using Microsoft.Extensions.Logging; using System; -using System.Security; using System.Threading; using System.Threading.Tasks; diff --git a/CryptoExchange.Net/RateLimiting/Interfaces/IRateLimitGuard.cs b/CryptoExchange.Net/RateLimiting/Interfaces/IRateLimitGuard.cs index 7d3749d0..57f5e063 100644 --- a/CryptoExchange.Net/RateLimiting/Interfaces/IRateLimitGuard.cs +++ b/CryptoExchange.Net/RateLimiting/Interfaces/IRateLimitGuard.cs @@ -1,6 +1,4 @@ using CryptoExchange.Net.Objects; -using System.Net.Http; -using System.Security; namespace CryptoExchange.Net.RateLimiting.Interfaces { diff --git a/CryptoExchange.Net/RateLimiting/RateLimitGate.cs b/CryptoExchange.Net/RateLimiting/RateLimitGate.cs index c73ea67e..60aaca55 100644 --- a/CryptoExchange.Net/RateLimiting/RateLimitGate.cs +++ b/CryptoExchange.Net/RateLimiting/RateLimitGate.cs @@ -7,7 +7,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Security; using System.Threading; using System.Threading.Tasks; diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedFeeAssetType.cs b/CryptoExchange.Net/SharedApis/Enums/SharedFeeAssetType.cs new file mode 100644 index 00000000..f1e08a57 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedFeeAssetType.cs @@ -0,0 +1,29 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Fee asset selection type + /// + public enum SharedFeeAssetType + { + /// + /// Fee is always in the base asset + /// + BaseAsset, + /// + /// Fee is always in the quote asset + /// + QuoteAsset, + /// + /// Fee is always in the input asset + /// + InputAsset, + /// + /// Fee is always in the output asset + /// + OutputAsset, + /// + /// Fee is variable + /// + Variable + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedFeeDeductionType.cs b/CryptoExchange.Net/SharedApis/Enums/SharedFeeDeductionType.cs new file mode 100644 index 00000000..3da2b0ec --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedFeeDeductionType.cs @@ -0,0 +1,17 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Fee deduction type + /// + public enum SharedFeeDeductionType + { + /// + /// The fee is deducted from the output amount. For example buying 1 ETH at 1000 USDT with a 1% fee would cost 1000 USDT and output 0.99 ETH + /// + DeductFromOutput, + /// + /// The fee is added to the order cost. For example buying 1 ETH at 1000 USDT with a 1% fee would cost 1010 USDT and output 1 ETH + /// + AddToCost + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedKlineInterval.cs b/CryptoExchange.Net/SharedApis/Enums/SharedKlineInterval.cs new file mode 100644 index 00000000..829ca12b --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedKlineInterval.cs @@ -0,0 +1,33 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Kline interval + /// + public enum SharedKlineInterval + { + /// + /// 5 min + /// + FiveMinutes = 60 * 5, + /// + /// 15 min + /// + FifteenMinutes = 60 * 15, + /// + /// 1 hour + /// + OneHour = 60 * 60, + /// + /// 1 day + /// + OneDay = 60 * 60 * 24, + /// + /// 1 week + /// + OneWeek = 60 * 60 * 24 * 7, + /// + /// 1 month + /// + OneMonth = 60 * 60 * 24 * 30 + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedLeverageSettingMode.cs b/CryptoExchange.Net/SharedApis/Enums/SharedLeverageSettingMode.cs new file mode 100644 index 00000000..7f35d8a5 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedLeverageSettingMode.cs @@ -0,0 +1,17 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Leverage setting mode + /// + public enum SharedLeverageSettingMode + { + /// + /// Leverage is configured per side (in hedge mode) + /// + PerSide, + /// + /// Leverage is configured for the symbol + /// + PerSymbol + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedMarginMode.cs b/CryptoExchange.Net/SharedApis/Enums/SharedMarginMode.cs new file mode 100644 index 00000000..7f82b258 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedMarginMode.cs @@ -0,0 +1,17 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Margin mode + /// + public enum SharedMarginMode + { + /// + /// Cross margin, margin is shared across symbols + /// + Cross, + /// + /// Isolated margin, margin is isolated on a symbol + /// + Isolated + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedOrderSide.cs b/CryptoExchange.Net/SharedApis/Enums/SharedOrderSide.cs new file mode 100644 index 00000000..7b87ab57 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedOrderSide.cs @@ -0,0 +1,17 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Side of an order + /// + public enum SharedOrderSide + { + /// + /// Buy order + /// + Buy, + /// + /// Sell order + /// + Sell + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedOrderStatus.cs b/CryptoExchange.Net/SharedApis/Enums/SharedOrderStatus.cs new file mode 100644 index 00000000..a7aa9288 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedOrderStatus.cs @@ -0,0 +1,21 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Status of an order + /// + public enum SharedOrderStatus + { + /// + /// Order is open waiting to be filled + /// + Open, + /// + /// Order has been fully filled + /// + Filled, + /// + /// Order has been canceled + /// + Canceled + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedOrderType.cs b/CryptoExchange.Net/SharedApis/Enums/SharedOrderType.cs new file mode 100644 index 00000000..ad591182 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedOrderType.cs @@ -0,0 +1,25 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Type of an order + /// + public enum SharedOrderType + { + /// + /// Limit order, execute at a specific price + /// + Limit, + /// + /// Limit maker order, a limit order with the condition that is will never be executed as a maker + /// + LimitMaker, + /// + /// Market order, execute at the best price currently available + /// + Market, + /// + /// Other order type, used for parsing unsupported order types + /// + Other + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedPaginationSupport.cs b/CryptoExchange.Net/SharedApis/Enums/SharedPaginationSupport.cs new file mode 100644 index 00000000..0d228d9d --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedPaginationSupport.cs @@ -0,0 +1,21 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Supported pagination type + /// + public enum SharedPaginationSupport + { + /// + /// Pagination is not supported for this exchange request + /// + NotSupported, + /// + /// Pagination is in ascending order + /// + Ascending, + /// + /// Pagination is in descending order + /// + Descending + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedPositionMode.cs b/CryptoExchange.Net/SharedApis/Enums/SharedPositionMode.cs new file mode 100644 index 00000000..ac268f67 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedPositionMode.cs @@ -0,0 +1,17 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Position mode + /// + public enum SharedPositionMode + { + /// + /// Hedge mode, a symbol can have both a long and a short position at the same time + /// + HedgeMode, + /// + /// One way mode, a symbol can only have one open position side at a time + /// + OneWay + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedPositionModeSelection.cs b/CryptoExchange.Net/SharedApis/Enums/SharedPositionModeSelection.cs new file mode 100644 index 00000000..bce8557b --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedPositionModeSelection.cs @@ -0,0 +1,17 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Position mode selection type + /// + public enum SharedPositionModeSelection + { + /// + /// Position mode is configured per symbol + /// + PerSymbol, + /// + /// Position mode is configured for the entire account + /// + PerAccount + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedPositionSide.cs b/CryptoExchange.Net/SharedApis/Enums/SharedPositionSide.cs new file mode 100644 index 00000000..98d28869 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedPositionSide.cs @@ -0,0 +1,17 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// The side of a position + /// + public enum SharedPositionSide + { + /// + /// Long position + /// + Long, + /// + /// Short position + /// + Short + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedQuoteQuantitySupport.cs b/CryptoExchange.Net/SharedApis/Enums/SharedQuoteQuantitySupport.cs new file mode 100644 index 00000000..6e2476df --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedQuoteQuantitySupport.cs @@ -0,0 +1,25 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Quote asset order quantity support + /// + public enum SharedQuantityType + { + /// + /// Quantity should be in the base asset + /// + BaseAsset, + /// + /// Quantity should be in the quote asset + /// + QuoteAsset, + /// + /// Quantity is in the number of contracts + /// + Contracts, + /// + /// Quantity can be either base or quote quantity + /// + BaseAndQuoteAsset + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedRole.cs b/CryptoExchange.Net/SharedApis/Enums/SharedRole.cs new file mode 100644 index 00000000..ef93b8be --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedRole.cs @@ -0,0 +1,17 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// The role of a trade + /// + public enum SharedRole + { + /// + /// Maker role, put an order on the order book which has been filled + /// + Maker, + /// + /// Taker role, took an order of the order book to fill + /// + Taker + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedSymbolType.cs b/CryptoExchange.Net/SharedApis/Enums/SharedSymbolType.cs new file mode 100644 index 00000000..fa3f2d99 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedSymbolType.cs @@ -0,0 +1,25 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Type of a symbol + /// + public enum SharedSymbolType + { + /// + /// Perpetual linear, contract has no delivery date and is settled in stablecoin + /// + PerpetualLinear, + /// + /// Perpetual inverse, contract has no delivery date and is settled in crypto + /// + PerpetualInverse, + /// + /// Delivery linear, contract has a specific delivery date and is settled in stablecoin + /// + DeliveryLinear, + /// + /// Delivery inverse, contract has a specific delivery date and is settled in crypto + /// + DeliveryInverse + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/SharedTimeInForce.cs b/CryptoExchange.Net/SharedApis/Enums/SharedTimeInForce.cs new file mode 100644 index 00000000..2f8bbe25 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/SharedTimeInForce.cs @@ -0,0 +1,21 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Time in force for an order + /// + public enum SharedTimeInForce + { + /// + /// Order is good until canceled + /// + GoodTillCanceled, + /// + /// Order should execute immediately, not executed part is canceled + /// + ImmediateOrCancel, + /// + /// Order should execute fully immediately or is fully canceled + /// + FillOrKill + } +} diff --git a/CryptoExchange.Net/SharedApis/Enums/TradingMode.cs b/CryptoExchange.Net/SharedApis/Enums/TradingMode.cs new file mode 100644 index 00000000..04344aa6 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Enums/TradingMode.cs @@ -0,0 +1,29 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Trading mode + /// + public enum TradingMode + { + /// + /// Spot trading + /// + Spot, + /// + /// Perpetual linear futures + /// + PerpetualLinear, + /// + /// Delivery linear futures + /// + DeliveryLinear, + /// + /// Perpetual inverse futures + /// + PerpetualInverse, + /// + /// Delivery inverse futures + /// + DeliveryInverse + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/INextPageToken.cs b/CryptoExchange.Net/SharedApis/Interfaces/INextPageToken.cs new file mode 100644 index 00000000..ceb1e73d --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/INextPageToken.cs @@ -0,0 +1,111 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// A token which a request can use to retrieve the next page if there are more pages in the result set + /// + public interface INextPageToken + { + } + + /// + /// A datetime offset token + /// + public record DateTimeToken: INextPageToken + { + /// + /// Last result time + /// + public DateTime LastTime { get; set; } + + /// + /// ctor + /// + public DateTimeToken(DateTime timestamp) + { + LastTime = timestamp; + } + } + + /// + /// A current page index token + /// + public record PageToken: INextPageToken + { + /// + /// The next page index + /// + public int Page { get; set; } + /// + /// Page size + /// + public int PageSize { get; set; } + + /// + /// ctor + /// + public PageToken(int page, int pageSize) + { + Page = page; + PageSize = pageSize; + } + } + + /// + /// A id offset token + /// + public record FromIdToken : INextPageToken + { + /// + /// The last id from previous result + /// + public string FromToken { get; set; } + + /// + /// ctor + /// + public FromIdToken(string fromToken) + { + FromToken = fromToken; + } + } + + /// + /// A cursor token + /// + public record CursorToken : INextPageToken + { + /// + /// The next page cursor + /// + public string Cursor { get; set; } + + /// + /// ctor + /// + public CursorToken(string cursor) + { + Cursor = cursor; + } + } + + /// + /// A result offset token + /// + public record OffsetToken : INextPageToken + { + /// + /// Offset in the result set + /// + public int Offset { get; set; } + + /// + /// ctor + /// + public OffsetToken(int offset) + { + Offset = offset; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/ISharedClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/ISharedClient.cs new file mode 100644 index 00000000..73bf105e --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/ISharedClient.cs @@ -0,0 +1,43 @@ +using CryptoExchange.Net.Objects; +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// A shared/common client interface + /// + public interface ISharedClient + { + /// + /// Name of the exchange + /// + string Exchange { get; } + + /// + /// Which trading modes this client supports + /// + TradingMode[] SupportedTradingModes { get; } + + /// + /// Format a base and quote asset to an exchange accepted symbol + /// + /// The base asset + /// The quote asset + /// The trading mode + /// The deliver date for a delivery futures symbol + /// + string FormatSymbol(string baseAsset, string quoteAsset, TradingMode tradingMode, DateTime? deliverDate = null); + + /// + /// Set a default exchange parameter. This can be used instead of passing in an ExchangeParameters object which each request. + /// + /// Parameter name + /// Parameter value + void SetDefaultExchangeParameter(string name, object value); + + /// + /// Reset the default exchange parameters, resets parameters for all exchanges + /// + void ResetDefaultExchangeParameters(); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFundingRateRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFundingRateRestClient.cs new file mode 100644 index 00000000..e502164e --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFundingRateRestClient.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for request funding rate records + /// + public interface IFundingRateRestClient : ISharedClient + { + /// + /// Funding rate request options + /// + GetFundingRateHistoryOptions GetFundingRateHistoryOptions { get; } + /// + /// Get funding rate records + /// + /// Request info + /// The pagination token from the previous request to continue pagination + /// Cancellation token + Task>> GetFundingRateHistoryAsync(GetFundingRateHistoryRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFuturesOrderRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFuturesOrderRestClient.cs new file mode 100644 index 00000000..71424328 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFuturesOrderRestClient.cs @@ -0,0 +1,136 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for placing and managing futures orders + /// + public interface IFuturesOrderRestClient : ISharedClient + { + /// + /// How the trading fee is deducted + /// + SharedFeeDeductionType FuturesFeeDeductionType { get; } + /// + /// How the asset is determined in which the trading fee is paid + /// + SharedFeeAssetType FuturesFeeAssetType { get; } + + /// + /// Supported order types + /// + IEnumerable FuturesSupportedOrderTypes { get; } + /// + /// Supported time in force + /// + IEnumerable FuturesSupportedTimeInForce { get; } + /// + /// Quantity types support + /// + SharedQuantitySupport FuturesSupportedOrderQuantity { get; } + + /// + /// Futures place order request options + /// + PlaceFuturesOrderOptions PlaceFuturesOrderOptions { get; } + /// + /// Place a new futures order + /// + /// Request info + /// Cancellation token + Task> PlaceFuturesOrderAsync(PlaceFuturesOrderRequest request, CancellationToken ct = default); + + /// + /// Futures get order request options + /// + EndpointOptions GetFuturesOrderOptions { get; } + /// + /// Get info on a specific futures order + /// + /// Request info + /// Cancellation token + Task> GetFuturesOrderAsync(GetOrderRequest request, CancellationToken ct = default); + + /// + /// Futures get open orders request options + /// + EndpointOptions GetOpenFuturesOrdersOptions { get; } + /// + /// Get info on a open futures orders + /// + /// Request info + /// Cancellation token + Task>> GetOpenFuturesOrdersAsync(GetOpenOrdersRequest request, CancellationToken ct = default); + + /// + /// Spot get closed orders request options + /// + PaginatedEndpointOptions GetClosedFuturesOrdersOptions { get; } + /// + /// Get info on closed futures orders + /// + /// Request info + /// The pagination token from the previous request to continue pagination + /// Cancellation token + Task>> GetClosedFuturesOrdersAsync(GetClosedOrdersRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default); + + /// + /// Futures get order trades request options + /// + EndpointOptions GetFuturesOrderTradesOptions { get; } + /// + /// Get trades for a specific futures order + /// + /// Request info + /// Cancellation token + Task>> GetFuturesOrderTradesAsync(GetOrderTradesRequest request, CancellationToken ct = default); + + /// + /// Futures user trades request options + /// + PaginatedEndpointOptions GetFuturesUserTradesOptions { get; } + /// + /// Get futures user trade records + /// + /// Request info + /// The pagination token from the previous request to continue pagination + /// Cancellation token + Task>> GetFuturesUserTradesAsync(GetUserTradesRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default); + + /// + /// Futures cancel order request options + /// + EndpointOptions CancelFuturesOrderOptions { get; } + /// + /// Cancel a futures order + /// + /// Request info + /// Cancellation token + Task> CancelFuturesOrderAsync(CancelOrderRequest request, CancellationToken ct = default); + + /// + /// Positions request options + /// + EndpointOptions GetPositionsOptions { get; } + /// + /// Get open position info + /// + /// Request info + /// Cancellation token + Task>> GetPositionsAsync(GetPositionsRequest request, CancellationToken ct = default); + + /// + /// Close position order request options + /// + EndpointOptions ClosePositionOptions { get; } + /// + /// Close a currently open position + /// + /// Request info + /// Cancellation token + /// + Task> ClosePositionAsync(ClosePositionRequest request, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFuturesSymbolRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFuturesSymbolRestClient.cs new file mode 100644 index 00000000..1a3bb17f --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFuturesSymbolRestClient.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for request futures symbol info + /// + public interface IFuturesSymbolRestClient : ISharedClient + { + /// + /// Futures symbol request options + /// + EndpointOptions GetFuturesSymbolsOptions { get; } + /// + /// Get info on all futures symbols supported on the exchagne + /// + /// Request info + /// Cancellation token + Task>> GetFuturesSymbolsAsync(GetSymbolsRequest request, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFuturesTickerRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFuturesTickerRestClient.cs new file mode 100644 index 00000000..c08ca0ad --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IFuturesTickerRestClient.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for requesting ticker info for futures symbols + /// + public interface IFuturesTickerRestClient : ISharedClient + { + /// + /// Futures get ticker request options + /// + EndpointOptions GetFuturesTickerOptions { get; } + /// + /// Get ticker info for a specific futures symbol + /// + /// Request info + /// Cancellation token + Task> GetFuturesTickerAsync(GetTickerRequest request, CancellationToken ct = default); + + /// + /// Futures get tickers request options + /// + EndpointOptions GetFuturesTickersOptions { get; } + /// + /// Get ticker info for aall futures symbols + /// + /// Request info + /// Cancellation token + Task>> GetFuturesTickersAsync(GetTickersRequest request, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IIndexPriceKlineRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IIndexPriceKlineRestClient.cs new file mode 100644 index 00000000..b77c3b05 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IIndexPriceKlineRestClient.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for getting the index price klines for a symbol + /// + public interface IIndexPriceKlineRestClient : ISharedClient + { + /// + /// Index price klines request options + /// + GetKlinesOptions GetIndexPriceKlinesOptions { get; } + /// + /// Get index price kline/candlestick data + /// + /// Request info + /// The pagination token from the previous request to continue pagination + /// Cancellation token + Task>> GetIndexPriceKlinesAsync(GetKlinesRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/ILeverageRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/ILeverageRestClient.cs new file mode 100644 index 00000000..0262f697 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/ILeverageRestClient.cs @@ -0,0 +1,39 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for managing the leverage of a symbol + /// + public interface ILeverageRestClient : ISharedClient + { + /// + /// How the leverage setting is configured on the exchange + /// + SharedLeverageSettingMode LeverageSettingType { get; } + + /// + /// Leverage request options + /// + EndpointOptions GetLeverageOptions { get; } + /// + /// Get the current leverage setting for a symbol + /// + /// Request info + /// Cancellation token + Task> GetLeverageAsync(GetLeverageRequest request, CancellationToken ct = default); + + /// + /// Leverage set request options + /// + SetLeverageOptions SetLeverageOptions { get; } + /// + /// Set the leverage for a symbol + /// + /// Request info + /// Cancellation token + Task> SetLeverageAsync(SetLeverageRequest request, CancellationToken ct = default); + + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IMarkPriceKlineRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IMarkPriceKlineRestClient.cs new file mode 100644 index 00000000..dca14145 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IMarkPriceKlineRestClient.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for getting the mark price klines for a symbol + /// + public interface IMarkPriceKlineRestClient : ISharedClient + { + /// + /// Mark price klines request options + /// + GetKlinesOptions GetMarkPriceKlinesOptions { get; } + /// + /// Get mark price kline/candlestick data + /// + /// Request info + /// The pagination token from the previous request to continue pagination + /// Cancellation token + Task>> GetMarkPriceKlinesAsync(GetKlinesRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IOpenInterestRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IOpenInterestRestClient.cs new file mode 100644 index 00000000..1dac2c8a --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IOpenInterestRestClient.cs @@ -0,0 +1,22 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for getting the open interest for a symbol + /// + public interface IOpenInterestRestClient : ISharedClient + { + /// + /// Open interest request options + /// + EndpointOptions GetOpenInterestOptions { get; } + /// + /// Get the open interest for a symbol + /// + /// Request info + /// Cancellation token + Task> GetOpenInterestAsync(GetOpenInterestRequest request, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IPositionHistoryRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IPositionHistoryRestClient.cs new file mode 100644 index 00000000..31135c45 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IPositionHistoryRestClient.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for getting position history + /// + public interface IPositionHistoryRestClient : ISharedClient + { + /// + /// Position history request options + /// + GetPositionHistoryOptions GetPositionHistoryOptions { get; } + /// + /// Get position history + /// + /// Request info + /// The pagination token from the previous request to continue pagination + /// Cancellation token + Task>> GetPositionHistoryAsync(GetPositionHistoryRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IPositionModeRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IPositionModeRestClient.cs new file mode 100644 index 00000000..733bf8be --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Futures/IPositionModeRestClient.cs @@ -0,0 +1,38 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for managing the position mode setting + /// + public interface IPositionModeRestClient : ISharedClient + { + /// + /// How the exchange handles setting the position mode + /// + SharedPositionModeSelection PositionModeSettingType { get; } + + /// + /// Position mode request options + /// + GetPositionModeOptions GetPositionModeOptions { get; } + /// + /// Get the current position mode setting + /// + /// Request info + /// Cancellation token + Task> GetPositionModeAsync(GetPositionModeRequest request, CancellationToken ct = default); + + /// + /// Position mode set request options + /// + SetPositionModeOptions SetPositionModeOptions { get; } + /// + /// Set the position mode to a new value + /// + /// Request info + /// Cancellation token + Task> SetPositionModeAsync(SetPositionModeRequest request, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/IAssetsRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IAssetsRestClient.cs new file mode 100644 index 00000000..ca0e1b44 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IAssetsRestClient.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for requesting asset info + /// + public interface IAssetsRestClient : ISharedClient + { + /// + /// Asset request options + /// + EndpointOptions GetAssetOptions { get; } + + /// + /// Get info on a specific asset + /// + /// Request info + /// Cancellation token + Task> GetAssetAsync(GetAssetRequest request, CancellationToken ct = default); + + /// + /// Assets request options + /// + EndpointOptions GetAssetsOptions { get; } + + /// + /// Get info on all assets the exchange supports + /// + /// Request info + /// Cancellation token + Task>> GetAssetsAsync(GetAssetsRequest request, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/IBalanceRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IBalanceRestClient.cs new file mode 100644 index 00000000..1220053c --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IBalanceRestClient.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for requesting user balance info + /// + public interface IBalanceRestClient : ISharedClient + { + /// + /// Balances request options + /// + EndpointOptions GetBalancesOptions { get; } + + /// + /// Get balances for the user + /// + /// Request info + /// Cancellation token + /// + Task>> GetBalancesAsync(GetBalancesRequest request, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/IDepositRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IDepositRestClient.cs new file mode 100644 index 00000000..261c275b --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IDepositRestClient.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for requesting deposit addresses and deposit records + /// + public interface IDepositRestClient : ISharedClient + { + /// + /// Deposit addresses request options + /// + EndpointOptions GetDepositAddressesOptions { get; } + + /// + /// Get deposit addresses for an asset + /// + /// Request info + /// Cancellation token + /// + Task>> GetDepositAddressesAsync(GetDepositAddressesRequest request, CancellationToken ct = default); + + /// + /// Deposits request options + /// + GetDepositsOptions GetDepositsOptions { get; } + + /// + /// Get deposit records + /// + /// Request info + /// The pagination token from the previous request to continue pagination + /// Cancellation token + /// + Task>> GetDepositsAsync(GetDepositsRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/IKlineRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IKlineRestClient.cs new file mode 100644 index 00000000..39cfb300 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IKlineRestClient.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for requesting kline/candlestick data + /// + public interface IKlineRestClient : ISharedClient + { + /// + /// Kline request options + /// + GetKlinesOptions GetKlinesOptions { get; } + + /// + /// Get kline/candlestick data + /// + /// Request info + /// The pagination token from the previous request to continue pagination + /// Cancellation token + /// + Task>> GetKlinesAsync(GetKlinesRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/IListenKeyRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IListenKeyRestClient.cs new file mode 100644 index 00000000..5ffd6cd6 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IListenKeyRestClient.cs @@ -0,0 +1,45 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for managing the listen key for user stream updates + /// + public interface IListenKeyRestClient : ISharedClient + { + /// + /// Start listen key request options + /// + EndpointOptions StartOptions { get; } + /// + /// Get the listen key which can be used for user data updates on the socket client + /// + /// Request info + /// Cancellation token + /// + Task> StartListenKeyAsync(StartListenKeyRequest request, CancellationToken ct = default); + /// + /// Keep-alive listen key request options + /// + EndpointOptions KeepAliveOptions { get; } + /// + /// Keep-alive the listen key, needs to be called at a regular interval (typically every 30 minutes) + /// + /// Request info + /// Cancellation token + /// + Task> KeepAliveListenKeyAsync(KeepAliveListenKeyRequest request, CancellationToken ct = default); + /// + /// Stop listen key request options + /// + EndpointOptions StopOptions { get; } + /// + /// Stop the listen key, updates will no longer be send to the user data stream for this listen key + /// + /// Request info + /// Cancellation token + /// + Task> StopListenKeyAsync(StopListenKeyRequest request, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/IOrderBookRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IOrderBookRestClient.cs new file mode 100644 index 00000000..2994d587 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IOrderBookRestClient.cs @@ -0,0 +1,24 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for retrieving the order book for a symbol + /// + public interface IOrderBookRestClient : ISharedClient + { + /// + /// Order book request options + /// + GetOrderBookOptions GetOrderBookOptions { get; } + + /// + /// Get the order book for a symbol + /// + /// Request info + /// Cancellation token + /// + Task> GetOrderBookAsync(GetOrderBookRequest request, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/IRecentTradeRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IRecentTradeRestClient.cs new file mode 100644 index 00000000..f89afdb7 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IRecentTradeRestClient.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for retrieving the most recent public trades + /// + public interface IRecentTradeRestClient : ISharedClient + { + /// + /// Recent trades request options + /// + GetRecentTradesOptions GetRecentTradesOptions { get; } + + /// + /// Get the most recent public trades + /// + /// Request info + /// Cancellation token + /// + Task>> GetRecentTradesAsync(GetRecentTradesRequest request, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/ITradeHistoryRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/ITradeHistoryRestClient.cs new file mode 100644 index 00000000..a99e7233 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/ITradeHistoryRestClient.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for retrieving trading history + /// + public interface ITradeHistoryRestClient : ISharedClient + { + /// + /// Trade history request options + /// + GetTradeHistoryOptions GetTradeHistoryOptions { get; } + + /// + /// Get public trade history + /// + /// Request info + /// The pagination token from the previous request to continue pagination + /// Cancellation token + /// + Task>> GetTradeHistoryAsync(GetTradeHistoryRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/IWithdrawRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IWithdrawRestClient.cs new file mode 100644 index 00000000..4ad2ac09 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IWithdrawRestClient.cs @@ -0,0 +1,24 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for requesting to withdraw funds from the exchange + /// + public interface IWithdrawRestClient : ISharedClient + { + /// + /// Withdraw request options + /// + WithdrawOptions WithdrawOptions { get; } + + /// + /// Request a withdrawal + /// + /// Request info + /// Cancellation token + /// + Task> WithdrawAsync(WithdrawRequest request, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/IWithdrawalRestClient .cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IWithdrawalRestClient .cs new file mode 100644 index 00000000..9e24915d --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/IWithdrawalRestClient .cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for retrieving withdrawal records + /// + public interface IWithdrawalRestClient : ISharedClient + { + /// + /// Withdrawal record request options + /// + GetWithdrawalsOptions GetWithdrawalsOptions { get; } + + /// + /// Get withdrawal records + /// + /// Request info + /// The pagination token from the previous request to continue pagination + /// Cancellation token + /// + Task>> GetWithdrawalsAsync(GetWithdrawalsRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Spot/ISpotOrderRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Spot/ISpotOrderRestClient.cs new file mode 100644 index 00000000..fa6dd66b --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Spot/ISpotOrderRestClient.cs @@ -0,0 +1,114 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for placing and managing spot orders + /// + public interface ISpotOrderRestClient : ISharedClient + { + /// + /// How the trading fee is deducted + /// + SharedFeeDeductionType SpotFeeDeductionType { get; } + /// + /// How the asset is determined in which the trading fee is paid + /// + SharedFeeAssetType SpotFeeAssetType { get; } + + /// + /// Supported order types + /// + IEnumerable SpotSupportedOrderTypes { get; } + /// + /// Supported time in force + /// + IEnumerable SpotSupportedTimeInForce { get; } + /// + /// Quantity types support + /// + SharedQuantitySupport SpotSupportedOrderQuantity { get; } + + /// + /// Spot place order request options + /// + PlaceSpotOrderOptions PlaceSpotOrderOptions { get; } + /// + /// Place a new spot order + /// + /// Request info + /// Cancellation token + Task> PlaceSpotOrderAsync(PlaceSpotOrderRequest request, CancellationToken ct = default); + + /// + /// Spot get order request options + /// + EndpointOptions GetSpotOrderOptions { get; } + /// + /// Get info on a specific spot order + /// + /// Request info + /// Cancellation token + Task> GetSpotOrderAsync(GetOrderRequest request, CancellationToken ct = default); + + /// + /// Spot get open orders request options + /// + EndpointOptions GetOpenSpotOrdersOptions { get; } + /// + /// Get info on a open spot orders + /// + /// Request info + /// Cancellation token + Task>> GetOpenSpotOrdersAsync(GetOpenOrdersRequest request, CancellationToken ct = default); + + /// + /// Spot get closed orders request options + /// + PaginatedEndpointOptions GetClosedSpotOrdersOptions { get; } + /// + /// Get info on closed spot orders + /// + /// Request info + /// The pagination token from the previous request to continue pagination + /// Cancellation token + Task>> GetClosedSpotOrdersAsync(GetClosedOrdersRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default); + + /// + /// Spot get order trades request options + /// + EndpointOptions GetSpotOrderTradesOptions { get; } + /// + /// Get trades for a specific spot order + /// + /// Request info + /// Cancellation token + Task>> GetSpotOrderTradesAsync(GetOrderTradesRequest request, CancellationToken ct = default); + + /// + /// Spot user trades request options + /// + PaginatedEndpointOptions GetSpotUserTradesOptions { get; } + /// + /// Get spot user trade records + /// + /// Request info + /// The pagination token from the previous request to continue pagination + /// Cancellation token + Task>> GetSpotUserTradesAsync(GetUserTradesRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default); + + /// + /// Spot cancel order request options + /// + EndpointOptions CancelSpotOrderOptions { get; } + /// + /// Cancel a spot order + /// + /// Request info + /// Cancellation token + Task> CancelSpotOrderAsync(CancelOrderRequest request, CancellationToken ct = default); + + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Spot/ISpotSymbolRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Spot/ISpotSymbolRestClient.cs new file mode 100644 index 00000000..b982bd0e --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Spot/ISpotSymbolRestClient.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for requesting spot symbols + /// + public interface ISpotSymbolRestClient : ISharedClient + { + /// + /// Spot symbols request options + /// + EndpointOptions GetSpotSymbolsOptions { get; } + + /// + /// Get info on all available spot symbols on the exchange + /// + /// Request info + /// Cancellation token + Task>> GetSpotSymbolsAsync(GetSymbolsRequest request, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Rest/Spot/ISpotTickerRestClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Spot/ISpotTickerRestClient.cs new file mode 100644 index 00000000..dbb7abc8 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Rest/Spot/ISpotTickerRestClient.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for requesting spot tickers + /// + public interface ISpotTickerRestClient : ISharedClient + { + /// + /// Spot ticker request options + /// + EndpointOptions GetSpotTickerOptions { get; } + /// + /// Get ticker for a specific spot symbol + /// + /// Request info + /// Cancellation token + Task> GetSpotTickerAsync(GetTickerRequest request, CancellationToken ct = default); + /// + /// Spot tickers request options + /// + EndpointOptions GetSpotTickersOptions { get; } + /// + /// Get tickers for all spot symbols + /// + /// Request info + /// Cancellation token + Task>> GetSpotTickersAsync(GetTickersRequest request, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Socket/Futures/IFuturesOrderSocketClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Socket/Futures/IFuturesOrderSocketClient.cs new file mode 100644 index 00000000..8cfa4eb5 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Socket/Futures/IFuturesOrderSocketClient.cs @@ -0,0 +1,28 @@ +using CryptoExchange.Net.Objects.Sockets; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for subscribing to user futures order updates + /// + public interface IFuturesOrderSocketClient : ISharedClient + { + /// + /// Futures orders subscription options + /// + EndpointOptions SubscribeFuturesOrderOptions { get; } + + /// + /// Subscribe to user futures order updates + /// + /// Request info + /// Update handler + /// Cancellation token, can be used to stop the updates + /// + Task> SubscribeToFuturesOrderUpdatesAsync(SubscribeFuturesOrderRequest request, Action>> handler, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Socket/Futures/IPositionSocketClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Socket/Futures/IPositionSocketClient.cs new file mode 100644 index 00000000..d657748d --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Socket/Futures/IPositionSocketClient.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.Threading; +using CryptoExchange.Net.Objects.Sockets; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for subscribing to position updates + /// + public interface IPositionSocketClient : ISharedClient + { + /// + /// Position subscription options + /// + EndpointOptions SubscribePositionOptions { get; } + + /// + /// Subscribe to user position updates + /// + /// Request info + /// Update handler + /// Cancellation token, can be used to stop the updates + /// + Task> SubscribeToPositionUpdatesAsync(SubscribePositionRequest request, Action>> handler, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Socket/IBalanceSocketClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Socket/IBalanceSocketClient.cs new file mode 100644 index 00000000..f9df2de0 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Socket/IBalanceSocketClient.cs @@ -0,0 +1,28 @@ +using CryptoExchange.Net.Objects.Sockets; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for subscribing to user balance updates + /// + public interface IBalanceSocketClient : ISharedClient + { + /// + /// Balance subscription options + /// + EndpointOptions SubscribeBalanceOptions { get; } + + /// + /// Subscribe to user balance updates + /// + /// Request info + /// Update handler + /// Cancellation token, can be used to stop the updates + /// + Task> SubscribeToBalanceUpdatesAsync(SubscribeBalancesRequest request, Action>> handler, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Socket/IBookTickerSocketClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Socket/IBookTickerSocketClient.cs new file mode 100644 index 00000000..ad2c575e --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Socket/IBookTickerSocketClient.cs @@ -0,0 +1,27 @@ +using CryptoExchange.Net.Objects.Sockets; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for subscribing to book ticker updates for a symbol + /// + public interface IBookTickerSocketClient : ISharedClient + { + /// + /// Book ticker subscription options + /// + EndpointOptions SubscribeBookTickerOptions { get; } + + /// + /// Subscribe to book ticker (best ask/bid) updates for a symbol + /// + /// Request info + /// Update handler + /// Cancellation token, can be used to stop the updates + /// + Task> SubscribeToBookTickerUpdatesAsync(SubscribeBookTickerRequest request, Action> handler, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Socket/IKlineSocketClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Socket/IKlineSocketClient.cs new file mode 100644 index 00000000..9a8c5201 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Socket/IKlineSocketClient.cs @@ -0,0 +1,27 @@ +using System; +using System.Threading.Tasks; +using System.Threading; +using CryptoExchange.Net.Objects.Sockets; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for subscribing to kline/candlestick updates for a symbol + /// + public interface IKlineSocketClient : ISharedClient + { + /// + /// Kline subscription options + /// + SubscribeKlineOptions SubscribeKlineOptions { get; } + + /// + /// Subscribe to kline/candlestick updates for a symbol + /// + /// Request info + /// Update handler + /// Cancellation token, can be used to stop the updates + /// + Task> SubscribeToKlineUpdatesAsync(SubscribeKlineRequest request, Action> handler, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Socket/IOrderBookSocketClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Socket/IOrderBookSocketClient.cs new file mode 100644 index 00000000..4cab64f7 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Socket/IOrderBookSocketClient.cs @@ -0,0 +1,27 @@ +using CryptoExchange.Net.Objects.Sockets; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for subscribing to order book snapshot updates for a symbol + /// + public interface IOrderBookSocketClient : ISharedClient + { + /// + /// Order book subscription options + /// + SubscribeOrderBookOptions SubscribeOrderBookOptions { get; } + + /// + /// Subscribe to order book snapshot updates for a symbol + /// + /// Request info + /// Update handler + /// Cancellation token, can be used to stop the updates + /// + Task> SubscribeToOrderBookUpdatesAsync(SubscribeOrderBookRequest request, Action> handler, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Socket/ITickerSocketClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Socket/ITickerSocketClient.cs new file mode 100644 index 00000000..329d1d37 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Socket/ITickerSocketClient.cs @@ -0,0 +1,27 @@ +using CryptoExchange.Net.Objects.Sockets; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for subscribing to ticker updates for a symbol + /// + public interface ITickerSocketClient : ISharedClient + { + /// + /// Ticker subscription options + /// + EndpointOptions SubscribeTickerOptions { get; } + + /// + /// Subscribe to ticker updates for a symbol + /// + /// Request info + /// Update handler + /// Cancellation token, can be used to stop the updates + /// + Task> SubscribeToTickerUpdatesAsync(SubscribeTickerRequest request, Action> handler, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Socket/ITickersSocketClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Socket/ITickersSocketClient.cs new file mode 100644 index 00000000..e187f1e4 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Socket/ITickersSocketClient.cs @@ -0,0 +1,28 @@ +using CryptoExchange.Net.Objects.Sockets; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for subscribing to ticker updates for all symbols + /// + public interface ITickersSocketClient : ISharedClient + { + /// + /// Tickers subscription options + /// + EndpointOptions SubscribeAllTickersOptions { get; } + + /// + /// Subscribe to tickers updates for all symbols + /// + /// Request info + /// Update handler + /// Cancellation token, can be used to stop the updates + /// + Task> SubscribeToAllTickersUpdatesAsync(SubscribeAllTickersRequest request, Action>> handler, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Socket/ITradeSocketClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Socket/ITradeSocketClient.cs new file mode 100644 index 00000000..a46b072a --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Socket/ITradeSocketClient.cs @@ -0,0 +1,28 @@ +using CryptoExchange.Net.Objects.Sockets; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for subscribing to public trade updates for a symbol + /// + public interface ITradeSocketClient : ISharedClient + { + /// + /// Trade subscription options + /// + EndpointOptions SubscribeTradeOptions { get; } + + /// + /// Subscribe to public trade updates for a symbol + /// + /// Request info + /// Update handler + /// Cancellation token, can be used to stop the updates + /// + Task> SubscribeToTradeUpdatesAsync(SubscribeTradeRequest request, Action>> handler, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Socket/IUserTradeSocketClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Socket/IUserTradeSocketClient.cs new file mode 100644 index 00000000..941afeda --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Socket/IUserTradeSocketClient.cs @@ -0,0 +1,28 @@ +using CryptoExchange.Net.Objects.Sockets; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for subscribing to user trade updates + /// + public interface IUserTradeSocketClient : ISharedClient + { + /// + /// User trade subscription options + /// + EndpointOptions SubscribeUserTradeOptions { get; } + + /// + /// Subscribe to user trade updates + /// + /// Request info + /// Update handler + /// Cancellation token, can be used to stop the updates + /// + Task> SubscribeToUserTradeUpdatesAsync(SubscribeUserTradeRequest request, Action>> handler, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Interfaces/Socket/Spot/ISpotOrderSocketClient.cs b/CryptoExchange.Net/SharedApis/Interfaces/Socket/Spot/ISpotOrderSocketClient.cs new file mode 100644 index 00000000..5852aff9 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Interfaces/Socket/Spot/ISpotOrderSocketClient.cs @@ -0,0 +1,28 @@ +using CryptoExchange.Net.Objects.Sockets; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Client for subscribing to user spot order updates + /// + public interface ISpotOrderSocketClient : ISharedClient + { + /// + /// Spot orders subscription options + /// + EndpointOptions SubscribeSpotOrderOptions { get; } + + /// + /// Subscribe to user spot order updates + /// + /// Request info + /// Update handler + /// Cancellation token, can be used to stop the updates + /// + Task> SubscribeToSpotOrderUpdatesAsync(SubscribeSpotOrderRequest request, Action>> handler, CancellationToken ct = default); + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/ExchangeEvent.cs b/CryptoExchange.Net/SharedApis/Models/ExchangeEvent.cs new file mode 100644 index 00000000..cb5d8340 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/ExchangeEvent.cs @@ -0,0 +1,33 @@ +using CryptoExchange.Net.Objects.Sockets; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// An update event for a specific exchange + /// + /// Type of the data + public class ExchangeEvent : DataEvent + { + /// + /// The exchange + /// + public string Exchange { get; } + + /// + /// ctor + /// + public ExchangeEvent(string exchange, DataEvent evnt) : + base(evnt.Data, + evnt.StreamId, + evnt.Symbol, + evnt.OriginalData, + evnt.Timestamp, + evnt.UpdateType) + { + Exchange = exchange; + } + + /// + public override string ToString() => $"{Exchange} - " + base.ToString(); + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/ExchangeParameter.cs b/CryptoExchange.Net/SharedApis/Models/ExchangeParameter.cs new file mode 100644 index 00000000..c317ac80 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/ExchangeParameter.cs @@ -0,0 +1,34 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Exchange parameter + /// + public class ExchangeParameter + { + /// + /// Exchange name + /// + public string Exchange { get; set; } + /// + /// Parameter name + /// + public string Name { get; set; } + /// + /// Parameter value + /// + public object Value { get; set; } + + /// + /// Create a new exchange parameter + /// + /// Exchange name + /// Parameter name + /// Parameter value + public ExchangeParameter(string exchange, string name, object value) + { + Exchange = exchange; + Name = name; + Value = value; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/ExchangeParameters.cs b/CryptoExchange.Net/SharedApis/Models/ExchangeParameters.cs new file mode 100644 index 00000000..f853f250 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/ExchangeParameters.cs @@ -0,0 +1,176 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Exchange parameters + /// + public class ExchangeParameters + { + private readonly List _parameters; + private static List _staticParameters = new List(); + + /// + /// ctor + /// + /// The parameters to add + public ExchangeParameters(params ExchangeParameter[] parameters) + { + _parameters = parameters.ToList(); + } + + /// + /// Add a new parameter value + /// + /// + public void AddValue(ExchangeParameter exchangeParameter) + { + _parameters.Add(exchangeParameter); + } + + /// + /// Check whether a specific parameter is provided in this specific instance + /// + /// The exchange name + /// Parameter name + /// Type of the parameter value + /// + public bool HasValue(string exchange, string name, Type type) + { + var val = _parameters.SingleOrDefault(x => x.Exchange == exchange && x.Name == name); + val ??= _staticParameters.SingleOrDefault(x => x.Exchange == exchange && x.Name == name); + + if (val == null) + return false; + + try + { + Type t = Nullable.GetUnderlyingType(type) ?? type; + Convert.ChangeType(val.Value, t); + return true; + } + catch + { + return false; + } + } + + /// + /// Check whether a specific parameter is provided in the default parameters or the provided instance + /// + /// The provided exchange parameter in the request + /// The exchange name + /// Parameter name + /// Type of the parameter value + /// + public static bool HasValue(ExchangeParameters? exchangeParameters, string exchange, string name, Type type) + { + var provided = exchangeParameters?.HasValue(exchange, name, type); + if (provided == true) + return true; + + var val = _staticParameters.SingleOrDefault(x => x.Exchange == exchange && x.Name == name); + if (val == null) + return false; + + try + { + Type t = Nullable.GetUnderlyingType(type) ?? type; + Convert.ChangeType(val.Value, t); + return true; + } + catch + { + return false; + } + } + + /// + /// Get the value of a parameter from this instance + /// + /// Type of the parameter value + /// Exchange name + /// Parameter name + public T? GetValue(string exchange, string name) + { + var val = _parameters.SingleOrDefault(x => x.Exchange == exchange && x.Name == name); + if (val == null) + return default; + + try + { + Type t = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T); + return (T)Convert.ChangeType(val.Value, t); + } + catch + { + throw new ArgumentException("Incorrect type for parameter, expected " + typeof(T).Name, name); + } + } + + /// + /// Get the value of a parameter from this instance or the default values + /// + /// Type of the parameter value + /// The request parameters + /// Exchange name + /// Parameter name + public static T? GetValue(ExchangeParameters? exchangeParameters, string exchange, string name) + { + T? value; + if (exchangeParameters == null) + { + var parameter = _staticParameters.SingleOrDefault(x => x.Exchange == exchange && x.Name == name); + if (parameter == null) + return default; + + if (parameter.Value is T val) + return val; + + try + { + Type t = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T); + return (T)Convert.ChangeType(parameter.Value, t); + } + catch + { + throw new ArgumentException("Incorrect type for parameter, expected " + typeof(T).Name, name); + } + } + else + { + value = exchangeParameters.GetValue(exchange, name); + } + + return value; + } + + /// + /// Set static parameters + /// + /// Exchange name + /// Parameter name + /// Parameter value + public static void SetStaticParameter(string exchange, string key, object value) + { + var existing = _staticParameters.SingleOrDefault(x => x.Exchange == exchange && x.Name == key); + if (existing != null) + { + existing.Value = value; + return; + } + + _staticParameters.Add(new ExchangeParameter(exchange, key, value)); + } + + /// + /// Reset the static parameters, clears all parameters for all exchanges + /// + public static void ResetStaticParameters() + { + _staticParameters.Clear(); + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/ExchangeResult.cs b/CryptoExchange.Net/SharedApis/Models/ExchangeResult.cs new file mode 100644 index 00000000..be09d54c --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/ExchangeResult.cs @@ -0,0 +1,44 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// A CallResult from an exchange + /// + /// + public class ExchangeResult : CallResult + { + /// + /// The exchange + /// + public string Exchange { get; } + + /// + /// ctor + /// + public ExchangeResult( + string exchange, + Error error) : + base(error) + { + Exchange = exchange; + } + + /// + /// ctor + /// + public ExchangeResult( + string exchange, + CallResult result) : + base( + result.Data, + result.OriginalData, + result.Error) + { + Exchange = exchange; + } + + /// + public override string ToString() => $"{Exchange} - " + base.ToString(); + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/ExchangeWebResult.cs b/CryptoExchange.Net/SharedApis/Models/ExchangeWebResult.cs new file mode 100644 index 00000000..6093e47a --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/ExchangeWebResult.cs @@ -0,0 +1,150 @@ +using CryptoExchange.Net.Objects; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Net.Http; +using System.Net; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// A WebCallResult from an exchange + /// + /// The result type + public class ExchangeWebResult : WebCallResult + { + /// + /// The exchange + /// + public string Exchange { get; } + + /// + /// The trade modes for which the result data is + /// + public TradingMode[]? DataTradeMode { get; } + + /// + /// Token to retrieve the next page with + /// + public INextPageToken? NextPageToken { get; } + + /// + /// ctor + /// + public ExchangeWebResult( + string exchange, + Error error) : + base(error) + { + Exchange = exchange; + } + + /// + /// ctor + /// + public ExchangeWebResult( + string exchange, + TradingMode dataTradeMode, + WebCallResult result, + INextPageToken? nextPageToken = null) : + base(result.ResponseStatusCode, + result.ResponseHeaders, + result.ResponseTime, + result.ResponseLength, + result.OriginalData, + result.RequestId, + result.RequestUrl, + result.RequestBody, + result.RequestMethod, + result.RequestHeaders, + result.DataSource, + result.Data, + result.Error) + { + DataTradeMode = new[] { dataTradeMode }; + Exchange = exchange; + NextPageToken = nextPageToken; + } + + /// + /// ctor + /// + public ExchangeWebResult( + string exchange, + TradingMode[]? dataTradeModes, + WebCallResult result, + INextPageToken? nextPageToken = null) : + base(result.ResponseStatusCode, + result.ResponseHeaders, + result.ResponseTime, + result.ResponseLength, + result.OriginalData, + result.RequestId, + result.RequestUrl, + result.RequestBody, + result.RequestMethod, + result.RequestHeaders, + result.DataSource, + result.Data, + result.Error) + { + DataTradeMode = dataTradeModes; + Exchange = exchange; + NextPageToken = nextPageToken; + } + + /// + /// Create a new result + /// + public ExchangeWebResult( + string exchange, + TradingMode[]? dataTradeModes, + HttpStatusCode? code, + IEnumerable>>? responseHeaders, + TimeSpan? responseTime, + long? responseLength, + string? originalData, + int? requestId, + string? requestUrl, + string? requestBody, + HttpMethod? requestMethod, + IEnumerable>>? requestHeaders, + ResultDataSource dataSource, + [AllowNull] T data, + Error? error, + INextPageToken? nextPageToken = null) : base( + code, + responseHeaders, + responseTime, + responseLength, + originalData, + requestId, + requestUrl, + requestBody, + requestMethod, + requestHeaders, + dataSource, + data, + error) + { + DataTradeMode = dataTradeModes; + Exchange = exchange; + NextPageToken = nextPageToken; + } + + + /// + /// Copy the ExchangeWebResult to a new data type + /// + /// The new type + /// The data of the new type + /// + public new ExchangeWebResult As([AllowNull] K data) + { + return new ExchangeWebResult(Exchange, DataTradeMode, ResponseStatusCode, ResponseHeaders, ResponseTime, ResponseLength, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, DataSource, data, Error, NextPageToken); + } + + /// + public override string ToString() => $"{Exchange} - " + base.ToString(); + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/EndpointOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/EndpointOptions.cs new file mode 100644 index 00000000..594a4bde --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/EndpointOptions.cs @@ -0,0 +1,146 @@ +using CryptoExchange.Net.Objects; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for an exchange endpoint + /// + public class EndpointOptions + { + /// + /// Required exchange-specific parameters + /// + public List RequiredExchangeParameters { get; set; } = new List(); + /// + /// Endpoint name + /// + public string EndpointName { get; set; } + /// + /// Information on the specific exchange request + /// + public string? RequestNotes { get; set; } + /// + /// Whether the call requires authentication + /// + public bool NeedsAuthentication { get; set; } + + /// + /// ctor + /// + public EndpointOptions(string endpointName, bool needAuthentication) + { + EndpointName = endpointName; + NeedsAuthentication = needAuthentication; + } + + /// + /// Validate a request + /// + /// Exchange name + /// Provided exchange parameters + /// Request trading mode + /// Supported trading modes + /// + public virtual Error? ValidateRequest(string exchange, ExchangeParameters? exchangeParameters, TradingMode? tradingMode, TradingMode[] supportedTradingModes) + { + if (tradingMode != null && !supportedTradingModes.Contains(tradingMode.Value)) + return new ArgumentError($"ApiType.{tradingMode} is not supported, supported types: {string.Join(", ", supportedTradingModes)}"); + + foreach (var param in RequiredExchangeParameters) + { + if (!string.IsNullOrEmpty(param.Name)) + { + if (ExchangeParameters.HasValue(exchangeParameters, exchange, param.Name!, param.ValueType) != true) + return new ArgumentError($"Required exchange parameter `{param.Name}` for exchange `{exchange}` is missing or has incorrect type. Expected type is {param.ValueType.Name}. Example: {param.ExampleValue}"); + } + else + { + if (param.Names.All(x => ExchangeParameters.HasValue(exchangeParameters, exchange, x, param.ValueType) != true)) + return new ArgumentError($"One of exchange parameters `{string.Join(", ", param.Names)}` for exchange `{exchange}` should be provided. Example: {param.ExampleValue}"); + } + } + + return null; + } + + /// + public virtual string ToString(string exchange) + { + var sb = new StringBuilder(); + sb.AppendLine($"{exchange} {EndpointName}"); + if (!string.IsNullOrEmpty(RequestNotes)) + sb.AppendLine(RequestNotes); + sb.AppendLine($"Needs authentication: {NeedsAuthentication}"); + sb.AppendLine($"Required exchange specific parameters: {string.Join(", ", RequiredExchangeParameters.Select(x => x.ToString()))}"); + return sb.ToString(); + } + } + + /// + /// Options for an exchange endpoint + /// + /// Type of data + public class EndpointOptions : EndpointOptions where T : SharedRequest + { + /// + /// Required optional parameters in the request + /// + public List RequiredOptionalParameters { get; set; } = new List(); + + /// + /// ctor + /// + public EndpointOptions(bool needsAuthentication) : base(typeof(T).Name, needsAuthentication) + { + } + + /// + /// Validate a request + /// + /// Exchange name + /// The request + /// Request trading mode + /// Supported trading modes + /// + public virtual Error? ValidateRequest(string exchange, T request, TradingMode? tradingMode, TradingMode[] supportedTradingModes) + { + foreach (var param in RequiredOptionalParameters) + { + if (!string.IsNullOrEmpty(param.Name)) + { + if (typeof(T).GetProperty(param.Name).GetValue(request, null) == null) + return new ArgumentError($"Required optional parameter `{param.Name}` for exchange `{exchange}` is missing. Example: {param.ExampleValue}"); + } + else + { + if (param.Names.All(x => typeof(T).GetProperty(param.Name).GetValue(request, null) == null)) + return new ArgumentError($"One of optional parameters `{string.Join(", ", param.Names)}` for exchange `{exchange}` should be provided. Example: {param.ExampleValue}"); + } + + } + + return ValidateRequest(exchange, request.ExchangeParameters, tradingMode, supportedTradingModes); + } + + /// + public override string ToString(string exchange) + { + var sb = new StringBuilder(); + sb.AppendLine($"{exchange} {typeof(T).Name}"); + sb.AppendLine($"Needs authentication: {NeedsAuthentication}"); + if (!string.IsNullOrEmpty(RequestNotes)) + sb.AppendLine(RequestNotes); + if (RequiredOptionalParameters.Any()) + sb.AppendLine($"Required optional parameters: {string.Join(", ", RequiredOptionalParameters.Select(x => x.ToString()))}"); + if (RequiredExchangeParameters.Any()) + sb.AppendLine($"Required exchange specific parameters: {string.Join(", ", RequiredExchangeParameters.Select(x => x.ToString()))}"); + return sb.ToString(); + } + } + +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetClosedOrdersOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetClosedOrdersOptions.cs new file mode 100644 index 00000000..78db2de0 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetClosedOrdersOptions.cs @@ -0,0 +1,41 @@ +using CryptoExchange.Net.Objects; +using System.Text; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for requesting closed orders + /// + public class GetClosedOrdersOptions : PaginatedEndpointOptions + { + /// + /// Whether the start/end time filter is supported + /// + public bool TimeFilterSupported { get; set; } + + /// + /// ctor + /// + public GetClosedOrdersOptions(SharedPaginationSupport paginationType, bool timeFilterSupported) : base(paginationType, true) + { + TimeFilterSupported = timeFilterSupported; + } + + /// + public override Error? ValidateRequest(string exchange, GetClosedOrdersRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes) + { + if (TimeFilterSupported && request.StartTime != null) + return new ArgumentError($"Time filter is not supported"); + + return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes); + } + + /// + public override string ToString(string exchange) + { + var sb = new StringBuilder(base.ToString(exchange)); + sb.AppendLine($"Time filter supported: {TimeFilterSupported}"); + return sb.ToString(); + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetDepositsOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetDepositsOptions.cs new file mode 100644 index 00000000..8ae8eeb2 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetDepositsOptions.cs @@ -0,0 +1,41 @@ +using CryptoExchange.Net.Objects; +using System.Text; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for requesting deposits + /// + public class GetDepositsOptions : PaginatedEndpointOptions + { + /// + /// Whether the start/end time filter is supported + /// + public bool TimeFilterSupported { get; set; } + + /// + /// ctor + /// + public GetDepositsOptions(SharedPaginationSupport paginationType, bool timeFilterSupported) : base(paginationType, true) + { + TimeFilterSupported = timeFilterSupported; + } + + /// + public override Error? ValidateRequest(string exchange, GetDepositsRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes) + { + if (TimeFilterSupported && request.StartTime != null) + return new ArgumentError($"Time filter is not supported"); + + return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes); + } + + /// + public override string ToString(string exchange) + { + var sb = new StringBuilder(base.ToString(exchange)); + sb.AppendLine($"Time filter supported: {TimeFilterSupported}"); + return sb.ToString(); + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetFundingRateHistoryOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetFundingRateHistoryOptions.cs new file mode 100644 index 00000000..07a0507b --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetFundingRateHistoryOptions.cs @@ -0,0 +1,15 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for requesting funding rate history + /// + public class GetFundingRateHistoryOptions : PaginatedEndpointOptions + { + /// + /// ctor + /// + public GetFundingRateHistoryOptions(SharedPaginationSupport paginationType, bool needsAuthentication) : base(paginationType, needsAuthentication) + { + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetKlinesOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetKlinesOptions.cs new file mode 100644 index 00000000..c862330d --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetKlinesOptions.cs @@ -0,0 +1,104 @@ +using CryptoExchange.Net.Objects; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for requesting kline/candlestick data + /// + public class GetKlinesOptions : PaginatedEndpointOptions + { + /// + /// The supported kline intervals + /// + public IEnumerable SupportIntervals { get; } + /// + /// Max number of data points which can be requested + /// + public int? MaxTotalDataPoints { get; set; } + /// + /// Max number of data points which can be requested in a single request + /// + public int? MaxRequestDataPoints { get; set; } + /// + /// The max age of the data that can be requested + /// + public TimeSpan? MaxAge { get; set; } + + /// + /// ctor + /// + public GetKlinesOptions(SharedPaginationSupport paginationType, bool needsAuthentication) : base(paginationType, needsAuthentication) + { + SupportIntervals = new[] + { + SharedKlineInterval.FiveMinutes, + SharedKlineInterval.FifteenMinutes, + SharedKlineInterval.OneHour, + SharedKlineInterval.FifteenMinutes, + SharedKlineInterval.OneDay, + SharedKlineInterval.OneWeek, + SharedKlineInterval.OneMonth + }; + } + + /// + /// ctor + /// + public GetKlinesOptions(SharedPaginationSupport paginationType, bool needsAuthentication, params SharedKlineInterval[] intervals) : base(paginationType, needsAuthentication) + { + SupportIntervals = intervals; + } + + /// + /// Check whether a specific interval is supported + /// + /// + /// + public bool IsSupported(SharedKlineInterval interval) => SupportIntervals.Contains(interval); + + /// + public override Error? ValidateRequest(string exchange, GetKlinesRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes) + { + if (!IsSupported(request.Interval)) + return new ArgumentError("Interval not supported"); + + if (MaxAge.HasValue && request.StartTime < DateTime.UtcNow.Add(-MaxAge.Value)) + return new ArgumentError($"Only the most recent {MaxAge} klines are available"); + + if (MaxRequestDataPoints.HasValue && request.Limit > MaxRequestDataPoints.Value) + return new ArgumentError($"Only {MaxRequestDataPoints} klines can be retrieved per request"); + + if (MaxTotalDataPoints.HasValue) + { + if (request.Limit > MaxTotalDataPoints.Value) + return new ArgumentError($"Only the most recent {MaxTotalDataPoints} klines are available"); + + if (request.StartTime.HasValue == true) + { + if (((request.EndTime ?? DateTime.UtcNow) - request.StartTime.Value).TotalSeconds / (int)request.Interval > MaxTotalDataPoints.Value) + return new ArgumentError($"Only the most recent {MaxTotalDataPoints} klines are available, time filter failed"); + } + } + + return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes); + } + + /// + public override string ToString(string exchange) + { + var sb = new StringBuilder(base.ToString(exchange)); + sb.AppendLine($"Supported SharedKlineInterval values: {string.Join(", ", SupportIntervals)}"); + if (MaxAge != null) + sb.AppendLine($"Max age of data: {MaxAge}"); + if (MaxTotalDataPoints != null) + sb.AppendLine($"Max total data points available: {MaxTotalDataPoints}"); + if (MaxRequestDataPoints != null) + sb.AppendLine($"Max data points per request: {MaxRequestDataPoints}"); + return sb.ToString(); + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetOrderBookOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetOrderBookOptions.cs new file mode 100644 index 00000000..2b59714c --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetOrderBookOptions.cs @@ -0,0 +1,71 @@ +using CryptoExchange.Net.Objects; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for requesting order book + /// + public class GetOrderBookOptions : EndpointOptions + { + /// + /// Supported order book depths + /// + public IEnumerable? SupportedLimits { get; set; } + + /// + /// The min order book depth + /// + public int? MinLimit { get; set; } + /// + /// The max order book depth + /// + public int? MaxLimit { get; set; } + + /// + /// ctor + /// + public GetOrderBookOptions(int minLimit, int maxLimit, bool authenticated) : base(authenticated) + { + MinLimit = minLimit; + MaxLimit = maxLimit; + } + + /// + /// ctor + /// + public GetOrderBookOptions(IEnumerable supportedLimits, bool authenticated) : base(authenticated) + { + SupportedLimits = supportedLimits; + } + + /// + public override Error? ValidateRequest(string exchange, GetOrderBookRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes) + { + if (request.Limit == null) + return null; + + if (MaxLimit.HasValue && request.Limit.Value > MaxLimit) + return new ArgumentError($"Max limit is {MaxLimit}"); + + if (MinLimit.HasValue && request.Limit.Value < MinLimit) + return new ArgumentError($"Min limit is {MaxLimit}"); + + if (SupportedLimits != null && !SupportedLimits.Contains(request.Limit.Value)) + return new ArgumentError($"Limit should be one of " + string.Join(", ", SupportedLimits)); + + return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes); + } + + /// + public override string ToString(string exchange) + { + var sb = new StringBuilder(base.ToString(exchange)); + sb.AppendLine($"Supported limit values: [{(SupportedLimits == null ? string.Join(", ", SupportedLimits) : $"{MinLimit}..{MaxLimit}")}]"); + return sb.ToString(); + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetPositionHistoryOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetPositionHistoryOptions.cs new file mode 100644 index 00000000..f51c3a45 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetPositionHistoryOptions.cs @@ -0,0 +1,15 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for requesting position history + /// + public class GetPositionHistoryOptions : PaginatedEndpointOptions + { + /// + /// ctor + /// + public GetPositionHistoryOptions(SharedPaginationSupport paginationType) : base(paginationType, true) + { + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetPositionModeOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetPositionModeOptions.cs new file mode 100644 index 00000000..7857d2ba --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetPositionModeOptions.cs @@ -0,0 +1,15 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for requesting current position mode + /// + public class GetPositionModeOptions : EndpointOptions + { + /// + /// ctor + /// + public GetPositionModeOptions() : base(true) + { + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetRecentTradesOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetRecentTradesOptions.cs new file mode 100644 index 00000000..a6b43ec8 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetRecentTradesOptions.cs @@ -0,0 +1,41 @@ +using CryptoExchange.Net.Objects; +using System.Text; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for requesting recent trades + /// + public class GetRecentTradesOptions : EndpointOptions + { + /// + /// The max number of trades that can be requested + /// + public int MaxLimit { get; set; } + + /// + /// ctor + /// + public GetRecentTradesOptions(int limit, bool authenticated) : base(authenticated) + { + MaxLimit = limit; + } + + /// + public Error? Validate(GetRecentTradesRequest request) + { + if (request.Limit > MaxLimit) + return new ArgumentError($"Only the most recent {MaxLimit} trades are available"); + + return null; + } + + /// + public override string ToString(string exchange) + { + var sb = new StringBuilder(base.ToString(exchange)); + sb.AppendLine($"Max data points: {MaxLimit}"); + return sb.ToString(); + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetTradeHistoryOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetTradeHistoryOptions.cs new file mode 100644 index 00000000..11fe7553 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetTradeHistoryOptions.cs @@ -0,0 +1,42 @@ +using CryptoExchange.Net.Objects; +using System; +using System.Text; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for requesting trade history + /// + public class GetTradeHistoryOptions : PaginatedEndpointOptions + { + /// + /// The max age of data that can be requested + /// + public TimeSpan? MaxAge { get; set; } + + /// + /// ctor + /// + public GetTradeHistoryOptions(SharedPaginationSupport paginationType, bool needsAuthentication) : base(paginationType, needsAuthentication) + { + } + + /// + public override Error? ValidateRequest(string exchange, GetTradeHistoryRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes) + { + if (MaxAge.HasValue && request.StartTime < DateTime.UtcNow.Add(-MaxAge.Value)) + return new ArgumentError($"Only the most recent {MaxAge} trades are available"); + + return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes); + } + + /// + public override string ToString(string exchange) + { + var sb = new StringBuilder(base.ToString(exchange)); + if (MaxAge != null) + sb.AppendLine($"Max age of data: {MaxAge}"); + return sb.ToString(); + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetWithdrawalsOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetWithdrawalsOptions.cs new file mode 100644 index 00000000..3699090c --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/GetWithdrawalsOptions.cs @@ -0,0 +1,41 @@ +using CryptoExchange.Net.Objects; +using System.Text; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for requesting withdrawals + /// + public class GetWithdrawalsOptions : PaginatedEndpointOptions + { + /// + /// Whether the start/end time filter is supported + /// + public bool TimeFilterSupported { get; set; } + + /// + /// ctor + /// + public GetWithdrawalsOptions(SharedPaginationSupport paginationType, bool timeFilterSupported) : base(paginationType, true) + { + TimeFilterSupported = timeFilterSupported; + } + + /// + public override Error? ValidateRequest(string exchange, GetWithdrawalsRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes) + { + if (TimeFilterSupported && request.StartTime != null) + return new ArgumentError($"Time filter is not supported"); + + return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes); + } + + /// + public override string ToString(string exchange) + { + var sb = new StringBuilder(base.ToString(exchange)); + sb.AppendLine($"Time filter supported: {TimeFilterSupported}"); + return sb.ToString(); + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/PaginatedEndpointOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/PaginatedEndpointOptions.cs new file mode 100644 index 00000000..b30769f8 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/PaginatedEndpointOptions.cs @@ -0,0 +1,32 @@ +using System.Text; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for paginated endpoints + /// + /// + public class PaginatedEndpointOptions : EndpointOptions where T : SharedRequest + { + /// + /// Type of pagination supported + /// + public SharedPaginationSupport PaginationSupport { get; } + + /// + /// ctor + /// + public PaginatedEndpointOptions(SharedPaginationSupport paginationType, bool needsAuthentication) : base(needsAuthentication) + { + PaginationSupport = paginationType; + } + + /// + public override string ToString(string exchange) + { + var sb = new StringBuilder(base.ToString(exchange)); + sb.AppendLine($"Pagination type: {PaginationSupport}"); + return sb.ToString(); + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/PlaceFuturesOrderOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/PlaceFuturesOrderOptions.cs new file mode 100644 index 00000000..d989a789 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/PlaceFuturesOrderOptions.cs @@ -0,0 +1,49 @@ +using CryptoExchange.Net.Objects; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for placing a new futures order + /// + public class PlaceFuturesOrderOptions : EndpointOptions + { + /// + /// ctor + /// + public PlaceFuturesOrderOptions() : base(true) + { + } + + /// + /// Validate a request + /// + public Error? ValidateRequest( + string exchange, + PlaceFuturesOrderRequest request, + TradingMode? tradingMode, + TradingMode[] supportedApiTypes, + IEnumerable supportedOrderTypes, + IEnumerable supportedTimeInForce, + SharedQuantitySupport quantitySupport) + { + if (request.OrderType == SharedOrderType.Other) + throw new ArgumentException("OrderType can't be `Other`", nameof(request.OrderType)); + + if (!supportedOrderTypes.Contains(request.OrderType)) + return new ArgumentError("Order type not supported"); + + if (request.TimeInForce != null && !supportedTimeInForce.Contains(request.TimeInForce.Value)) + return new ArgumentError("Order time in force not supported"); + + var quantityError = quantitySupport.Validate(request.Side, request.OrderType, request.Quantity, request.QuoteQuantity); + if (quantityError != null) + return quantityError; + + return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes); + } + + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/PlaceSpotOrderOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/PlaceSpotOrderOptions.cs new file mode 100644 index 00000000..36edbf26 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/PlaceSpotOrderOptions.cs @@ -0,0 +1,49 @@ +using CryptoExchange.Net.Objects; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for placing a new spot order + /// + public class PlaceSpotOrderOptions : EndpointOptions + { + + /// + /// ctor + /// + public PlaceSpotOrderOptions() : base(true) + { + } + + /// + /// Validate a request + /// + public Error? ValidateRequest( + string exchange, + PlaceSpotOrderRequest request, + TradingMode? tradingMode, + TradingMode[] supportedApiTypes, + IEnumerable supportedOrderTypes, + IEnumerable supportedTimeInForce, + SharedQuantitySupport quantitySupport) + { + if (request.OrderType == SharedOrderType.Other) + throw new ArgumentException("OrderType can't be `Other`", nameof(request.OrderType)); + + if (!supportedOrderTypes.Contains(request.OrderType)) + return new ArgumentError("Order type not supported"); + + if (request.TimeInForce != null && !supportedTimeInForce.Contains(request.TimeInForce.Value)) + return new ArgumentError("Order time in force not supported"); + + var quantityError = quantitySupport.Validate(request.Side, request.OrderType, request.Quantity, request.QuoteQuantity); + if (quantityError != null) + return quantityError; + + return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes); + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/SetLeverageOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/SetLeverageOptions.cs new file mode 100644 index 00000000..e776588a --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/SetLeverageOptions.cs @@ -0,0 +1,15 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for setting leverage + /// + public class SetLeverageOptions : EndpointOptions + { + /// + /// ctor + /// + public SetLeverageOptions() : base(true) + { + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/SetPositionModeOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/SetPositionModeOptions.cs new file mode 100644 index 00000000..e74913cc --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/SetPositionModeOptions.cs @@ -0,0 +1,15 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for setting position mode + /// + public class SetPositionModeOptions : EndpointOptions + { + /// + /// ctor + /// + public SetPositionModeOptions() : base(true) + { + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/WithdrawOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/WithdrawOptions.cs new file mode 100644 index 00000000..17dfda8e --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Endpoints/WithdrawOptions.cs @@ -0,0 +1,15 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for requesting a withdrawal + /// + public class WithdrawOptions : EndpointOptions + { + /// + /// ctor + /// + public WithdrawOptions() : base(true) + { + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/ParameterDescription.cs b/CryptoExchange.Net/SharedApis/Models/Options/ParameterDescription.cs new file mode 100644 index 00000000..7636556c --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/ParameterDescription.cs @@ -0,0 +1,61 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Parameter description + /// + public class ParameterDescription + { + /// + /// Name of the parameter + /// + public string? Name { get; set; } + /// + /// Names of the parameters + /// + public string[]? Names { get; set; } + /// + /// Type of the value + /// + public Type ValueType { get; set; } + /// + /// Parameter description + /// + public string Description { get; set; } + /// + /// Example value + /// + public object ExampleValue { get; set; } + + /// + /// ctor + /// + public ParameterDescription(string parameterName, Type valueType, string description, object exampleValue) + { + Name = parameterName; + ValueType = valueType; + Description = description; + ExampleValue = exampleValue; + } + + /// + /// ctor + /// + public ParameterDescription(string[] parameterNames, Type valueType, string description, object exampleValue) + { + Names = parameterNames; + ValueType = valueType; + Description = description; + ExampleValue = exampleValue; + } + + /// + public override string ToString() + { + if (Name != null) + return $"[{ValueType.Name}] {Name}: {Description} | example: {ExampleValue}"; + return $"[{ValueType.Name}] {string.Join(" / ", Names)}: {Description} | example: {ExampleValue}"; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Subscriptions/SubscribeKlineOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Subscriptions/SubscribeKlineOptions.cs new file mode 100644 index 00000000..c746c304 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Subscriptions/SubscribeKlineOptions.cs @@ -0,0 +1,61 @@ +using CryptoExchange.Net.Objects; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for subscribing to kline/candlestick updates + /// + public class SubscribeKlineOptions : EndpointOptions + { + /// + /// Kline intervals supported for updates + /// + public IEnumerable SupportIntervals { get; } + + /// + /// ctor + /// + public SubscribeKlineOptions(bool needsAuthentication) : base(needsAuthentication) + { + SupportIntervals = new[] + { + SharedKlineInterval.FiveMinutes, + SharedKlineInterval.FifteenMinutes, + SharedKlineInterval.OneHour, + SharedKlineInterval.FifteenMinutes, + SharedKlineInterval.OneDay, + SharedKlineInterval.OneWeek, + SharedKlineInterval.OneMonth + }; + } + + /// + /// ctor + /// + public SubscribeKlineOptions(bool needsAuthentication, params SharedKlineInterval[] intervals) : base(needsAuthentication) + { + SupportIntervals = intervals; + } + + /// + /// Check whether a specific interval is supported + /// + /// Interval + /// + public bool IsSupported(SharedKlineInterval interval) => SupportIntervals.Contains(interval); + + /// + /// Validate a request + /// + public override Error? ValidateRequest(string exchange, SubscribeKlineRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes) + { + if (!IsSupported(request.Interval)) + return new ArgumentError("Interval not supported"); + + return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes); + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Options/Subscriptions/SubscribeOrderBookOptions.cs b/CryptoExchange.Net/SharedApis/Models/Options/Subscriptions/SubscribeOrderBookOptions.cs new file mode 100644 index 00000000..9b4bf278 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Options/Subscriptions/SubscribeOrderBookOptions.cs @@ -0,0 +1,37 @@ +using CryptoExchange.Net.Objects; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Options for subscribing to order book snapshot updates + /// + public class SubscribeOrderBookOptions : EndpointOptions + { + /// + /// Order book depths supported for updates + /// + public IEnumerable SupportedLimits { get; } + + /// + /// ctor + /// + public SubscribeOrderBookOptions(bool needsAuthentication, IEnumerable limits) : base(needsAuthentication) + { + SupportedLimits = limits; + } + + /// + /// Validate a request + /// + public override Error? ValidateRequest(string exchange, SubscribeOrderBookRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes) + { + if (request.Limit != null && !SupportedLimits.Contains(request.Limit.Value)) + return new ArgumentError("Limit not supported"); + + return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes); + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/CancelOrderRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/CancelOrderRequest.cs new file mode 100644 index 00000000..07f3ca45 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/CancelOrderRequest.cs @@ -0,0 +1,24 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to cancel a currently open order + /// + public record CancelOrderRequest : SharedSymbolRequest + { + /// + /// Id of order to cancel + /// + public string OrderId { get; set; } + + /// + /// ctor + /// + /// Symbol the order is on + /// Id of the order to close + /// Exchange specific parameters + public CancelOrderRequest(SharedSymbol symbol, string orderId, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + OrderId = orderId; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/ClosePositionRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/ClosePositionRequest.cs new file mode 100644 index 00000000..73fe265a --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/ClosePositionRequest.cs @@ -0,0 +1,48 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to close a currently open position + /// + public record ClosePositionRequest : SharedSymbolRequest + { + /// + /// The current position mode of the account for the symbol + /// + public SharedPositionMode PositionMode { get; set; } + /// + /// The position side to close. Required when in hedge mode + /// + public SharedPositionSide? PositionSide { get; set; } + /// + /// Margin mode + /// + public SharedMarginMode? MarginMode { get; set; } + /// + /// Quantity of the position to close. Note that the quantity is needed for some exchanges, but will not be respected on other exchanges; don't use it as partial close quantity + /// + public decimal? Quantity { get; set; } + + /// + /// ctor + /// + /// Symbol to close the position on + /// The current position mode of the account for the symbol + /// The position side to close. Required when in hedge mode + /// Margin mode + /// Quantity of the position to close. Note that the quantity is needed for some exchanges, but will not be respected on all exchanges + /// Exchange specific parameters + public ClosePositionRequest( + SharedSymbol symbol, + SharedPositionMode mode, + SharedPositionSide? positionSide = null, + SharedMarginMode? marginMode = null, + decimal? quantity = null, + ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + PositionMode = mode; + PositionSide = positionSide; + MarginMode = marginMode; + Quantity = quantity; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetAssetRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetAssetRequest.cs new file mode 100644 index 00000000..c8a0a64a --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetAssetRequest.cs @@ -0,0 +1,23 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve info on a specific asset + /// + public record GetAssetRequest : SharedRequest + { + /// + /// Asset name + /// + public string Asset { get; set; } + + /// + /// ctor + /// + /// Asset to retrieve info on + /// Exchange specific parameters + public GetAssetRequest(string asset, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + Asset = asset; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetAssetsRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetAssetsRequest.cs new file mode 100644 index 00000000..7ef35a06 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetAssetsRequest.cs @@ -0,0 +1,18 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve a list of supported assets + /// + public record GetAssetsRequest : SharedRequest + { + /// + /// ctor + /// + /// Exchange specific parameters + public GetAssetsRequest(ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetBalancesRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetBalancesRequest.cs new file mode 100644 index 00000000..2cab40b3 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetBalancesRequest.cs @@ -0,0 +1,25 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve balance info for the user + /// + public record GetBalancesRequest : SharedRequest + { + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + + /// + /// ctor + /// + /// Trading mode + /// Exchange specific parameters + public GetBalancesRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + TradingMode = tradingMode; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetClosedOrdersRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetClosedOrdersRequest.cs new file mode 100644 index 00000000..4920d8e3 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetClosedOrdersRequest.cs @@ -0,0 +1,38 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve closed orders for a symbol + /// + public record GetClosedOrdersRequest : SharedSymbolRequest + { + /// + /// Filter by start time + /// + public DateTime? StartTime { get; } + /// + /// Filter by end time + /// + public DateTime? EndTime { get; } + /// + /// Max number of results + /// + public int? Limit { get; } + + /// + /// ctor + /// + /// Symbol to get closed orders for + /// Filter by start time + /// Filter by end time + /// Max number of results + /// Exchange specific parameters + public GetClosedOrdersRequest(SharedSymbol symbol, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + StartTime = startTime; + EndTime = endTime; + Limit = limit; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetDepositAddressesRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetDepositAddressesRequest.cs new file mode 100644 index 00000000..53c060c6 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetDepositAddressesRequest.cs @@ -0,0 +1,29 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve the deposit addresses for an asset + /// + public record GetDepositAddressesRequest : SharedRequest + { + /// + /// Asset to get address for + /// + public string Asset { get; set; } + /// + /// Network name + /// + public string? Network { get; set; } + + /// + /// ctor + /// + /// Asset name to get address for + /// Network name + /// Exchange specific parameters + public GetDepositAddressesRequest(string asset, string? network = null, ExchangeParameters? exchangeParameters = null): base(exchangeParameters) + { + Asset = asset; + Network = network; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetDepositsRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetDepositsRequest.cs new file mode 100644 index 00000000..5f53be22 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetDepositsRequest.cs @@ -0,0 +1,43 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve deposit history records + /// + public record GetDepositsRequest : SharedRequest + { + /// + /// Filter by asset + /// + public string? Asset { get; set; } + /// + /// Filter by start time + /// + public DateTime? StartTime { get; } + /// + /// Filter by end time + /// + public DateTime? EndTime { get; } + /// + /// Max number of results + /// + public int? Limit { get; } + + /// + /// ctor + /// + /// Filter by asset + /// Filter by start time + /// Filter by end time + /// Max number of results + /// Exchange specific parameters + public GetDepositsRequest(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + Asset = asset; + StartTime = startTime; + EndTime = endTime; + Limit = limit; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetFundingRateHistoryRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetFundingRateHistoryRequest.cs new file mode 100644 index 00000000..213657fe --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetFundingRateHistoryRequest.cs @@ -0,0 +1,38 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve funding rate history data + /// + public record GetFundingRateHistoryRequest : SharedSymbolRequest + { + /// + /// Filter by start time + /// + public DateTime? StartTime { get; set; } + /// + /// Filter by end time + /// + public DateTime? EndTime { get; set; } + /// + /// Max number of results + /// + public int? Limit { get; set; } + + /// + /// ctor + /// + /// Symbol to request klines for + /// Filter by start time + /// Filter by end time + /// Max number of results + /// Exchange specific parameters + public GetFundingRateHistoryRequest(SharedSymbol symbol, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + StartTime = startTime; + EndTime = endTime; + Limit = limit; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetKlinesRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetKlinesRequest.cs new file mode 100644 index 00000000..6eef5a22 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetKlinesRequest.cs @@ -0,0 +1,44 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve kline/candlestick data + /// + public record GetKlinesRequest : SharedSymbolRequest + { + /// + /// The kline interval + /// + public SharedKlineInterval Interval { get; set; } + /// + /// Filter by start time + /// + public DateTime? StartTime { get; set; } + /// + /// Filter by end time + /// + public DateTime? EndTime { get; set; } + /// + /// Max number of results + /// + public int? Limit { get; set; } + + /// + /// ctor + /// + /// Symbol to request klines for + /// Interval of the klines + /// Filter by start time + /// Filter by end time + /// Max number of results + /// Exchange specific parameters + public GetKlinesRequest(SharedSymbol symbol, SharedKlineInterval interval, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + Interval = interval; + StartTime = startTime; + EndTime = endTime; + Limit = limit; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetLeverageRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetLeverageRequest.cs new file mode 100644 index 00000000..05aa6e8c --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetLeverageRequest.cs @@ -0,0 +1,30 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve the leverage setting for a symbol + /// + public record GetLeverageRequest : SharedSymbolRequest + { + /// + /// Position side, required when in hedge mode + /// + public SharedPositionSide? PositionSide { get; set; } + /// + /// Margin mode + /// + public SharedMarginMode? MarginMode { get; set; } + + /// + /// ctor + /// + /// Symbol to request leverage for + /// Position side to get leverage for when in hedge mode + /// Margin mode + /// Exchange specific parameters + public GetLeverageRequest(SharedSymbol symbol, SharedPositionSide? positionSide = null, SharedMarginMode? marginMode = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + PositionSide = positionSide; + MarginMode = marginMode; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetOpenInterestRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetOpenInterestRequest.cs new file mode 100644 index 00000000..f6a58dd9 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetOpenInterestRequest.cs @@ -0,0 +1,17 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve the current open interest for a symbol + /// + public record GetOpenInterestRequest : SharedSymbolRequest + { + /// + /// ctor + /// + /// Symbol to retrieve open orders for + /// Exchange specific parameters + public GetOpenInterestRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetOpenOrdersRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetOpenOrdersRequest.cs new file mode 100644 index 00000000..9f35a10c --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetOpenOrdersRequest.cs @@ -0,0 +1,39 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve the current open orders + /// + public record GetOpenOrdersRequest : SharedRequest + { + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + /// + /// Symbol filter + /// + public SharedSymbol? Symbol { get; set; } + + /// + /// ctor + /// + /// Trading mode + /// Exchange specific parameters + public GetOpenOrdersRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + TradingMode = tradingMode; + } + + /// + /// ctor + /// + /// Symbol to retrieve open orders for + /// Exchange specific parameters + public GetOpenOrdersRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + Symbol = symbol; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetOrderBookRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetOrderBookRequest.cs new file mode 100644 index 00000000..2f9d0258 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetOrderBookRequest.cs @@ -0,0 +1,24 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve the current order book + /// + public record GetOrderBookRequest: SharedSymbolRequest + { + /// + /// Depth of the order book + /// + public int? Limit { get; set; } + + /// + /// ctor + /// + /// The symbol the order is on + /// Depth of the order book + /// Exchange specific parameters + public GetOrderBookRequest(SharedSymbol symbol, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + Limit = limit; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetOrderRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetOrderRequest.cs new file mode 100644 index 00000000..cd868008 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetOrderRequest.cs @@ -0,0 +1,24 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve info on a specifc order + /// + public record GetOrderRequest : SharedSymbolRequest + { + /// + /// Id of the order + /// + public string OrderId { get; set; } + + /// + /// ctor + /// + /// The symbol the order is on + /// The id of the order + /// Exchange specific parameters + public GetOrderRequest(SharedSymbol symbol, string orderId, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + OrderId = orderId; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetOrderTradesRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetOrderTradesRequest.cs new file mode 100644 index 00000000..f9ad1412 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetOrderTradesRequest.cs @@ -0,0 +1,24 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve the trades for a specific order + /// + public record GetOrderTradesRequest : SharedSymbolRequest + { + /// + /// The id of the order to retrieve trades for + /// + public string OrderId { get; set; } + + /// + /// ctor + /// + /// The symbol the order is on + /// The id of the order + /// Exchange specific parameters + public GetOrderTradesRequest(SharedSymbol symbol, string orderId, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + OrderId = orderId; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetPositionHistoryRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetPositionHistoryRequest.cs new file mode 100644 index 00000000..cc2ec6e1 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetPositionHistoryRequest.cs @@ -0,0 +1,64 @@ +using CryptoExchange.Net.Objects; +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve the position close history + /// + public record GetPositionHistoryRequest : SharedRequest + { + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + /// + /// Symbol + /// + public SharedSymbol? Symbol { get; set; } + /// + /// Filter by start time + /// + public DateTime? StartTime { get; set; } + /// + /// Filter by end time + /// + public DateTime? EndTime { get; set; } + /// + /// Max number of results + /// + public int? Limit { get; set; } + + /// + /// ctor + /// + /// Symbol filter + /// Filter by start time + /// Filter by end time + /// Max number of results + /// Exchange specific parameters + public GetPositionHistoryRequest(SharedSymbol symbol, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + Symbol = symbol; + StartTime = startTime; + EndTime = endTime; + Limit = limit; + } + + /// + /// ctor + /// + /// Trade mode + /// Filter by start time + /// Filter by end time + /// Max number of results + /// Exchange specific parameters + public GetPositionHistoryRequest(TradingMode? tradeMode = null, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + TradingMode = tradeMode; + StartTime = startTime; + EndTime = endTime; + Limit = limit; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetPositionModeRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetPositionModeRequest.cs new file mode 100644 index 00000000..7ff9b11b --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetPositionModeRequest.cs @@ -0,0 +1,39 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve the current position mode + /// + public record GetPositionModeRequest : SharedRequest + { + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + /// + /// Symbol. Some exchanges set position mode per symbol + /// + public SharedSymbol? Symbol { get; set; } + + /// + /// ctor + /// + /// Symbol to retrieve position mode for + /// Exchange specific parameters + public GetPositionModeRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + Symbol = symbol; + } + + /// + /// ctor + /// + /// Trading mode + /// Exchange specific parameters + public GetPositionModeRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + TradingMode = tradingMode; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetPositionsRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetPositionsRequest.cs new file mode 100644 index 00000000..bed5794a --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetPositionsRequest.cs @@ -0,0 +1,39 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve open positions + /// + public record GetPositionsRequest : SharedRequest + { + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + /// + /// Symbol filter, required for some exchanges + /// + public SharedSymbol? Symbol { get; set; } + + /// + /// ctor + /// + /// Trading mode + /// Exchange specific parameters + public GetPositionsRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + TradingMode = tradingMode; + } + + /// + /// ctor + /// + /// Symbol to retriecve positions for + /// Exchange specific parameters + public GetPositionsRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + Symbol = symbol; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetRecentTradesRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetRecentTradesRequest.cs new file mode 100644 index 00000000..37f5ea7d --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetRecentTradesRequest.cs @@ -0,0 +1,24 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve the most recent trades of a symbol + /// + public record GetRecentTradesRequest : SharedSymbolRequest + { + /// + /// Max number of results + /// + public int? Limit { get; set; } + + /// + /// ctor + /// + /// Symbol to retrieve trades for + /// Max number of results + /// Exchange specific parameters + public GetRecentTradesRequest(SharedSymbol symbol, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + Limit = limit; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetSymbolsRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetSymbolsRequest.cs new file mode 100644 index 00000000..d90a10e9 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetSymbolsRequest.cs @@ -0,0 +1,25 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve symbol info + /// + public record GetSymbolsRequest : SharedRequest + { + /// + /// Filter by trading mode + /// + public TradingMode? TradingMode { get; set; } + + /// + /// ctor + /// + /// Trading mode filter + /// Exchange specific parameters + public GetSymbolsRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + TradingMode = tradingMode; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetTickerRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetTickerRequest.cs new file mode 100644 index 00000000..e5fb40a1 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetTickerRequest.cs @@ -0,0 +1,17 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve ticker info for a symbol + /// + public record GetTickerRequest : SharedSymbolRequest + { + /// + /// ctor + /// + /// Symbol to retrieve ticker for + /// Exchange specific parameters + public GetTickerRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetTickersRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetTickersRequest.cs new file mode 100644 index 00000000..c3267f40 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetTickersRequest.cs @@ -0,0 +1,26 @@ + +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve all symbol tickers + /// + public record GetTickersRequest : SharedRequest + { + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + + /// + /// ctor + /// + /// Trading mode + /// Exchange specific parameters + public GetTickersRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + TradingMode = tradingMode; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetTradeHistoryRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetTradeHistoryRequest.cs new file mode 100644 index 00000000..8664f747 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetTradeHistoryRequest.cs @@ -0,0 +1,38 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve the public trade history + /// + public record GetTradeHistoryRequest : SharedSymbolRequest + { + /// + /// Filter by start time + /// + public DateTime StartTime { get; } + /// + /// Filter by end time + /// + public DateTime EndTime { get; } + /// + /// Max number of results + /// + public int? Limit { get; } + + /// + /// ctor + /// + /// Symbol to retrieve trades for + /// Filter by start time + /// Filter by end time + /// Max number of results + /// Exchange specific parameters + public GetTradeHistoryRequest(SharedSymbol symbol, DateTime startTime, DateTime endTime, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + StartTime = startTime; + EndTime = endTime; + Limit = limit; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetUserTradesRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetUserTradesRequest.cs new file mode 100644 index 00000000..8fd84078 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetUserTradesRequest.cs @@ -0,0 +1,38 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve the trades of the user + /// + public record GetUserTradesRequest : SharedSymbolRequest + { + /// + /// Filter by start time + /// + public DateTime? StartTime { get; } + /// + /// Filter by end time + /// + public DateTime? EndTime { get; } + /// + /// Max number of results + /// + public int? Limit { get; } + + /// + /// ctor + /// + /// Symbol to retrieve trades for + /// Filter by start time + /// Filter by end time + /// Max number of results + /// Exchange specific parameters + public GetUserTradesRequest(SharedSymbol symbol, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + StartTime = startTime; + EndTime = endTime; + Limit = limit; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/GetWithdrawalsRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/GetWithdrawalsRequest.cs new file mode 100644 index 00000000..5130079d --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/GetWithdrawalsRequest.cs @@ -0,0 +1,43 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to retrieve the withdrawal history + /// + public record GetWithdrawalsRequest : SharedRequest + { + /// + /// Filter by asset + /// + public string? Asset { get; set; } + /// + /// Filter by start time + /// + public DateTime? StartTime { get; } + /// + /// Filter by end time + /// + public DateTime? EndTime { get; } + /// + /// Max number of results + /// + public int? Limit { get; } + + /// + /// ctor + /// + /// Filter by asset + /// Filter by start time + /// Filter by end time + /// Max number of results + /// Exchange specific parameters + public GetWithdrawalsRequest(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + Asset = asset; + StartTime = startTime; + EndTime = endTime; + Limit = limit; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/KeepAliveListenKeyRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/KeepAliveListenKeyRequest.cs new file mode 100644 index 00000000..410f2570 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/KeepAliveListenKeyRequest.cs @@ -0,0 +1,31 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to keep-alive the update stream for the specified listen key + /// + public record KeepAliveListenKeyRequest : SharedRequest + { + /// + /// The key to stop updates for + /// + public string ListenKey { get; set; } + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + + /// + /// ctor + /// + /// The key to keep alive + /// Trading mode + /// Exchange specific parameters + public KeepAliveListenKeyRequest(string listenKey, TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + ListenKey = listenKey; + TradingMode = tradingMode; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/PlaceFuturesOrderRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/PlaceFuturesOrderRequest.cs new file mode 100644 index 00000000..59cdfb82 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/PlaceFuturesOrderRequest.cs @@ -0,0 +1,98 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to place a new futures order + /// + public record PlaceFuturesOrderRequest : SharedSymbolRequest + { + /// + /// Side of the order + /// + public SharedOrderSide Side { get; set; } + /// + /// Type of the order + /// + public SharedOrderType OrderType { get; set; } + /// + /// Time in force of the order + /// + public SharedTimeInForce? TimeInForce { get; set; } + /// + /// Quantity of the order in base asset. + /// + public decimal? Quantity { get; set; } + /// + /// Quantity of the order in quote asset. + /// + public decimal? QuoteQuantity { get; set; } + /// + /// Price of the order + /// + public decimal? Price { get; set; } + /// + /// Client order id + /// + public string? ClientOrderId { get; set; } + /// + /// Position side of the order. Required when in hedge mode, ignored in one-way mode + /// + public SharedPositionSide? PositionSide { get; set; } + /// + /// Margin mode + /// + public SharedMarginMode? MarginMode { get; set; } + /// + /// Reduce only order + /// + public bool? ReduceOnly { get; set; } + /// + /// Leverage for the position. Note that leverage might not be applied during order placement but instead needs to be set before opening the position depending on the exchange. In this case use the SetLeverageAsync method. + /// + public decimal? Leverage { get; set; } + + /// + /// ctor + /// + /// Symbol to place the order on + + /// Side of the order + /// Type of the order + /// Quantity of the order + /// Quantity of the order in quote asset + /// Price of the order + /// Time in force + /// Client order id + /// Reduce only + /// Leverage for the position. Note that leverage might not be applied during order placement but instead needs to be set before opening the position depending on the exchange. In this case use the SetLeverageAsync method. + /// Position side of the order. Required when in hedge mode, ignored in one-way mode + /// Margin mode + /// Exchange specific parameters + public PlaceFuturesOrderRequest( + SharedSymbol symbol, + SharedOrderSide side, + SharedOrderType orderType, + decimal? quantity = null, + decimal? quoteQuantity = null, + decimal? price = null, + bool? reduceOnly = null, + decimal? leverage = null, + SharedTimeInForce? timeInForce = null, + SharedPositionSide? positionSide = null, + SharedMarginMode? marginMode = null, + string? clientOrderId = null, + ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + Side = side; + OrderType = orderType; + Quantity = quantity; + QuoteQuantity = quoteQuantity; + Price = price; + MarginMode = marginMode; + ClientOrderId = clientOrderId; + ReduceOnly = reduceOnly; + Leverage = leverage; + TimeInForce = timeInForce; + PositionSide = positionSide; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/PlaceSpotOrderRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/PlaceSpotOrderRequest.cs new file mode 100644 index 00000000..a2a2c992 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/PlaceSpotOrderRequest.cs @@ -0,0 +1,69 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to place a new spot order + /// + public record PlaceSpotOrderRequest : SharedSymbolRequest + { + /// + /// Type of the order + /// + public SharedOrderType OrderType { get; set; } + /// + /// Side of the order + /// + public SharedOrderSide Side { get; set; } + /// + /// Time in force of the order + /// + public SharedTimeInForce? TimeInForce { get; set; } + /// + /// Quantity of the order in base asset or contracts, depending on the exchange. + /// + public decimal? Quantity { get; set; } + /// + /// Quantity of the order in quote asset. + /// + public decimal? QuoteQuantity { get; set; } + /// + /// Price of the order + /// + public decimal? Price { get; set; } + /// + /// Client order id + /// + public string? ClientOrderId { get; set; } + + /// + /// ctor + /// + /// Symbol to place the order on + /// Side of the order + /// Type of the order + /// Quantity of the order + /// Quantity of the order in quote asset + /// Price of the order + /// Time in force + /// Client order id + /// Exchange specific parameters + public PlaceSpotOrderRequest( + SharedSymbol symbol, + SharedOrderSide side, + SharedOrderType orderType, + decimal? quantity = null, + decimal? quoteQuantity = null, + decimal? price = null, + SharedTimeInForce? timeInForce = null, + string? clientOrderId = null, + ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + OrderType = orderType; + Side = side; + Quantity = quantity; + QuoteQuantity = quoteQuantity; + Price = price; + TimeInForce = timeInForce; + ClientOrderId = clientOrderId; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/SetLeverageRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/SetLeverageRequest.cs new file mode 100644 index 00000000..2ae8cc28 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/SetLeverageRequest.cs @@ -0,0 +1,36 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to change the current leverage + /// + public record SetLeverageRequest : SharedSymbolRequest + { + /// + /// Leverage to change to + /// + public decimal Leverage { get; set; } + /// + /// Position side to change leverage for. Some exchanges set leverage per side + /// + public SharedPositionSide? Side { get; set; } + /// + /// Margin mode of the position leverage to change + /// + public SharedMarginMode? MarginMode { get; set; } + + /// + /// ctor + /// + /// Symbol to change the leverage for + /// Leverage to change to + /// Position side to change leverage for. Some exchanges set leverage per side + /// Margin mode + /// Exchange specific parameters + public SetLeverageRequest(SharedSymbol symbol, decimal leverage, SharedPositionSide? positionSide = null, SharedMarginMode? marginMode = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + Leverage = leverage; + Side = positionSide; + MarginMode = marginMode; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/SetPositionModeRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/SetPositionModeRequest.cs new file mode 100644 index 00000000..0d65f0c8 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/SetPositionModeRequest.cs @@ -0,0 +1,47 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to change the current position mode + /// + public record SetPositionModeRequest : SharedRequest + { + /// + /// Symbol to change the mode for. Depending on the exchange position mode is set for the whole account or per symbol + /// + public SharedSymbol? Symbol { get; set; } + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + /// + /// Position mode to change to + /// + public SharedPositionMode PositionMode { get; set; } + + /// + /// ctor + /// + /// Position mode to change to + /// Trading mode + /// Exchange specific parameters + public SetPositionModeRequest(SharedPositionMode positionMode, TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + TradingMode = tradingMode; + PositionMode = positionMode; + } + + /// + /// ctor + /// + /// Symbol to change to position mode for + /// Position mode to change to + /// Exchange specific parameters + public SetPositionModeRequest(SharedSymbol symbol, SharedPositionMode positionMode, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + PositionMode = positionMode; + Symbol = symbol; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/StartListenKeyRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/StartListenKeyRequest.cs new file mode 100644 index 00000000..b6dcb45f --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/StartListenKeyRequest.cs @@ -0,0 +1,25 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to start the update stream for the current user + /// + public record StartListenKeyRequest : SharedRequest + { + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + + /// + /// ctor + /// + /// Trading mode + /// Exchange specific parameters + public StartListenKeyRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + TradingMode = tradingMode; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/StopListenKeyRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/StopListenKeyRequest.cs new file mode 100644 index 00000000..4a59a8a6 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/StopListenKeyRequest.cs @@ -0,0 +1,31 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to stop the update stream for the specific listen key + /// + public record StopListenKeyRequest : SharedRequest + { + /// + /// The key to stop updates for + /// + public string ListenKey { get; set; } + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + + /// + /// ctor + /// + /// The key to stop updates for + /// Trading mode + /// Exchange specific parameters + public StopListenKeyRequest(string listenKey, TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + ListenKey = listenKey; + TradingMode = tradingMode; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Rest/WithdrawRequest.cs b/CryptoExchange.Net/SharedApis/Models/Rest/WithdrawRequest.cs new file mode 100644 index 00000000..d2c8bca3 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Rest/WithdrawRequest.cs @@ -0,0 +1,47 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to withdraw funds from the exchange + /// + public record WithdrawRequest : SharedRequest + { + /// + /// Asset to withdraw + /// + public string Asset { get; set; } + /// + /// Address to withdraw to + /// + public string Address { get; set; } + /// + /// Quantity to withdraw + /// + public decimal Quantity { get; set; } + /// + /// Address tag + /// + public string? AddressTag { get; set; } + /// + /// Network to use + /// + public string? Network { get; set; } + + /// + /// ctor + /// + /// Asset to withdraw + /// Quantity to withdraw + /// Address to withdraw to + /// Network to use + /// Address tag + /// Exchange specific parameters + public WithdrawRequest(string asset, decimal quantity, string address, string? network = null, string? addressTag = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + Asset = asset; + Address = address; + Quantity = quantity; + Network = network; + AddressTag = addressTag; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/SharedQuantitySupport.cs b/CryptoExchange.Net/SharedApis/Models/SharedQuantitySupport.cs new file mode 100644 index 00000000..f25b5f25 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/SharedQuantitySupport.cs @@ -0,0 +1,78 @@ +using CryptoExchange.Net.Objects; +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Support for different quantity notations + /// + public record SharedQuantitySupport + { + /// + /// Supported quantity notations for buy limit orders + /// + public SharedQuantityType BuyLimit { get; } + /// + /// Supported quantity notations for sell limit orders + /// + public SharedQuantityType SellLimit { get; } + /// + /// Supported quantity notations for buy market orders + /// + public SharedQuantityType BuyMarket { get; } + /// + /// Supported quantity notations for sell market orders + /// + public SharedQuantityType SellMarket { get; } + + /// + /// ctor + /// + public SharedQuantitySupport(SharedQuantityType buyLimit, SharedQuantityType sellLimit, SharedQuantityType buyMarket, SharedQuantityType sellMarket) + { + BuyLimit = buyLimit; + SellLimit = sellLimit; + BuyMarket = buyMarket; + SellMarket = sellMarket; + } + + private SharedQuantityType GetSupportedQuantityType(SharedOrderSide side, SharedOrderType orderType) + { + if (side == SharedOrderSide.Buy && (orderType == SharedOrderType.Limit || orderType == SharedOrderType.LimitMaker)) return BuyLimit; + if (side == SharedOrderSide.Buy && orderType == SharedOrderType.Market) return BuyMarket; + if (side == SharedOrderSide.Sell && (orderType == SharedOrderType.Limit || orderType == SharedOrderType.LimitMaker)) return SellLimit; + if (side == SharedOrderSide.Sell && orderType == SharedOrderType.Market) return SellMarket; + + throw new ArgumentException("Unknown side/type combination"); + } + + /// + /// Validate a request + /// + /// + /// + /// + /// + /// + public Error? Validate(SharedOrderSide side, SharedOrderType type, decimal? quantity, decimal? quoteQuantity) + { + var supportedType = GetSupportedQuantityType(side, type); + if (supportedType == SharedQuantityType.BaseAndQuoteAsset) + return null; + + if ((supportedType == SharedQuantityType.BaseAsset || supportedType == SharedQuantityType.Contracts) && quoteQuantity != null) + return new ArgumentError($"Quote quantity not supported for {side}.{type} order, specify Quantity instead"); + + if (supportedType == SharedQuantityType.QuoteAsset && quantity != null) + return new ArgumentError($"Quantity not supported for {side}.{type} order, specify QuoteQuantity instead"); + + return null; + } + + /// + public override string ToString() + { + return $"Limit buy: {BuyLimit}, limit sell: {SellLimit}, market buy: {BuyMarket}, market sell: {SellMarket}"; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/SharedRequest.cs b/CryptoExchange.Net/SharedApis/Models/SharedRequest.cs new file mode 100644 index 00000000..2ee2aae8 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/SharedRequest.cs @@ -0,0 +1,21 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request + /// + public record SharedRequest + { + /// + /// Exchange parameters. Some calls may require exchange specific parameters to execute the request. + /// + public ExchangeParameters? ExchangeParameters { get; set; } + + /// + /// ctor + /// + public SharedRequest(ExchangeParameters? exchangeParameters = null) + { + ExchangeParameters = exchangeParameters; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/SharedSymbolRequest.cs b/CryptoExchange.Net/SharedApis/Models/SharedSymbolRequest.cs new file mode 100644 index 00000000..b022692a --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/SharedSymbolRequest.cs @@ -0,0 +1,21 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Symbol request + /// + public record SharedSymbolRequest : SharedRequest + { + /// + /// The symbol + /// + public SharedSymbol Symbol { get; set; } + + /// + /// ctor + /// + public SharedSymbolRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + Symbol = symbol; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeAllTickersRequest.cs b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeAllTickersRequest.cs new file mode 100644 index 00000000..c2e38cb3 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeAllTickersRequest.cs @@ -0,0 +1,25 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to subscribe to ticker updates for all symbols + /// + public record SubscribeAllTickersRequest : SharedRequest + { + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + + /// + /// ctor + /// + /// Trading mode + /// Exchange specific parameters + public SubscribeAllTickersRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + TradingMode = tradingMode; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeBalancesRequest.cs b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeBalancesRequest.cs new file mode 100644 index 00000000..0179434a --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeBalancesRequest.cs @@ -0,0 +1,31 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to subscribe to balance updates + /// + public record SubscribeBalancesRequest: SharedRequest + { + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + /// + /// The listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client + /// + public string? ListenKey { get; set; } + + /// + /// ctor + /// + /// Listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client + /// Trading mode + /// Exchange specific parameters + public SubscribeBalancesRequest(string? listenKey = null, TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + TradingMode = tradingMode; + ListenKey = listenKey; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeBookTickerRequest.cs b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeBookTickerRequest.cs new file mode 100644 index 00000000..5cc5563e --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeBookTickerRequest.cs @@ -0,0 +1,17 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to subscribe to book ticker updates + /// + public record SubscribeBookTickerRequest : SharedSymbolRequest + { + /// + /// ctor + /// + /// The symbol to subscribe to + /// Exchange specific parameters + public SubscribeBookTickerRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeFuturesOrderRequest.cs b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeFuturesOrderRequest.cs new file mode 100644 index 00000000..a27ba51c --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeFuturesOrderRequest.cs @@ -0,0 +1,31 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to subscribe to futures order updates + /// + public record SubscribeFuturesOrderRequest : SharedRequest + { + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + /// + /// The listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client + /// + public string? ListenKey { get; set; } + + /// + /// ctor + /// + /// Listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client + /// Trading mode + /// Exchange specific parameters + public SubscribeFuturesOrderRequest(string? listenKey = null, TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null): base(exchangeParameters) + { + TradingMode = tradingMode; + ListenKey = listenKey; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeKlineRequest.cs b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeKlineRequest.cs new file mode 100644 index 00000000..315423f6 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeKlineRequest.cs @@ -0,0 +1,24 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to subscribe to kline/candlestick updates + /// + public record SubscribeKlineRequest : SharedSymbolRequest + { + /// + /// The kline interval + /// + public SharedKlineInterval Interval { get; set; } + + /// + /// ctor + /// + /// The symbol to subscribe to + /// Kline interval + /// Exchange specific parameters + public SubscribeKlineRequest(SharedSymbol symbol, SharedKlineInterval interval, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + Interval = interval; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeOrderBookRequest.cs b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeOrderBookRequest.cs new file mode 100644 index 00000000..e88ae1dc --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeOrderBookRequest.cs @@ -0,0 +1,24 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to subscribe to order book snapshot updates + /// + public record SubscribeOrderBookRequest : SharedSymbolRequest + { + /// + /// The order book depth + /// + public int? Limit { get; set; } + + /// + /// ctor + /// + /// The symbol to subscribe to + /// Order book depth + /// Exchange specific parameters + public SubscribeOrderBookRequest(SharedSymbol symbol, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + Limit = limit; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Socket/SubscribePositionRequest.cs b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribePositionRequest.cs new file mode 100644 index 00000000..6ead3522 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribePositionRequest.cs @@ -0,0 +1,31 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to subscribe to position updates + /// + public record SubscribePositionRequest: SharedRequest + { + /// + /// The listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client + /// + public string? ListenKey { get; set; } + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + + /// + /// ctor + /// + /// Listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client + /// Trading mode + /// Exchange specific parameters + public SubscribePositionRequest(string? listenKey = null, TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + TradingMode = tradingMode; + ListenKey = listenKey; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeSpotOrderRequest.cs b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeSpotOrderRequest.cs new file mode 100644 index 00000000..3cb88a3d --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeSpotOrderRequest.cs @@ -0,0 +1,23 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to subscribe to spot order updates + /// + public record SubscribeSpotOrderRequest : SharedRequest + { + /// + /// The listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client + /// + public string? ListenKey { get; set; } + + /// + /// ctor + /// + /// Listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client + /// Exchange specific parameters + public SubscribeSpotOrderRequest(string? listenKey = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + ListenKey = listenKey; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeTickerRequest.cs b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeTickerRequest.cs new file mode 100644 index 00000000..5eef7aec --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeTickerRequest.cs @@ -0,0 +1,17 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to subscribe to ticker updates + /// + public record SubscribeTickerRequest : SharedSymbolRequest + { + /// + /// ctor + /// + /// The symbol to subscribe to + /// Exchange specific parameters + public SubscribeTickerRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeTradeRequest.cs b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeTradeRequest.cs new file mode 100644 index 00000000..d4160759 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeTradeRequest.cs @@ -0,0 +1,17 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to subscribe to trade updates + /// + public record SubscribeTradeRequest : SharedSymbolRequest + { + /// + /// ctor + /// + /// The symbol to subscribe to + /// Exchange specific parameters + public SubscribeTradeRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters) + { + } + } +} diff --git a/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeUserTradeRequest.cs b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeUserTradeRequest.cs new file mode 100644 index 00000000..d4df63cb --- /dev/null +++ b/CryptoExchange.Net/SharedApis/Models/Socket/SubscribeUserTradeRequest.cs @@ -0,0 +1,31 @@ +using CryptoExchange.Net.Objects; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Request to subscribe to user trade updates + /// + public record SubscribeUserTradeRequest : SharedRequest + { + /// + /// Trading mode + /// + public TradingMode? TradingMode { get; set; } + /// + /// The listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client + /// + public string? ListenKey { get; set; } + + /// + /// ctor + /// + /// Listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client + /// Trading mode + /// Exchange specific parameters + public SubscribeUserTradeRequest(string? listenKey = null, TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters) + { + TradingMode = tradingMode; + ListenKey = listenKey; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedAsset.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedAsset.cs new file mode 100644 index 00000000..c3d9cfcc --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedAsset.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Asset info + /// + public record SharedAsset + { + /// + /// Name of the asset + /// + public string Name { get; set; } + /// + /// Full or alternative name of the asset + /// + public string? FullName { get; set; } + /// + /// Asset networks info + /// + public IEnumerable? Networks { get; set; } = Array.Empty(); + + /// + /// ctor + /// + public SharedAsset(string name) + { + Name = name; + } + } + + /// + /// Asset network info + /// + public record SharedAssetNetwork + { + /// + /// Network name + /// + public string Name { get; set; } + /// + /// Network full/alternative name + /// + public string? FullName { get; set; } + /// + /// Withdrawal fee + /// + public decimal? WithdrawFee { get; set; } + /// + /// Minimal withdrawal quantity + /// + public decimal? MinWithdrawQuantity { get; set; } + /// + /// Max withdrawal quantity + /// + public decimal? MaxWithdrawQuantity { get; set; } + /// + /// Withdrawals are enabled + /// + public bool? WithdrawEnabled { get; set; } + /// + /// Deposits are enabled + /// + public bool? DepositEnabled { get; set; } + /// + /// Min number of confirmations + /// + public int? MinConfirmations { get; set; } + + /// + /// ctor + /// + public SharedAssetNetwork(string name) + { + Name = name; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedBalance.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedBalance.cs new file mode 100644 index 00000000..ee622d15 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedBalance.cs @@ -0,0 +1,35 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Balance info + /// + public record SharedBalance + { + /// + /// Asset name + /// + public string Asset { get; set; } + /// + /// Available quantity + /// + public decimal Available { get; set; } + /// + /// Total quantity + /// + public decimal Total { get; set; } + /// + /// Isolated margin symbol, only applicable for isolated margin futures + /// + public string? IsolatedMarginSymbol { get; set; } + + /// + /// ctor + /// + public SharedBalance(string asset, decimal available, decimal total) + { + Asset = asset; + Available = available; + Total = total; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedBookTicker.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedBookTicker.cs new file mode 100644 index 00000000..fc3a4545 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedBookTicker.cs @@ -0,0 +1,36 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Book ticker + /// + public record SharedBookTicker + { + /// + /// Price of the best ask + /// + public decimal BestAskPrice { get; set; } + /// + /// Quantity of the best ask + /// + public decimal BestAskQuantity { get; set; } + /// + /// Price of the best bid + /// + public decimal BestBidPrice { get; set; } + /// + /// Quantity of the best bid + /// + public decimal BestBidQuantity { get; set; } + + /// + /// ctor + /// + public SharedBookTicker(decimal bestAskPrice, decimal bestAskQuantity, decimal bestBidPrice, decimal bestBidQuantity) + { + BestAskPrice = bestAskPrice; + BestAskQuantity = bestAskQuantity; + BestBidPrice = bestBidPrice; + BestBidQuantity = bestBidQuantity; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedDeposit.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedDeposit.cs new file mode 100644 index 00000000..a59a141b --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedDeposit.cs @@ -0,0 +1,59 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Deposit info + /// + public record SharedDeposit + { + /// + /// The id of the deposit + /// + public string? Id { get; set; } + /// + /// The asset of the deposit + /// + public string Asset { get; set; } + /// + /// The quantity that was deposited + /// + public decimal Quantity { get; set; } + /// + /// Timestamp of the deposit + /// + public DateTime Timestamp { get; set; } + /// + /// Network used + /// + public string? Network { get; set; } + /// + /// Number of confirmations + /// + public int? Confirmations { get; set; } + /// + /// Transaction id + /// + public string? TransactionId { get; set; } + /// + /// Tag + /// + public string? Tag { get; set; } + /// + /// Whether the deposit was completed successfully + /// + public bool Completed { get; set; } + + /// + /// ctor + /// + public SharedDeposit(string asset, decimal quantity, bool completed, DateTime timestamp) + { + Asset = asset; + Quantity = quantity; + Timestamp = timestamp; + Completed = completed; + } + } + +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedDepositAddress.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedDepositAddress.cs new file mode 100644 index 00000000..871d23f6 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedDepositAddress.cs @@ -0,0 +1,35 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Deposit address info + /// + public record SharedDepositAddress + { + /// + /// Asset the address is for + /// + public string Asset { get; set; } + /// + /// Deposit address + /// + public string Address { get; set; } + /// + /// The network + /// + public string? Network { get; set; } + /// + /// Tag or memo + /// + public string? TagOrMemo { get; set; } + + /// + /// ctor + /// + public SharedDepositAddress(string asset, string address) + { + Asset = asset; + Address = address; + } + } + +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedFundingRate.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedFundingRate.cs new file mode 100644 index 00000000..34547360 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedFundingRate.cs @@ -0,0 +1,28 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Funding rate + /// + public record SharedFundingRate + { + /// + /// The funding rate + /// + public decimal FundingRate { get; set; } + /// + /// Timestamp + /// + public DateTime Timestamp { get; set; } + + /// + /// ctor + /// + public SharedFundingRate(decimal fundingRate, DateTime timestamp) + { + FundingRate = fundingRate; + Timestamp = timestamp; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedFuturesKline.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedFuturesKline.cs new file mode 100644 index 00000000..33dd858a --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedFuturesKline.cs @@ -0,0 +1,43 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Mark/index price kline + /// + public record SharedFuturesKline + { + /// + /// Open time + /// + public DateTime OpenTime { get; set; } + /// + /// Close price + /// + public decimal ClosePrice { get; set; } + /// + /// High price + /// + public decimal HighPrice { get; set; } + /// + /// Low price + /// + public decimal LowPrice { get; set; } + /// + /// Open price + /// + public decimal OpenPrice { get; set; } + + /// + /// ctor + /// + public SharedFuturesKline(DateTime openTime, decimal closePrice, decimal highPrice, decimal lowPrice, decimal openPrice) + { + OpenTime = openTime; + ClosePrice = closePrice; + HighPrice = highPrice; + LowPrice = lowPrice; + OpenPrice = openPrice; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedFuturesOrder.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedFuturesOrder.cs new file mode 100644 index 00000000..3ad4dc1c --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedFuturesOrder.cs @@ -0,0 +1,115 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Futures order info + /// + public record SharedFuturesOrder + { + /// + /// Symbol + /// + public string Symbol { get; set; } + /// + /// Id of the order + /// + public string OrderId { get; set; } + /// + /// Type of the order + /// + public SharedOrderType OrderType { get; set; } + /// + /// Side of the order + /// + public SharedOrderSide Side { get; set; } + /// + /// Status of the order + /// + public SharedOrderStatus Status { get; set; } + /// + /// Time in force for the order + /// + public SharedTimeInForce? TimeInForce { get; set; } + /// + /// Position side + /// + public SharedPositionSide? PositionSide { get; set; } + /// + /// Reduce only + /// + public bool? ReduceOnly { get; set; } + /// + /// Order quantity in the base asset or number of contracts + /// + public decimal? Quantity { get; set; } + /// + /// Quantity filled in the base asset or number of contracts + /// + public decimal? QuantityFilled { get; set; } + /// + /// Quantity of the order in quote asset + /// + public decimal? QuoteQuantity { get; set; } + /// + /// Quantity filled in the quote asset + /// + public decimal? QuoteQuantityFilled { get; set; } + /// + /// Order price + /// + public decimal? OrderPrice { get; set; } + /// + /// Average price + /// + public decimal? AveragePrice { get; set; } + /// + /// Client order id + /// + public string? ClientOrderId { get; set; } + /// + /// Asset the fee is in + /// + public string? FeeAsset { get; set; } + /// + /// Fee paid + /// + public decimal? Fee { get; set; } + /// + /// Leverage + /// + public decimal? Leverage { get; set; } + /// + /// Timestamp the order was created + /// + public DateTime? CreateTime { get; set; } + /// + /// Last update timestamp + /// + public DateTime? UpdateTime { get; set; } + + /// + /// Last trade info, only available for websocket order updates if the API provides this data in the update + /// + public SharedUserTrade? LastTrade { get; set; } + + /// + /// ctor + /// + public SharedFuturesOrder( + string symbol, + string orderId, + SharedOrderType orderType, + SharedOrderSide orderSide, + SharedOrderStatus orderStatus, + DateTime? createTime) + { + Symbol = symbol; + OrderId = orderId; + OrderType = orderType; + Side = orderSide; + Status = orderStatus; + CreateTime = createTime; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedFuturesSymbol.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedFuturesSymbol.cs new file mode 100644 index 00000000..39a461ff --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedFuturesSymbol.cs @@ -0,0 +1,31 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Futures symbol info + /// + public record SharedFuturesSymbol : SharedSpotSymbol + { + /// + /// Symbol type + /// + public SharedSymbolType SymbolType { get; set; } + /// + /// The size of a single contract + /// + public decimal? ContractSize { get; set; } + /// + /// Delivery time of the contract + /// + public DateTime? DeliveryTime { get; set; } + + /// + /// ctor + /// + public SharedFuturesSymbol(SharedSymbolType symbolType, string baseAsset, string quoteAsset, string symbol, bool trading) : base(baseAsset, quoteAsset, symbol, trading) + { + SymbolType = symbolType; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedFuturesTicker.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedFuturesTicker.cs new file mode 100644 index 00000000..713de371 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedFuturesTicker.cs @@ -0,0 +1,64 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Futures ticker info + /// + public record SharedFuturesTicker + { + /// + /// The symbol + /// + public string Symbol { get; set; } + /// + /// Last trade price + /// + public decimal LastPrice { get; set; } + /// + /// High price in the last 24h + /// + public decimal HighPrice { get; set; } + /// + /// Low price in the last 24h + /// + public decimal LowPrice { get; set; } + /// + /// The volume in the last 24h + /// + public decimal Volume { get; set; } + /// + /// Change percentage in the last 24h + /// + public decimal? ChangePercentage { get; set; } + /// + /// Current mark price + /// + public decimal? MarkPrice { get; set; } + /// + /// Current index price + /// + public decimal? IndexPrice { get; set; } + /// + /// Current funding rate + /// + public decimal? FundingRate { get; set; } + /// + /// Next funding time + /// + public DateTime? NextFundingTime { get; set; } + + /// + /// ctor + /// + public SharedFuturesTicker(string symbol, decimal lastPrice, decimal highPrice, decimal lowPrice, decimal volume, decimal? changePercentage) + { + Symbol = symbol; + LastPrice = lastPrice; + HighPrice = highPrice; + LowPrice = lowPrice; + Volume = volume; + ChangePercentage = changePercentage; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedId.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedId.cs new file mode 100644 index 00000000..24147b8d --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedId.cs @@ -0,0 +1,21 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Id + /// + public record SharedId + { + /// + /// The id + /// + public string Id { get; set; } + + /// + /// Id + /// + public SharedId(string id) + { + Id = id; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedKline.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedKline.cs new file mode 100644 index 00000000..2033d229 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedKline.cs @@ -0,0 +1,48 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Kline info + /// + public record SharedKline + { + /// + /// Open time + /// + public DateTime OpenTime { get; set; } + /// + /// Close price + /// + public decimal ClosePrice { get; set; } + /// + /// High price + /// + public decimal HighPrice { get; set; } + /// + /// Low price + /// + public decimal LowPrice { get; set; } + /// + /// Open price + /// + public decimal OpenPrice { get; set; } + /// + /// Volume in the base asset + /// + public decimal Volume { get; set; } + + /// + /// ctor + /// + public SharedKline(DateTime openTime, decimal closePrice, decimal highPrice, decimal lowPrice, decimal openPrice, decimal volume) + { + OpenTime = openTime; + ClosePrice = closePrice; + HighPrice = highPrice; + LowPrice = lowPrice; + OpenPrice = openPrice; + Volume = volume; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedLeverage.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedLeverage.cs new file mode 100644 index 00000000..881f22a7 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedLeverage.cs @@ -0,0 +1,29 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Leverage info + /// + public record SharedLeverage + { + /// + /// Leverage value + /// + public decimal Leverage { get; set; } + /// + /// Side for the leverage + /// + public SharedPositionSide? Side { get; set; } + /// + /// Margin mode + /// + public SharedMarginMode? MarginMode { get; set; } + + /// + /// ctor + /// + public SharedLeverage(decimal leverage) + { + Leverage = leverage; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedOpenInterest.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedOpenInterest.cs new file mode 100644 index 00000000..b25b173c --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedOpenInterest.cs @@ -0,0 +1,21 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Open interest + /// + public record SharedOpenInterest + { + /// + /// Current open interest + /// + public decimal OpenInterest { get; set; } + + /// + /// ctor + /// + public SharedOpenInterest(decimal openInterest) + { + OpenInterest = openInterest; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedOrderBook.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedOrderBook.cs new file mode 100644 index 00000000..4fecefc9 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedOrderBook.cs @@ -0,0 +1,30 @@ +using CryptoExchange.Net.Interfaces; +using System.Collections.Generic; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Order book info + /// + public record SharedOrderBook + { + /// + /// Asks list + /// + public IEnumerable Asks { get; set; } + /// + /// Bids list + /// + public IEnumerable Bids { get; set; } + + /// + /// ctor + /// + public SharedOrderBook(IEnumerable asks, IEnumerable bids) + { + Asks = asks; + Bids = bids; + } + } + +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedPosition.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedPosition.cs new file mode 100644 index 00000000..fac4dd06 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedPosition.cs @@ -0,0 +1,53 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Position info + /// + public record SharedPosition + { + /// + /// Symbol + /// + public string Symbol { get; set; } + /// + /// Current size of the position + /// + public decimal PositionSize { get; set; } + /// + /// Side of the position + /// + public SharedPositionSide PositionSide { get; set; } + /// + /// Average open price + /// + public decimal? AverageOpenPrice { get; set; } + /// + /// Current unrealized profit/loss + /// + public decimal? UnrealizedPnl { get; set; } + /// + /// Liquidation price + /// + public decimal? LiquidationPrice { get; set; } + /// + /// Leverage + /// + public decimal? Leverage { get; set; } + /// + /// Last update time + /// + public DateTime? UpdateTime { get; set; } + + /// + /// ctor + /// + public SharedPosition(string symbol, decimal positionSize, DateTime? updateTime) + { + Symbol = symbol; + PositionSize = positionSize; + UpdateTime = updateTime; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedPositionHistory.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedPositionHistory.cs new file mode 100644 index 00000000..42263a96 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedPositionHistory.cs @@ -0,0 +1,72 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Position history + /// + public record SharedPositionHistory + { + /// + /// Symbol of the position + /// + public string Symbol { get; set; } + /// + /// The side of the position + /// + public SharedPositionSide PositionSide { get; set; } + /// + /// Average open price + /// + public decimal AverageOpenPrice { get; set; } + /// + /// Average close price + /// + public decimal AverageClosePrice { get; set; } + /// + /// Position size + /// + public decimal Quantity { get; set; } + /// + /// Realized profit/loss + /// + public decimal RealizedPnl { get; set; } + /// + /// Timestamp the position was closed + /// + public DateTime Timestamp { get; set; } + /// + /// Position id + /// + public string? PositionId { get; set; } + /// + /// Leverage of the position + /// + public decimal? Leverage { get; set; } + /// + /// Id of the order that closed the position + /// + public string? OrderId { get; set; } + + /// + /// ctor + /// + public SharedPositionHistory( + string symbol, + SharedPositionSide side, + decimal openPrice, + decimal closePrice, + decimal quantity, + decimal realizedPnl, + DateTime timestamp) + { + Symbol = symbol; + PositionSide = side; + AverageOpenPrice = openPrice; + AverageClosePrice = closePrice; + Quantity = quantity; + RealizedPnl = realizedPnl; + Timestamp = timestamp; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedPositionModeResult.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedPositionModeResult.cs new file mode 100644 index 00000000..eba0c4ee --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedPositionModeResult.cs @@ -0,0 +1,21 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Position mode result + /// + public record SharedPositionModeResult + { + /// + /// The current position mode + /// + public SharedPositionMode PositionMode { get; set; } + + /// + /// ctor + /// + public SharedPositionModeResult(SharedPositionMode positionMode) + { + PositionMode = positionMode; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedSpotOrder.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedSpotOrder.cs new file mode 100644 index 00000000..2cb82b1d --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedSpotOrder.cs @@ -0,0 +1,102 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Spot order info + /// + public record SharedSpotOrder + { + /// + /// The symbol the order is on + /// + public string Symbol { get; set; } + /// + /// The id of the order + /// + public string OrderId { get; set; } + /// + /// The type of the order + /// + public SharedOrderType OrderType { get; set; } + /// + /// The side of the order + /// + public SharedOrderSide Side { get; set; } + /// + /// Status of the order + /// + public SharedOrderStatus Status { get; set; } + /// + /// Time in force for the order + /// + public SharedTimeInForce? TimeInForce { get; set; } + /// + /// Order quantity in base asset + /// + public decimal? Quantity { get; set; } + /// + /// Quantity filled in base asset, note that this quantity has not yet included trading fees paid + /// + public decimal? QuantityFilled { get; set; } + /// + /// Order quantity in quote asset + /// + public decimal? QuoteQuantity { get; set; } + /// + /// Quantity filled in the quote asset, note that this quantity has not yet included trading fees paid + /// + public decimal? QuoteQuantityFilled { get; set; } + /// + /// Order price + /// + public decimal? OrderPrice { get; set; } + /// + /// Average fill price + /// + public decimal? AveragePrice { get; set; } + /// + /// Client order id + /// + public string? ClientOrderId { get; set; } + /// + /// Asset the fee is in + /// + public string? FeeAsset { get; set; } + /// + /// Fee paid for the order + /// + public decimal? Fee { get; set; } + /// + /// Timestamp the order was created + /// + public DateTime? CreateTime { get; set; } + /// + /// Last update timestamp + /// + public DateTime? UpdateTime { get; set; } + /// + /// Last trade info, only available for websocket order updates if the API provides this data in the update + /// + public SharedUserTrade? LastTrade { get; set; } + + /// + /// ctor + /// + public SharedSpotOrder( + string symbol, + string orderId, + SharedOrderType orderType, + SharedOrderSide orderSide, + SharedOrderStatus orderStatus, + DateTime? createTime) + { + Symbol = symbol; + OrderId = orderId; + OrderType = orderType; + Side = orderSide; + Status = orderStatus; + CreateTime = createTime; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedSpotSymbol.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedSpotSymbol.cs new file mode 100644 index 00000000..0908d0a7 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedSpotSymbol.cs @@ -0,0 +1,64 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Symbol info + /// + public record SharedSpotSymbol + { + /// + /// Base asset of the symbol + /// + public string BaseAsset { get; set; } + /// + /// Quote asset of the symbol + /// + public string QuoteAsset { get; set; } + /// + /// The name of the symbol + /// + public string Name { get; set; } + /// + /// Minimal quantity of an order in the base asset + /// + public decimal? MinTradeQuantity { get; set; } + /// + /// Minimal notional value (quantity * price) of an order + /// + public decimal? MinNotionalValue { get; set; } + /// + /// Max quantity of an order in the base asset + /// + public decimal? MaxTradeQuantity { get; set; } + /// + /// Step by which the quantity should increase + /// + public decimal? QuantityStep { get; set; } + /// + /// Step by which the price should increase + /// + public decimal? PriceStep { get; set; } + /// + /// The max amount of decimal places for quantity + /// + public int? QuantityDecimals { get; set; } + /// + /// The max amount of decimal places for price + /// + public int? PriceDecimals { get; set; } + /// + /// Whether the symbol is currently available for trading + /// + public bool Trading { get; set; } + + /// + /// ctor + /// + public SharedSpotSymbol(string baseAsset, string quoteAsset, string symbol, bool trading) + { + BaseAsset = baseAsset; + QuoteAsset = quoteAsset; + Name = symbol; + Trading = trading; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedSpotTicker.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedSpotTicker.cs new file mode 100644 index 00000000..fd641a41 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedSpotTicker.cs @@ -0,0 +1,46 @@ +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Ticker info + /// + public record SharedSpotTicker + { + /// + /// Symbol name + /// + public string Symbol { get; set; } + /// + /// Last trade price + /// + public decimal? LastPrice { get; set; } + /// + /// Highest price in last 24h + /// + public decimal? HighPrice { get; set; } + /// + /// Lowest price in last 24h + /// + public decimal? LowPrice { get; set; } + /// + /// Trade volume in base asset in the last 24h + /// + public decimal Volume { get; set; } + /// + /// Change percentage in the last 24h + /// + public decimal? ChangePercentage { get; set; } + + /// + /// ctor + /// + public SharedSpotTicker(string symbol, decimal? lastPrice, decimal? highPrice, decimal? lowPrice, decimal volume, decimal? changePercentage) + { + Symbol = symbol; + LastPrice = lastPrice; + HighPrice = highPrice; + LowPrice = lowPrice; + Volume = volume; + ChangePercentage = changePercentage; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedTrade.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedTrade.cs new file mode 100644 index 00000000..4f6e051e --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedTrade.cs @@ -0,0 +1,33 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// Public trade info + /// + public record SharedTrade + { + /// + /// Quantity of the trade + /// + public decimal Quantity { get; set; } + /// + /// Price of the trade + /// + public decimal Price { get; set; } + /// + /// Trade time + /// + public DateTime Timestamp { get; set; } + + /// + /// ctor + /// + public SharedTrade(decimal quantity, decimal price, DateTime timestamp) + { + Quantity = quantity; + Price = price; + Timestamp = timestamp; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedUserTrade.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedUserTrade.cs new file mode 100644 index 00000000..49e85d42 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedUserTrade.cs @@ -0,0 +1,65 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// A user trade + /// + public record SharedUserTrade + { + /// + /// Symbol the trade was on + /// + public string Symbol { get; set; } + /// + /// The trade id + /// + public string Id { get; set; } + /// + /// Traded quantity + /// + public decimal Quantity { get; set; } + /// + /// Trade price + /// + public decimal Price { get; set; } + /// + /// Trade timestamp + /// + public DateTime Timestamp { get; set; } + /// + /// The order id + /// + public string OrderId { get; set; } + /// + /// Side of the trade + /// + public SharedOrderSide Side { get; set; } + /// + /// Fee paid for the trade + /// + public decimal? Fee { get; set; } + /// + /// The asset the fee is in + /// + public string? FeeAsset { get; set; } + /// + /// Trade role + /// + public SharedRole? Role { get; set; } + + /// + /// ctor + /// + public SharedUserTrade(string symbol, string orderId, string id, SharedOrderSide side, decimal quantity, decimal price, DateTime timestamp) + { + Symbol = symbol; + OrderId = orderId; + Id = id; + Side = side; + Quantity = quantity; + Price = price; + Timestamp = timestamp; + } + } +} diff --git a/CryptoExchange.Net/SharedApis/ResponseModels/SharedWithdrawal.cs b/CryptoExchange.Net/SharedApis/ResponseModels/SharedWithdrawal.cs new file mode 100644 index 00000000..190b359f --- /dev/null +++ b/CryptoExchange.Net/SharedApis/ResponseModels/SharedWithdrawal.cs @@ -0,0 +1,68 @@ +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// A withdrawal record + /// + public record SharedWithdrawal + { + /// + /// The id of the withdrawal + /// + public string? Id { get; set; } + /// + /// The asset that was withdrawn + /// + public string Asset { get; set; } + /// + /// The withdrawal address + /// + public string Address { get; set; } + /// + /// Quantity that was withdrawn + /// + public decimal Quantity { get; set; } + /// + /// The timestamp of the withdrawal + /// + public DateTime Timestamp { get; set; } + /// + /// Whether the withdrawal was successfully completed + /// + public bool Completed { get; set; } + /// + /// Tag + /// + public string? Tag { get; set; } + /// + /// Used network + /// + public string? Network { get; set; } + /// + /// Transaction id + /// + public string? TransactionId { get; set; } + /// + /// Number of confirmations + /// + public int? Confirmations { get; set; } + /// + /// Fee paid + /// + public decimal? Fee { get; set; } + + /// + /// ctor + /// + public SharedWithdrawal(string asset, string address, decimal quantity, bool completed, DateTime timestamp) + { + Asset = asset; + Address = address; + Quantity = quantity; + Completed = completed; + Timestamp = timestamp; + } + } + +} diff --git a/CryptoExchange.Net/SharedApis/SharedSymbol.cs b/CryptoExchange.Net/SharedApis/SharedSymbol.cs new file mode 100644 index 00000000..471173a1 --- /dev/null +++ b/CryptoExchange.Net/SharedApis/SharedSymbol.cs @@ -0,0 +1,65 @@ +using CryptoExchange.Net.Objects; +using System; + +namespace CryptoExchange.Net.SharedApis +{ + /// + /// A symbol representation based on a base and quote asset + /// + public class SharedSymbol + { + /// + /// The base asset of the symbol + /// + public string BaseAsset { get; set; } + /// + /// The quote asset of the symbol + /// + public string QuoteAsset { get; set; } + /// + /// The symbol name, can be used to overwrite the default formatted name + /// + public string? SymbolName { get; set; } + /// + /// The trading mode of the symbol. This determines how the base and quote asset should be formatted into the symbol name + /// + public TradingMode TradingMode { get; set; } + /// + /// Delivery time of the symbol, used for delivery futures to format the symbol name + /// + public DateTime? DeliverTime { get; set; } + + /// + /// Create a new SharedSymbol + /// + public SharedSymbol(TradingMode tradingMode, string baseAsset, string quoteAsset, DateTime? deliverTime = null) + { + TradingMode = tradingMode; + BaseAsset = baseAsset; + QuoteAsset = quoteAsset; + DeliverTime = deliverTime; + } + + /// + /// Create a new SharedSymbol and override the formatted name + /// + public SharedSymbol(TradingMode tradingMode, string baseAsset, string quoteAsset, string symbolName) + { + TradingMode = tradingMode; + BaseAsset = baseAsset; + QuoteAsset = quoteAsset; + SymbolName = symbolName; + } + + /// + /// Get the symbol name using the provided formatting function + /// + public string GetSymbol(Func format) + { + if (!string.IsNullOrEmpty(SymbolName)) + return SymbolName!; + + return format(BaseAsset, QuoteAsset, TradingMode, DeliverTime); + } + } +} diff --git a/CryptoExchange.Net/Sockets/DedicatedConnectionConfig.cs b/CryptoExchange.Net/Sockets/DedicatedConnectionConfig.cs index 15840e44..96d03933 100644 --- a/CryptoExchange.Net/Sockets/DedicatedConnectionConfig.cs +++ b/CryptoExchange.Net/Sockets/DedicatedConnectionConfig.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace CryptoExchange.Net.Sockets +namespace CryptoExchange.Net.Sockets { /// /// Dedicated connection configuration diff --git a/CryptoExchange.Net/Sockets/Query.cs b/CryptoExchange.Net/Sockets/Query.cs index 54d0954e..d79279dc 100644 --- a/CryptoExchange.Net/Sockets/Query.cs +++ b/CryptoExchange.Net/Sockets/Query.cs @@ -1,7 +1,6 @@ using CryptoExchange.Net.Interfaces; using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects.Sockets; -using CryptoExchange.Net.Requests; using System; using System.Collections.Generic; using System.Threading; diff --git a/CryptoExchange.Net/Sockets/SocketConnection.cs b/CryptoExchange.Net/Sockets/SocketConnection.cs index 40185746..3e696fdd 100644 --- a/CryptoExchange.Net/Sockets/SocketConnection.cs +++ b/CryptoExchange.Net/Sockets/SocketConnection.cs @@ -51,6 +51,11 @@ public record SocketConnectionState( /// public event Action? ConnectionClosed; + /// + /// Failed to resubscribe all subscription on the reconnected socket + /// + public event Action? ResubscribingFailed; + /// /// Connecting restored event /// @@ -334,7 +339,8 @@ protected virtual Task HandleReconnectedAsync() var reconnectSuccessful = await ProcessReconnectAsync().ConfigureAwait(false); if (!reconnectSuccessful) { - _logger.FailedReconnectProcessing(SocketId, reconnectSuccessful.Error?.ToString()); + _logger.FailedReconnectProcessing(SocketId, reconnectSuccessful.Error!.ToString()); + _ = Task.Run(() => ResubscribingFailed?.Invoke(reconnectSuccessful.Error)); _ = _socket.ReconnectAsync().ConfigureAwait(false); } else diff --git a/CryptoExchange.Net/Testing/Comparers/JsonNetComparer.cs b/CryptoExchange.Net/Testing/Comparers/JsonNetComparer.cs index e1b74f4a..3c317e48 100644 --- a/CryptoExchange.Net/Testing/Comparers/JsonNetComparer.cs +++ b/CryptoExchange.Net/Testing/Comparers/JsonNetComparer.cs @@ -5,7 +5,6 @@ using System.Globalization; using System.Linq; using System.Reflection; -using System.Text.Json.Nodes; using CryptoExchange.Net.Converters; using CryptoExchange.Net.Converters.JsonNet; using Newtonsoft.Json; diff --git a/CryptoExchange.Net/Testing/TestHelpers.cs b/CryptoExchange.Net/Testing/TestHelpers.cs index 044fa288..59d1e7a2 100644 --- a/CryptoExchange.Net/Testing/TestHelpers.cs +++ b/CryptoExchange.Net/Testing/TestHelpers.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Net; using System.Net.Http; -using System.Net.Sockets; using System.Reflection; using System.Text; using System.Threading.Tasks; @@ -170,7 +169,7 @@ private static void CheckForMissingInterfaces(Type clientType, Type implementati { var assembly = Assembly.GetAssembly(clientType); var interfaceType = clientType.GetInterface("I" + clientType.Name); - var clientInterfaces = assembly.GetTypes().Where(t => t.Name.StartsWith("I" + clientType.Name)); + var clientInterfaces = assembly.GetTypes().Where(t => t.Name.StartsWith("I" + clientType.Name) && !t.Name.EndsWith("Shared")); foreach (var clientInterface in clientInterfaces) { diff --git a/Examples/BlazorClient/BlazorClient.csproj b/Examples/BlazorClient/BlazorClient.csproj index b3fa91e0..9d18469e 100644 --- a/Examples/BlazorClient/BlazorClient.csproj +++ b/Examples/BlazorClient/BlazorClient.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 diff --git a/Examples/ConsoleClient/ConsoleClient.csproj b/Examples/ConsoleClient/ConsoleClient.csproj index f0e2bc7b..590b49ea 100644 --- a/Examples/ConsoleClient/ConsoleClient.csproj +++ b/Examples/ConsoleClient/ConsoleClient.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net8.0 diff --git a/README.md b/README.md index 4c032238..b024066b 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The following API's are directly supported. Note that there are 3rd party implem |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)| |Gate.io|[JKorf/GateIo.Net](https://github.com/JKorf/GateIo.Net)|[![Nuget version](https://img.shields.io/nuget/v/GateIo.net.svg?style=flat-square)](https://www.nuget.org/packages/GateIo.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)| +|HTX|[JKorf/HTX.Net](https://github.com/JKorf/HTX.Net)|[![Nuget version](https://img.shields.io/nuget/v/JKorf.HTX.net.svg?style=flat-square)](https://www.nuget.org/packages/JKorf.HTX.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)| diff --git a/docs/index.html b/docs/index.html index 79872312..2e08c2c8 100644 --- a/docs/index.html +++ b/docs/index.html @@ -85,7 +85,15 @@ - + + + + @@ -237,7 +248,10 @@

Installation

Coinex + + @@ -342,7 +364,10 @@

Dependency Injection

Coinex + + @@ -428,7 +462,10 @@

Dependency Injection

Coinex + + @@ -859,7 +957,10 @@

REST API client

Coinex + + + + +