1
0
mirror of https://github.com/JKorf/CryptoExchange.Net.git synced 2026-10-16 16:10:53 +00:00

Shared exchange functionality (#214)

This commit is contained in:
Jan Korf
2024-09-27 09:17:44 +02:00
committed by GitHub
parent 5d3de52da6
commit b8686d60b9
199 changed files with 7219 additions and 277 deletions
@@ -0,0 +1,33 @@
using CryptoExchange.Net.Objects.Sockets;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// An update event for a specific exchange
/// </summary>
/// <typeparam name="T">Type of the data</typeparam>
public class ExchangeEvent<T> : DataEvent<T>
{
/// <summary>
/// The exchange
/// </summary>
public string Exchange { get; }
/// <summary>
/// ctor
/// </summary>
public ExchangeEvent(string exchange, DataEvent<T> evnt) :
base(evnt.Data,
evnt.StreamId,
evnt.Symbol,
evnt.OriginalData,
evnt.Timestamp,
evnt.UpdateType)
{
Exchange = exchange;
}
/// <inheritdoc />
public override string ToString() => $"{Exchange} - " + base.ToString();
}
}
@@ -0,0 +1,34 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Exchange parameter
/// </summary>
public class ExchangeParameter
{
/// <summary>
/// Exchange name
/// </summary>
public string Exchange { get; set; }
/// <summary>
/// Parameter name
/// </summary>
public string Name { get; set; }
/// <summary>
/// Parameter value
/// </summary>
public object Value { get; set; }
/// <summary>
/// Create a new exchange parameter
/// </summary>
/// <param name="exchange">Exchange name</param>
/// <param name="name">Parameter name</param>
/// <param name="value">Parameter value</param>
public ExchangeParameter(string exchange, string name, object value)
{
Exchange = exchange;
Name = name;
Value = value;
}
}
}
@@ -0,0 +1,176 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Exchange parameters
/// </summary>
public class ExchangeParameters
{
private readonly List<ExchangeParameter> _parameters;
private static List<ExchangeParameter> _staticParameters = new List<ExchangeParameter>();
/// <summary>
/// ctor
/// </summary>
/// <param name="parameters">The parameters to add</param>
public ExchangeParameters(params ExchangeParameter[] parameters)
{
_parameters = parameters.ToList();
}
/// <summary>
/// Add a new parameter value
/// </summary>
/// <param name="exchangeParameter"></param>
public void AddValue(ExchangeParameter exchangeParameter)
{
_parameters.Add(exchangeParameter);
}
/// <summary>
/// Check whether a specific parameter is provided in this specific instance
/// </summary>
/// <param name="exchange">The exchange name</param>
/// <param name="name">Parameter name</param>
/// <param name="type">Type of the parameter value</param>
/// <returns></returns>
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;
}
}
/// <summary>
/// Check whether a specific parameter is provided in the default parameters or the provided instance
/// </summary>
/// <param name="exchangeParameters">The provided exchange parameter in the request</param>
/// <param name="exchange">The exchange name</param>
/// <param name="name">Parameter name</param>
/// <param name="type">Type of the parameter value</param>
/// <returns></returns>
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;
}
}
/// <summary>
/// Get the value of a parameter from this instance
/// </summary>
/// <typeparam name="T">Type of the parameter value</typeparam>
/// <param name="exchange">Exchange name</param>
/// <param name="name">Parameter name</param>
public T? GetValue<T>(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);
}
}
/// <summary>
/// Get the value of a parameter from this instance or the default values
/// </summary>
/// <typeparam name="T">Type of the parameter value</typeparam>
/// <param name="exchangeParameters">The request parameters</param>
/// <param name="exchange">Exchange name</param>
/// <param name="name">Parameter name</param>
public static T? GetValue<T>(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<T>(exchange, name);
}
return value;
}
/// <summary>
/// Set static parameters
/// </summary>
/// <param name="exchange">Exchange name</param>
/// <param name="key">Parameter name</param>
/// <param name="value">Parameter value</param>
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));
}
/// <summary>
/// Reset the static parameters, clears all parameters for all exchanges
/// </summary>
public static void ResetStaticParameters()
{
_staticParameters.Clear();
}
}
}
@@ -0,0 +1,44 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// A CallResult from an exchange
/// </summary>
/// <typeparam name="T"></typeparam>
public class ExchangeResult<T> : CallResult<T>
{
/// <summary>
/// The exchange
/// </summary>
public string Exchange { get; }
/// <summary>
/// ctor
/// </summary>
public ExchangeResult(
string exchange,
Error error) :
base(error)
{
Exchange = exchange;
}
/// <summary>
/// ctor
/// </summary>
public ExchangeResult(
string exchange,
CallResult<T> result) :
base(
result.Data,
result.OriginalData,
result.Error)
{
Exchange = exchange;
}
/// <inheritdoc />
public override string ToString() => $"{Exchange} - " + base.ToString();
}
}
@@ -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
{
/// <summary>
/// A WebCallResult from an exchange
/// </summary>
/// <typeparam name="T">The result type</typeparam>
public class ExchangeWebResult<T> : WebCallResult<T>
{
/// <summary>
/// The exchange
/// </summary>
public string Exchange { get; }
/// <summary>
/// The trade modes for which the result data is
/// </summary>
public TradingMode[]? DataTradeMode { get; }
/// <summary>
/// Token to retrieve the next page with
/// </summary>
public INextPageToken? NextPageToken { get; }
/// <summary>
/// ctor
/// </summary>
public ExchangeWebResult(
string exchange,
Error error) :
base(error)
{
Exchange = exchange;
}
/// <summary>
/// ctor
/// </summary>
public ExchangeWebResult(
string exchange,
TradingMode dataTradeMode,
WebCallResult<T> 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;
}
/// <summary>
/// ctor
/// </summary>
public ExchangeWebResult(
string exchange,
TradingMode[]? dataTradeModes,
WebCallResult<T> 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;
}
/// <summary>
/// Create a new result
/// </summary>
public ExchangeWebResult(
string exchange,
TradingMode[]? dataTradeModes,
HttpStatusCode? code,
IEnumerable<KeyValuePair<string, IEnumerable<string>>>? responseHeaders,
TimeSpan? responseTime,
long? responseLength,
string? originalData,
int? requestId,
string? requestUrl,
string? requestBody,
HttpMethod? requestMethod,
IEnumerable<KeyValuePair<string, IEnumerable<string>>>? 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;
}
/// <summary>
/// Copy the ExchangeWebResult to a new data type
/// </summary>
/// <typeparam name="K">The new type</typeparam>
/// <param name="data">The data of the new type</param>
/// <returns></returns>
public new ExchangeWebResult<K> As<K>([AllowNull] K data)
{
return new ExchangeWebResult<K>(Exchange, DataTradeMode, ResponseStatusCode, ResponseHeaders, ResponseTime, ResponseLength, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, DataSource, data, Error, NextPageToken);
}
/// <inheritdoc />
public override string ToString() => $"{Exchange} - " + base.ToString();
}
}
@@ -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();
}
}
}
@@ -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)
{
}
}
}
@@ -0,0 +1,61 @@
using System;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Parameter description
/// </summary>
public class ParameterDescription
{
/// <summary>
/// Name of the parameter
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Names of the parameters
/// </summary>
public string[]? Names { get; set; }
/// <summary>
/// Type of the value
/// </summary>
public Type ValueType { get; set; }
/// <summary>
/// Parameter description
/// </summary>
public string Description { get; set; }
/// <summary>
/// Example value
/// </summary>
public object ExampleValue { get; set; }
/// <summary>
/// ctor
/// </summary>
public ParameterDescription(string parameterName, Type valueType, string description, object exampleValue)
{
Name = parameterName;
ValueType = valueType;
Description = description;
ExampleValue = exampleValue;
}
/// <summary>
/// ctor
/// </summary>
public ParameterDescription(string[] parameterNames, Type valueType, string description, object exampleValue)
{
Names = parameterNames;
ValueType = valueType;
Description = description;
ExampleValue = exampleValue;
}
/// <inheritdoc />
public override string ToString()
{
if (Name != null)
return $"[{ValueType.Name}] {Name}: {Description} | example: {ExampleValue}";
return $"[{ValueType.Name}] {string.Join(" / ", Names)}: {Description} | example: {ExampleValue}";
}
}
}
@@ -0,0 +1,61 @@
using CryptoExchange.Net.Objects;
using System;
using System.Collections.Generic;
using System.Linq;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Options for subscribing to kline/candlestick updates
/// </summary>
public class SubscribeKlineOptions : EndpointOptions<SubscribeKlineRequest>
{
/// <summary>
/// Kline intervals supported for updates
/// </summary>
public IEnumerable<SharedKlineInterval> SupportIntervals { get; }
/// <summary>
/// ctor
/// </summary>
public SubscribeKlineOptions(bool needsAuthentication) : base(needsAuthentication)
{
SupportIntervals = new[]
{
SharedKlineInterval.FiveMinutes,
SharedKlineInterval.FifteenMinutes,
SharedKlineInterval.OneHour,
SharedKlineInterval.FifteenMinutes,
SharedKlineInterval.OneDay,
SharedKlineInterval.OneWeek,
SharedKlineInterval.OneMonth
};
}
/// <summary>
/// ctor
/// </summary>
public SubscribeKlineOptions(bool needsAuthentication, params SharedKlineInterval[] intervals) : base(needsAuthentication)
{
SupportIntervals = intervals;
}
/// <summary>
/// Check whether a specific interval is supported
/// </summary>
/// <param name="interval">Interval</param>
/// <returns></returns>
public bool IsSupported(SharedKlineInterval interval) => SupportIntervals.Contains(interval);
/// <summary>
/// Validate a request
/// </summary>
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);
}
}
}
@@ -0,0 +1,37 @@
using CryptoExchange.Net.Objects;
using System;
using System.Collections.Generic;
using System.Linq;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Options for subscribing to order book snapshot updates
/// </summary>
public class SubscribeOrderBookOptions : EndpointOptions<SubscribeOrderBookRequest>
{
/// <summary>
/// Order book depths supported for updates
/// </summary>
public IEnumerable<int> SupportedLimits { get; }
/// <summary>
/// ctor
/// </summary>
public SubscribeOrderBookOptions(bool needsAuthentication, IEnumerable<int> limits) : base(needsAuthentication)
{
SupportedLimits = limits;
}
/// <summary>
/// Validate a request
/// </summary>
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);
}
}
}
@@ -0,0 +1,24 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to cancel a currently open order
/// </summary>
public record CancelOrderRequest : SharedSymbolRequest
{
/// <summary>
/// Id of order to cancel
/// </summary>
public string OrderId { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol the order is on</param>
/// <param name="orderId">Id of the order to close</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public CancelOrderRequest(SharedSymbol symbol, string orderId, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
OrderId = orderId;
}
}
}
@@ -0,0 +1,48 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to close a currently open position
/// </summary>
public record ClosePositionRequest : SharedSymbolRequest
{
/// <summary>
/// The current position mode of the account for the symbol
/// </summary>
public SharedPositionMode PositionMode { get; set; }
/// <summary>
/// The position side to close. Required when in hedge mode
/// </summary>
public SharedPositionSide? PositionSide { get; set; }
/// <summary>
/// Margin mode
/// </summary>
public SharedMarginMode? MarginMode { get; set; }
/// <summary>
/// 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
/// </summary>
public decimal? Quantity { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to close the position on</param>
/// <param name="mode">The current position mode of the account for the symbol</param>
/// <param name="positionSide">The position side to close. Required when in hedge mode</param>
/// <param name="marginMode">Margin mode</param>
/// <param name="quantity">Quantity of the position to close. Note that the quantity is needed for some exchanges, but will not be respected on all exchanges</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
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;
}
}
}
@@ -0,0 +1,23 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve info on a specific asset
/// </summary>
public record GetAssetRequest : SharedRequest
{
/// <summary>
/// Asset name
/// </summary>
public string Asset { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="asset">Asset to retrieve info on</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetAssetRequest(string asset, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
Asset = asset;
}
}
}
@@ -0,0 +1,18 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve a list of supported assets
/// </summary>
public record GetAssetsRequest : SharedRequest
{
/// <summary>
/// ctor
/// </summary>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetAssetsRequest(ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
}
}
}
@@ -0,0 +1,25 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve balance info for the user
/// </summary>
public record GetBalancesRequest : SharedRequest
{
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="tradingMode">Trading mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetBalancesRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
TradingMode = tradingMode;
}
}
}
@@ -0,0 +1,38 @@
using System;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve closed orders for a symbol
/// </summary>
public record GetClosedOrdersRequest : SharedSymbolRequest
{
/// <summary>
/// Filter by start time
/// </summary>
public DateTime? StartTime { get; }
/// <summary>
/// Filter by end time
/// </summary>
public DateTime? EndTime { get; }
/// <summary>
/// Max number of results
/// </summary>
public int? Limit { get; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to get closed orders for</param>
/// <param name="startTime">Filter by start time</param>
/// <param name="endTime">Filter by end time</param>
/// <param name="limit">Max number of results</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
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;
}
}
}
@@ -0,0 +1,29 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve the deposit addresses for an asset
/// </summary>
public record GetDepositAddressesRequest : SharedRequest
{
/// <summary>
/// Asset to get address for
/// </summary>
public string Asset { get; set; }
/// <summary>
/// Network name
/// </summary>
public string? Network { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="asset">Asset name to get address for</param>
/// <param name="network">Network name</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetDepositAddressesRequest(string asset, string? network = null, ExchangeParameters? exchangeParameters = null): base(exchangeParameters)
{
Asset = asset;
Network = network;
}
}
}
@@ -0,0 +1,43 @@
using System;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve deposit history records
/// </summary>
public record GetDepositsRequest : SharedRequest
{
/// <summary>
/// Filter by asset
/// </summary>
public string? Asset { get; set; }
/// <summary>
/// Filter by start time
/// </summary>
public DateTime? StartTime { get; }
/// <summary>
/// Filter by end time
/// </summary>
public DateTime? EndTime { get; }
/// <summary>
/// Max number of results
/// </summary>
public int? Limit { get; }
/// <summary>
/// ctor
/// </summary>
/// <param name="asset">Filter by asset</param>
/// <param name="startTime">Filter by start time</param>
/// <param name="endTime">Filter by end time</param>
/// <param name="limit">Max number of results</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
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;
}
}
}
@@ -0,0 +1,38 @@
using System;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve funding rate history data
/// </summary>
public record GetFundingRateHistoryRequest : SharedSymbolRequest
{
/// <summary>
/// Filter by start time
/// </summary>
public DateTime? StartTime { get; set; }
/// <summary>
/// Filter by end time
/// </summary>
public DateTime? EndTime { get; set; }
/// <summary>
/// Max number of results
/// </summary>
public int? Limit { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to request klines for</param>
/// <param name="startTime">Filter by start time</param>
/// <param name="endTime">Filter by end time</param>
/// <param name="limit">Max number of results</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
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;
}
}
}
@@ -0,0 +1,44 @@
using System;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve kline/candlestick data
/// </summary>
public record GetKlinesRequest : SharedSymbolRequest
{
/// <summary>
/// The kline interval
/// </summary>
public SharedKlineInterval Interval { get; set; }
/// <summary>
/// Filter by start time
/// </summary>
public DateTime? StartTime { get; set; }
/// <summary>
/// Filter by end time
/// </summary>
public DateTime? EndTime { get; set; }
/// <summary>
/// Max number of results
/// </summary>
public int? Limit { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to request klines for</param>
/// <param name="interval">Interval of the klines</param>
/// <param name="startTime">Filter by start time</param>
/// <param name="endTime">Filter by end time</param>
/// <param name="limit">Max number of results</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
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;
}
}
}
@@ -0,0 +1,30 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve the leverage setting for a symbol
/// </summary>
public record GetLeverageRequest : SharedSymbolRequest
{
/// <summary>
/// Position side, required when in hedge mode
/// </summary>
public SharedPositionSide? PositionSide { get; set; }
/// <summary>
/// Margin mode
/// </summary>
public SharedMarginMode? MarginMode { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to request leverage for</param>
/// <param name="positionSide">Position side to get leverage for when in hedge mode</param>
/// <param name="marginMode">Margin mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetLeverageRequest(SharedSymbol symbol, SharedPositionSide? positionSide = null, SharedMarginMode? marginMode = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
PositionSide = positionSide;
MarginMode = marginMode;
}
}
}
@@ -0,0 +1,17 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve the current open interest for a symbol
/// </summary>
public record GetOpenInterestRequest : SharedSymbolRequest
{
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to retrieve open orders for</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetOpenInterestRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
}
}
}
@@ -0,0 +1,39 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve the current open orders
/// </summary>
public record GetOpenOrdersRequest : SharedRequest
{
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// Symbol filter
/// </summary>
public SharedSymbol? Symbol { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="tradingMode">Trading mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetOpenOrdersRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
TradingMode = tradingMode;
}
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to retrieve open orders for</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetOpenOrdersRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
Symbol = symbol;
}
}
}
@@ -0,0 +1,24 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve the current order book
/// </summary>
public record GetOrderBookRequest: SharedSymbolRequest
{
/// <summary>
/// Depth of the order book
/// </summary>
public int? Limit { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">The symbol the order is on</param>
/// <param name="limit">Depth of the order book</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetOrderBookRequest(SharedSymbol symbol, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
Limit = limit;
}
}
}
@@ -0,0 +1,24 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve info on a specifc order
/// </summary>
public record GetOrderRequest : SharedSymbolRequest
{
/// <summary>
/// Id of the order
/// </summary>
public string OrderId { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">The symbol the order is on</param>
/// <param name="orderId">The id of the order</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetOrderRequest(SharedSymbol symbol, string orderId, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
OrderId = orderId;
}
}
}
@@ -0,0 +1,24 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve the trades for a specific order
/// </summary>
public record GetOrderTradesRequest : SharedSymbolRequest
{
/// <summary>
/// The id of the order to retrieve trades for
/// </summary>
public string OrderId { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">The symbol the order is on</param>
/// <param name="orderId">The id of the order</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetOrderTradesRequest(SharedSymbol symbol, string orderId, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
OrderId = orderId;
}
}
}
@@ -0,0 +1,64 @@
using CryptoExchange.Net.Objects;
using System;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve the position close history
/// </summary>
public record GetPositionHistoryRequest : SharedRequest
{
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// Symbol
/// </summary>
public SharedSymbol? Symbol { get; set; }
/// <summary>
/// Filter by start time
/// </summary>
public DateTime? StartTime { get; set; }
/// <summary>
/// Filter by end time
/// </summary>
public DateTime? EndTime { get; set; }
/// <summary>
/// Max number of results
/// </summary>
public int? Limit { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol filter</param>
/// <param name="startTime">Filter by start time</param>
/// <param name="endTime">Filter by end time</param>
/// <param name="limit">Max number of results</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
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;
}
/// <summary>
/// ctor
/// </summary>
/// <param name="tradeMode">Trade mode</param>
/// <param name="startTime">Filter by start time</param>
/// <param name="endTime">Filter by end time</param>
/// <param name="limit">Max number of results</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
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;
}
}
}
@@ -0,0 +1,39 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve the current position mode
/// </summary>
public record GetPositionModeRequest : SharedRequest
{
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// Symbol. Some exchanges set position mode per symbol
/// </summary>
public SharedSymbol? Symbol { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to retrieve position mode for</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetPositionModeRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
Symbol = symbol;
}
/// <summary>
/// ctor
/// </summary>
/// <param name="tradingMode">Trading mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetPositionModeRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
TradingMode = tradingMode;
}
}
}
@@ -0,0 +1,39 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve open positions
/// </summary>
public record GetPositionsRequest : SharedRequest
{
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// Symbol filter, required for some exchanges
/// </summary>
public SharedSymbol? Symbol { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="tradingMode">Trading mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetPositionsRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
TradingMode = tradingMode;
}
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to retriecve positions for</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetPositionsRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
Symbol = symbol;
}
}
}
@@ -0,0 +1,24 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve the most recent trades of a symbol
/// </summary>
public record GetRecentTradesRequest : SharedSymbolRequest
{
/// <summary>
/// Max number of results
/// </summary>
public int? Limit { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to retrieve trades for</param>
/// <param name="limit">Max number of results</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetRecentTradesRequest(SharedSymbol symbol, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
Limit = limit;
}
}
}
@@ -0,0 +1,25 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve symbol info
/// </summary>
public record GetSymbolsRequest : SharedRequest
{
/// <summary>
/// Filter by trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="tradingMode">Trading mode filter</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetSymbolsRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
TradingMode = tradingMode;
}
}
}
@@ -0,0 +1,17 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve ticker info for a symbol
/// </summary>
public record GetTickerRequest : SharedSymbolRequest
{
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to retrieve ticker for</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetTickerRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
}
}
}
@@ -0,0 +1,26 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve all symbol tickers
/// </summary>
public record GetTickersRequest : SharedRequest
{
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="tradingMode">Trading mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetTickersRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
TradingMode = tradingMode;
}
}
}
@@ -0,0 +1,38 @@
using System;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve the public trade history
/// </summary>
public record GetTradeHistoryRequest : SharedSymbolRequest
{
/// <summary>
/// Filter by start time
/// </summary>
public DateTime StartTime { get; }
/// <summary>
/// Filter by end time
/// </summary>
public DateTime EndTime { get; }
/// <summary>
/// Max number of results
/// </summary>
public int? Limit { get; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to retrieve trades for</param>
/// <param name="startTime">Filter by start time</param>
/// <param name="endTime">Filter by end time</param>
/// <param name="limit">Max number of results</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public GetTradeHistoryRequest(SharedSymbol symbol, DateTime startTime, DateTime endTime, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
StartTime = startTime;
EndTime = endTime;
Limit = limit;
}
}
}
@@ -0,0 +1,38 @@
using System;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve the trades of the user
/// </summary>
public record GetUserTradesRequest : SharedSymbolRequest
{
/// <summary>
/// Filter by start time
/// </summary>
public DateTime? StartTime { get; }
/// <summary>
/// Filter by end time
/// </summary>
public DateTime? EndTime { get; }
/// <summary>
/// Max number of results
/// </summary>
public int? Limit { get; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to retrieve trades for</param>
/// <param name="startTime">Filter by start time</param>
/// <param name="endTime">Filter by end time</param>
/// <param name="limit">Max number of results</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
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;
}
}
}
@@ -0,0 +1,43 @@
using System;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to retrieve the withdrawal history
/// </summary>
public record GetWithdrawalsRequest : SharedRequest
{
/// <summary>
/// Filter by asset
/// </summary>
public string? Asset { get; set; }
/// <summary>
/// Filter by start time
/// </summary>
public DateTime? StartTime { get; }
/// <summary>
/// Filter by end time
/// </summary>
public DateTime? EndTime { get; }
/// <summary>
/// Max number of results
/// </summary>
public int? Limit { get; }
/// <summary>
/// ctor
/// </summary>
/// <param name="asset">Filter by asset</param>
/// <param name="startTime">Filter by start time</param>
/// <param name="endTime">Filter by end time</param>
/// <param name="limit">Max number of results</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
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;
}
}
}
@@ -0,0 +1,31 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to keep-alive the update stream for the specified listen key
/// </summary>
public record KeepAliveListenKeyRequest : SharedRequest
{
/// <summary>
/// The key to stop updates for
/// </summary>
public string ListenKey { get; set; }
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="listenKey">The key to keep alive</param>
/// <param name="tradingMode">Trading mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public KeepAliveListenKeyRequest(string listenKey, TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
ListenKey = listenKey;
TradingMode = tradingMode;
}
}
}
@@ -0,0 +1,98 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to place a new futures order
/// </summary>
public record PlaceFuturesOrderRequest : SharedSymbolRequest
{
/// <summary>
/// Side of the order
/// </summary>
public SharedOrderSide Side { get; set; }
/// <summary>
/// Type of the order
/// </summary>
public SharedOrderType OrderType { get; set; }
/// <summary>
/// Time in force of the order
/// </summary>
public SharedTimeInForce? TimeInForce { get; set; }
/// <summary>
/// Quantity of the order in base asset.
/// </summary>
public decimal? Quantity { get; set; }
/// <summary>
/// Quantity of the order in quote asset.
/// </summary>
public decimal? QuoteQuantity { get; set; }
/// <summary>
/// Price of the order
/// </summary>
public decimal? Price { get; set; }
/// <summary>
/// Client order id
/// </summary>
public string? ClientOrderId { get; set; }
/// <summary>
/// Position side of the order. Required when in hedge mode, ignored in one-way mode
/// </summary>
public SharedPositionSide? PositionSide { get; set; }
/// <summary>
/// Margin mode
/// </summary>
public SharedMarginMode? MarginMode { get; set; }
/// <summary>
/// Reduce only order
/// </summary>
public bool? ReduceOnly { get; set; }
/// <summary>
/// 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.
/// </summary>
public decimal? Leverage { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to place the order on</param>
/// <param name="side">Side of the order</param>
/// <param name="orderType">Type of the order</param>
/// <param name="quantity">Quantity of the order</param>
/// <param name="quoteQuantity">Quantity of the order in quote asset</param>
/// <param name="price">Price of the order</param>
/// <param name="timeInForce">Time in force</param>
/// <param name="clientOrderId">Client order id</param>
/// <param name="reduceOnly">Reduce only</param>
/// <param name="leverage">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.</param>
/// <param name="positionSide">Position side of the order. Required when in hedge mode, ignored in one-way mode</param>
/// <param name="marginMode">Margin mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
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;
}
}
}
@@ -0,0 +1,69 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to place a new spot order
/// </summary>
public record PlaceSpotOrderRequest : SharedSymbolRequest
{
/// <summary>
/// Type of the order
/// </summary>
public SharedOrderType OrderType { get; set; }
/// <summary>
/// Side of the order
/// </summary>
public SharedOrderSide Side { get; set; }
/// <summary>
/// Time in force of the order
/// </summary>
public SharedTimeInForce? TimeInForce { get; set; }
/// <summary>
/// Quantity of the order in base asset or contracts, depending on the exchange.
/// </summary>
public decimal? Quantity { get; set; }
/// <summary>
/// Quantity of the order in quote asset.
/// </summary>
public decimal? QuoteQuantity { get; set; }
/// <summary>
/// Price of the order
/// </summary>
public decimal? Price { get; set; }
/// <summary>
/// Client order id
/// </summary>
public string? ClientOrderId { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to place the order on</param>
/// <param name="side">Side of the order</param>
/// <param name="orderType">Type of the order</param>
/// <param name="quantity">Quantity of the order</param>
/// <param name="quoteQuantity">Quantity of the order in quote asset</param>
/// <param name="price">Price of the order</param>
/// <param name="timeInForce">Time in force</param>
/// <param name="clientOrderId">Client order id</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
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;
}
}
}
@@ -0,0 +1,36 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to change the current leverage
/// </summary>
public record SetLeverageRequest : SharedSymbolRequest
{
/// <summary>
/// Leverage to change to
/// </summary>
public decimal Leverage { get; set; }
/// <summary>
/// Position side to change leverage for. Some exchanges set leverage per side
/// </summary>
public SharedPositionSide? Side { get; set; }
/// <summary>
/// Margin mode of the position leverage to change
/// </summary>
public SharedMarginMode? MarginMode { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to change the leverage for</param>
/// <param name="leverage">Leverage to change to</param>
/// <param name="positionSide">Position side to change leverage for. Some exchanges set leverage per side</param>
/// <param name="marginMode">Margin mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public SetLeverageRequest(SharedSymbol symbol, decimal leverage, SharedPositionSide? positionSide = null, SharedMarginMode? marginMode = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
Leverage = leverage;
Side = positionSide;
MarginMode = marginMode;
}
}
}
@@ -0,0 +1,47 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to change the current position mode
/// </summary>
public record SetPositionModeRequest : SharedRequest
{
/// <summary>
/// Symbol to change the mode for. Depending on the exchange position mode is set for the whole account or per symbol
/// </summary>
public SharedSymbol? Symbol { get; set; }
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// Position mode to change to
/// </summary>
public SharedPositionMode PositionMode { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="positionMode">Position mode to change to</param>
/// <param name="tradingMode">Trading mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public SetPositionModeRequest(SharedPositionMode positionMode, TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
TradingMode = tradingMode;
PositionMode = positionMode;
}
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">Symbol to change to position mode for</param>
/// <param name="positionMode">Position mode to change to</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public SetPositionModeRequest(SharedSymbol symbol, SharedPositionMode positionMode, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
PositionMode = positionMode;
Symbol = symbol;
}
}
}
@@ -0,0 +1,25 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to start the update stream for the current user
/// </summary>
public record StartListenKeyRequest : SharedRequest
{
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="tradingMode">Trading mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public StartListenKeyRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
TradingMode = tradingMode;
}
}
}
@@ -0,0 +1,31 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to stop the update stream for the specific listen key
/// </summary>
public record StopListenKeyRequest : SharedRequest
{
/// <summary>
/// The key to stop updates for
/// </summary>
public string ListenKey { get; set; }
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="listenKey">The key to stop updates for</param>
/// <param name="tradingMode">Trading mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public StopListenKeyRequest(string listenKey, TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
ListenKey = listenKey;
TradingMode = tradingMode;
}
}
}
@@ -0,0 +1,47 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to withdraw funds from the exchange
/// </summary>
public record WithdrawRequest : SharedRequest
{
/// <summary>
/// Asset to withdraw
/// </summary>
public string Asset { get; set; }
/// <summary>
/// Address to withdraw to
/// </summary>
public string Address { get; set; }
/// <summary>
/// Quantity to withdraw
/// </summary>
public decimal Quantity { get; set; }
/// <summary>
/// Address tag
/// </summary>
public string? AddressTag { get; set; }
/// <summary>
/// Network to use
/// </summary>
public string? Network { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="asset">Asset to withdraw</param>
/// <param name="quantity">Quantity to withdraw</param>
/// <param name="address">Address to withdraw to</param>
/// <param name="network">Network to use</param>
/// <param name="addressTag">Address tag</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
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;
}
}
}
@@ -0,0 +1,78 @@
using CryptoExchange.Net.Objects;
using System;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Support for different quantity notations
/// </summary>
public record SharedQuantitySupport
{
/// <summary>
/// Supported quantity notations for buy limit orders
/// </summary>
public SharedQuantityType BuyLimit { get; }
/// <summary>
/// Supported quantity notations for sell limit orders
/// </summary>
public SharedQuantityType SellLimit { get; }
/// <summary>
/// Supported quantity notations for buy market orders
/// </summary>
public SharedQuantityType BuyMarket { get; }
/// <summary>
/// Supported quantity notations for sell market orders
/// </summary>
public SharedQuantityType SellMarket { get; }
/// <summary>
/// ctor
/// </summary>
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");
}
/// <summary>
/// Validate a request
/// </summary>
/// <param name="side"></param>
/// <param name="type"></param>
/// <param name="quantity"></param>
/// <param name="quoteQuantity"></param>
/// <returns></returns>
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;
}
/// <inheritdoc />
public override string ToString()
{
return $"Limit buy: {BuyLimit}, limit sell: {SellLimit}, market buy: {BuyMarket}, market sell: {SellMarket}";
}
}
}
@@ -0,0 +1,21 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request
/// </summary>
public record SharedRequest
{
/// <summary>
/// Exchange parameters. Some calls may require exchange specific parameters to execute the request.
/// </summary>
public ExchangeParameters? ExchangeParameters { get; set; }
/// <summary>
/// ctor
/// </summary>
public SharedRequest(ExchangeParameters? exchangeParameters = null)
{
ExchangeParameters = exchangeParameters;
}
}
}
@@ -0,0 +1,21 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Symbol request
/// </summary>
public record SharedSymbolRequest : SharedRequest
{
/// <summary>
/// The symbol
/// </summary>
public SharedSymbol Symbol { get; set; }
/// <summary>
/// ctor
/// </summary>
public SharedSymbolRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
Symbol = symbol;
}
}
}
@@ -0,0 +1,25 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to subscribe to ticker updates for all symbols
/// </summary>
public record SubscribeAllTickersRequest : SharedRequest
{
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="tradingMode">Trading mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public SubscribeAllTickersRequest(TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
TradingMode = tradingMode;
}
}
}
@@ -0,0 +1,31 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to subscribe to balance updates
/// </summary>
public record SubscribeBalancesRequest: SharedRequest
{
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// The listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client
/// </summary>
public string? ListenKey { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="listenKey">Listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client</param>
/// <param name="tradingMode">Trading mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public SubscribeBalancesRequest(string? listenKey = null, TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
TradingMode = tradingMode;
ListenKey = listenKey;
}
}
}
@@ -0,0 +1,17 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to subscribe to book ticker updates
/// </summary>
public record SubscribeBookTickerRequest : SharedSymbolRequest
{
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">The symbol to subscribe to</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public SubscribeBookTickerRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
}
}
}
@@ -0,0 +1,31 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to subscribe to futures order updates
/// </summary>
public record SubscribeFuturesOrderRequest : SharedRequest
{
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// The listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client
/// </summary>
public string? ListenKey { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="listenKey">Listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client</param>
/// <param name="tradingMode">Trading mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public SubscribeFuturesOrderRequest(string? listenKey = null, TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null): base(exchangeParameters)
{
TradingMode = tradingMode;
ListenKey = listenKey;
}
}
}
@@ -0,0 +1,24 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to subscribe to kline/candlestick updates
/// </summary>
public record SubscribeKlineRequest : SharedSymbolRequest
{
/// <summary>
/// The kline interval
/// </summary>
public SharedKlineInterval Interval { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">The symbol to subscribe to</param>
/// <param name="interval">Kline interval</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public SubscribeKlineRequest(SharedSymbol symbol, SharedKlineInterval interval, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
Interval = interval;
}
}
}
@@ -0,0 +1,24 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to subscribe to order book snapshot updates
/// </summary>
public record SubscribeOrderBookRequest : SharedSymbolRequest
{
/// <summary>
/// The order book depth
/// </summary>
public int? Limit { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">The symbol to subscribe to</param>
/// <param name="limit">Order book depth</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public SubscribeOrderBookRequest(SharedSymbol symbol, int? limit = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
Limit = limit;
}
}
}
@@ -0,0 +1,31 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to subscribe to position updates
/// </summary>
public record SubscribePositionRequest: SharedRequest
{
/// <summary>
/// The listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client
/// </summary>
public string? ListenKey { get; set; }
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="listenKey">Listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client</param>
/// <param name="tradingMode">Trading mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public SubscribePositionRequest(string? listenKey = null, TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
TradingMode = tradingMode;
ListenKey = listenKey;
}
}
}
@@ -0,0 +1,23 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to subscribe to spot order updates
/// </summary>
public record SubscribeSpotOrderRequest : SharedRequest
{
/// <summary>
/// The listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client
/// </summary>
public string? ListenKey { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="listenKey">Listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public SubscribeSpotOrderRequest(string? listenKey = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
ListenKey = listenKey;
}
}
}
@@ -0,0 +1,17 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to subscribe to ticker updates
/// </summary>
public record SubscribeTickerRequest : SharedSymbolRequest
{
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">The symbol to subscribe to</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public SubscribeTickerRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
}
}
}
@@ -0,0 +1,17 @@
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to subscribe to trade updates
/// </summary>
public record SubscribeTradeRequest : SharedSymbolRequest
{
/// <summary>
/// ctor
/// </summary>
/// <param name="symbol">The symbol to subscribe to</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public SubscribeTradeRequest(SharedSymbol symbol, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
{
}
}
}
@@ -0,0 +1,31 @@
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.SharedApis
{
/// <summary>
/// Request to subscribe to user trade updates
/// </summary>
public record SubscribeUserTradeRequest : SharedRequest
{
/// <summary>
/// Trading mode
/// </summary>
public TradingMode? TradingMode { get; set; }
/// <summary>
/// The listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client
/// </summary>
public string? ListenKey { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="listenKey">Listen key, needed for some exchanges. Can be obtained by the StartListenKeyAsync on the shared rest client</param>
/// <param name="tradingMode">Trading mode</param>
/// <param name="exchangeParameters">Exchange specific parameters</param>
public SubscribeUserTradeRequest(string? listenKey = null, TradingMode? tradingMode = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
{
TradingMode = tradingMode;
ListenKey = listenKey;
}
}
}