mirror of
https://github.com/JKorf/CryptoExchange.Net.git
synced 2026-08-16 10:53:08 +00:00
Shared exchange functionality (#214)
This commit is contained in:
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for an exchange endpoint
|
||||
/// </summary>
|
||||
public class EndpointOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Required exchange-specific parameters
|
||||
/// </summary>
|
||||
public List<ParameterDescription> RequiredExchangeParameters { get; set; } = new List<ParameterDescription>();
|
||||
/// <summary>
|
||||
/// Endpoint name
|
||||
/// </summary>
|
||||
public string EndpointName { get; set; }
|
||||
/// <summary>
|
||||
/// Information on the specific exchange request
|
||||
/// </summary>
|
||||
public string? RequestNotes { get; set; }
|
||||
/// <summary>
|
||||
/// Whether the call requires authentication
|
||||
/// </summary>
|
||||
public bool NeedsAuthentication { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public EndpointOptions(string endpointName, bool needAuthentication)
|
||||
{
|
||||
EndpointName = endpointName;
|
||||
NeedsAuthentication = needAuthentication;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a request
|
||||
/// </summary>
|
||||
/// <param name="exchange">Exchange name</param>
|
||||
/// <param name="exchangeParameters">Provided exchange parameters</param>
|
||||
/// <param name="tradingMode">Request trading mode</param>
|
||||
/// <param name="supportedTradingModes">Supported trading modes</param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Options for an exchange endpoint
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of data</typeparam>
|
||||
public class EndpointOptions<T> : EndpointOptions where T : SharedRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Required optional parameters in the request
|
||||
/// </summary>
|
||||
public List<ParameterDescription> RequiredOptionalParameters { get; set; } = new List<ParameterDescription>();
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public EndpointOptions(bool needsAuthentication) : base(typeof(T).Name, needsAuthentication)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a request
|
||||
/// </summary>
|
||||
/// <param name="exchange">Exchange name</param>
|
||||
/// <param name="request">The request</param>
|
||||
/// <param name="tradingMode">Request trading mode</param>
|
||||
/// <param name="supportedTradingModes">Supported trading modes</param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for requesting closed orders
|
||||
/// </summary>
|
||||
public class GetClosedOrdersOptions : PaginatedEndpointOptions<GetClosedOrdersRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the start/end time filter is supported
|
||||
/// </summary>
|
||||
public bool TimeFilterSupported { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetClosedOrdersOptions(SharedPaginationSupport paginationType, bool timeFilterSupported) : base(paginationType, true)
|
||||
{
|
||||
TimeFilterSupported = timeFilterSupported;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString(string exchange)
|
||||
{
|
||||
var sb = new StringBuilder(base.ToString(exchange));
|
||||
sb.AppendLine($"Time filter supported: {TimeFilterSupported}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for requesting deposits
|
||||
/// </summary>
|
||||
public class GetDepositsOptions : PaginatedEndpointOptions<GetDepositsRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the start/end time filter is supported
|
||||
/// </summary>
|
||||
public bool TimeFilterSupported { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetDepositsOptions(SharedPaginationSupport paginationType, bool timeFilterSupported) : base(paginationType, true)
|
||||
{
|
||||
TimeFilterSupported = timeFilterSupported;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString(string exchange)
|
||||
{
|
||||
var sb = new StringBuilder(base.ToString(exchange));
|
||||
sb.AppendLine($"Time filter supported: {TimeFilterSupported}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for requesting funding rate history
|
||||
/// </summary>
|
||||
public class GetFundingRateHistoryOptions : PaginatedEndpointOptions<GetFundingRateHistoryRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetFundingRateHistoryOptions(SharedPaginationSupport paginationType, bool needsAuthentication) : base(paginationType, needsAuthentication)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for requesting kline/candlestick data
|
||||
/// </summary>
|
||||
public class GetKlinesOptions : PaginatedEndpointOptions<GetKlinesRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported kline intervals
|
||||
/// </summary>
|
||||
public IEnumerable<SharedKlineInterval> SupportIntervals { get; }
|
||||
/// <summary>
|
||||
/// Max number of data points which can be requested
|
||||
/// </summary>
|
||||
public int? MaxTotalDataPoints { get; set; }
|
||||
/// <summary>
|
||||
/// Max number of data points which can be requested in a single request
|
||||
/// </summary>
|
||||
public int? MaxRequestDataPoints { get; set; }
|
||||
/// <summary>
|
||||
/// The max age of the data that can be requested
|
||||
/// </summary>
|
||||
public TimeSpan? MaxAge { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetKlinesOptions(SharedPaginationSupport paginationType, bool needsAuthentication, params SharedKlineInterval[] intervals) : base(paginationType, needsAuthentication)
|
||||
{
|
||||
SupportIntervals = intervals;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check whether a specific interval is supported
|
||||
/// </summary>
|
||||
/// <param name="interval"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsSupported(SharedKlineInterval interval) => SupportIntervals.Contains(interval);
|
||||
|
||||
/// <inheritdoc />
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for requesting order book
|
||||
/// </summary>
|
||||
public class GetOrderBookOptions : EndpointOptions<GetOrderBookRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// Supported order book depths
|
||||
/// </summary>
|
||||
public IEnumerable<int>? SupportedLimits { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The min order book depth
|
||||
/// </summary>
|
||||
public int? MinLimit { get; set; }
|
||||
/// <summary>
|
||||
/// The max order book depth
|
||||
/// </summary>
|
||||
public int? MaxLimit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetOrderBookOptions(int minLimit, int maxLimit, bool authenticated) : base(authenticated)
|
||||
{
|
||||
MinLimit = minLimit;
|
||||
MaxLimit = maxLimit;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetOrderBookOptions(IEnumerable<int> supportedLimits, bool authenticated) : base(authenticated)
|
||||
{
|
||||
SupportedLimits = supportedLimits;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for requesting position history
|
||||
/// </summary>
|
||||
public class GetPositionHistoryOptions : PaginatedEndpointOptions<GetPositionHistoryRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetPositionHistoryOptions(SharedPaginationSupport paginationType) : base(paginationType, true)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for requesting current position mode
|
||||
/// </summary>
|
||||
public class GetPositionModeOptions : EndpointOptions<GetPositionModeRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetPositionModeOptions() : base(true)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for requesting recent trades
|
||||
/// </summary>
|
||||
public class GetRecentTradesOptions : EndpointOptions<GetRecentTradesRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// The max number of trades that can be requested
|
||||
/// </summary>
|
||||
public int MaxLimit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetRecentTradesOptions(int limit, bool authenticated) : base(authenticated)
|
||||
{
|
||||
MaxLimit = limit;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Error? Validate(GetRecentTradesRequest request)
|
||||
{
|
||||
if (request.Limit > MaxLimit)
|
||||
return new ArgumentError($"Only the most recent {MaxLimit} trades are available");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString(string exchange)
|
||||
{
|
||||
var sb = new StringBuilder(base.ToString(exchange));
|
||||
sb.AppendLine($"Max data points: {MaxLimit}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for requesting trade history
|
||||
/// </summary>
|
||||
public class GetTradeHistoryOptions : PaginatedEndpointOptions<GetTradeHistoryRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// The max age of data that can be requested
|
||||
/// </summary>
|
||||
public TimeSpan? MaxAge { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetTradeHistoryOptions(SharedPaginationSupport paginationType, bool needsAuthentication) : base(paginationType, needsAuthentication)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for requesting withdrawals
|
||||
/// </summary>
|
||||
public class GetWithdrawalsOptions : PaginatedEndpointOptions<GetWithdrawalsRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the start/end time filter is supported
|
||||
/// </summary>
|
||||
public bool TimeFilterSupported { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetWithdrawalsOptions(SharedPaginationSupport paginationType, bool timeFilterSupported) : base(paginationType, true)
|
||||
{
|
||||
TimeFilterSupported = timeFilterSupported;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString(string exchange)
|
||||
{
|
||||
var sb = new StringBuilder(base.ToString(exchange));
|
||||
sb.AppendLine($"Time filter supported: {TimeFilterSupported}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for paginated endpoints
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class PaginatedEndpointOptions<T> : EndpointOptions<T> where T : SharedRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Type of pagination supported
|
||||
/// </summary>
|
||||
public SharedPaginationSupport PaginationSupport { get; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public PaginatedEndpointOptions(SharedPaginationSupport paginationType, bool needsAuthentication) : base(needsAuthentication)
|
||||
{
|
||||
PaginationSupport = paginationType;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString(string exchange)
|
||||
{
|
||||
var sb = new StringBuilder(base.ToString(exchange));
|
||||
sb.AppendLine($"Pagination type: {PaginationSupport}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for placing a new futures order
|
||||
/// </summary>
|
||||
public class PlaceFuturesOrderOptions : EndpointOptions<PlaceFuturesOrderRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public PlaceFuturesOrderOptions() : base(true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a request
|
||||
/// </summary>
|
||||
public Error? ValidateRequest(
|
||||
string exchange,
|
||||
PlaceFuturesOrderRequest request,
|
||||
TradingMode? tradingMode,
|
||||
TradingMode[] supportedApiTypes,
|
||||
IEnumerable<SharedOrderType> supportedOrderTypes,
|
||||
IEnumerable<SharedTimeInForce> 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for placing a new spot order
|
||||
/// </summary>
|
||||
public class PlaceSpotOrderOptions : EndpointOptions<PlaceSpotOrderRequest>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public PlaceSpotOrderOptions() : base(true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a request
|
||||
/// </summary>
|
||||
public Error? ValidateRequest(
|
||||
string exchange,
|
||||
PlaceSpotOrderRequest request,
|
||||
TradingMode? tradingMode,
|
||||
TradingMode[] supportedApiTypes,
|
||||
IEnumerable<SharedOrderType> supportedOrderTypes,
|
||||
IEnumerable<SharedTimeInForce> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for setting leverage
|
||||
/// </summary>
|
||||
public class SetLeverageOptions : EndpointOptions<SetLeverageRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public SetLeverageOptions() : base(true)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for setting position mode
|
||||
/// </summary>
|
||||
public class SetPositionModeOptions : EndpointOptions<SetPositionModeRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public SetPositionModeOptions() : base(true)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for requesting a withdrawal
|
||||
/// </summary>
|
||||
public class WithdrawOptions : EndpointOptions<WithdrawRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public WithdrawOptions() : base(true)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user