mirror of
https://github.com/JKorf/CryptoExchange.Net.git
synced 2026-08-11 16:32:57 +00:00
Shared interfaces pagination update (#274)
Updated INextPageToken parameter on Shared interfaces to PageRequest type, functionality unchanged Added SupportsAscending and SupportsDescending properties to PaginatedEndpointOptions to expose supported data directions Added MaxAge property to PaginatedEndpointOptions to expose the max age of data that can be requested Added Direction property to Shared interfaces paginated requests to configure pagination data direction Removed PaginationSupport property from PaginatedEndpointOptions, replaced by above new properties Updated Shared GetTradeHistoryRequest EndTime property to be optional Updated I(Futures/Spot)OrderRestClient.GetClosed(Futures/Spot)OrdersOptions from PaginatedEndpointOptions<GetClosedOrdersRequest> to GetClosedOrdersOptions Updated I(Futures/Spot)OrderRestClient.Get(Futures/Spot)UserTradesOptions from PaginatedEndpointOptions<GetUserTradesRequest> to GetUserTradesOptions Updated rate limiting PathStartFilter to ignore added or missing slash before the path Fixed KlineTracker throwing exception if there is no data in the initial snapshot
This commit is contained in:
@@ -96,7 +96,7 @@ namespace CryptoExchange.Net.UnitTests
|
|||||||
// assert
|
// assert
|
||||||
ClassicAssert.IsFalse(result.Success);
|
ClassicAssert.IsFalse(result.Success);
|
||||||
Assert.That(result.Error != null);
|
Assert.That(result.Error != null);
|
||||||
Assert.That(result.Error is ServerError);
|
Assert.That(result.Error is DeserializeError);
|
||||||
Assert.That(result.Error.Message.Contains(response));
|
Assert.That(result.Error.Message.Contains(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using CryptoExchange.Net.SharedApis;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -310,11 +311,11 @@ namespace CryptoExchange.Net
|
|||||||
/// <param name="request">The request parameters</param>
|
/// <param name="request">The request parameters</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static async IAsyncEnumerable<ExchangeWebResult<T[]>> ExecutePages<T, U>(Func<U, INextPageToken?, CancellationToken, Task<ExchangeWebResult<T[]>>> paginatedFunc, U request, [EnumeratorCancellation]CancellationToken ct = default)
|
public static async IAsyncEnumerable<ExchangeWebResult<T[]>> ExecutePages<T, U>(Func<U, PageRequest?, CancellationToken, Task<ExchangeWebResult<T[]>>> paginatedFunc, U request, [EnumeratorCancellation]CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
var result = new List<T>();
|
var result = new List<T>();
|
||||||
ExchangeWebResult<T[]> batch;
|
ExchangeWebResult<T[]> batch;
|
||||||
INextPageToken? nextPageToken = null;
|
PageRequest? nextPageToken = null;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
batch = await paginatedFunc(request, nextPageToken, ct).ConfigureAwait(false);
|
batch = await paginatedFunc(request, nextPageToken, ct).ConfigureAwait(false);
|
||||||
@@ -323,12 +324,42 @@ namespace CryptoExchange.Net
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
result.AddRange(batch.Data);
|
result.AddRange(batch.Data);
|
||||||
nextPageToken = batch.NextPageToken;
|
nextPageToken = batch.NextPageRequest;
|
||||||
if (nextPageToken == null)
|
if (nextPageToken == null)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply filters to the data set
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type</typeparam>
|
||||||
|
/// <param name="data">Data set</param>
|
||||||
|
/// <param name="timeSelector">Time selector for the data</param>
|
||||||
|
/// <param name="startTime">Start time filter</param>
|
||||||
|
/// <param name="endTime">End time filter</param>
|
||||||
|
/// <param name="direction">Data direction</param>
|
||||||
|
public static IEnumerable<T> ApplyFilter<T>(
|
||||||
|
IEnumerable<T> data,
|
||||||
|
Func<T, DateTime> timeSelector,
|
||||||
|
DateTime? startTime,
|
||||||
|
DateTime? endTime,
|
||||||
|
DataDirection direction)
|
||||||
|
{
|
||||||
|
if (direction == DataDirection.Ascending)
|
||||||
|
data = data.OrderBy(timeSelector);
|
||||||
|
else
|
||||||
|
data = data.OrderByDescending(timeSelector);
|
||||||
|
|
||||||
|
if (startTime != null)
|
||||||
|
data = data.Where(x => timeSelector(x) >= startTime.Value);
|
||||||
|
|
||||||
|
if (endTime != null)
|
||||||
|
data = data.Where(x => timeSelector(x) < endTime.Value);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Apply the rules (price and quantity step size and decimals precision, min/max quantity) from the symbol to the quantity and price
|
/// Apply the rules (price and quantity step size and decimals precision, min/max quantity) from the symbol to the quantity and price
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -531,11 +531,11 @@ namespace CryptoExchange.Net.Objects
|
|||||||
/// <param name="exchange">The exchange</param>
|
/// <param name="exchange">The exchange</param>
|
||||||
/// <param name="tradeMode">Trade mode the result applies to</param>
|
/// <param name="tradeMode">Trade mode the result applies to</param>
|
||||||
/// <param name="data">Data</param>
|
/// <param name="data">Data</param>
|
||||||
/// <param name="nextPageToken">Next page token</param>
|
/// <param name="nextPageRequest">Next page request</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public ExchangeWebResult<K> AsExchangeResult<K>(string exchange, TradingMode tradeMode, [AllowNull] K data, INextPageToken? nextPageToken = null)
|
public ExchangeWebResult<K> AsExchangeResult<K>(string exchange, TradingMode tradeMode, [AllowNull] K data, PageRequest? nextPageRequest = null)
|
||||||
{
|
{
|
||||||
return new ExchangeWebResult<K>(exchange, tradeMode, As<K>(data), nextPageToken);
|
return new ExchangeWebResult<K>(exchange, tradeMode, As<K>(data), nextPageRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -545,11 +545,11 @@ namespace CryptoExchange.Net.Objects
|
|||||||
/// <param name="exchange">The exchange</param>
|
/// <param name="exchange">The exchange</param>
|
||||||
/// <param name="tradeModes">Trade modes the result applies to</param>
|
/// <param name="tradeModes">Trade modes the result applies to</param>
|
||||||
/// <param name="data">Data</param>
|
/// <param name="data">Data</param>
|
||||||
/// <param name="nextPageToken">Next page token</param>
|
/// <param name="nextPageRequest">Next page token</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public ExchangeWebResult<K> AsExchangeResult<K>(string exchange, TradingMode[]? tradeModes, [AllowNull] K data, INextPageToken? nextPageToken = null)
|
public ExchangeWebResult<K> AsExchangeResult<K>(string exchange, TradingMode[]? tradeModes, [AllowNull] K data, PageRequest? nextPageRequest = null)
|
||||||
{
|
{
|
||||||
return new ExchangeWebResult<K>(exchange, tradeModes, As<K>(data), nextPageToken);
|
return new ExchangeWebResult<K>(exchange, tradeModes, As<K>(data), nextPageRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ namespace CryptoExchange.Net.RateLimiting.Filters
|
|||||||
/// <param name="path"></param>
|
/// <param name="path"></param>
|
||||||
public PathStartFilter(string path)
|
public PathStartFilter(string path)
|
||||||
{
|
{
|
||||||
_path = path;
|
_path = path.TrimStart('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Passes(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey)
|
public bool Passes(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey)
|
||||||
=> definition.Path.StartsWith(_path, StringComparison.OrdinalIgnoreCase);
|
=> definition.Path.TrimStart('/').StartsWith(_path, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,111 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A token which a request can use to retrieve the next page if there are more pages in the result set
|
|
||||||
/// </summary>
|
|
||||||
public interface INextPageToken
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A datetime offset token
|
|
||||||
/// </summary>
|
|
||||||
public record DateTimeToken: INextPageToken
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Last result time
|
|
||||||
/// </summary>
|
|
||||||
public DateTime LastTime { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ctor
|
|
||||||
/// </summary>
|
|
||||||
public DateTimeToken(DateTime timestamp)
|
|
||||||
{
|
|
||||||
LastTime = timestamp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A current page index token
|
|
||||||
/// </summary>
|
|
||||||
public record PageToken: INextPageToken
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The next page index
|
|
||||||
/// </summary>
|
|
||||||
public int Page { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Page size
|
|
||||||
/// </summary>
|
|
||||||
public int PageSize { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ctor
|
|
||||||
/// </summary>
|
|
||||||
public PageToken(int page, int pageSize)
|
|
||||||
{
|
|
||||||
Page = page;
|
|
||||||
PageSize = pageSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A id offset token
|
|
||||||
/// </summary>
|
|
||||||
public record FromIdToken : INextPageToken
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The last id from previous result
|
|
||||||
/// </summary>
|
|
||||||
public string FromToken { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ctor
|
|
||||||
/// </summary>
|
|
||||||
public FromIdToken(string fromToken)
|
|
||||||
{
|
|
||||||
FromToken = fromToken;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A cursor token
|
|
||||||
/// </summary>
|
|
||||||
public record CursorToken : INextPageToken
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The next page cursor
|
|
||||||
/// </summary>
|
|
||||||
public string Cursor { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ctor
|
|
||||||
/// </summary>
|
|
||||||
public CursorToken(string cursor)
|
|
||||||
{
|
|
||||||
Cursor = cursor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A result offset token
|
|
||||||
/// </summary>
|
|
||||||
public record OffsetToken : INextPageToken
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Offset in the result set
|
|
||||||
/// </summary>
|
|
||||||
public int Offset { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ctor
|
|
||||||
/// </summary>
|
|
||||||
public OffsetToken(int offset)
|
|
||||||
{
|
|
||||||
Offset = offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,8 +16,8 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Get funding rate records
|
/// Get funding rate records
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request">Request info</param>
|
/// <param name="request">Request info</param>
|
||||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
Task<ExchangeWebResult<SharedFundingRate[]>> GetFundingRateHistoryAsync(GetFundingRateHistoryRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default);
|
Task<ExchangeWebResult<SharedFundingRate[]>> GetFundingRateHistoryAsync(GetFundingRateHistoryRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,14 +73,14 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Spot get closed orders request options
|
/// Spot get closed orders request options
|
||||||
/// </summary>
|
/// </summary>
|
||||||
PaginatedEndpointOptions<GetClosedOrdersRequest> GetClosedFuturesOrdersOptions { get; }
|
GetClosedOrdersOptions GetClosedFuturesOrdersOptions { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get info on closed futures orders
|
/// Get info on closed futures orders
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request">Request info</param>
|
/// <param name="request">Request info</param>
|
||||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
Task<ExchangeWebResult<SharedFuturesOrder[]>> GetClosedFuturesOrdersAsync(GetClosedOrdersRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default);
|
Task<ExchangeWebResult<SharedFuturesOrder[]>> GetClosedFuturesOrdersAsync(GetClosedOrdersRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Futures get order trades request options
|
/// Futures get order trades request options
|
||||||
@@ -96,14 +96,14 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Futures user trades request options
|
/// Futures user trades request options
|
||||||
/// </summary>
|
/// </summary>
|
||||||
PaginatedEndpointOptions<GetUserTradesRequest> GetFuturesUserTradesOptions { get; }
|
GetUserTradesOptions GetFuturesUserTradesOptions { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get futures user trade records
|
/// Get futures user trade records
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request">Request info</param>
|
/// <param name="request">Request info</param>
|
||||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
Task<ExchangeWebResult<SharedUserTrade[]>> GetFuturesUserTradesAsync(GetUserTradesRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default);
|
Task<ExchangeWebResult<SharedUserTrade[]>> GetFuturesUserTradesAsync(GetUserTradesRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Futures cancel order request options
|
/// Futures cancel order request options
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Get index price kline/candlestick data
|
/// Get index price kline/candlestick data
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request">Request info</param>
|
/// <param name="request">Request info</param>
|
||||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
Task<ExchangeWebResult<SharedFuturesKline[]>> GetIndexPriceKlinesAsync(GetKlinesRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default);
|
Task<ExchangeWebResult<SharedFuturesKline[]>> GetIndexPriceKlinesAsync(GetKlinesRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Get mark price kline/candlestick data
|
/// Get mark price kline/candlestick data
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request">Request info</param>
|
/// <param name="request">Request info</param>
|
||||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
Task<ExchangeWebResult<SharedFuturesKline[]>> GetMarkPriceKlinesAsync(GetKlinesRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default);
|
Task<ExchangeWebResult<SharedFuturesKline[]>> GetMarkPriceKlinesAsync(GetKlinesRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Get position history
|
/// Get position history
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request">Request info</param>
|
/// <param name="request">Request info</param>
|
||||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
Task<ExchangeWebResult<SharedPositionHistory[]>> GetPositionHistoryAsync(GetPositionHistoryRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default);
|
Task<ExchangeWebResult<SharedPositionHistory[]>> GetPositionHistoryAsync(GetPositionHistoryRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Get deposit records
|
/// Get deposit records
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request">Request info</param>
|
/// <param name="request">Request info</param>
|
||||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<ExchangeWebResult<SharedDeposit[]>> GetDepositsAsync(GetDepositsRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default);
|
Task<ExchangeWebResult<SharedDeposit[]>> GetDepositsAsync(GetDepositsRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Get kline/candlestick data
|
/// Get kline/candlestick data
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request">Request info</param>
|
/// <param name="request">Request info</param>
|
||||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<ExchangeWebResult<SharedKline[]>> GetKlinesAsync(GetKlinesRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default);
|
Task<ExchangeWebResult<SharedKline[]>> GetKlinesAsync(GetKlinesRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Get public trade history
|
/// Get public trade history
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request">Request info</param>
|
/// <param name="request">Request info</param>
|
||||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<ExchangeWebResult<SharedTrade[]>> GetTradeHistoryAsync(GetTradeHistoryRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default);
|
Task<ExchangeWebResult<SharedTrade[]>> GetTradeHistoryAsync(GetTradeHistoryRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Get withdrawal records
|
/// Get withdrawal records
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request">Request info</param>
|
/// <param name="request">Request info</param>
|
||||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<ExchangeWebResult<SharedWithdrawal[]>> GetWithdrawalsAsync(GetWithdrawalsRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default);
|
Task<ExchangeWebResult<SharedWithdrawal[]>> GetWithdrawalsAsync(GetWithdrawalsRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,14 +72,14 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Spot get closed orders request options
|
/// Spot get closed orders request options
|
||||||
/// </summary>
|
/// </summary>
|
||||||
PaginatedEndpointOptions<GetClosedOrdersRequest> GetClosedSpotOrdersOptions { get; }
|
GetClosedOrdersOptions GetClosedSpotOrdersOptions { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get info on closed spot orders
|
/// Get info on closed spot orders
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request">Request info</param>
|
/// <param name="request">Request info</param>
|
||||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
Task<ExchangeWebResult<SharedSpotOrder[]>> GetClosedSpotOrdersAsync(GetClosedOrdersRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default);
|
Task<ExchangeWebResult<SharedSpotOrder[]>> GetClosedSpotOrdersAsync(GetClosedOrdersRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Spot get order trades request options
|
/// Spot get order trades request options
|
||||||
@@ -95,14 +95,14 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Spot user trades request options
|
/// Spot user trades request options
|
||||||
/// </summary>
|
/// </summary>
|
||||||
PaginatedEndpointOptions<GetUserTradesRequest> GetSpotUserTradesOptions { get; }
|
GetUserTradesOptions GetSpotUserTradesOptions { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get spot user trade records
|
/// Get spot user trade records
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request">Request info</param>
|
/// <param name="request">Request info</param>
|
||||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
Task<ExchangeWebResult<SharedUserTrade[]>> GetSpotUserTradesAsync(GetUserTradesRequest request, INextPageToken? nextPageToken = null, CancellationToken ct = default);
|
Task<ExchangeWebResult<SharedUserTrade[]>> GetSpotUserTradesAsync(GetUserTradesRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Spot cancel order request options
|
/// Spot cancel order request options
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
public TradingMode[]? DataTradeMode { get; }
|
public TradingMode[]? DataTradeMode { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Token to retrieve the next page with
|
/// Next page request, can be passed to the next request on the same endpoint to get the next page
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public INextPageToken? NextPageToken { get; }
|
public PageRequest? NextPageRequest { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
@@ -46,7 +46,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
string exchange,
|
string exchange,
|
||||||
TradingMode dataTradeMode,
|
TradingMode dataTradeMode,
|
||||||
WebCallResult<T> result,
|
WebCallResult<T> result,
|
||||||
INextPageToken? nextPageToken = null) :
|
PageRequest? nextPageToken = null) :
|
||||||
base(result.ResponseStatusCode,
|
base(result.ResponseStatusCode,
|
||||||
result.HttpVersion,
|
result.HttpVersion,
|
||||||
result.ResponseHeaders,
|
result.ResponseHeaders,
|
||||||
@@ -64,7 +64,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
{
|
{
|
||||||
DataTradeMode = new[] { dataTradeMode };
|
DataTradeMode = new[] { dataTradeMode };
|
||||||
Exchange = exchange;
|
Exchange = exchange;
|
||||||
NextPageToken = nextPageToken;
|
NextPageRequest = nextPageToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -74,7 +74,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
string exchange,
|
string exchange,
|
||||||
TradingMode[]? dataTradeModes,
|
TradingMode[]? dataTradeModes,
|
||||||
WebCallResult<T> result,
|
WebCallResult<T> result,
|
||||||
INextPageToken? nextPageToken = null) :
|
PageRequest? nextPageRequest = null) :
|
||||||
base(result.ResponseStatusCode,
|
base(result.ResponseStatusCode,
|
||||||
result.HttpVersion,
|
result.HttpVersion,
|
||||||
result.ResponseHeaders,
|
result.ResponseHeaders,
|
||||||
@@ -92,7 +92,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
{
|
{
|
||||||
DataTradeMode = dataTradeModes;
|
DataTradeMode = dataTradeModes;
|
||||||
Exchange = exchange;
|
Exchange = exchange;
|
||||||
NextPageToken = nextPageToken;
|
NextPageRequest = nextPageRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -115,7 +115,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
ResultDataSource dataSource,
|
ResultDataSource dataSource,
|
||||||
[AllowNull] T data,
|
[AllowNull] T data,
|
||||||
Error? error,
|
Error? error,
|
||||||
INextPageToken? nextPageToken = null) : base(
|
PageRequest? nextPageToken = null) : base(
|
||||||
code,
|
code,
|
||||||
httpVersion,
|
httpVersion,
|
||||||
responseHeaders,
|
responseHeaders,
|
||||||
@@ -133,7 +133,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
{
|
{
|
||||||
DataTradeMode = dataTradeModes;
|
DataTradeMode = dataTradeModes;
|
||||||
Exchange = exchange;
|
Exchange = exchange;
|
||||||
NextPageToken = nextPageToken;
|
NextPageRequest = nextPageToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -144,7 +144,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public new ExchangeWebResult<K> As<K>([AllowNull] K data)
|
public new ExchangeWebResult<K> As<K>([AllowNull] K data)
|
||||||
{
|
{
|
||||||
return new ExchangeWebResult<K>(Exchange, DataTradeMode, ResponseStatusCode, HttpVersion, ResponseHeaders, ResponseTime, ResponseLength, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, DataSource, data, Error, NextPageToken);
|
return new ExchangeWebResult<K>(Exchange, DataTradeMode, ResponseStatusCode, HttpVersion, ResponseHeaders, ResponseTime, ResponseLength, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, DataSource, data, Error, NextPageRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
namespace CryptoExchange.Net.SharedApis
|
||||||
@@ -8,24 +9,36 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class GetClosedOrdersOptions : PaginatedEndpointOptions<GetClosedOrdersRequest>
|
public class GetClosedOrdersOptions : PaginatedEndpointOptions<GetClosedOrdersRequest>
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Whether the start/end time filter is supported
|
|
||||||
/// </summary>
|
|
||||||
public bool TimeFilterSupported { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GetClosedOrdersOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit) : base(paginationType, timeFilterSupported, maxLimit, true)
|
public GetClosedOrdersOptions(bool supportsAscending, bool supportsDescending, bool timeFilterSupported, int maxLimit)
|
||||||
|
: base(supportsAscending, supportsDescending, timeFilterSupported, maxLimit, true)
|
||||||
{
|
{
|
||||||
TimeFilterSupported = timeFilterSupported;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Error? ValidateRequest(string exchange, GetClosedOrdersRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
public override Error? ValidateRequest(string exchange, GetClosedOrdersRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
||||||
{
|
{
|
||||||
if (!TimeFilterSupported && request.StartTime != null)
|
if (!SupportsAscending && request.Direction == DataDirection.Ascending)
|
||||||
return ArgumentError.Invalid(nameof(GetClosedOrdersRequest.StartTime), $"Time filter is not supported");
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Ascending direction is not supported");
|
||||||
|
|
||||||
|
if (!SupportsDescending && request.Direction == DataDirection.Descending)
|
||||||
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Descending direction is not supported");
|
||||||
|
|
||||||
|
if (MaxAge.HasValue && request.StartTime < DateTime.UtcNow.Add(-MaxAge.Value))
|
||||||
|
return ArgumentError.Invalid(nameof(GetKlinesRequest.StartTime), $"Only the most recent {MaxAge} period data is available");
|
||||||
|
|
||||||
|
if (!TimePeriodFilterSupport)
|
||||||
|
{
|
||||||
|
// When going descending we can still allow startTime filter to limit the results
|
||||||
|
var now = DateTime.UtcNow;
|
||||||
|
if ((request.Direction != DataDirection.Descending && request.StartTime != null)
|
||||||
|
|| (request.EndTime != null && now - request.EndTime > TimeSpan.FromSeconds(5)))
|
||||||
|
{
|
||||||
|
return ArgumentError.Invalid(nameof(GetDepositsRequest.StartTime), $"Time filter is not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes);
|
return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes);
|
||||||
}
|
}
|
||||||
@@ -34,7 +47,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
public override string ToString(string exchange)
|
public override string ToString(string exchange)
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder(base.ToString(exchange));
|
var sb = new StringBuilder(base.ToString(exchange));
|
||||||
sb.AppendLine($"Time filter supported: {TimeFilterSupported}");
|
sb.AppendLine($"Time filter supported: {TimePeriodFilterSupport}");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
namespace CryptoExchange.Net.SharedApis
|
||||||
@@ -8,24 +9,36 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class GetDepositsOptions : PaginatedEndpointOptions<GetDepositsRequest>
|
public class GetDepositsOptions : PaginatedEndpointOptions<GetDepositsRequest>
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Whether the start/end time filter is supported
|
|
||||||
/// </summary>
|
|
||||||
public bool TimeFilterSupported { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GetDepositsOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit) : base(paginationType, timeFilterSupported, maxLimit, true)
|
public GetDepositsOptions(bool supportsAscending, bool supportsDescending, bool timeFilterSupported, int maxLimit)
|
||||||
|
: base(supportsAscending, supportsDescending, timeFilterSupported, maxLimit, true)
|
||||||
{
|
{
|
||||||
TimeFilterSupported = timeFilterSupported;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Error? ValidateRequest(string exchange, GetDepositsRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
public override Error? ValidateRequest(string exchange, GetDepositsRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
||||||
{
|
{
|
||||||
if (!TimeFilterSupported && request.StartTime != null)
|
if (!SupportsAscending && request.Direction == DataDirection.Ascending)
|
||||||
return ArgumentError.Invalid(nameof(GetDepositsRequest.StartTime), $"Time filter is not supported");
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Ascending direction is not supported");
|
||||||
|
|
||||||
|
if (!SupportsDescending && request.Direction == DataDirection.Descending)
|
||||||
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Descending direction is not supported");
|
||||||
|
|
||||||
|
if (MaxAge.HasValue && request.StartTime < DateTime.UtcNow.Add(-MaxAge.Value))
|
||||||
|
return ArgumentError.Invalid(nameof(GetKlinesRequest.StartTime), $"Only the most recent {MaxAge} period data is available");
|
||||||
|
|
||||||
|
if (!TimePeriodFilterSupport)
|
||||||
|
{
|
||||||
|
// When going descending we can still allow startTime filter to limit the results
|
||||||
|
var now = DateTime.UtcNow;
|
||||||
|
if ((request.Direction != DataDirection.Descending && request.StartTime != null)
|
||||||
|
|| (request.EndTime != null && now - request.EndTime > TimeSpan.FromSeconds(5)))
|
||||||
|
{
|
||||||
|
return ArgumentError.Invalid(nameof(GetDepositsRequest.StartTime), $"Time filter is not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes);
|
return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes);
|
||||||
}
|
}
|
||||||
@@ -34,7 +47,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
public override string ToString(string exchange)
|
public override string ToString(string exchange)
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder(base.ToString(exchange));
|
var sb = new StringBuilder(base.ToString(exchange));
|
||||||
sb.AppendLine($"Time filter supported: {TimeFilterSupported}");
|
sb.AppendLine($"Time filter supported: {TimePeriodFilterSupport}");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+41
-2
@@ -1,4 +1,8 @@
|
|||||||
namespace CryptoExchange.Net.SharedApis
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Options for requesting funding rate history
|
/// Options for requesting funding rate history
|
||||||
@@ -8,8 +12,43 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GetFundingRateHistoryOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit, bool needsAuthentication) : base(paginationType, timeFilterSupported, maxLimit, needsAuthentication)
|
public GetFundingRateHistoryOptions(bool supportsAscending, bool supportsDescending, bool timeFilterSupported, int maxLimit, bool needsAuthentication)
|
||||||
|
: base(supportsAscending, supportsDescending, timeFilterSupported, maxLimit, needsAuthentication)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override Error? ValidateRequest(string exchange, GetFundingRateHistoryRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
||||||
|
{
|
||||||
|
if (!SupportsAscending && request.Direction == DataDirection.Ascending)
|
||||||
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Ascending direction is not supported");
|
||||||
|
|
||||||
|
if (!SupportsDescending && request.Direction == DataDirection.Descending)
|
||||||
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Descending direction is not supported");
|
||||||
|
|
||||||
|
if (MaxAge.HasValue && request.StartTime < DateTime.UtcNow.Add(-MaxAge.Value))
|
||||||
|
return ArgumentError.Invalid(nameof(GetKlinesRequest.StartTime), $"Only the most recent {MaxAge} period data is available");
|
||||||
|
|
||||||
|
if (!TimePeriodFilterSupport)
|
||||||
|
{
|
||||||
|
// When going descending we can still allow startTime filter to limit the results
|
||||||
|
var now = DateTime.UtcNow;
|
||||||
|
if ((request.Direction != DataDirection.Descending && request.StartTime != null)
|
||||||
|
|| (request.EndTime != null && now - request.EndTime > TimeSpan.FromSeconds(5)))
|
||||||
|
{
|
||||||
|
return ArgumentError.Invalid(nameof(GetDepositsRequest.StartTime), $"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: {TimePeriodFilterSupport}");
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,15 +18,12 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Max number of data points which can be requested
|
/// Max number of data points which can be requested
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? MaxTotalDataPoints { get; set; }
|
public int? MaxTotalDataPoints { get; set; }
|
||||||
/// <summary>
|
|
||||||
/// The max age of the data that can be requested
|
|
||||||
/// </summary>
|
|
||||||
public TimeSpan? MaxAge { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GetKlinesOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit, bool needsAuthentication) : base(paginationType, timeFilterSupported, maxLimit, needsAuthentication)
|
public GetKlinesOptions(bool supportsAscending, bool supportsDescending, bool timeFilterSupported, int maxLimit, bool needsAuthentication)
|
||||||
|
: base(supportsAscending, supportsDescending, timeFilterSupported, maxLimit, needsAuthentication)
|
||||||
{
|
{
|
||||||
SupportIntervals = new[]
|
SupportIntervals = new[]
|
||||||
{
|
{
|
||||||
@@ -50,7 +47,8 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GetKlinesOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit, bool needsAuthentication, params SharedKlineInterval[] intervals) : base(paginationType, timeFilterSupported, maxLimit, needsAuthentication)
|
public GetKlinesOptions(bool supportsAscending, bool supportsDescending, bool timeFilterSupported, int maxLimit, bool needsAuthentication, params SharedKlineInterval[] intervals)
|
||||||
|
: base(supportsAscending, supportsDescending, timeFilterSupported, maxLimit, needsAuthentication)
|
||||||
{
|
{
|
||||||
SupportIntervals = intervals;
|
SupportIntervals = intervals;
|
||||||
}
|
}
|
||||||
@@ -68,12 +66,29 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
if (!IsSupported(request.Interval))
|
if (!IsSupported(request.Interval))
|
||||||
return ArgumentError.Invalid(nameof(GetKlinesRequest.Interval), "Interval not supported");
|
return ArgumentError.Invalid(nameof(GetKlinesRequest.Interval), "Interval not supported");
|
||||||
|
|
||||||
|
if (!SupportsAscending && request.Direction == DataDirection.Ascending)
|
||||||
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Ascending direction is not supported");
|
||||||
|
|
||||||
|
if (!SupportsDescending && request.Direction == DataDirection.Descending)
|
||||||
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Descending direction is not supported");
|
||||||
|
|
||||||
if (MaxAge.HasValue && request.StartTime < DateTime.UtcNow.Add(-MaxAge.Value))
|
if (MaxAge.HasValue && request.StartTime < DateTime.UtcNow.Add(-MaxAge.Value))
|
||||||
return ArgumentError.Invalid(nameof(GetKlinesRequest.StartTime), $"Only the most recent {MaxAge} klines are available");
|
return ArgumentError.Invalid(nameof(GetKlinesRequest.StartTime), $"Only the most recent {MaxAge} klines are available");
|
||||||
|
|
||||||
if (request.Limit > MaxLimit)
|
if (request.Limit > MaxLimit)
|
||||||
return ArgumentError.Invalid(nameof(GetKlinesRequest.Limit), $"Only {MaxLimit} klines can be retrieved per request");
|
return ArgumentError.Invalid(nameof(GetKlinesRequest.Limit), $"Only {MaxLimit} klines can be retrieved per request");
|
||||||
|
|
||||||
|
if (!TimePeriodFilterSupport)
|
||||||
|
{
|
||||||
|
// When going descending we can still allow startTime filter to limit the results
|
||||||
|
var now = DateTime.UtcNow;
|
||||||
|
if ((request.Direction == DataDirection.Ascending && request.StartTime != null)
|
||||||
|
|| (request.EndTime != null && now - request.EndTime > TimeSpan.FromSeconds(5)))
|
||||||
|
{
|
||||||
|
return ArgumentError.Invalid(nameof(GetDepositsRequest.StartTime), $"Time filter is not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (MaxTotalDataPoints.HasValue)
|
if (MaxTotalDataPoints.HasValue)
|
||||||
{
|
{
|
||||||
if (request.Limit > MaxTotalDataPoints.Value)
|
if (request.Limit > MaxTotalDataPoints.Value)
|
||||||
@@ -93,6 +108,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
public override string ToString(string exchange)
|
public override string ToString(string exchange)
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder(base.ToString(exchange));
|
var sb = new StringBuilder(base.ToString(exchange));
|
||||||
|
sb.AppendLine($"Time filter supported: {TimePeriodFilterSupport}");
|
||||||
sb.AppendLine($"Supported SharedKlineInterval values: {string.Join(", ", SupportIntervals)}");
|
sb.AppendLine($"Supported SharedKlineInterval values: {string.Join(", ", SupportIntervals)}");
|
||||||
if (MaxAge != null)
|
if (MaxAge != null)
|
||||||
sb.AppendLine($"Max age of data: {MaxAge}");
|
sb.AppendLine($"Max age of data: {MaxAge}");
|
||||||
|
|||||||
+41
-2
@@ -1,4 +1,8 @@
|
|||||||
namespace CryptoExchange.Net.SharedApis
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Options for requesting position history
|
/// Options for requesting position history
|
||||||
@@ -8,8 +12,43 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GetPositionHistoryOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit) : base(paginationType, timeFilterSupported, maxLimit, true)
|
public GetPositionHistoryOptions(bool supportsAscending, bool supportsDescending, bool timeFilterSupported, int maxLimit)
|
||||||
|
: base(supportsAscending, supportsDescending, timeFilterSupported, maxLimit, true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override Error? ValidateRequest(string exchange, GetPositionHistoryRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
||||||
|
{
|
||||||
|
if (!SupportsAscending && request.Direction == DataDirection.Ascending)
|
||||||
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Ascending direction is not supported");
|
||||||
|
|
||||||
|
if (!SupportsDescending && request.Direction == DataDirection.Descending)
|
||||||
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Descending direction is not supported");
|
||||||
|
|
||||||
|
if (MaxAge.HasValue && request.StartTime < DateTime.UtcNow.Add(-MaxAge.Value))
|
||||||
|
return ArgumentError.Invalid(nameof(GetKlinesRequest.StartTime), $"Only the most recent {MaxAge} period data is available");
|
||||||
|
|
||||||
|
if (!TimePeriodFilterSupport)
|
||||||
|
{
|
||||||
|
// When going descending we can still allow startTime filter to limit the results
|
||||||
|
var now = DateTime.UtcNow;
|
||||||
|
if ((request.Direction != DataDirection.Descending && request.StartTime != null)
|
||||||
|
|| (request.EndTime != null && now - request.EndTime > TimeSpan.FromSeconds(5)))
|
||||||
|
{
|
||||||
|
return ArgumentError.Invalid(nameof(GetDepositsRequest.StartTime), $"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: {TimePeriodFilterSupport}");
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,34 +9,27 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class GetTradeHistoryOptions : PaginatedEndpointOptions<GetTradeHistoryRequest>
|
public class GetTradeHistoryOptions : PaginatedEndpointOptions<GetTradeHistoryRequest>
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The max age of data that can be requested
|
|
||||||
/// </summary>
|
|
||||||
public TimeSpan? MaxAge { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GetTradeHistoryOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit, bool needsAuthentication) : base(paginationType, timeFilterSupported, maxLimit, needsAuthentication)
|
public GetTradeHistoryOptions(bool supportsAscending, bool supportsDescending, bool timeFilterSupported, int maxLimit, bool needsAuthentication)
|
||||||
|
: base(supportsAscending, supportsDescending, timeFilterSupported, maxLimit, needsAuthentication)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Error? ValidateRequest(string exchange, GetTradeHistoryRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
public override Error? ValidateRequest(string exchange, GetTradeHistoryRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
||||||
{
|
{
|
||||||
|
if (!SupportsAscending && request.Direction == DataDirection.Ascending)
|
||||||
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Ascending direction is not supported");
|
||||||
|
|
||||||
|
if (!SupportsDescending && request.Direction == DataDirection.Descending)
|
||||||
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Descending direction is not supported");
|
||||||
|
|
||||||
if (MaxAge.HasValue && request.StartTime < DateTime.UtcNow.Add(-MaxAge.Value))
|
if (MaxAge.HasValue && request.StartTime < DateTime.UtcNow.Add(-MaxAge.Value))
|
||||||
return ArgumentError.Invalid(nameof(GetTradeHistoryRequest.StartTime), $"Only the most recent {MaxAge} trades are available");
|
return ArgumentError.Invalid(nameof(GetKlinesRequest.StartTime), $"Only the most recent {MaxAge} period data is available");
|
||||||
|
|
||||||
return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes);
|
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,54 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Options for requesting user trades
|
||||||
|
/// </summary>
|
||||||
|
public class GetUserTradesOptions : PaginatedEndpointOptions<GetUserTradesRequest>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// ctor
|
||||||
|
/// </summary>
|
||||||
|
public GetUserTradesOptions(bool supportsAscending, bool supportsDescending, bool timeFilterSupported, int maxLimit)
|
||||||
|
: base(supportsAscending, supportsDescending, timeFilterSupported, maxLimit, true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override Error? ValidateRequest(string exchange, GetUserTradesRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
||||||
|
{
|
||||||
|
if (!SupportsAscending && request.Direction == DataDirection.Ascending)
|
||||||
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Ascending direction is not supported");
|
||||||
|
|
||||||
|
if (!SupportsDescending && request.Direction == DataDirection.Descending)
|
||||||
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Descending direction is not supported");
|
||||||
|
|
||||||
|
if (MaxAge.HasValue && request.StartTime < DateTime.UtcNow.Add(-MaxAge.Value))
|
||||||
|
return ArgumentError.Invalid(nameof(GetKlinesRequest.StartTime), $"Only the most recent {MaxAge} period data is available");
|
||||||
|
|
||||||
|
if (!TimePeriodFilterSupport)
|
||||||
|
{
|
||||||
|
// When going descending we can still allow startTime filter to limit the results
|
||||||
|
var now = DateTime.UtcNow;
|
||||||
|
if ((request.Direction != DataDirection.Descending && request.StartTime != null)
|
||||||
|
|| (request.EndTime != null && now - request.EndTime > TimeSpan.FromSeconds(5)))
|
||||||
|
{
|
||||||
|
return ArgumentError.Invalid(nameof(GetDepositsRequest.StartTime), $"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: {TimePeriodFilterSupport}");
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
namespace CryptoExchange.Net.SharedApis
|
||||||
@@ -8,24 +9,36 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class GetWithdrawalsOptions : PaginatedEndpointOptions<GetWithdrawalsRequest>
|
public class GetWithdrawalsOptions : PaginatedEndpointOptions<GetWithdrawalsRequest>
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Whether the start/end time filter is supported
|
|
||||||
/// </summary>
|
|
||||||
public bool TimeFilterSupported { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GetWithdrawalsOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit) : base(paginationType, timeFilterSupported, maxLimit, true)
|
public GetWithdrawalsOptions(bool supportsAscending, bool supportsDescending, bool timeFilterSupported, int maxLimit)
|
||||||
|
: base(supportsAscending, supportsDescending, timeFilterSupported, maxLimit, true)
|
||||||
{
|
{
|
||||||
TimeFilterSupported = timeFilterSupported;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Error? ValidateRequest(string exchange, GetWithdrawalsRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
public override Error? ValidateRequest(string exchange, GetWithdrawalsRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
||||||
{
|
{
|
||||||
if (!TimeFilterSupported && request.StartTime != null)
|
if (!SupportsAscending && request.Direction == DataDirection.Ascending)
|
||||||
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.StartTime), $"Time filter is not supported");
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Ascending direction is not supported");
|
||||||
|
|
||||||
|
if (!SupportsDescending && request.Direction == DataDirection.Descending)
|
||||||
|
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.Direction), $"Descending direction is not supported");
|
||||||
|
|
||||||
|
if (MaxAge.HasValue && request.StartTime < DateTime.UtcNow.Add(-MaxAge.Value))
|
||||||
|
return ArgumentError.Invalid(nameof(GetKlinesRequest.StartTime), $"Only the most recent {MaxAge} period data is available");
|
||||||
|
|
||||||
|
if (!TimePeriodFilterSupport)
|
||||||
|
{
|
||||||
|
// When going descending we can still allow startTime filter to limit the results
|
||||||
|
var now = DateTime.UtcNow;
|
||||||
|
if ((request.Direction != DataDirection.Descending && request.StartTime != null)
|
||||||
|
|| (request.EndTime != null && now - request.EndTime > TimeSpan.FromSeconds(5)))
|
||||||
|
{
|
||||||
|
return ArgumentError.Invalid(nameof(GetDepositsRequest.StartTime), $"Time filter is not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes);
|
return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes);
|
||||||
}
|
}
|
||||||
@@ -34,7 +47,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
public override string ToString(string exchange)
|
public override string ToString(string exchange)
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder(base.ToString(exchange));
|
var sb = new StringBuilder(base.ToString(exchange));
|
||||||
sb.AppendLine($"Time filter supported: {TimeFilterSupported}");
|
sb.AppendLine($"Time filter supported: {TimePeriodFilterSupport}");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
namespace CryptoExchange.Net.SharedApis
|
||||||
@@ -14,9 +15,13 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Type of pagination supported
|
/// Whether ascending data retrieval and pagination is available
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SharedPaginationSupport PaginationSupport { get; }
|
public bool SupportsAscending { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Whether ascending data retrieval and pagination is available
|
||||||
|
/// </summary>
|
||||||
|
public bool SupportsDescending { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether filtering based on start/end time is supported
|
/// Whether filtering based on start/end time is supported
|
||||||
@@ -28,12 +33,23 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int MaxLimit { get; set; }
|
public int MaxLimit { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Max age of data that can be requested
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan? MaxAge { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PaginatedEndpointOptions(SharedPaginationSupport paginationType, bool timePeriodSupport, int maxLimit, bool needsAuthentication) : base(needsAuthentication)
|
public PaginatedEndpointOptions(
|
||||||
|
bool supportsAscending,
|
||||||
|
bool supportsDescending,
|
||||||
|
bool timePeriodSupport,
|
||||||
|
int maxLimit,
|
||||||
|
bool needsAuthentication) : base(needsAuthentication)
|
||||||
{
|
{
|
||||||
PaginationSupport = paginationType;
|
SupportsAscending = supportsAscending;
|
||||||
|
SupportsDescending = supportsDescending;
|
||||||
TimePeriodFilterSupport = timePeriodSupport;
|
TimePeriodFilterSupport = timePeriodSupport;
|
||||||
MaxLimit = maxLimit;
|
MaxLimit = maxLimit;
|
||||||
}
|
}
|
||||||
@@ -42,9 +58,11 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
public override string ToString(string exchange)
|
public override string ToString(string exchange)
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder(base.ToString(exchange));
|
var sb = new StringBuilder(base.ToString(exchange));
|
||||||
sb.AppendLine($"Pagination type: {PaginationSupport}");
|
sb.AppendLine($"Ascending retrieval supported: {SupportsAscending}");
|
||||||
|
sb.AppendLine($"Descending retrieval supported: {SupportsDescending}");
|
||||||
sb.AppendLine($"Time period filter support: {TimePeriodFilterSupport}");
|
sb.AppendLine($"Time period filter support: {TimePeriodFilterSupport}");
|
||||||
sb.AppendLine($"Max limit: {MaxLimit}");
|
sb.AppendLine($"Max limit: {MaxLimit}");
|
||||||
|
sb.AppendLine($"Max age: {MaxAge}");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Data direction
|
||||||
|
/// </summary>
|
||||||
|
public enum DataDirection
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Old to new order
|
||||||
|
/// </summary>
|
||||||
|
Ascending,
|
||||||
|
/// <summary>
|
||||||
|
/// New to old order
|
||||||
|
/// </summary>
|
||||||
|
Descending
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Next page request info
|
||||||
|
/// </summary>
|
||||||
|
public class PageRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Pagination cursor
|
||||||
|
/// </summary>
|
||||||
|
public string? Cursor { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Page number
|
||||||
|
/// </summary>
|
||||||
|
public int? Page { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Result offset
|
||||||
|
/// </summary>
|
||||||
|
public int? Offset { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// From id filter
|
||||||
|
/// </summary>
|
||||||
|
public string? FromId { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Start time filter
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? StartTime { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// End time filter
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? EndTime { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,405 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Pagination methods
|
||||||
|
/// </summary>
|
||||||
|
public static class Pagination
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Get pagination parameters
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="direction">The data direction</param>
|
||||||
|
/// <param name="limit">Result limit</param>
|
||||||
|
/// <param name="requestStartTime">User request start time</param>
|
||||||
|
/// <param name="requestEndTime">User request end time</param>
|
||||||
|
/// <param name="paginationRequest">Provided page request</param>
|
||||||
|
/// <param name="setOtherTimeLimiter">Whether to set start time if direction is descending, or end time if direction is ascending</param>
|
||||||
|
/// <param name="maxPeriod">Max period the time filters can span</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static PaginationParameters GetPaginationParameters(
|
||||||
|
DataDirection direction,
|
||||||
|
int limit,
|
||||||
|
DateTime? requestStartTime,
|
||||||
|
DateTime requestEndTime,
|
||||||
|
PageRequest? paginationRequest,
|
||||||
|
bool setOtherTimeLimiter = true,
|
||||||
|
TimeSpan? maxPeriod = null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var startTime = paginationRequest?.StartTime ?? requestStartTime;
|
||||||
|
var endTime = paginationRequest?.EndTime ?? requestEndTime;
|
||||||
|
if (maxPeriod != null)
|
||||||
|
{
|
||||||
|
if (direction == DataDirection.Ascending)
|
||||||
|
{
|
||||||
|
if (startTime == null)
|
||||||
|
{
|
||||||
|
startTime = endTime.Add(-maxPeriod.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
endTime = startTime.Value.Add(maxPeriod.Value);
|
||||||
|
if (endTime > DateTime.UtcNow)
|
||||||
|
endTime = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startTime = endTime.Add(-maxPeriod.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PaginationParameters
|
||||||
|
{
|
||||||
|
Limit = limit,
|
||||||
|
StartTime = direction == DataDirection.Ascending || setOtherTimeLimiter ? startTime : null,
|
||||||
|
EndTime = direction == DataDirection.Descending || setOtherTimeLimiter ? endTime : null,
|
||||||
|
Direction = direction,
|
||||||
|
FromId = paginationRequest?.FromId,
|
||||||
|
Offset = paginationRequest?.Offset,
|
||||||
|
Page = paginationRequest?.Page,
|
||||||
|
Cursor = paginationRequest?.Cursor
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the next page request parameters from result kline data
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nextPageRequest">Callback for returning the next page request</param>
|
||||||
|
/// <param name="resultCount">Number of results in data</param>
|
||||||
|
/// <param name="timestamps">Timestamps of the result data</param>
|
||||||
|
/// <param name="requestStartTime">User request start time</param>
|
||||||
|
/// <param name="requestEndTime">User request end time</param>
|
||||||
|
/// <param name="lastPaginationData">The last used pagination data</param>
|
||||||
|
/// <param name="interval">Kline interval</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static PageRequest? GetNextPageRequestKlines(
|
||||||
|
Func<PageRequest?> nextPageRequest,
|
||||||
|
int resultCount,
|
||||||
|
IEnumerable<DateTime> timestamps,
|
||||||
|
DateTime? requestStartTime,
|
||||||
|
DateTime requestEndTime,
|
||||||
|
PaginationParameters lastPaginationData,
|
||||||
|
SharedKlineInterval interval
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (HasNextPageKlines(resultCount, timestamps, requestStartTime, requestEndTime, lastPaginationData.Limit, lastPaginationData.Direction, interval))
|
||||||
|
{
|
||||||
|
var result = nextPageRequest();
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
result.StartTime ??= lastPaginationData.StartTime;
|
||||||
|
result.EndTime ??= lastPaginationData.EndTime;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the next page request parameters from result data
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nextPageRequest">Callback for returning the next page request</param>
|
||||||
|
/// <param name="resultCount">Number of results in data</param>
|
||||||
|
/// <param name="timestamps">Timestamps of the result data</param>
|
||||||
|
/// <param name="requestStartTime">User request start time</param>
|
||||||
|
/// <param name="requestEndTime">User request end time</param>
|
||||||
|
/// <param name="lastPaginationData">The last used pagination data</param>
|
||||||
|
/// <param name="maxPeriod">Max period the time filters can span</param>
|
||||||
|
/// <param name="maxAge">Max age of the data</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static PageRequest? GetNextPageRequest(
|
||||||
|
Func<PageRequest?> nextPageRequest,
|
||||||
|
int resultCount,
|
||||||
|
IEnumerable<DateTime> timestamps,
|
||||||
|
DateTime? requestStartTime,
|
||||||
|
DateTime requestEndTime,
|
||||||
|
PaginationParameters lastPaginationData,
|
||||||
|
TimeSpan? maxPeriod = null,
|
||||||
|
TimeSpan? maxAge = null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (HasNextPage(resultCount, timestamps, requestStartTime, requestEndTime, lastPaginationData.Limit, lastPaginationData.Direction))
|
||||||
|
{
|
||||||
|
var result = nextPageRequest();
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
result.StartTime ??= lastPaginationData.StartTime;
|
||||||
|
result.EndTime ??= lastPaginationData.EndTime;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxPeriod != null)
|
||||||
|
{
|
||||||
|
if (HasNextPeriod(requestStartTime, requestEndTime, lastPaginationData.Direction, lastPaginationData, maxPeriod.Value, maxAge))
|
||||||
|
{
|
||||||
|
var (startTime, endTime) = GetNextPeriod(requestStartTime, requestEndTime, lastPaginationData.Direction, lastPaginationData, maxPeriod.Value, maxAge);
|
||||||
|
return new PageRequest
|
||||||
|
{
|
||||||
|
StartTime = startTime,
|
||||||
|
EndTime = endTime
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether there is (potentially) another page available
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="resultCount">Number of result entries</param>
|
||||||
|
/// <param name="timestamps">Timestamps</param>
|
||||||
|
/// <param name="requestStartTime">User request start time</param>
|
||||||
|
/// <param name="requestEndTime">User request end time</param>
|
||||||
|
/// <param name="limit">Max number of results requested</param>
|
||||||
|
/// <param name="direction">Data direction</param>
|
||||||
|
/// <param name="interval">Kline interval</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool HasNextPageKlines(
|
||||||
|
int resultCount,
|
||||||
|
IEnumerable<DateTime> timestamps,
|
||||||
|
DateTime? requestStartTime,
|
||||||
|
DateTime requestEndTime,
|
||||||
|
int limit,
|
||||||
|
DataDirection direction,
|
||||||
|
SharedKlineInterval interval
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (resultCount < limit)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (direction == DataDirection.Ascending)
|
||||||
|
{
|
||||||
|
if (timestamps.Max().AddSeconds((int)interval) >= requestEndTime)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (timestamps.Min().AddSeconds((int)interval) < requestStartTime)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether there is (potentially) another page available
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="resultCount">Number of result entries</param>
|
||||||
|
/// <param name="timestamps">Timestamps</param>
|
||||||
|
/// <param name="requestStartTime">User request start time</param>
|
||||||
|
/// <param name="requestEndTime">User request end time</param>
|
||||||
|
/// <param name="limit">Max number of results requested</param>
|
||||||
|
/// <param name="direction">Data direction</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool HasNextPage(
|
||||||
|
int resultCount,
|
||||||
|
IEnumerable<DateTime> timestamps,
|
||||||
|
DateTime? requestStartTime,
|
||||||
|
DateTime requestEndTime,
|
||||||
|
int limit,
|
||||||
|
DataDirection direction)
|
||||||
|
{
|
||||||
|
if (resultCount < limit)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!timestamps.Any())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (direction == DataDirection.Ascending)
|
||||||
|
{
|
||||||
|
if (timestamps.Max() >= requestEndTime)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (timestamps.Min() < requestStartTime)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the next page PageRequest
|
||||||
|
/// </summary>
|
||||||
|
public static PageRequest NextPageFromPage(PaginationParameters lastPaginationData)
|
||||||
|
{
|
||||||
|
return new PageRequest { Page = (lastPaginationData.Page ?? 1) + 1 };
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Get the next offset PageRequest
|
||||||
|
/// </summary>
|
||||||
|
public static PageRequest NextPageFromOffset(PaginationParameters lastPaginationData, int resultCount)
|
||||||
|
{
|
||||||
|
return new PageRequest { Offset = (lastPaginationData.Offset ?? 0) + resultCount };
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Get the next page cursor PageRequest
|
||||||
|
/// </summary>
|
||||||
|
public static PageRequest NextPageFromCursor(string nextCursor)
|
||||||
|
{
|
||||||
|
return new PageRequest { Cursor = nextCursor };
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Get the next id PageRequest
|
||||||
|
/// </summary>
|
||||||
|
public static PageRequest NextPageFromId(long nextFromId)
|
||||||
|
{
|
||||||
|
return new PageRequest { FromId = nextFromId.ToString() };
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Get the next id PageRequest
|
||||||
|
/// </summary>
|
||||||
|
public static PageRequest NextPageFromId(string nextFromId)
|
||||||
|
{
|
||||||
|
return new PageRequest { FromId = nextFromId };
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Get the next start/end time PageRequest
|
||||||
|
/// </summary>
|
||||||
|
public static PageRequest NextPageFromTime(PaginationParameters lastPaginationData, DateTime lastTimestamp, bool setOtherTimeLimiter = true)
|
||||||
|
{
|
||||||
|
if (lastPaginationData.Direction == DataDirection.Ascending)
|
||||||
|
return new PageRequest { StartTime = lastTimestamp.AddMilliseconds(1), EndTime = setOtherTimeLimiter ? lastPaginationData.EndTime : null };
|
||||||
|
else
|
||||||
|
return new PageRequest { EndTime = lastTimestamp.AddMilliseconds(-1), StartTime = setOtherTimeLimiter ? lastPaginationData.StartTime : null };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the next start/end time klines PageRequest
|
||||||
|
/// </summary>
|
||||||
|
public static PageRequest NextPageFromTimeKlines(DataDirection direction, GetKlinesRequest request, DateTime lastTimestamp, int limit)
|
||||||
|
{
|
||||||
|
if (direction == DataDirection.Ascending)
|
||||||
|
{
|
||||||
|
var nextStartTime = lastTimestamp.AddSeconds((int)request.Interval);
|
||||||
|
var endTime = nextStartTime.AddSeconds(limit * (int)request.Interval);
|
||||||
|
var requestEndTime = request.EndTime ?? DateTime.UtcNow;
|
||||||
|
if (endTime > requestEndTime)
|
||||||
|
endTime = requestEndTime;
|
||||||
|
|
||||||
|
return new PageRequest { StartTime = nextStartTime, EndTime = endTime };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var nextEndTime = lastTimestamp.AddSeconds(-(int)request.Interval);
|
||||||
|
var startTime = nextEndTime.AddSeconds(-(limit * (int)request.Interval));
|
||||||
|
var requestStartTime = request.StartTime ?? DateTime.UtcNow;
|
||||||
|
if (startTime < requestStartTime)
|
||||||
|
startTime = requestStartTime;
|
||||||
|
return new PageRequest { StartTime = startTime, EndTime = nextEndTime };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether another time period is to be requested
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="requestStartTime">User request start time</param>
|
||||||
|
/// <param name="requestEndTime">User request end time</param>
|
||||||
|
/// <param name="direction">Data direction</param>
|
||||||
|
/// <param name="lastPaginationParameters">Pagination parameters used</param>
|
||||||
|
/// <param name="period">Max time period a request can span</param>
|
||||||
|
/// <param name="maxAge">Max age of data that can be requested</param>
|
||||||
|
public static bool HasNextPeriod(
|
||||||
|
DateTime? requestStartTime,
|
||||||
|
DateTime requestEndTime,
|
||||||
|
DataDirection direction,
|
||||||
|
PaginationParameters lastPaginationParameters,
|
||||||
|
TimeSpan period,
|
||||||
|
TimeSpan? maxAge)
|
||||||
|
{
|
||||||
|
if (direction == DataDirection.Ascending && lastPaginationParameters.StartTime == null)
|
||||||
|
throw new InvalidOperationException("Invalid pagination data; no start time for ascending pagination");
|
||||||
|
|
||||||
|
if (direction == DataDirection.Ascending)
|
||||||
|
{
|
||||||
|
return (requestEndTime - lastPaginationParameters.EndTime!.Value).TotalSeconds > 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var lastPageStartTime = lastPaginationParameters.StartTime ?? lastPaginationParameters.EndTime!.Value.Add(-period);
|
||||||
|
if (requestStartTime != null)
|
||||||
|
{
|
||||||
|
var nextPeriodDuration = lastPageStartTime - requestStartTime.Value;
|
||||||
|
return nextPeriodDuration.TotalSeconds > 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var nextStartTime = lastPageStartTime - period;
|
||||||
|
if (maxAge != null)
|
||||||
|
{
|
||||||
|
var minStartTime = DateTime.UtcNow - maxAge.Value;
|
||||||
|
if ((nextStartTime.Add(period) - minStartTime).TotalSeconds < 1)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nextPeriodDuration = lastPageStartTime - nextStartTime;
|
||||||
|
return (nextPeriodDuration).TotalSeconds > 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the start/end time for the next data period
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="requestStartTime">User request start time</param>
|
||||||
|
/// <param name="requestEndTime">User request end time</param>
|
||||||
|
/// <param name="direction">Data direction</param>
|
||||||
|
/// <param name="lastPaginationParameters">Pagination parameters used</param>
|
||||||
|
/// <param name="period">Max time period a request can span</param>
|
||||||
|
/// <param name="maxAge">Max age of data that can be requested</param>
|
||||||
|
public static (DateTime? startTime, DateTime? endTime) GetNextPeriod(
|
||||||
|
DateTime? requestStartTime,
|
||||||
|
DateTime requestEndTime,
|
||||||
|
DataDirection direction,
|
||||||
|
PaginationParameters lastPaginationParameters,
|
||||||
|
TimeSpan period,
|
||||||
|
TimeSpan? maxAge
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DateTime? nextStartTime = null;
|
||||||
|
DateTime? nextEndTime = null;
|
||||||
|
if (direction == DataDirection.Ascending)
|
||||||
|
{
|
||||||
|
if (lastPaginationParameters.StartTime != null)
|
||||||
|
nextStartTime = lastPaginationParameters.StartTime.Value.Add(period);
|
||||||
|
if (lastPaginationParameters.EndTime != null)
|
||||||
|
nextEndTime = lastPaginationParameters.EndTime.Value.Add(period);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (lastPaginationParameters.StartTime != null)
|
||||||
|
nextStartTime = lastPaginationParameters.StartTime.Value.Add(-period);
|
||||||
|
if (lastPaginationParameters.EndTime != null)
|
||||||
|
nextEndTime = lastPaginationParameters.EndTime.Value.Add(-period);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextStartTime != null && nextStartTime < requestStartTime)
|
||||||
|
nextStartTime = requestStartTime;
|
||||||
|
|
||||||
|
if (nextStartTime != null && maxAge != null && nextStartTime < DateTime.UtcNow - maxAge)
|
||||||
|
{
|
||||||
|
nextStartTime = DateTime.UtcNow.Add(-maxAge.Value);
|
||||||
|
// Add 30 seconds to max sure the client/server time offset and latency doesn't push the timestamp over the limit
|
||||||
|
nextStartTime = nextStartTime.Value.Add(TimeSpan.FromSeconds(30));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextEndTime != null && nextEndTime > requestEndTime)
|
||||||
|
nextEndTime = requestEndTime;
|
||||||
|
|
||||||
|
return (nextStartTime, nextEndTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Pagination parameters
|
||||||
|
/// </summary>
|
||||||
|
public record PaginationParameters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Data direction
|
||||||
|
/// </summary>
|
||||||
|
public DataDirection Direction { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Start time filter
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? StartTime { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// End time filter
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? EndTime { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Id filter
|
||||||
|
/// </summary>
|
||||||
|
public string? FromId { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Result offset
|
||||||
|
/// </summary>
|
||||||
|
public int? Offset { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Page number
|
||||||
|
/// </summary>
|
||||||
|
public int? Page { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Pagination cursor
|
||||||
|
/// </summary>
|
||||||
|
public string? Cursor { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Max number of results
|
||||||
|
/// </summary>
|
||||||
|
public int Limit { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,10 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Max number of results
|
/// Max number of results
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? Limit { get; }
|
public int? Limit { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Data direction
|
||||||
|
/// </summary>
|
||||||
|
public DataDirection? Direction { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
@@ -27,12 +31,14 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <param name="startTime">Filter by start time</param>
|
/// <param name="startTime">Filter by start time</param>
|
||||||
/// <param name="endTime">Filter by end time</param>
|
/// <param name="endTime">Filter by end time</param>
|
||||||
/// <param name="limit">Max number of results</param>
|
/// <param name="limit">Max number of results</param>
|
||||||
|
/// <param name="direction">Data direction</param>
|
||||||
/// <param name="exchangeParameters">Exchange specific parameters</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)
|
public GetClosedOrdersRequest(SharedSymbol symbol, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, DataDirection? direction = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
|
||||||
{
|
{
|
||||||
StartTime = startTime;
|
StartTime = startTime;
|
||||||
EndTime = endTime;
|
EndTime = endTime;
|
||||||
Limit = limit;
|
Limit = limit;
|
||||||
|
Direction = direction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Max number of results
|
/// Max number of results
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? Limit { get; }
|
public int? Limit { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Data direction
|
||||||
|
/// </summary>
|
||||||
|
public DataDirection? Direction { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
@@ -31,13 +35,15 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <param name="startTime">Filter by start time</param>
|
/// <param name="startTime">Filter by start time</param>
|
||||||
/// <param name="endTime">Filter by end time</param>
|
/// <param name="endTime">Filter by end time</param>
|
||||||
/// <param name="limit">Max number of results</param>
|
/// <param name="limit">Max number of results</param>
|
||||||
|
/// <param name="direction">Data direction</param>
|
||||||
/// <param name="exchangeParameters">Exchange specific parameters</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)
|
public GetDepositsRequest(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, DataDirection? direction = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
|
||||||
{
|
{
|
||||||
Asset = asset;
|
Asset = asset;
|
||||||
StartTime = startTime;
|
StartTime = startTime;
|
||||||
EndTime = endTime;
|
EndTime = endTime;
|
||||||
Limit = limit;
|
Limit = limit;
|
||||||
|
Direction = direction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Max number of results
|
/// Max number of results
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? Limit { get; set; }
|
public int? Limit { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Data direction
|
||||||
|
/// </summary>
|
||||||
|
public DataDirection? Direction { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
@@ -27,12 +31,14 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <param name="startTime">Filter by start time</param>
|
/// <param name="startTime">Filter by start time</param>
|
||||||
/// <param name="endTime">Filter by end time</param>
|
/// <param name="endTime">Filter by end time</param>
|
||||||
/// <param name="limit">Max number of results</param>
|
/// <param name="limit">Max number of results</param>
|
||||||
|
/// <param name="direction">Data direction</param>
|
||||||
/// <param name="exchangeParameters">Exchange specific parameters</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)
|
public GetFundingRateHistoryRequest(SharedSymbol symbol, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, DataDirection? direction = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
|
||||||
{
|
{
|
||||||
StartTime = startTime;
|
StartTime = startTime;
|
||||||
EndTime = endTime;
|
EndTime = endTime;
|
||||||
Limit = limit;
|
Limit = limit;
|
||||||
|
Direction = direction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Max number of results
|
/// Max number of results
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? Limit { get; set; }
|
public int? Limit { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Data direction
|
||||||
|
/// </summary>
|
||||||
|
public DataDirection? Direction { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
@@ -32,13 +36,15 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <param name="startTime">Filter by start time</param>
|
/// <param name="startTime">Filter by start time</param>
|
||||||
/// <param name="endTime">Filter by end time</param>
|
/// <param name="endTime">Filter by end time</param>
|
||||||
/// <param name="limit">Max number of results</param>
|
/// <param name="limit">Max number of results</param>
|
||||||
|
/// <param name="direction">Data direction</param>
|
||||||
/// <param name="exchangeParameters">Exchange specific parameters</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)
|
public GetKlinesRequest(SharedSymbol symbol, SharedKlineInterval interval, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, DataDirection? direction = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
|
||||||
{
|
{
|
||||||
Interval = interval;
|
Interval = interval;
|
||||||
StartTime = startTime;
|
StartTime = startTime;
|
||||||
EndTime = endTime;
|
EndTime = endTime;
|
||||||
Limit = limit;
|
Limit = limit;
|
||||||
|
Direction = direction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Max number of results
|
/// Max number of results
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? Limit { get; set; }
|
public int? Limit { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Data direction
|
||||||
|
/// </summary>
|
||||||
|
public DataDirection? Direction { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
@@ -35,13 +39,15 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <param name="startTime">Filter by start time</param>
|
/// <param name="startTime">Filter by start time</param>
|
||||||
/// <param name="endTime">Filter by end time</param>
|
/// <param name="endTime">Filter by end time</param>
|
||||||
/// <param name="limit">Max number of results</param>
|
/// <param name="limit">Max number of results</param>
|
||||||
|
/// <param name="direction">Data direction</param>
|
||||||
/// <param name="exchangeParameters">Exchange specific parameters</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)
|
public GetPositionHistoryRequest(SharedSymbol symbol, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, DataDirection? direction = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
|
||||||
{
|
{
|
||||||
Symbol = symbol;
|
Symbol = symbol;
|
||||||
StartTime = startTime;
|
StartTime = startTime;
|
||||||
EndTime = endTime;
|
EndTime = endTime;
|
||||||
Limit = limit;
|
Limit = limit;
|
||||||
|
Direction = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -51,13 +57,15 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <param name="startTime">Filter by start time</param>
|
/// <param name="startTime">Filter by start time</param>
|
||||||
/// <param name="endTime">Filter by end time</param>
|
/// <param name="endTime">Filter by end time</param>
|
||||||
/// <param name="limit">Max number of results</param>
|
/// <param name="limit">Max number of results</param>
|
||||||
|
/// <param name="direction">Data direction</param>
|
||||||
/// <param name="exchangeParameters">Exchange specific parameters</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)
|
public GetPositionHistoryRequest(TradingMode? tradeMode = null, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, DataDirection? direction = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
|
||||||
{
|
{
|
||||||
TradingMode = tradeMode;
|
TradingMode = tradeMode;
|
||||||
StartTime = startTime;
|
StartTime = startTime;
|
||||||
EndTime = endTime;
|
EndTime = endTime;
|
||||||
Limit = limit;
|
Limit = limit;
|
||||||
|
Direction = direction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,15 +10,19 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Filter by start time
|
/// Filter by start time
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime StartTime { get; }
|
public DateTime StartTime { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Filter by end time
|
/// Filter by end time
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime EndTime { get; }
|
public DateTime? EndTime { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Max number of results
|
/// Max number of results
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? Limit { get; }
|
public int? Limit { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Data direction
|
||||||
|
/// </summary>
|
||||||
|
public DataDirection? Direction { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
@@ -27,12 +31,14 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <param name="startTime">Filter by start time</param>
|
/// <param name="startTime">Filter by start time</param>
|
||||||
/// <param name="endTime">Filter by end time</param>
|
/// <param name="endTime">Filter by end time</param>
|
||||||
/// <param name="limit">Max number of results</param>
|
/// <param name="limit">Max number of results</param>
|
||||||
|
/// <param name="direction">Data direction</param>
|
||||||
/// <param name="exchangeParameters">Exchange specific parameters</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)
|
public GetTradeHistoryRequest(SharedSymbol symbol, DateTime startTime, DateTime? endTime = null, int? limit = null, DataDirection? direction = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
|
||||||
{
|
{
|
||||||
StartTime = startTime;
|
StartTime = startTime;
|
||||||
EndTime = endTime;
|
EndTime = endTime;
|
||||||
Limit = limit;
|
Limit = limit;
|
||||||
|
Direction = direction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Max number of results
|
/// Max number of results
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? Limit { get; }
|
public int? Limit { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Data direction
|
||||||
|
/// </summary>
|
||||||
|
public DataDirection? Direction { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
@@ -27,12 +31,14 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <param name="startTime">Filter by start time</param>
|
/// <param name="startTime">Filter by start time</param>
|
||||||
/// <param name="endTime">Filter by end time</param>
|
/// <param name="endTime">Filter by end time</param>
|
||||||
/// <param name="limit">Max number of results</param>
|
/// <param name="limit">Max number of results</param>
|
||||||
|
/// <param name="direction">Data direction</param>
|
||||||
/// <param name="exchangeParameters">Exchange specific parameters</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)
|
public GetUserTradesRequest(SharedSymbol symbol, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, DataDirection? direction = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
|
||||||
{
|
{
|
||||||
StartTime = startTime;
|
StartTime = startTime;
|
||||||
EndTime = endTime;
|
EndTime = endTime;
|
||||||
Limit = limit;
|
Limit = limit;
|
||||||
|
Direction = direction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// Max number of results
|
/// Max number of results
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? Limit { get; }
|
public int? Limit { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Data direction
|
||||||
|
/// </summary>
|
||||||
|
public DataDirection? Direction { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
@@ -31,13 +35,15 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <param name="startTime">Filter by start time</param>
|
/// <param name="startTime">Filter by start time</param>
|
||||||
/// <param name="endTime">Filter by end time</param>
|
/// <param name="endTime">Filter by end time</param>
|
||||||
/// <param name="limit">Max number of results</param>
|
/// <param name="limit">Max number of results</param>
|
||||||
|
/// <param name="direction">Data direction</param>
|
||||||
/// <param name="exchangeParameters">Exchange specific parameters</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)
|
public GetWithdrawalsRequest(string? asset = null, DateTime? startTime = null, DateTime? endTime = null, int? limit = null, DataDirection? direction = null, ExchangeParameters? exchangeParameters = null) : base(exchangeParameters)
|
||||||
{
|
{
|
||||||
Asset = asset;
|
Asset = asset;
|
||||||
StartTime = startTime;
|
StartTime = startTime;
|
||||||
EndTime = endTime;
|
EndTime = endTime;
|
||||||
Limit = limit;
|
Limit = limit;
|
||||||
|
Direction = direction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -332,7 +332,8 @@ namespace CryptoExchange.Net.Trackers.Klines
|
|||||||
_data.Add(item.OpenTime, item);
|
_data.Add(item.OpenTime, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
_firstTimestamp = _data.Min(v => v.Key);
|
_firstTimestamp = _data.Count == 0 ? null : _data.Min(v => v.Key);
|
||||||
|
|
||||||
ApplyWindow(false);
|
ApplyWindow(false);
|
||||||
_logger.KlineTrackerInitialDataSet(SymbolName, _data.Last().Key);
|
_logger.KlineTrackerInitialDataSet(SymbolName, _data.Last().Key);
|
||||||
}
|
}
|
||||||
@@ -375,7 +376,7 @@ namespace CryptoExchange.Net.Trackers.Klines
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_firstTimestamp = _data.Min(x => x.Key);
|
_firstTimestamp = _data.Count == 0 ? null : _data.Min(x => x.Key);
|
||||||
_changed = true;
|
_changed = true;
|
||||||
|
|
||||||
SetSyncStatus();
|
SetSyncStatus();
|
||||||
|
|||||||
@@ -259,11 +259,11 @@ namespace CryptoExchange.Net.Trackers.Trades
|
|||||||
var startTime = Period == null ? DateTime.UtcNow.AddMinutes(-5) : DateTime.UtcNow.Add(-Period.Value);
|
var startTime = Period == null ? DateTime.UtcNow.AddMinutes(-5) : DateTime.UtcNow.Add(-Period.Value);
|
||||||
var request = new GetTradeHistoryRequest(Symbol, startTime, DateTime.UtcNow);
|
var request = new GetTradeHistoryRequest(Symbol, startTime, DateTime.UtcNow);
|
||||||
var data = new List<SharedTrade>();
|
var data = new List<SharedTrade>();
|
||||||
await foreach(var result in ExchangeHelpers.ExecutePages(_historyRestClient.GetTradeHistoryAsync, request).ConfigureAwait(false))
|
await foreach (var result in ExchangeHelpers.ExecutePages(_historyRestClient.GetTradeHistoryAsync, request).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
if (!result)
|
if (!result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (Limit != null && data.Count > Limit)
|
if (Limit != null && data.Count > Limit)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user