mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2026-02-16 14:13:46 +00:00
wip
This commit is contained in:
parent
c5fa985841
commit
d4965ad68d
@ -311,11 +311,11 @@ namespace CryptoExchange.Net
|
||||
/// <param name="request">The request parameters</param>
|
||||
/// <param name="ct">Cancellation token</param>
|
||||
/// <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>();
|
||||
ExchangeWebResult<T[]> batch;
|
||||
INextPageToken? nextPageToken = null;
|
||||
PageRequest? nextPageToken = null;
|
||||
while (true)
|
||||
{
|
||||
batch = await paginatedFunc(request, nextPageToken, ct).ConfigureAwait(false);
|
||||
@ -324,7 +324,7 @@ namespace CryptoExchange.Net
|
||||
break;
|
||||
|
||||
result.AddRange(batch.Data);
|
||||
nextPageToken = batch.NextPageToken;
|
||||
nextPageToken = batch.NextPageRequest;
|
||||
if (nextPageToken == null)
|
||||
break;
|
||||
}
|
||||
@ -335,9 +335,9 @@ namespace CryptoExchange.Net
|
||||
Func<T, DateTime> timeSelector,
|
||||
DateTime? startTime,
|
||||
DateTime? endTime,
|
||||
PageDirection direction)
|
||||
DataDirection direction)
|
||||
{
|
||||
if (direction == PageDirection.Ascending)
|
||||
if (direction == DataDirection.Ascending)
|
||||
data = data.OrderBy(timeSelector);
|
||||
else
|
||||
data = data.OrderByDescending(timeSelector);
|
||||
@ -357,12 +357,15 @@ namespace CryptoExchange.Net
|
||||
DateTime? startTime,
|
||||
DateTime? endTime,
|
||||
int limit,
|
||||
PageDirection paginationDirection)
|
||||
DataDirection paginationDirection)
|
||||
{
|
||||
if (resultCount < limit)
|
||||
return false;
|
||||
|
||||
if (paginationDirection == PageDirection.Ascending)
|
||||
if (!timestamps.Any())
|
||||
return false;
|
||||
|
||||
if (paginationDirection == DataDirection.Ascending)
|
||||
{
|
||||
if (timestamps.Max() >= endTime)
|
||||
return false;
|
||||
@ -382,13 +385,230 @@ namespace CryptoExchange.Net
|
||||
{
|
||||
FromId,
|
||||
Time,
|
||||
Offset
|
||||
}
|
||||
|
||||
public enum TimeParameterSetType
|
||||
{
|
||||
None,
|
||||
OnlyMatchingDirection,
|
||||
Both
|
||||
}
|
||||
|
||||
// 1.1 Apply moving time filter, set the startTime to new startTime in future (asc) or endTime to new endTime in the past (desc), while setting other time parameter to null
|
||||
// 1.2 Apply moving time filter, set the startTime to new startTime in future (asc) or endTime to new endTime in the past (desc), set the other time parameter to a max period offset value
|
||||
// 2. Apply fromId filter, set the fromId to the new fromId (direction depends on id filter direction)
|
||||
// 3. Apply offset filter, set the offset to the new offset (direction depends on id filter direction)
|
||||
|
||||
|
||||
|
||||
public static PaginationParameters ApplyFromIdFilter(PageRequest pageRequest)
|
||||
{
|
||||
if (pageRequest.FromId == null)
|
||||
throw new Exception();
|
||||
|
||||
return new PaginationParameters { FromId = pageRequest.FromId };
|
||||
}
|
||||
|
||||
public static PaginationParameters ApplyOffsetFilter(PageRequest pageRequest)
|
||||
{
|
||||
if (pageRequest.Offset == null)
|
||||
throw new Exception();
|
||||
|
||||
return new PaginationParameters { Offset = pageRequest.Offset };
|
||||
}
|
||||
|
||||
public static PaginationParameters ApplyAscendingMovingStartTimeFilter(PageRequest pageRequest)
|
||||
{
|
||||
if (pageRequest.StartTime == null)
|
||||
throw new Exception();
|
||||
|
||||
return new PaginationParameters
|
||||
{
|
||||
StartTime = pageRequest.StartTime,
|
||||
};
|
||||
}
|
||||
|
||||
public static PaginationParameters ApplyDescendingMovingEndTimeFilter(PageRequest pageRequest)
|
||||
{
|
||||
if (pageRequest.EndTime == null)
|
||||
throw new Exception();
|
||||
|
||||
return new PaginationParameters
|
||||
{
|
||||
EndTime = pageRequest.EndTime,
|
||||
};
|
||||
}
|
||||
|
||||
public static PageRequest? GetNextPageRequest(
|
||||
Func<PageRequest> normalNextPageCallback,
|
||||
int responseLength,
|
||||
IEnumerable<DateTime> timeSelector,
|
||||
int limit,
|
||||
PageRequest? previousPageRequest,
|
||||
TimeParameterSetType parameterSetType,
|
||||
DateTime? currentRequestStartTime,
|
||||
DataDirection direction,
|
||||
DateTime? requestStartTime,
|
||||
DateTime? requestEndTime,
|
||||
TimeSpan? maxTimePeriodPerRequest = null
|
||||
)
|
||||
{
|
||||
if (CheckForNextPage(responseLength, timeSelector, previousPageRequest?.StartTime ?? requestStartTime, previousPageRequest?.EndTime ?? requestEndTime, limit, direction))
|
||||
{
|
||||
var result = normalNextPageCallback();
|
||||
if (parameterSetType == TimeParameterSetType.OnlyMatchingDirection)
|
||||
{
|
||||
if (direction == DataDirection.Ascending)
|
||||
result.StartTime ??= previousPageRequest?.StartTime ?? requestStartTime;
|
||||
else
|
||||
result.EndTime ??= previousPageRequest?.EndTime ?? requestEndTime;
|
||||
}
|
||||
else if (parameterSetType == TimeParameterSetType.Both)
|
||||
{
|
||||
result.StartTime ??= previousPageRequest?.StartTime ?? requestStartTime;
|
||||
result.EndTime ??= previousPageRequest?.EndTime ?? requestEndTime;
|
||||
}
|
||||
|
||||
//if (previousPageRequest != null && result.StartTime == null && result.EndTime == null)
|
||||
//{
|
||||
// result.StartTime = previousPageRequest.StartTime;
|
||||
// result.EndTime = previousPageRequest.EndTime;
|
||||
//}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (maxTimePeriodPerRequest == null)
|
||||
return null;
|
||||
|
||||
if (requestEndTime == null)
|
||||
requestEndTime = DateTime.UtcNow;
|
||||
|
||||
#warning this is only for DESC?
|
||||
// No next page, for this set, but we might have split for multiple time periods
|
||||
PageRequest? nextPageRequest = null;
|
||||
if (requestStartTime.HasValue
|
||||
&& previousPageRequest?.StartTime != requestStartTime
|
||||
&& (requestEndTime - requestStartTime) > maxTimePeriodPerRequest)
|
||||
{
|
||||
var currentStartTime = (currentRequestStartTime ?? (requestEndTime.Value.Add(-maxTimePeriodPerRequest.Value)));
|
||||
var nextPeriod = currentStartTime.Add(-maxTimePeriodPerRequest.Value);
|
||||
var nextStartTime = nextPeriod < requestStartTime ? requestStartTime : nextPeriod;
|
||||
if (currentStartTime - nextStartTime > TimeSpan.FromSeconds(1))
|
||||
{
|
||||
nextPageRequest = new PageRequest
|
||||
{
|
||||
Offset = 0,
|
||||
EndTime = currentStartTime,
|
||||
StartTime = nextStartTime
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return nextPageRequest;
|
||||
}
|
||||
|
||||
public static PaginationParameters ApplyPaginationParameters(
|
||||
DataDirection direction,
|
||||
PageRequest? pageRequest,
|
||||
PaginationFilterType? filterTypeAsc,
|
||||
PaginationFilterType? filterTypeDec,
|
||||
TimeParameterSetType parameterSetType,
|
||||
DateTime? requestStartTime,
|
||||
DateTime? requestEndTime,
|
||||
TimeSpan? maxTimePeriodPerRequest = null)
|
||||
{
|
||||
var filterType = direction == DataDirection.Ascending ? filterTypeAsc : filterTypeDec;
|
||||
if (filterType == null)
|
||||
throw new Exception();
|
||||
|
||||
if (requestEndTime == null)
|
||||
requestEndTime = DateTime.UtcNow;
|
||||
|
||||
if (pageRequest == null)
|
||||
{
|
||||
// No pagination data yet, initial request
|
||||
var result = new PaginationParameters
|
||||
{
|
||||
StartTime = ShouldSet(parameterSetType, direction, true) ? requestStartTime : null,
|
||||
EndTime = ShouldSet(parameterSetType, direction, false) ? requestEndTime : null
|
||||
};
|
||||
|
||||
ApplyMaxTimePeriodPerRequest(maxTimePeriodPerRequest, direction, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (filterType == PaginationFilterType.FromId)
|
||||
// From id doesn't need any other parameters
|
||||
return ApplyFromIdFilter(pageRequest);
|
||||
|
||||
if (filterType == PaginationFilterType.Offset)
|
||||
{
|
||||
var result = ApplyOffsetFilter(pageRequest);
|
||||
result.StartTime = pageRequest.StartTime ?? requestStartTime;
|
||||
result.EndTime = pageRequest.EndTime ?? requestEndTime;
|
||||
ApplyMaxTimePeriodPerRequest(maxTimePeriodPerRequest, direction, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (filterType == PaginationFilterType.Time)
|
||||
{
|
||||
var result = direction == DataDirection.Ascending
|
||||
? ApplyAscendingMovingStartTimeFilter(pageRequest)
|
||||
: ApplyDescendingMovingEndTimeFilter(pageRequest);
|
||||
|
||||
if (parameterSetType == TimeParameterSetType.Both)
|
||||
{
|
||||
if (direction == DataDirection.Ascending)
|
||||
result.EndTime = requestEndTime;
|
||||
else
|
||||
result.StartTime = requestStartTime;
|
||||
|
||||
ApplyMaxTimePeriodPerRequest(maxTimePeriodPerRequest, direction, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
private static void ApplyMaxTimePeriodPerRequest(TimeSpan? maxTimePeriodPerRequest, DataDirection direction, PaginationParameters parameters)
|
||||
{
|
||||
if (maxTimePeriodPerRequest != null
|
||||
&& parameters.StartTime.HasValue
|
||||
&& parameters.EndTime.HasValue
|
||||
&& (parameters.EndTime - parameters.StartTime) > maxTimePeriodPerRequest)
|
||||
{
|
||||
if (direction == DataDirection.Ascending)
|
||||
parameters.EndTime = parameters.StartTime.Value.Add(maxTimePeriodPerRequest.Value);
|
||||
else
|
||||
parameters.StartTime = parameters.EndTime.Value.Add(-maxTimePeriodPerRequest.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ShouldSet(TimeParameterSetType type, DataDirection direction, bool startTime)
|
||||
{
|
||||
if (type == TimeParameterSetType.None)
|
||||
return false;
|
||||
|
||||
if (type == TimeParameterSetType.Both)
|
||||
return true;
|
||||
|
||||
if (direction == DataDirection.Ascending)
|
||||
// If ascending startTime is the moving
|
||||
return startTime;
|
||||
|
||||
// If descending startTime is the opposite
|
||||
return !startTime;
|
||||
}
|
||||
|
||||
public static (DateTime? startTime, DateTime? endTime, long? fromId) ApplyPaginationRequestFilters(
|
||||
PaginationFilterType? ascendingFilterType,
|
||||
PaginationFilterType? descendingFilterType,
|
||||
PageDirection defaultDirection,
|
||||
PageDirection requestDirection,
|
||||
DataDirection defaultDirection,
|
||||
DataDirection requestDirection,
|
||||
DateTime? userFilterStartTime,
|
||||
DateTime? userFilterEndTime,
|
||||
DateTime? paginationStartTime,
|
||||
@ -396,10 +616,10 @@ namespace CryptoExchange.Net
|
||||
TimeSpan? maxTimePeriod,
|
||||
string? paginationFromId)
|
||||
{
|
||||
if (requestDirection == PageDirection.Ascending && userFilterStartTime == null)
|
||||
if (requestDirection == DataDirection.Ascending && userFilterStartTime == null)
|
||||
throw new InvalidOperationException("Ascending without start time");
|
||||
|
||||
var filterType = requestDirection == PageDirection.Ascending ? ascendingFilterType : descendingFilterType;
|
||||
var filterType = requestDirection == DataDirection.Ascending ? ascendingFilterType : descendingFilterType;
|
||||
if (filterType == PaginationFilterType.FromId)
|
||||
{
|
||||
long? fromId = ApplyFromId(paginationFromId);
|
||||
@ -410,7 +630,7 @@ namespace CryptoExchange.Net
|
||||
&& fromId == null
|
||||
&& startTime == null)
|
||||
{
|
||||
if (requestDirection == PageDirection.Ascending)
|
||||
if (requestDirection == DataDirection.Ascending)
|
||||
{
|
||||
// If user requests in ASC order but the default is DESC order and user provides no parameters
|
||||
// set startTime to a specific date to search data from that time forward
|
||||
@ -437,19 +657,19 @@ namespace CryptoExchange.Net
|
||||
if (fromId == null && startTime != null && endTime != null)
|
||||
{
|
||||
// If we're not filtering by fromId we don't want to specify bot start and end time to prevent limitations in time period
|
||||
if (requestDirection == PageDirection.Ascending) endTime = null;
|
||||
if (requestDirection == PageDirection.Descending) startTime = null;
|
||||
if (requestDirection == DataDirection.Ascending) endTime = null;
|
||||
if (requestDirection == DataDirection.Descending) startTime = null;
|
||||
}
|
||||
|
||||
return (startTime, endTime, fromId);
|
||||
}
|
||||
else // Time
|
||||
{
|
||||
DateTime? startTime = requestDirection == PageDirection.Descending ? null : ApplyTime(userFilterStartTime, paginationStartTime);
|
||||
DateTime? endTime = (requestDirection == PageDirection.Ascending && paginationStartTime != null) ? null : ApplyTime(userFilterEndTime, paginationEndTime);
|
||||
DateTime? startTime = requestDirection == DataDirection.Descending ? null : ApplyTime(userFilterStartTime, paginationStartTime);
|
||||
DateTime? endTime = (requestDirection == DataDirection.Ascending && paginationStartTime != null) ? null : ApplyTime(userFilterEndTime, paginationEndTime);
|
||||
if (maxTimePeriod.HasValue && endTime - startTime > maxTimePeriod.Value)
|
||||
{
|
||||
if (requestDirection == PageDirection.Ascending)
|
||||
if (requestDirection == DataDirection.Ascending)
|
||||
endTime = startTime.Value.Add(maxTimePeriod.Value);
|
||||
else
|
||||
startTime = endTime.Value.Add(-maxTimePeriod.Value);
|
||||
|
||||
@ -519,7 +519,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <param name="exchange">The exchange</param>
|
||||
/// <param name="tradeModes">Trade modes the result applies to</param>
|
||||
/// <returns></returns>
|
||||
public ExchangeWebResult<T> AsExchangeResult(string exchange, TradingMode[] tradeModes)
|
||||
public ExchangeWebResult<T> AsExchangeResult(string exchange, TradingMode[]? tradeModes)
|
||||
{
|
||||
return new ExchangeWebResult<T>(exchange, tradeModes, this);
|
||||
}
|
||||
@ -533,25 +533,11 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <param name="data">Data</param>
|
||||
/// <param name="nextPageToken">Next page token</param>
|
||||
/// <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? nextPageToken = null)
|
||||
{
|
||||
return new ExchangeWebResult<K>(exchange, tradeMode, As<K>(data), nextPageToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy the WebCallResult to an ExchangeWebResult of a new data type
|
||||
/// </summary>
|
||||
/// <typeparam name="K">The new type</typeparam>
|
||||
/// <param name="exchange">The exchange</param>
|
||||
/// <param name="tradeMode">Trade mode the result applies to</param>
|
||||
/// <param name="data">Data</param>
|
||||
/// <param name="nextPageToken">Next page token</param>
|
||||
/// <returns></returns>
|
||||
public ExchangeWebResult<K> AsExchangeResult<K>(string exchange, TradingMode tradeMode, [AllowNull] K data, PageRequest? nextPageRequest)
|
||||
{
|
||||
return new ExchangeWebResult<K>(exchange, tradeMode, As<K>(data), nextPageRequest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy the WebCallResult to an ExchangeWebResult of a new data type
|
||||
/// </summary>
|
||||
@ -561,7 +547,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <param name="data">Data</param>
|
||||
/// <param name="nextPageToken">Next page token</param>
|
||||
/// <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? nextPageToken = null)
|
||||
{
|
||||
return new ExchangeWebResult<K>(exchange, tradeModes, As<K>(data), nextPageToken);
|
||||
}
|
||||
|
||||
@ -1,131 +1,131 @@
|
||||
using System;
|
||||
//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
|
||||
{
|
||||
//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>
|
||||
// /// 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>
|
||||
// /// ctor
|
||||
// /// </summary>
|
||||
// public DateTimeToken(DateTime timestamp)
|
||||
// {
|
||||
// LastTime = timestamp;
|
||||
// }
|
||||
|
||||
public DateTimeToken GetNextToken(DateTime nextTime) => this with { LastTime = nextTime };
|
||||
}
|
||||
// public DateTimeToken GetNextToken(DateTime nextTime) => this with { LastTime = nextTime };
|
||||
// }
|
||||
|
||||
/// <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>
|
||||
// /// 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>
|
||||
// /// ctor
|
||||
// /// </summary>
|
||||
// public PageToken(int page, int pageSize)
|
||||
// {
|
||||
// Page = page;
|
||||
// PageSize = pageSize;
|
||||
// }
|
||||
|
||||
public PageToken GetNextToken() => this with { Page = Page + 1 };
|
||||
}
|
||||
// public PageToken GetNextToken() => this with { Page = Page + 1 };
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// A id offset token
|
||||
/// </summary>
|
||||
public record FromIdToken : INextPageToken
|
||||
{
|
||||
/// <summary>
|
||||
/// The last id from previous result
|
||||
/// </summary>
|
||||
public string FromToken { get; set; }
|
||||
// /// <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>
|
||||
// /// ctor
|
||||
// /// </summary>
|
||||
// public FromIdToken(string fromToken)
|
||||
// {
|
||||
// FromToken = fromToken;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public FromIdToken(long fromToken)
|
||||
{
|
||||
FromToken = fromToken.ToString();
|
||||
}
|
||||
// /// <summary>
|
||||
// /// ctor
|
||||
// /// </summary>
|
||||
// public FromIdToken(long fromToken)
|
||||
// {
|
||||
// FromToken = fromToken.ToString();
|
||||
// }
|
||||
|
||||
public FromIdToken GetNextToken(string nextToken) => this with { FromToken = nextToken };
|
||||
public FromIdToken GetNextToken(long nextToken) => this with { FromToken = nextToken.ToString() };
|
||||
}
|
||||
// public FromIdToken GetNextToken(string nextToken) => this with { FromToken = nextToken };
|
||||
// public FromIdToken GetNextToken(long nextToken) => this with { FromToken = nextToken.ToString() };
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// A cursor token
|
||||
/// </summary>
|
||||
public record CursorToken : INextPageToken
|
||||
{
|
||||
/// <summary>
|
||||
/// The next page cursor
|
||||
/// </summary>
|
||||
public string Cursor { get; set; }
|
||||
// /// <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>
|
||||
// /// ctor
|
||||
// /// </summary>
|
||||
// public CursorToken(string cursor)
|
||||
// {
|
||||
// Cursor = cursor;
|
||||
// }
|
||||
|
||||
public CursorToken GetNextToken(string nextCursor) => this with { Cursor = nextCursor };
|
||||
}
|
||||
// public CursorToken GetNextToken(string nextCursor) => this with { Cursor = nextCursor };
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// A result offset token
|
||||
/// </summary>
|
||||
public record OffsetToken : INextPageToken
|
||||
{
|
||||
/// <summary>
|
||||
/// Offset in the result set
|
||||
/// </summary>
|
||||
public int Offset { get; set; }
|
||||
// /// <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;
|
||||
}
|
||||
// /// <summary>
|
||||
// /// ctor
|
||||
// /// </summary>
|
||||
// public OffsetToken(int offset)
|
||||
// {
|
||||
// Offset = offset;
|
||||
// }
|
||||
|
||||
public OffsetToken GetNextToken() => this with { Offset = Offset + Offset };
|
||||
}
|
||||
}
|
||||
// public OffsetToken GetNextToken() => this with { Offset = Offset + Offset };
|
||||
// }
|
||||
//}
|
||||
|
||||
@ -18,6 +18,6 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="request">Request info</param>
|
||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="request">Request info</param>
|
||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</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>
|
||||
/// Futures get order trades request options
|
||||
@ -103,7 +103,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="request">Request info</param>
|
||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</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>
|
||||
/// Futures cancel order request options
|
||||
|
||||
@ -18,6 +18,6 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="request">Request info</param>
|
||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,6 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="request">Request info</param>
|
||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,6 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="request">Request info</param>
|
||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,6 +33,6 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
||||
/// <param name="ct">Cancellation token</param>
|
||||
/// <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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,6 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
||||
/// <param name="ct">Cancellation token</param>
|
||||
/// <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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,6 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</param>
|
||||
/// <param name="ct">Cancellation token</param>
|
||||
/// <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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="request">Request info</param>
|
||||
/// <param name="nextPageToken">The pagination token from the previous request to continue pagination</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>
|
||||
/// Spot cancel order request options
|
||||
|
||||
@ -23,11 +23,6 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// </summary>
|
||||
public TradingMode[]? DataTradeMode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Token to retrieve the next page with
|
||||
/// </summary>
|
||||
public INextPageToken? NextPageToken { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@ -51,63 +46,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
string exchange,
|
||||
TradingMode dataTradeMode,
|
||||
WebCallResult<T> result,
|
||||
INextPageToken? nextPageToken = null) :
|
||||
base(result.ResponseStatusCode,
|
||||
result.HttpVersion,
|
||||
result.ResponseHeaders,
|
||||
result.ResponseTime,
|
||||
result.ResponseLength,
|
||||
result.OriginalData,
|
||||
result.RequestId,
|
||||
result.RequestUrl,
|
||||
result.RequestBody,
|
||||
result.RequestMethod,
|
||||
result.RequestHeaders,
|
||||
result.DataSource,
|
||||
result.Data,
|
||||
result.Error)
|
||||
{
|
||||
DataTradeMode = new[] { dataTradeMode };
|
||||
Exchange = exchange;
|
||||
NextPageToken = nextPageToken;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public ExchangeWebResult(
|
||||
string exchange,
|
||||
TradingMode[]? dataTradeModes,
|
||||
WebCallResult<T> result,
|
||||
INextPageToken? nextPageToken = null) :
|
||||
base(result.ResponseStatusCode,
|
||||
result.HttpVersion,
|
||||
result.ResponseHeaders,
|
||||
result.ResponseTime,
|
||||
result.ResponseLength,
|
||||
result.OriginalData,
|
||||
result.RequestId,
|
||||
result.RequestUrl,
|
||||
result.RequestBody,
|
||||
result.RequestMethod,
|
||||
result.RequestHeaders,
|
||||
result.DataSource,
|
||||
result.Data,
|
||||
result.Error)
|
||||
{
|
||||
DataTradeMode = dataTradeModes;
|
||||
Exchange = exchange;
|
||||
NextPageToken = nextPageToken;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public ExchangeWebResult(
|
||||
string exchange,
|
||||
TradingMode dataTradeMode,
|
||||
WebCallResult<T> result,
|
||||
PageRequest? nextPageToken) :
|
||||
PageRequest? nextPageToken = null) :
|
||||
base(result.ResponseStatusCode,
|
||||
result.HttpVersion,
|
||||
result.ResponseHeaders,
|
||||
@ -135,7 +74,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
string exchange,
|
||||
TradingMode[]? dataTradeModes,
|
||||
WebCallResult<T> result,
|
||||
PageRequest? nextPageRequest) :
|
||||
PageRequest? nextPageRequest = null) :
|
||||
base(result.ResponseStatusCode,
|
||||
result.HttpVersion,
|
||||
result.ResponseHeaders,
|
||||
@ -176,7 +115,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
ResultDataSource dataSource,
|
||||
[AllowNull] T data,
|
||||
Error? error,
|
||||
INextPageToken? nextPageToken = null) : base(
|
||||
PageRequest? nextPageToken = null) : base(
|
||||
code,
|
||||
httpVersion,
|
||||
responseHeaders,
|
||||
@ -194,7 +133,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
DataTradeMode = dataTradeModes;
|
||||
Exchange = exchange;
|
||||
NextPageToken = nextPageToken;
|
||||
NextPageRequest = nextPageToken;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -205,7 +144,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <returns></returns>
|
||||
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 />
|
||||
|
||||
@ -8,23 +8,18 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// </summary>
|
||||
public class GetClosedOrdersOptions : PaginatedEndpointOptions<GetClosedOrdersRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the start/end time filter is supported
|
||||
/// </summary>
|
||||
public bool TimeFilterSupported { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetClosedOrdersOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit) : base(timeFilterSupported, maxLimit, true)
|
||||
public GetClosedOrdersOptions(bool supportsAscending, bool supportsDescending, bool timeFilterSupported, int maxLimit)
|
||||
: base(supportsAscending, supportsDescending, timeFilterSupported, maxLimit, true)
|
||||
{
|
||||
TimeFilterSupported = timeFilterSupported;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Error? ValidateRequest(string exchange, GetClosedOrdersRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
||||
{
|
||||
if (!TimeFilterSupported && request.StartTime != null)
|
||||
if (!TimePeriodFilterSupport && request.StartTime != null)
|
||||
return ArgumentError.Invalid(nameof(GetClosedOrdersRequest.StartTime), $"Time filter is not supported");
|
||||
|
||||
return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes);
|
||||
@ -34,7 +29,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
public override string ToString(string exchange)
|
||||
{
|
||||
var sb = new StringBuilder(base.ToString(exchange));
|
||||
sb.AppendLine($"Time filter supported: {TimeFilterSupported}");
|
||||
sb.AppendLine($"Time filter supported: {TimePeriodFilterSupport}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,23 +8,18 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// </summary>
|
||||
public class GetDepositsOptions : PaginatedEndpointOptions<GetDepositsRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the start/end time filter is supported
|
||||
/// </summary>
|
||||
public bool TimeFilterSupported { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetDepositsOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit) : base(timeFilterSupported, maxLimit, true)
|
||||
public GetDepositsOptions(bool supportsAscending, bool supportsDescending, bool timeFilterSupported, int maxLimit)
|
||||
: base(supportsAscending, supportsDescending, timeFilterSupported, maxLimit, true)
|
||||
{
|
||||
TimeFilterSupported = timeFilterSupported;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Error? ValidateRequest(string exchange, GetDepositsRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
||||
{
|
||||
if (!TimeFilterSupported && request.StartTime != null)
|
||||
if (!TimePeriodFilterSupport && request.StartTime != null)
|
||||
return ArgumentError.Invalid(nameof(GetDepositsRequest.StartTime), $"Time filter is not supported");
|
||||
|
||||
return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes);
|
||||
@ -34,7 +29,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
public override string ToString(string exchange)
|
||||
{
|
||||
var sb = new StringBuilder(base.ToString(exchange));
|
||||
sb.AppendLine($"Time filter supported: {TimeFilterSupported}");
|
||||
sb.AppendLine($"Time filter supported: {TimePeriodFilterSupport}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for requesting funding rate history
|
||||
@ -8,8 +11,26 @@
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetFundingRateHistoryOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit, bool needsAuthentication) : base(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 (!TimePeriodFilterSupport && request.StartTime != null)
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,7 +26,8 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetKlinesOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit, bool needsAuthentication) : base(timeFilterSupported, maxLimit, needsAuthentication)
|
||||
public GetKlinesOptions(bool supportsAscending, bool supportsDescending, bool timeFilterSupported, int maxLimit, bool needsAuthentication)
|
||||
: base(supportsAscending, supportsDescending, timeFilterSupported, maxLimit, needsAuthentication)
|
||||
{
|
||||
SupportIntervals = new[]
|
||||
{
|
||||
@ -50,7 +51,8 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetKlinesOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit, bool needsAuthentication, params SharedKlineInterval[] intervals) : base(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;
|
||||
}
|
||||
@ -68,6 +70,9 @@ namespace CryptoExchange.Net.SharedApis
|
||||
if (!IsSupported(request.Interval))
|
||||
return ArgumentError.Invalid(nameof(GetKlinesRequest.Interval), "Interval not supported");
|
||||
|
||||
if (!TimePeriodFilterSupport && request.StartTime != null)
|
||||
return ArgumentError.Invalid(nameof(GetDepositsRequest.StartTime), $"Time filter is not supported");
|
||||
|
||||
if (MaxAge.HasValue && request.StartTime < DateTime.UtcNow.Add(-MaxAge.Value))
|
||||
return ArgumentError.Invalid(nameof(GetKlinesRequest.StartTime), $"Only the most recent {MaxAge} klines are available");
|
||||
|
||||
@ -93,6 +98,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
public override string ToString(string exchange)
|
||||
{
|
||||
var sb = new StringBuilder(base.ToString(exchange));
|
||||
sb.AppendLine($"Time filter supported: {TimePeriodFilterSupport}");
|
||||
sb.AppendLine($"Supported SharedKlineInterval values: {string.Join(", ", SupportIntervals)}");
|
||||
if (MaxAge != null)
|
||||
sb.AppendLine($"Max age of data: {MaxAge}");
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for requesting position history
|
||||
@ -8,8 +11,26 @@
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetPositionHistoryOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit) : base(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 (!TimePeriodFilterSupport && request.StartTime != null)
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,8 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetTradeHistoryOptions(bool timeFilterSupported, int maxLimit, bool needsAuthentication) : base(timeFilterSupported, maxLimit, needsAuthentication)
|
||||
public GetTradeHistoryOptions(bool supportsAscending, bool supportsDescending, bool timeFilterSupported, int maxLimit, bool needsAuthentication)
|
||||
: base(supportsAscending, supportsDescending, timeFilterSupported, maxLimit, needsAuthentication)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -8,23 +8,18 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// </summary>
|
||||
public class GetWithdrawalsOptions : PaginatedEndpointOptions<GetWithdrawalsRequest>
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the start/end time filter is supported
|
||||
/// </summary>
|
||||
public bool TimeFilterSupported { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public GetWithdrawalsOptions(SharedPaginationSupport paginationType, bool timeFilterSupported, int maxLimit) : base(timeFilterSupported, maxLimit, true)
|
||||
public GetWithdrawalsOptions(bool supportsAscending, bool supportsDescending, bool timeFilterSupported, int maxLimit)
|
||||
: base(supportsAscending, supportsDescending, timeFilterSupported, maxLimit, true)
|
||||
{
|
||||
TimeFilterSupported = timeFilterSupported;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Error? ValidateRequest(string exchange, GetWithdrawalsRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
||||
{
|
||||
if (!TimeFilterSupported && request.StartTime != null)
|
||||
if (!TimePeriodFilterSupport && request.StartTime != null)
|
||||
return ArgumentError.Invalid(nameof(GetWithdrawalsRequest.StartTime), $"Time filter is not supported");
|
||||
|
||||
return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes);
|
||||
@ -34,7 +29,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
public override string ToString(string exchange)
|
||||
{
|
||||
var sb = new StringBuilder(base.ToString(exchange));
|
||||
sb.AppendLine($"Time filter supported: {TimeFilterSupported}");
|
||||
sb.AppendLine($"Time filter supported: {TimePeriodFilterSupport}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for paginated endpoints
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
#if NET5_0_OR_GREATER
|
||||
public class PageEndpointOptions<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T> : EndpointOptions<T> where T : SharedRequest
|
||||
#else
|
||||
public class PageEndpointOptions<T> : EndpointOptions<T> where T : SharedRequest
|
||||
#endif
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public PageEndpointOptions(bool needsAuthentication) : base(needsAuthentication)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString(string exchange)
|
||||
{
|
||||
var sb = new StringBuilder(base.ToString(exchange));
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13,13 +13,14 @@ namespace CryptoExchange.Net.SharedApis
|
||||
public class PaginatedEndpointOptions<T> : EndpointOptions<T> where T : SharedRequest
|
||||
#endif
|
||||
{
|
||||
///// <summary>
|
||||
///// Type of pagination supported
|
||||
///// </summary>
|
||||
//public SharedPaginationSupport PaginationSupport { get; }
|
||||
|
||||
public bool SupportsAscendingPagination { get; set; }
|
||||
public bool SupportsDescendingPagination { get; set; }
|
||||
/// <summary>
|
||||
/// Whether ascending data retrieval and pagination is available
|
||||
/// </summary>
|
||||
public bool SupportsAscending { get; set; }
|
||||
/// <summary>
|
||||
/// Whether ascending data retrieval and pagination is available
|
||||
/// </summary>
|
||||
public bool SupportsDescending { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether filtering based on start/end time is supported
|
||||
@ -34,8 +35,15 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public PaginatedEndpointOptions(bool timePeriodSupport, int maxLimit, bool needsAuthentication) : base(needsAuthentication)
|
||||
public PaginatedEndpointOptions(
|
||||
bool supportsAscending,
|
||||
bool supportsDescending,
|
||||
bool timePeriodSupport,
|
||||
int maxLimit,
|
||||
bool needsAuthentication) : base(needsAuthentication)
|
||||
{
|
||||
SupportsAscending = supportsAscending;
|
||||
SupportsDescending = supportsDescending;
|
||||
TimePeriodFilterSupport = timePeriodSupport;
|
||||
MaxLimit = maxLimit;
|
||||
}
|
||||
@ -44,8 +52,8 @@ namespace CryptoExchange.Net.SharedApis
|
||||
public override string ToString(string exchange)
|
||||
{
|
||||
var sb = new StringBuilder(base.ToString(exchange));
|
||||
sb.AppendLine($"Pagination ASC supported: {SupportsAscendingPagination}");
|
||||
sb.AppendLine($"Pagination DESC supported: {SupportsDescendingPagination}");
|
||||
sb.AppendLine($"Ascending retrieval supported: {SupportsAscending}");
|
||||
sb.AppendLine($"Descending retrieval supported: {SupportsDescending}");
|
||||
sb.AppendLine($"Time period filter support: {TimePeriodFilterSupport}");
|
||||
sb.AppendLine($"Max limit: {MaxLimit}");
|
||||
return sb.ToString();
|
||||
|
||||
@ -6,32 +6,37 @@ using System.Text;
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
|
||||
public enum PageDirection
|
||||
public enum DataDirection
|
||||
{
|
||||
Ascending, // Old to new
|
||||
Descending // New to old
|
||||
}
|
||||
|
||||
public record PaginationParameters
|
||||
{
|
||||
public DateTime? StartTime { get; set; }
|
||||
public DateTime? EndTime { get; set; }
|
||||
public string? FromId { get; set; }
|
||||
public int? Offset { get; set; }
|
||||
}
|
||||
public class PageRequest
|
||||
{
|
||||
public string? NextCursor { get; set; }
|
||||
public int? NextPage { get; set; }
|
||||
public int? NextOffset { get; set; }
|
||||
public string? NextFromId { get; set; }
|
||||
public DateTime? NextStartTime { get; set; }
|
||||
public DateTime? NextEndTime { get; set; }
|
||||
public string? Cursor { get; set; }
|
||||
public int? Page { get; set; }
|
||||
public int? Offset { get; set; }
|
||||
public string? FromId { get; set; }
|
||||
public DateTime? StartTime { get; set; }
|
||||
public DateTime? EndTime { get; set; }
|
||||
|
||||
|
||||
public static PageRequest FromNextCursor(string nextCursor) => new PageRequest { NextCursor = nextCursor };
|
||||
public static PageRequest FromNextPage(int nextPage) => new PageRequest { NextPage = nextPage };
|
||||
public static PageRequest FromNextOffset(int nextOffset) => new PageRequest { NextOffset = nextOffset };
|
||||
public static PageRequest NextCursor(string nextCursor) => new PageRequest { Cursor = nextCursor };
|
||||
public static PageRequest NextPage(int nextPage) => new PageRequest { Page = nextPage };
|
||||
public static PageRequest NextOffset(int nextOffset) => new PageRequest { Offset = nextOffset };
|
||||
|
||||
public static PageRequest FromNextFromIdAsc(IEnumerable<long> idSelector) => new PageRequest { NextFromId = (idSelector.Max() + 1).ToString() };
|
||||
public static PageRequest FromNextFromIdDesc(IEnumerable<long> idSelector) => new PageRequest { NextFromId = (idSelector.Min() - 1).ToString() };
|
||||
public static PageRequest FromNextStartTimeAsc(IEnumerable<DateTime> timestampSelector) => new PageRequest { NextStartTime = timestampSelector.Max().AddMilliseconds(1) };
|
||||
public static PageRequest FromNextStartTimeDesc(IEnumerable<DateTime> timestampSelector) => new PageRequest { NextStartTime = timestampSelector.Min().AddMilliseconds(-1) };
|
||||
public static PageRequest FromNextEndTimeAsc(IEnumerable<DateTime> timestampSelector) => new PageRequest { NextEndTime = timestampSelector.Max().AddMilliseconds(1) };
|
||||
public static PageRequest FromNextEndTimeDesc(IEnumerable<DateTime> timestampSelector) => new PageRequest { NextEndTime = timestampSelector.Min().AddMilliseconds(-1) };
|
||||
public static PageRequest NextFromIdAsc(IEnumerable<long> idSelector) => new PageRequest { FromId = (idSelector.Max() + 1).ToString() };
|
||||
public static PageRequest NextFromIdDesc(IEnumerable<long> idSelector) => new PageRequest { FromId = (idSelector.Min() - 1).ToString() };
|
||||
public static PageRequest NextStartTimeAsc(IEnumerable<DateTime> timestampSelector) => new PageRequest { StartTime = timestampSelector.Max().AddMilliseconds(1) };
|
||||
public static PageRequest NextEndTimeDesc(IEnumerable<DateTime> timestampSelector) => new PageRequest { EndTime = timestampSelector.Min().AddMilliseconds(-1) };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -19,8 +19,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// Max number of results
|
||||
/// </summary>
|
||||
public int? Limit { get; }
|
||||
|
||||
public PageDirection? Direction { get; set; }
|
||||
/// <summary>
|
||||
/// Data direction
|
||||
/// </summary>
|
||||
public DataDirection? Direction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
@ -29,12 +31,14 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="startTime">Filter by start time</param>
|
||||
/// <param name="endTime">Filter by end time</param>
|
||||
/// <param name="limit">Max number of results</param>
|
||||
/// <param name="direction">Data direction</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;
|
||||
EndTime = endTime;
|
||||
Limit = limit;
|
||||
Direction = direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// Max number of results
|
||||
/// </summary>
|
||||
public int? Limit { get; }
|
||||
/// <summary>
|
||||
/// Data direction
|
||||
/// </summary>
|
||||
public DataDirection? Direction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
@ -31,13 +35,15 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="startTime">Filter by start time</param>
|
||||
/// <param name="endTime">Filter by end time</param>
|
||||
/// <param name="limit">Max number of results</param>
|
||||
/// <param name="direction">Data direction</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;
|
||||
StartTime = startTime;
|
||||
EndTime = endTime;
|
||||
Limit = limit;
|
||||
Direction = direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// Max number of results
|
||||
/// </summary>
|
||||
public int? Limit { get; set; }
|
||||
/// <summary>
|
||||
/// Data direction
|
||||
/// </summary>
|
||||
public DataDirection? Direction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
@ -27,12 +31,14 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="startTime">Filter by start time</param>
|
||||
/// <param name="endTime">Filter by end time</param>
|
||||
/// <param name="limit">Max number of results</param>
|
||||
/// <param name="direction">Data direction</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;
|
||||
EndTime = endTime;
|
||||
Limit = limit;
|
||||
Direction = direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// Max number of results
|
||||
/// </summary>
|
||||
public int? Limit { get; set; }
|
||||
/// <summary>
|
||||
/// Data direction
|
||||
/// </summary>
|
||||
public DataDirection? Direction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
@ -32,13 +36,15 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="startTime">Filter by start time</param>
|
||||
/// <param name="endTime">Filter by end time</param>
|
||||
/// <param name="limit">Max number of results</param>
|
||||
/// <param name="direction">Data direction</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;
|
||||
StartTime = startTime;
|
||||
EndTime = endTime;
|
||||
Limit = limit;
|
||||
Direction = direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,6 +27,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// Max number of results
|
||||
/// </summary>
|
||||
public int? Limit { get; set; }
|
||||
/// <summary>
|
||||
/// Data direction
|
||||
/// </summary>
|
||||
public DataDirection? Direction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
@ -35,13 +39,15 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="startTime">Filter by start time</param>
|
||||
/// <param name="endTime">Filter by end time</param>
|
||||
/// <param name="limit">Max number of results</param>
|
||||
/// <param name="direction">Data direction</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;
|
||||
StartTime = startTime;
|
||||
EndTime = endTime;
|
||||
Limit = limit;
|
||||
Direction = direction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -51,13 +57,15 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="startTime">Filter by start time</param>
|
||||
/// <param name="endTime">Filter by end time</param>
|
||||
/// <param name="limit">Max number of results</param>
|
||||
/// <param name="direction">Data direction</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;
|
||||
StartTime = startTime;
|
||||
EndTime = endTime;
|
||||
Limit = limit;
|
||||
Direction = direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,8 +19,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// Max number of results
|
||||
/// </summary>
|
||||
public int? Limit { get; set; }
|
||||
|
||||
public PageDirection? Direction { get; set; }
|
||||
/// <summary>
|
||||
/// Data direction
|
||||
/// </summary>
|
||||
public DataDirection? Direction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
@ -29,12 +31,14 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="startTime">Filter by start time</param>
|
||||
/// <param name="endTime">Filter by end time</param>
|
||||
/// <param name="limit">Max number of results</param>
|
||||
/// <param name="direction">Data direction</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, int? limit = null, DataDirection? direction = null, ExchangeParameters? exchangeParameters = null) : base(symbol, exchangeParameters)
|
||||
{
|
||||
StartTime = startTime;
|
||||
EndTime = endTime;
|
||||
Limit = limit;
|
||||
Direction = direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// Max number of results
|
||||
/// </summary>
|
||||
public int? Limit { get; }
|
||||
/// <summary>
|
||||
/// Data direction
|
||||
/// </summary>
|
||||
public DataDirection? Direction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
@ -27,12 +31,14 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="startTime">Filter by start time</param>
|
||||
/// <param name="endTime">Filter by end time</param>
|
||||
/// <param name="limit">Max number of results</param>
|
||||
/// <param name="direction">Data direction</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;
|
||||
EndTime = endTime;
|
||||
Limit = limit;
|
||||
Direction = direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// Max number of results
|
||||
/// </summary>
|
||||
public int? Limit { get; }
|
||||
/// <summary>
|
||||
/// Data direction
|
||||
/// </summary>
|
||||
public DataDirection? Direction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
@ -31,13 +35,15 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="startTime">Filter by start time</param>
|
||||
/// <param name="endTime">Filter by end time</param>
|
||||
/// <param name="limit">Max number of results</param>
|
||||
/// <param name="direction">Data direction</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;
|
||||
StartTime = startTime;
|
||||
EndTime = endTime;
|
||||
Limit = limit;
|
||||
Direction = direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user