mirror of
https://github.com/JKorf/CryptoExchange.Net.git
synced 2026-10-14 07:01:46 +00:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 45a42fb028 | |||
| c59bb0f625 | |||
| 8419af278d | |||
| 911e09be61 | |||
| 876c2d27f7 | |||
| dc4a6af695 | |||
| c56e31abab | |||
| 08972d3d63 | |||
| 357809fd0c | |||
| 7629455dec | |||
| 9df960361a | |||
| f215b729ed | |||
| 431ef93611 | |||
| a545efbb45 | |||
| 67bf7d08cb | |||
| 2704693600 | |||
| 1643487e73 | |||
| 1a0101a45f | |||
| 20977e28b7 | |||
| d0f5a8d6cc | |||
| 2fff7a307f | |||
| ca2bf414a7 | |||
| 5f101e3b88 | |||
| 32e74e9bc4 | |||
| d93d6b7a2e | |||
| d0ce2563de | |||
| 407509e9cd | |||
| 3dd68dcad4 |
@@ -0,0 +1,281 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CryptoExchange.Net.UnitTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class RequestCoalescerTests
|
||||
{
|
||||
private static readonly TimeSpan _testTimeout = TimeSpan.FromSeconds(5);
|
||||
|
||||
[Test]
|
||||
public async Task ExecuteAsync_WithIdenticalRequests_ShouldExecuteRequestOnce()
|
||||
{
|
||||
var coalescer = CreateCoalescer();
|
||||
var key = CreateKey();
|
||||
var requestCompletion = CreateCompletionSource<string>();
|
||||
var requestStarted = CreateCompletionSource<bool>();
|
||||
var requestCount = 0;
|
||||
|
||||
async Task<string> ExecuteRequest(CancellationToken cancellationToken)
|
||||
{
|
||||
Interlocked.Increment(ref requestCount);
|
||||
requestStarted.TrySetResult(true);
|
||||
return await requestCompletion.Task;
|
||||
}
|
||||
|
||||
var first = coalescer.ExecuteAsync(key, ExecuteRequest, () => "canceled", CancellationToken.None);
|
||||
await requestStarted.Task.WaitAsync(_testTimeout);
|
||||
var second = coalescer.ExecuteAsync(key, ExecuteRequest, () => "canceled", CancellationToken.None);
|
||||
|
||||
Assert.That(requestCount, Is.EqualTo(1));
|
||||
|
||||
requestCompletion.SetResult("result");
|
||||
|
||||
Assert.That(await first.WaitAsync(_testTimeout), Is.EqualTo("result"));
|
||||
Assert.That(await second.WaitAsync(_testTimeout), Is.EqualTo("result"));
|
||||
Assert.That(requestCount, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExecuteAsync_WithDifferentKeys_ShouldExecuteEachRequest()
|
||||
{
|
||||
var coalescer = CreateCoalescer();
|
||||
var firstCompletion = CreateCompletionSource<string>();
|
||||
var secondCompletion = CreateCompletionSource<string>();
|
||||
var firstStarted = CreateCompletionSource<bool>();
|
||||
var secondStarted = CreateCompletionSource<bool>();
|
||||
var requestCount = 0;
|
||||
|
||||
var first = coalescer.ExecuteAsync(
|
||||
CreateKey(parameters: "symbol=ETH"),
|
||||
async cancellationToken =>
|
||||
{
|
||||
Interlocked.Increment(ref requestCount);
|
||||
firstStarted.TrySetResult(true);
|
||||
return await firstCompletion.Task;
|
||||
},
|
||||
() => "canceled",
|
||||
CancellationToken.None);
|
||||
|
||||
var second = coalescer.ExecuteAsync(
|
||||
CreateKey(parameters: "symbol=BTC"),
|
||||
async cancellationToken =>
|
||||
{
|
||||
Interlocked.Increment(ref requestCount);
|
||||
secondStarted.TrySetResult(true);
|
||||
return await secondCompletion.Task;
|
||||
},
|
||||
() => "canceled",
|
||||
CancellationToken.None);
|
||||
|
||||
await Task.WhenAll(firstStarted.Task, secondStarted.Task).WaitAsync(_testTimeout);
|
||||
Assert.That(requestCount, Is.EqualTo(2));
|
||||
|
||||
firstCompletion.SetResult("first");
|
||||
secondCompletion.SetResult("second");
|
||||
|
||||
Assert.That(await first.WaitAsync(_testTimeout), Is.EqualTo("first"));
|
||||
Assert.That(await second.WaitAsync(_testTimeout), Is.EqualTo("second"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExecuteAsync_WhenOneListenerCancels_ShouldKeepSharedRequestRunning()
|
||||
{
|
||||
var coalescer = CreateCoalescer();
|
||||
var requestCompletion = CreateCompletionSource<string>();
|
||||
var requestStarted = CreateCompletionSource<CancellationToken>();
|
||||
var requestCount = 0;
|
||||
using var firstCancellationSource = new CancellationTokenSource();
|
||||
|
||||
async Task<string> ExecuteRequest(CancellationToken cancellationToken)
|
||||
{
|
||||
Interlocked.Increment(ref requestCount);
|
||||
requestStarted.TrySetResult(cancellationToken);
|
||||
return await requestCompletion.Task;
|
||||
}
|
||||
|
||||
var first = coalescer.ExecuteAsync(CreateKey(), ExecuteRequest, () => "canceled", firstCancellationSource.Token);
|
||||
var requestCancellationToken = await requestStarted.Task.WaitAsync(_testTimeout);
|
||||
var second = coalescer.ExecuteAsync(CreateKey(), ExecuteRequest, () => "canceled", CancellationToken.None);
|
||||
|
||||
firstCancellationSource.Cancel();
|
||||
|
||||
Assert.That(await first.WaitAsync(_testTimeout), Is.EqualTo("canceled"));
|
||||
Assert.That(requestCancellationToken.IsCancellationRequested, Is.False);
|
||||
Assert.That(requestCount, Is.EqualTo(1));
|
||||
|
||||
requestCompletion.SetResult("result");
|
||||
|
||||
Assert.That(await second.WaitAsync(_testTimeout), Is.EqualTo("result"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExecuteAsync_WhenAllListenersCancel_ShouldCancelSharedRequest()
|
||||
{
|
||||
var coalescer = CreateCoalescer();
|
||||
var requestStarted = CreateCompletionSource<bool>();
|
||||
var requestCanceled = CreateCompletionSource<bool>();
|
||||
using var firstCancellationSource = new CancellationTokenSource();
|
||||
using var secondCancellationSource = new CancellationTokenSource();
|
||||
|
||||
async Task<string> ExecuteRequest(CancellationToken cancellationToken)
|
||||
{
|
||||
using (cancellationToken.Register(() => requestCanceled.TrySetResult(true)))
|
||||
{
|
||||
requestStarted.TrySetResult(true);
|
||||
await requestCanceled.Task;
|
||||
return "request canceled";
|
||||
}
|
||||
}
|
||||
|
||||
var first = coalescer.ExecuteAsync(CreateKey(), ExecuteRequest, () => "listener canceled", firstCancellationSource.Token);
|
||||
await requestStarted.Task.WaitAsync(_testTimeout);
|
||||
var second = coalescer.ExecuteAsync(CreateKey(), ExecuteRequest, () => "listener canceled", secondCancellationSource.Token);
|
||||
|
||||
firstCancellationSource.Cancel();
|
||||
Assert.That(await first.WaitAsync(_testTimeout), Is.EqualTo("listener canceled"));
|
||||
Assert.That(requestCanceled.Task.IsCompleted, Is.False);
|
||||
|
||||
secondCancellationSource.Cancel();
|
||||
|
||||
Assert.That(await second.WaitAsync(_testTimeout), Is.EqualTo("listener canceled"));
|
||||
Assert.That(await requestCanceled.Task.WaitAsync(_testTimeout), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExecuteAsync_WithAlreadyCanceledListener_ShouldNotStartRequest()
|
||||
{
|
||||
var coalescer = CreateCoalescer();
|
||||
var requestCount = 0;
|
||||
using var cancellationSource = new CancellationTokenSource();
|
||||
cancellationSource.Cancel();
|
||||
|
||||
var result = await coalescer.ExecuteAsync(
|
||||
CreateKey(),
|
||||
cancellationToken =>
|
||||
{
|
||||
Interlocked.Increment(ref requestCount);
|
||||
return Task.FromResult("result");
|
||||
},
|
||||
() => "canceled",
|
||||
cancellationSource.Token);
|
||||
|
||||
Assert.That(result, Is.EqualTo("canceled"));
|
||||
Assert.That(requestCount, Is.Zero);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExecuteAsync_AfterRequestCompletes_ShouldStartNewRequest()
|
||||
{
|
||||
var coalescer = CreateCoalescer();
|
||||
var requestCount = 0;
|
||||
|
||||
Task<int> ExecuteRequest(CancellationToken cancellationToken)
|
||||
=> Task.FromResult(Interlocked.Increment(ref requestCount));
|
||||
|
||||
var first = await coalescer.ExecuteAsync(CreateKey(typeof(int)), ExecuteRequest, () => -1, CancellationToken.None);
|
||||
var second = await coalescer.ExecuteAsync(CreateKey(typeof(int)), ExecuteRequest, () => -1, CancellationToken.None);
|
||||
|
||||
Assert.That(first, Is.EqualTo(1));
|
||||
Assert.That(second, Is.EqualTo(2));
|
||||
Assert.That(requestCount, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExecuteAsync_AfterRequestFails_ShouldStartNewRequest()
|
||||
{
|
||||
var coalescer = CreateCoalescer();
|
||||
var requestCount = 0;
|
||||
|
||||
Task<string> ExecuteRequest(CancellationToken cancellationToken)
|
||||
{
|
||||
if (Interlocked.Increment(ref requestCount) == 1)
|
||||
return Task.FromException<string>(new InvalidOperationException("Request failed"));
|
||||
|
||||
return Task.FromResult("result");
|
||||
}
|
||||
|
||||
Assert.ThrowsAsync<InvalidOperationException>(async () =>
|
||||
await coalescer.ExecuteAsync(CreateKey(), ExecuteRequest, () => "canceled", CancellationToken.None));
|
||||
|
||||
Assert.That(
|
||||
coalescer.ExecuteAsync(CreateKey(), ExecuteRequest, () => "canceled", CancellationToken.None).GetAwaiter().GetResult(),
|
||||
Is.EqualTo("result"));
|
||||
Assert.That(requestCount, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExecuteAsync_WhenAbandonedRequestCompletes_ShouldNotRemoveReplacementRequest()
|
||||
{
|
||||
var coalescer = CreateCoalescer();
|
||||
var key = CreateKey();
|
||||
var oldRequestCompletion = CreateCompletionSource<string>();
|
||||
var oldRequestStarted = CreateCompletionSource<bool>();
|
||||
var replacementCompletion = CreateCompletionSource<string>();
|
||||
var replacementStarted = CreateCompletionSource<bool>();
|
||||
var requestCount = 0;
|
||||
using var cancellationSource = new CancellationTokenSource();
|
||||
|
||||
async Task<string> ExecuteOldRequest(CancellationToken cancellationToken)
|
||||
{
|
||||
Interlocked.Increment(ref requestCount);
|
||||
oldRequestStarted.TrySetResult(true);
|
||||
return await oldRequestCompletion.Task;
|
||||
}
|
||||
|
||||
async Task<string> ExecuteReplacementRequest(CancellationToken cancellationToken)
|
||||
{
|
||||
Interlocked.Increment(ref requestCount);
|
||||
replacementStarted.TrySetResult(true);
|
||||
return await replacementCompletion.Task;
|
||||
}
|
||||
|
||||
var abandonedListener = coalescer.ExecuteAsync(key, ExecuteOldRequest, () => "canceled", cancellationSource.Token);
|
||||
await oldRequestStarted.Task.WaitAsync(_testTimeout);
|
||||
var oldPhysicalRequest = GetPhysicalRequest(coalescer, key);
|
||||
|
||||
cancellationSource.Cancel();
|
||||
Assert.That(await abandonedListener.WaitAsync(_testTimeout), Is.EqualTo("canceled"));
|
||||
|
||||
var replacementListener = coalescer.ExecuteAsync(key, ExecuteReplacementRequest, () => "canceled", CancellationToken.None);
|
||||
await replacementStarted.Task.WaitAsync(_testTimeout);
|
||||
|
||||
oldRequestCompletion.SetResult("old result");
|
||||
await oldPhysicalRequest.WaitAsync(_testTimeout);
|
||||
|
||||
var joinedReplacementListener = coalescer.ExecuteAsync(key, ExecuteReplacementRequest, () => "canceled", CancellationToken.None);
|
||||
Assert.That(requestCount, Is.EqualTo(2));
|
||||
|
||||
replacementCompletion.SetResult("replacement result");
|
||||
|
||||
Assert.That(await replacementListener.WaitAsync(_testTimeout), Is.EqualTo("replacement result"));
|
||||
Assert.That(await joinedReplacementListener.WaitAsync(_testTimeout), Is.EqualTo("replacement result"));
|
||||
Assert.That(requestCount, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
private static RequestCoalescer CreateCoalescer()
|
||||
=> new RequestCoalescer(NullLogger.Instance);
|
||||
|
||||
private static RequestCoalescingKey CreateKey(Type? responseType = null, string? parameters = null)
|
||||
=> new RequestCoalescingKey("GET", "https://localhost/test", parameters, responseType ?? typeof(string));
|
||||
|
||||
private static TaskCompletionSource<T> CreateCompletionSource<T>()
|
||||
=> new TaskCompletionSource<T>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
private static Task GetPhysicalRequest(RequestCoalescer coalescer, RequestCoalescingKey key)
|
||||
{
|
||||
var requestsField = typeof(RequestCoalescer).GetField("_requests", BindingFlags.Instance | BindingFlags.NonPublic)!;
|
||||
var requests = (IDictionary)requestsField.GetValue(coalescer)!;
|
||||
var entry = requests[key]!;
|
||||
var requestProperty = entry.GetType().GetProperty("Request")!;
|
||||
return ((Lazy<Task<object>>)requestProperty.GetValue(entry)!).Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
using CryptoExchange.Net.SharedApis;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
|
||||
namespace CryptoExchange.Net.UnitTests
|
||||
{
|
||||
[TestFixture]
|
||||
internal class SharedApiClientTests
|
||||
{
|
||||
[Test]
|
||||
public void GetCapability_ShouldUseCapabilityTradingModes()
|
||||
{
|
||||
var sharedApi = new TestSharedApi(
|
||||
[TradingMode.Spot, TradingMode.PerpetualLinear],
|
||||
[TradingMode.Spot]);
|
||||
var client = new TestSharedApiClient(sharedApi);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(client.GetCapability<ITestCapability>(TradingMode.Spot)?.Capability, Is.SameAs(sharedApi));
|
||||
Assert.That(client.GetCapability<ITestCapability>(TradingMode.PerpetualLinear), Is.Null);
|
||||
Assert.That(client.GetCapabilities<ITestCapability>(TradingMode.Spot), Has.Count.EqualTo(1));
|
||||
Assert.That(client.GetCapabilities<ITestCapability>(TradingMode.PerpetualLinear), Is.Empty);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CapabilityTradingModes_ShouldDefaultToSharedApiTradingModes()
|
||||
{
|
||||
var sharedApi = new TestSharedApi(
|
||||
[TradingMode.Spot, TradingMode.PerpetualLinear],
|
||||
null);
|
||||
var client = new TestSharedApiClient(sharedApi);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(client.GetCapability<ITestCapability>(TradingMode.Spot)?.Capability, Is.SameAs(sharedApi));
|
||||
Assert.That(client.GetCapability<ITestCapability>(TradingMode.PerpetualLinear)?.Capability, Is.SameAs(sharedApi));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCapabilities_WithReference_ShouldReturnMatchingCapabilities()
|
||||
{
|
||||
var sharedApi = new TestSharedApi(
|
||||
[TradingMode.Spot],
|
||||
[TradingMode.Spot]);
|
||||
var client = new TestSharedApiClient(sharedApi);
|
||||
|
||||
var result = client.GetCapabilities(
|
||||
new SharedCapabilityReference<ITestCapability>(),
|
||||
TradingMode.Spot);
|
||||
|
||||
Assert.That(result, Has.Count.EqualTo(1));
|
||||
Assert.That(result[0].Capability, Is.SameAs(sharedApi));
|
||||
Assert.That(result[0].Options, Is.SameAs(sharedApi.CapabilityOptions));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Discover_ShouldReturnAllSharedApiInformation()
|
||||
{
|
||||
var restApi = new TestRestSharedApi();
|
||||
var socketApi = new TestSocketSharedApi();
|
||||
var client = new TestDiSharedApiClient(
|
||||
restApi,
|
||||
socketApi);
|
||||
|
||||
var result = client.Discover();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(result.PreferredTransport, Is.EqualTo(SharedTransport.Socket));
|
||||
Assert.That(result.SharedApis, Has.Length.EqualTo(2));
|
||||
Assert.That(result.SharedApis[0].Transport, Is.EqualTo(SharedTransport.Rest));
|
||||
Assert.That(result.SharedApis[1].Transport, Is.EqualTo(SharedTransport.Socket));
|
||||
Assert.That(result.SharedApis[0].SupportedTradingModes, Is.EqualTo(new[] { TradingMode.Spot }));
|
||||
Assert.That(result.SharedApis[0].Capabilities, Has.Length.EqualTo(1));
|
||||
Assert.That(result.SharedApis[0].Authenticated, Is.False);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RegisterSharedApiClient_ShouldResolvePreferredTransport()
|
||||
{
|
||||
var restApi = new TestRestSharedApi();
|
||||
var socketApi = new TestSocketSharedApi();
|
||||
var services = new ServiceCollection();
|
||||
|
||||
services.AddSingleton(restApi);
|
||||
services.AddSingleton(socketApi);
|
||||
|
||||
services.RegisterSharedApiClient<
|
||||
ITestSharedApiClient,
|
||||
TestDiSharedApiClient>(sharedApis => sharedApis
|
||||
.Add(client => client.Rest)
|
||||
.Add(client => client.Socket));
|
||||
|
||||
using var provider = services.BuildServiceProvider();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(
|
||||
provider.GetRequiredService<ITestSharedApiClient>(),
|
||||
Is.Not.Null);
|
||||
|
||||
Assert.That(
|
||||
provider.GetRequiredService<ISharedApiClientBase>(),
|
||||
Is.InstanceOf<TestDiSharedApiClient>());
|
||||
|
||||
Assert.That(
|
||||
provider.GetRequiredService<ITestCapability>(),
|
||||
Is.SameAs(socketApi));
|
||||
|
||||
Assert.That(
|
||||
provider.GetServices<ITestCapability>().ToArray(),
|
||||
Is.EqualTo(new[] { socketApi }));
|
||||
|
||||
Assert.That(
|
||||
provider.GetRequiredService<ITestRestCapability>(),
|
||||
Is.SameAs(restApi));
|
||||
|
||||
Assert.That(
|
||||
provider.GetRequiredService<ITestSocketCapability>(),
|
||||
Is.SameAs(socketApi));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CapabilityTradingModes_ShouldIntersectApiApplicableAndOverrideModes()
|
||||
{
|
||||
var sharedApi = new TestSharedApi(
|
||||
[TradingMode.Spot, TradingMode.PerpetualLinear, TradingMode.DeliveryLinear],
|
||||
[TradingMode.Spot, TradingMode.PerpetualLinear],
|
||||
[TradingMode.PerpetualLinear, TradingMode.DeliveryLinear]);
|
||||
|
||||
Assert.That(
|
||||
sharedApi.CapabilityOptions.SupportedTradingModes,
|
||||
Is.EqualTo(new[] { TradingMode.PerpetualLinear }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CapabilityOptions_ShouldApplyIntrinsicTradingModes()
|
||||
{
|
||||
var apiModes = new[]
|
||||
{
|
||||
TradingMode.Spot,
|
||||
TradingMode.PerpetualLinear,
|
||||
TradingMode.DeliveryLinear,
|
||||
TradingMode.PerpetualInverse,
|
||||
TradingMode.DeliveryInverse
|
||||
};
|
||||
var spotOptions = new PlaceSpotOrderOptions("TestExchange");
|
||||
var futuresOptions = new GetPositionsOptions("TestExchange", false);
|
||||
var perpetualOptions = new GetFundingRateHistoryOptions(
|
||||
"TestExchange",
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
100,
|
||||
false);
|
||||
var unrestrictedOptions = new GetTickerOptions("TestExchange");
|
||||
|
||||
_ = new TestOptionsHost(apiModes, spotOptions);
|
||||
_ = new TestOptionsHost(apiModes, futuresOptions);
|
||||
_ = new TestOptionsHost(apiModes, perpetualOptions);
|
||||
_ = new TestOptionsHost(apiModes, unrestrictedOptions);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(spotOptions.SupportedTradingModes, Is.EqualTo(new[] { TradingMode.Spot }));
|
||||
Assert.That(futuresOptions.SupportedTradingModes, Is.EqualTo(new[]
|
||||
{
|
||||
TradingMode.PerpetualLinear,
|
||||
TradingMode.DeliveryLinear,
|
||||
TradingMode.PerpetualInverse,
|
||||
TradingMode.DeliveryInverse
|
||||
}));
|
||||
Assert.That(perpetualOptions.SupportedTradingModes, Is.EqualTo(new[]
|
||||
{
|
||||
TradingMode.PerpetualLinear,
|
||||
TradingMode.PerpetualInverse
|
||||
}));
|
||||
Assert.That(unrestrictedOptions.SupportedTradingModes, Is.EqualTo(apiModes));
|
||||
});
|
||||
}
|
||||
|
||||
private interface ITestCapability : ISharedApiCapability
|
||||
{
|
||||
}
|
||||
|
||||
private interface ITestRestCapability : ITestCapability, ISharedRest
|
||||
{
|
||||
}
|
||||
|
||||
private interface ITestSocketCapability : ITestCapability, ISharedSocket
|
||||
{
|
||||
}
|
||||
|
||||
private interface ITestRestSharedApi : ITestRestCapability
|
||||
{
|
||||
}
|
||||
|
||||
private interface ITestSocketSharedApi : ITestSocketCapability
|
||||
{
|
||||
}
|
||||
|
||||
private interface ITestSharedApiClient : ISharedApiClientBase
|
||||
{
|
||||
ITestRestSharedApi Rest { get; }
|
||||
ITestSocketSharedApi Socket { get; }
|
||||
}
|
||||
|
||||
private sealed class TestCapabilityOptions : CapabilityOptions<SharedRequest, ITestCapability>
|
||||
{
|
||||
public override string Description => "Test capability";
|
||||
|
||||
public TestCapabilityOptions(TradingMode[]? applicableTradingModes)
|
||||
: base("TestExchange", false, "TestOperation", [], applicableTradingModes)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class TestSharedApi : SharedApiBase, ITestCapability
|
||||
{
|
||||
public TestCapabilityOptions CapabilityOptions { get; }
|
||||
|
||||
public TestSharedApi(TradingMode[] apiTradingModes, TradingMode[]? capabilityTradingModes)
|
||||
: this(apiTradingModes, capabilityTradingModes, null)
|
||||
{
|
||||
}
|
||||
|
||||
public TestSharedApi(
|
||||
TradingMode[] apiTradingModes,
|
||||
TradingMode[]? capabilityTradingModes,
|
||||
TradingMode[]? applicableTradingModes)
|
||||
: base(
|
||||
SharedTransport.Rest,
|
||||
"TestExchange",
|
||||
apiTradingModes,
|
||||
() => false,
|
||||
(baseAsset, quoteAsset, tradingMode, deliverDate) => $"{baseAsset}{quoteAsset}")
|
||||
{
|
||||
var options = new TestCapabilityOptions(applicableTradingModes)
|
||||
{
|
||||
SupportedTradingModeOverrides = capabilityTradingModes
|
||||
};
|
||||
|
||||
SetCapabilities(options);
|
||||
CapabilityOptions = options;
|
||||
}
|
||||
|
||||
public override SharedClientInfo Discover() => new();
|
||||
}
|
||||
|
||||
private sealed class TestOptionsHost : SharedApiBase
|
||||
{
|
||||
public TestOptionsHost(TradingMode[] apiTradingModes, CapabilityOptions capabilityOptions)
|
||||
: base(
|
||||
SharedTransport.Rest,
|
||||
"TestExchange",
|
||||
apiTradingModes,
|
||||
() => false,
|
||||
(baseAsset, quoteAsset, tradingMode, deliverDate) => $"{baseAsset}{quoteAsset}")
|
||||
{
|
||||
SetCapabilities(capabilityOptions);
|
||||
}
|
||||
|
||||
public override SharedClientInfo Discover() => new();
|
||||
}
|
||||
|
||||
private abstract class TestTransportSharedApi : SharedApiBase
|
||||
{
|
||||
protected TestTransportSharedApi(SharedTransport transport)
|
||||
: base(
|
||||
transport,
|
||||
"TestExchange",
|
||||
[TradingMode.Spot],
|
||||
() => false,
|
||||
(baseAsset, quoteAsset, tradingMode, deliverDate) => $"{baseAsset}{quoteAsset}")
|
||||
{
|
||||
SetCapabilities(new TestCapabilityOptions([TradingMode.Spot]));
|
||||
}
|
||||
|
||||
public override SharedClientInfo Discover() => new()
|
||||
{
|
||||
Exchange = this.Exchange,
|
||||
TypeName = GetType().Name,
|
||||
SupportedTradingModes = this.SupportedTradingModes,
|
||||
Transport = this.Transport,
|
||||
Authenticated = this.Authenticated,
|
||||
Capabilities = ((ISharedApi)this).Capabilities.ToArray()
|
||||
};
|
||||
}
|
||||
|
||||
private sealed class TestRestSharedApi : TestTransportSharedApi, ITestRestSharedApi
|
||||
{
|
||||
public TestRestSharedApi() : base(SharedTransport.Rest)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class TestSocketSharedApi : TestTransportSharedApi, ITestSocketSharedApi
|
||||
{
|
||||
public TestSocketSharedApi() : base(SharedTransport.Socket)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class TestDiSharedApiClient : SharedApiClientBase, ITestSharedApiClient
|
||||
{
|
||||
public ITestRestSharedApi Rest { get; }
|
||||
public ITestSocketSharedApi Socket { get; }
|
||||
|
||||
public TestDiSharedApiClient(
|
||||
TestRestSharedApi rest,
|
||||
TestSocketSharedApi socket)
|
||||
: base(SharedTransport.Socket, rest, socket)
|
||||
{
|
||||
Rest = rest;
|
||||
Socket = socket;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class TestSharedApiClient : SharedApiClientBase
|
||||
{
|
||||
public TestSharedApiClient(params ISharedApiCapability[] sharedApis)
|
||||
: base(SharedTransport.Rest, sharedApis)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using CryptoExchange.Net.SharedApis;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CryptoExchange.Net.UnitTests
|
||||
{
|
||||
[TestFixture]
|
||||
internal class SharedCapabilitiesTests
|
||||
{
|
||||
[Test]
|
||||
public void AllSharedApiCapabilities_ShouldBeListedInSharedCapabilities()
|
||||
{
|
||||
var markerTypes = new[]
|
||||
{
|
||||
typeof(ISharedApiCapability),
|
||||
typeof(ISharedRest),
|
||||
typeof(ISharedSocket),
|
||||
typeof(ISharedSubscription)
|
||||
};
|
||||
|
||||
var expectedCapabilities = typeof(ISharedApiCapability).Assembly
|
||||
.GetTypes()
|
||||
.Where(x => x.IsInterface
|
||||
&& typeof(ISharedApiCapability).IsAssignableFrom(x)
|
||||
&& !markerTypes.Contains(x))
|
||||
.OrderBy(x => x.FullName)
|
||||
.ToArray();
|
||||
|
||||
var listedCapabilities = GetTypeAndNestedTypes(typeof(SharedCapabilities))
|
||||
.SelectMany(x => x.GetProperties(
|
||||
BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly))
|
||||
.SelectMany(x => x.PropertyType.GetGenericArguments())
|
||||
.Where(x => x.IsInterface
|
||||
&& typeof(ISharedApiCapability).IsAssignableFrom(x))
|
||||
.ToArray();
|
||||
|
||||
var missingCapabilities = expectedCapabilities
|
||||
.Except(listedCapabilities)
|
||||
.Select(x => x.Name)
|
||||
.ToArray();
|
||||
|
||||
var unknownCapabilities = listedCapabilities
|
||||
.Except(expectedCapabilities)
|
||||
.Select(x => x.Name)
|
||||
.ToArray();
|
||||
|
||||
var duplicateCapabilities = listedCapabilities
|
||||
.GroupBy(x => x)
|
||||
.Where(x => x.Count() > 1)
|
||||
.Select(x => x.Key.Name)
|
||||
.ToArray();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(
|
||||
missingCapabilities,
|
||||
Is.Empty,
|
||||
$"Capabilities missing from SharedCapabilities: " +
|
||||
string.Join(", ", missingCapabilities));
|
||||
|
||||
Assert.That(
|
||||
unknownCapabilities,
|
||||
Is.Empty,
|
||||
$"Unknown capabilities listed in SharedCapabilities: " +
|
||||
string.Join(", ", unknownCapabilities));
|
||||
|
||||
Assert.That(
|
||||
duplicateCapabilities,
|
||||
Is.Empty,
|
||||
$"Capabilities listed multiple times in SharedCapabilities: " +
|
||||
string.Join(", ", duplicateCapabilities));
|
||||
});
|
||||
}
|
||||
|
||||
private static IEnumerable<Type> GetTypeAndNestedTypes(Type type)
|
||||
{
|
||||
yield return type;
|
||||
|
||||
foreach (var nestedType in type.GetNestedTypes(BindingFlags.Public))
|
||||
{
|
||||
foreach (var result in GetTypeAndNestedTypes(nestedType))
|
||||
yield return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
using NUnit.Framework;
|
||||
using CryptoExchange.Net.SharedApis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CryptoExchange.Net.UnitTests
|
||||
{
|
||||
[TestFixture]
|
||||
internal class SharedParametersTests
|
||||
{
|
||||
[Test]
|
||||
public void AllSharedAPIOptions_ShouldListAllDefaultParametersInRequestParameterRules()
|
||||
{
|
||||
var failures = new List<string>();
|
||||
|
||||
var optionsTypes = typeof(CapabilityOptions).Assembly
|
||||
.GetTypes()
|
||||
.Where(x => x.IsClass
|
||||
&& !x.IsAbstract
|
||||
&& typeof(CapabilityOptions).IsAssignableFrom(x))
|
||||
.OrderBy(x => x.FullName)
|
||||
.ToArray();
|
||||
|
||||
foreach (var optionsType in optionsTypes)
|
||||
{
|
||||
var genericOptionsType = GetGenericOptionsType(optionsType);
|
||||
if (genericOptionsType == null)
|
||||
{
|
||||
if (optionsType == typeof(ClosePositionOptions))
|
||||
continue;
|
||||
|
||||
failures.Add($"{optionsType.Name}: unable to determine request type");
|
||||
continue;
|
||||
}
|
||||
|
||||
var requestType = genericOptionsType.GetGenericArguments()[0];
|
||||
var defaultRulesField = GetDefaultParameterRulesField(optionsType);
|
||||
if (defaultRulesField == null)
|
||||
{
|
||||
failures.Add($"{optionsType.Name}: no _defaultParameterRules field found");
|
||||
continue;
|
||||
}
|
||||
|
||||
var rules = (RequestParameterDescription[]?)defaultRulesField.GetValue(null);
|
||||
if (rules == null)
|
||||
{
|
||||
failures.Add($"{optionsType.Name}: _defaultParameterRules is null");
|
||||
continue;
|
||||
}
|
||||
|
||||
var constructorParameterNames = requestType
|
||||
.GetConstructors(BindingFlags.Instance | BindingFlags.Public)
|
||||
.SelectMany(x => x.GetParameters())
|
||||
.Where(x => !string.Equals(
|
||||
x.Name,
|
||||
"exchangeParameters",
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
.Select(x => x.Name!)
|
||||
.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var parameterProperties = requestType
|
||||
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
|
||||
.Where(x => x.DeclaringType == requestType
|
||||
|| constructorParameterNames.Contains(x.Name))
|
||||
.Where(x => x.Name != nameof(SharedRequest.ExchangeParameters))
|
||||
.Select(x => x.Name)
|
||||
.OrderBy(x => x)
|
||||
.ToArray();
|
||||
|
||||
var ruleNames = rules
|
||||
.Select(x => x.Name)
|
||||
.ToHashSet(StringComparer.Ordinal);
|
||||
|
||||
foreach (var parameterProperty in parameterProperties)
|
||||
{
|
||||
if (!ruleNames.Contains(parameterProperty))
|
||||
{
|
||||
failures.Add(
|
||||
$"{optionsType.Name}: request property " +
|
||||
$"{requestType.Name}.{parameterProperty} has no default request parameter rule");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Assert.That(
|
||||
failures,
|
||||
Is.Empty,
|
||||
$"Missing default request parameter rules:{Environment.NewLine}" +
|
||||
string.Join(Environment.NewLine, failures));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RequiredExchangeParameter_ShouldAcceptNameOrAnyAlias()
|
||||
{
|
||||
const string exchange = "TestExchange";
|
||||
var options = new GetTickerOptions(exchange)
|
||||
{
|
||||
ExchangeParameterRules =
|
||||
[
|
||||
ExchangeParameterRule.Required(
|
||||
"Parameter",
|
||||
"Test parameter",
|
||||
1,
|
||||
"Alias1",
|
||||
"Alias2")
|
||||
]
|
||||
};
|
||||
|
||||
var missingResult = options.ValidateRequest(null, null, [TradingMode.Spot]);
|
||||
var nameResult = options.ValidateRequest(
|
||||
new ExchangeParameters(new ExchangeParameter(exchange, "Parameter", 1)),
|
||||
null,
|
||||
[TradingMode.Spot]);
|
||||
var firstAliasResult = options.ValidateRequest(
|
||||
new ExchangeParameters(new ExchangeParameter(exchange, "Alias1", 1)),
|
||||
null,
|
||||
[TradingMode.Spot]);
|
||||
var secondAliasResult = options.ValidateRequest(
|
||||
new ExchangeParameters(new ExchangeParameter(exchange, "Alias2", 1)),
|
||||
null,
|
||||
[TradingMode.Spot]);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(missingResult, Is.Not.Null);
|
||||
Assert.That(nameResult, Is.Null);
|
||||
Assert.That(firstAliasResult, Is.Null);
|
||||
Assert.That(secondAliasResult, Is.Null);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RequiredExchangeParameterWithoutAliases_ShouldBeRequired()
|
||||
{
|
||||
const string exchange = "TestExchange";
|
||||
var options = new GetTickerOptions(exchange)
|
||||
{
|
||||
ExchangeParameterRules =
|
||||
[
|
||||
ExchangeParameterRule.Required(
|
||||
"Parameter",
|
||||
"Test parameter",
|
||||
1)
|
||||
]
|
||||
};
|
||||
|
||||
var result = options.ValidateRequest(null, null, [TradingMode.Spot]);
|
||||
|
||||
Assert.That(result, Is.Not.Null);
|
||||
}
|
||||
|
||||
private static Type? GetGenericOptionsType(Type optionsType)
|
||||
{
|
||||
for (var type = optionsType; type != null; type = type.BaseType)
|
||||
{
|
||||
if (type.IsGenericType
|
||||
&& type.GetGenericTypeDefinition() == typeof(CapabilityOptions<,>))
|
||||
return type;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static FieldInfo? GetDefaultParameterRulesField(Type optionsType)
|
||||
{
|
||||
for (var type = optionsType; type != null; type = type.BaseType)
|
||||
{
|
||||
var field = type.GetField(
|
||||
"_defaultParameterRules",
|
||||
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
|
||||
if (field != null)
|
||||
return field;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,6 +98,10 @@ namespace CryptoExchange.Net.Clients
|
||||
/// Configured environment name
|
||||
/// </summary>
|
||||
public abstract string EnvironmentName { get; }
|
||||
/// <summary>
|
||||
/// Request coalescer
|
||||
/// </summary>
|
||||
protected RequestCoalescer RequestCoalescer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
@@ -123,6 +127,7 @@ namespace CryptoExchange.Net.Clients
|
||||
{
|
||||
TimeOffsetManager.RegisterRestApi(ClientName);
|
||||
|
||||
RequestCoalescer = new RequestCoalescer(_logger);
|
||||
RequestFactory.Configure(options, httpClient);
|
||||
}
|
||||
|
||||
@@ -177,8 +182,7 @@ namespace CryptoExchange.Net.Clients
|
||||
/// <param name="weight">Override the request weight for this request definition, for example when the weight depends on the parameters</param>
|
||||
/// <param name="weightSingleLimiter">Specify the weight to apply to the individual rate limit guard for this request</param>
|
||||
/// <param name="rateLimitKeySuffix">An additional optional suffix for the key selector. Can be used to make rate limiting work based on parameters.</param>
|
||||
/// <returns></returns>
|
||||
protected virtual async Task<HttpResult<T>> SendAsync<T>(
|
||||
protected virtual Task<HttpResult<T>> SendAsync<T>(
|
||||
RequestDefinition definition,
|
||||
Parameters? uriParameters,
|
||||
Parameters? bodyParameters,
|
||||
@@ -187,6 +191,61 @@ namespace CryptoExchange.Net.Clients
|
||||
int? weight = null,
|
||||
int? weightSingleLimiter = null,
|
||||
string? rateLimitKeySuffix = null)
|
||||
{
|
||||
if (!ShouldCoalesce(definition, additionalHeaders))
|
||||
{
|
||||
return SendCoreAsync<T>(
|
||||
definition,
|
||||
uriParameters,
|
||||
bodyParameters,
|
||||
cancellationToken,
|
||||
additionalHeaders,
|
||||
weight,
|
||||
weightSingleLimiter,
|
||||
rateLimitKeySuffix);
|
||||
}
|
||||
|
||||
var key = GetRequestCoalescingKey<T>(
|
||||
definition,
|
||||
uriParameters);
|
||||
|
||||
return RequestCoalescer.ExecuteAsync(
|
||||
key,
|
||||
requestCancellationToken => SendCoreAsync<T>(
|
||||
definition,
|
||||
uriParameters,
|
||||
bodyParameters,
|
||||
requestCancellationToken,
|
||||
additionalHeaders,
|
||||
weight,
|
||||
weightSingleLimiter,
|
||||
rateLimitKeySuffix),
|
||||
() => HttpResult.Fail<T>(
|
||||
Exchange,
|
||||
new CancellationRequestedError()),
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a request to the base address based on the request definition
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Response type</typeparam>
|
||||
/// <param name="definition">Request definition</param>
|
||||
/// <param name="uriParameters">Request query parameters</param>
|
||||
/// <param name="bodyParameters">Request body parameters</param>
|
||||
/// <param name="cancellationToken">Cancellation token</param>
|
||||
/// <param name="additionalHeaders">Additional headers for this request</param>
|
||||
/// <param name="weight">Override the request weight for this request definition, for example when the weight depends on the parameters</param>
|
||||
/// <param name="weightSingleLimiter">Specify the weight to apply to the individual rate limit guard for this request</param>
|
||||
/// <param name="rateLimitKeySuffix">An additional optional suffix for the key selector. Can be used to make rate limiting work based on parameters.</param>
|
||||
protected virtual async Task<HttpResult<T>> SendCoreAsync<T>(RequestDefinition definition,
|
||||
Parameters? uriParameters,
|
||||
Parameters? bodyParameters,
|
||||
CancellationToken cancellationToken,
|
||||
Dictionary<string, string>? additionalHeaders = null,
|
||||
int? weight = null,
|
||||
int? weightSingleLimiter = null,
|
||||
string? rateLimitKeySuffix = null)
|
||||
{
|
||||
var requestId = ExchangeHelpers.NextId();
|
||||
if (definition.Authenticated && GetAuthenticationProvider() == null)
|
||||
@@ -688,7 +747,10 @@ namespace CryptoExchange.Net.Clients
|
||||
stringData = stringSerializer.Serialize(parameters.BodyValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
stringData = stringSerializer.Serialize(parameters);
|
||||
}
|
||||
|
||||
request.SetContent(stringData, RequestBodyContentEncoding, contentType);
|
||||
}
|
||||
else if (contentType == Constants.FormContentHeader)
|
||||
@@ -808,6 +870,34 @@ namespace CryptoExchange.Net.Clients
|
||||
return definition.FullUrl + definition + parameters?.ToFormData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether a request can be coalesced or not
|
||||
/// </summary>
|
||||
protected virtual bool ShouldCoalesce(
|
||||
RequestDefinition definition,
|
||||
Dictionary<string, string>? additionalHeaders)
|
||||
{
|
||||
return ClientOptions.RequestCoalescingEnabled // Enabled in client options
|
||||
&& !definition.PreventRequestCoalescing // Enabled in request definition
|
||||
&& definition.Method == HttpMethod.Get // Is a GET request
|
||||
&& !definition.Authenticated // Not an authenticated request
|
||||
&& (additionalHeaders == null || additionalHeaders.Count == 0); // No additional headers that might change the response
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a unique key for coalescing requests based on the request definition, parameters, and the type of the expected response.
|
||||
/// </summary>
|
||||
protected virtual RequestCoalescingKey GetRequestCoalescingKey<T>(
|
||||
RequestDefinition definition,
|
||||
Parameters? uriParameters)
|
||||
{
|
||||
return new RequestCoalescingKey(
|
||||
definition.Method.Method,
|
||||
definition.FullUrl,
|
||||
uriParameters?.ToFormData(),
|
||||
typeof(T));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void SetOptions(UpdateOptions options)
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ using CryptoExchange.Net.SharedApis;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
@@ -395,7 +396,6 @@ namespace CryptoExchange.Net
|
||||
services.AddTransient(x => (IBookTickerRestClient)client(x)!);
|
||||
if (typeof(ITransferRestClient).IsAssignableFrom(typeof(T)))
|
||||
services.AddTransient(x => (ITransferRestClient)client(x)!);
|
||||
|
||||
if (typeof(ISpotOrderRestClient).IsAssignableFrom(typeof(T)))
|
||||
services.AddTransient(x => (ISpotOrderRestClient)client(x)!);
|
||||
if (typeof(ISpotSymbolRestClient).IsAssignableFrom(typeof(T)))
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace CryptoExchange.Net.Logging.Extensions
|
||||
private static readonly Action<ILogger, string, Exception?> _restApiCacheHit;
|
||||
private static readonly Action<ILogger, string, Exception?> _restApiCacheNotHit;
|
||||
private static readonly Action<ILogger, int?, Exception?> _restApiCancellationRequested;
|
||||
private static readonly Action<ILogger, string, string, Exception?> _restApiRequestsJoined;
|
||||
|
||||
static RestApiClientLoggingExtensions()
|
||||
{
|
||||
@@ -89,7 +90,11 @@ namespace CryptoExchange.Net.Logging.Extensions
|
||||
LogLevel.Debug,
|
||||
new EventId(4012, "RestApiCancellationRequested"),
|
||||
"[Req {RequestId}] request cancelled by user");
|
||||
|
||||
|
||||
_restApiRequestsJoined = LoggerMessage.Define<string, string>(
|
||||
LogLevel.Debug,
|
||||
new EventId(4013, "RestApiRequestsJoined"),
|
||||
"Request for {Method} {Path} joined with in flight request");
|
||||
}
|
||||
|
||||
public static void RestApiErrorReceived(this ILogger logger, int? requestId, HttpStatusCode? responseStatusCode, long responseTime, string? error, string? originalData, Exception? exception)
|
||||
@@ -151,9 +156,15 @@ namespace CryptoExchange.Net.Logging.Extensions
|
||||
{
|
||||
_restApiCacheNotHit(logger, key, null);
|
||||
}
|
||||
|
||||
public static void RestApiCancellationRequested(this ILogger logger, int? requestId)
|
||||
{
|
||||
_restApiCancellationRequested(logger, requestId, null);
|
||||
}
|
||||
|
||||
public static void RestApiRequestsJoined(this ILogger logger, string method, string path)
|
||||
{
|
||||
_restApiRequestsJoined(logger, method, path, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,11 @@ namespace CryptoExchange.Net.Objects.Options
|
||||
= new Version(1, 1);
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Whether concurrent identical REST requests may share the same in-flight request when allowed by the request definition.
|
||||
/// </summary>
|
||||
public bool RequestCoalescingEnabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Http client keep alive interval for keeping connections open. Only applied when using dotnet8.0 or higher and dependency injection
|
||||
/// </summary>
|
||||
@@ -73,6 +78,7 @@ namespace CryptoExchange.Net.Objects.Options
|
||||
item.CachingEnabled = CachingEnabled;
|
||||
item.CachingMaxAge = CachingMaxAge;
|
||||
item.HttpVersion = HttpVersion;
|
||||
item.RequestCoalescingEnabled = RequestCoalescingEnabled;
|
||||
item.HttpKeepAliveInterval = HttpKeepAliveInterval;
|
||||
#if NET5_0_OR_GREATER
|
||||
item.HttpMaxConnectionsPerServer = HttpMaxConnectionsPerServer;
|
||||
|
||||
@@ -0,0 +1,277 @@
|
||||
using CryptoExchange.Net.Logging.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CryptoExchange.Net.Objects
|
||||
{
|
||||
/// <summary>
|
||||
/// Request coalescer, used to detect multiple identical requests and wait for and return only a single actual request result
|
||||
/// </summary>
|
||||
public class RequestCoalescer
|
||||
{
|
||||
private sealed class RequestEntry
|
||||
{
|
||||
public RequestCoalescingKey Key { get; }
|
||||
|
||||
public CancellationTokenSource CancellationSource { get; } = new();
|
||||
|
||||
public Lazy<Task<object>> Request { get; set; } = null!;
|
||||
|
||||
public int ListenerCount { get; set; }
|
||||
|
||||
public bool Completed { get; set; }
|
||||
|
||||
public bool CancellationInProgress { get; set; }
|
||||
|
||||
public bool Disposed { get; set; }
|
||||
|
||||
public RequestEntry(RequestCoalescingKey key)
|
||||
{
|
||||
Key = key;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly object _sync = new();
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly Dictionary<RequestCoalescingKey, RequestEntry> _requests = new();
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public RequestCoalescer(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute a request, coalescing identical requests into a single request
|
||||
/// </summary>
|
||||
public Task<TResult> ExecuteAsync<TResult>(
|
||||
RequestCoalescingKey key,
|
||||
Func<CancellationToken, Task<TResult>> requestFactory,
|
||||
Func<TResult> cancellationResultFactory,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
return Task.FromResult(cancellationResultFactory());
|
||||
|
||||
RequestEntry entry;
|
||||
bool joined;
|
||||
|
||||
lock (_sync)
|
||||
{
|
||||
joined = _requests.TryGetValue(key, out entry!);
|
||||
|
||||
if (!joined)
|
||||
{
|
||||
entry = CreateEntry(key, requestFactory);
|
||||
_requests.Add(key, entry);
|
||||
}
|
||||
|
||||
entry.ListenerCount++;
|
||||
}
|
||||
|
||||
if (joined)
|
||||
_logger.RestApiRequestsJoined(key.Method, key.Url);
|
||||
|
||||
return WaitAsync(
|
||||
entry,
|
||||
cancellationResultFactory,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
private RequestEntry CreateEntry<TResult>(
|
||||
RequestCoalescingKey key,
|
||||
Func<CancellationToken, Task<TResult>> requestFactory)
|
||||
{
|
||||
var entry = new RequestEntry(key);
|
||||
|
||||
entry.Request = new Lazy<Task<object>>(
|
||||
() => ExecuteCoreAsync(
|
||||
entry,
|
||||
async requestCancellationToken =>
|
||||
(await requestFactory(requestCancellationToken).ConfigureAwait(false))!),
|
||||
LazyThreadSafetyMode.ExecutionAndPublication);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
private async Task<object> ExecuteCoreAsync(
|
||||
RequestEntry entry,
|
||||
Func<CancellationToken, Task<object>> requestFactory)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await requestFactory(entry.CancellationSource.Token).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
CompleteRequest(entry);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<TResult> WaitAsync<TResult>(
|
||||
RequestEntry entry,
|
||||
Func<TResult> cancellationResultFactory,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var requestTask = entry.Request.Value;
|
||||
|
||||
if (!cancellationToken.CanBeCanceled)
|
||||
return (TResult)await requestTask.ConfigureAwait(false);
|
||||
|
||||
var cancellationCompletion = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
using (cancellationToken.Register(
|
||||
state => ((TaskCompletionSource<bool>)state!).TrySetResult(true),
|
||||
cancellationCompletion))
|
||||
{
|
||||
var completedTask = await Task.WhenAny(requestTask, cancellationCompletion.Task).ConfigureAwait(false);
|
||||
if (completedTask != requestTask)
|
||||
return cancellationResultFactory();
|
||||
}
|
||||
|
||||
return (TResult)await requestTask.ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseListener(entry);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReleaseListener(RequestEntry entry)
|
||||
{
|
||||
var cancelRequest = false;
|
||||
var disposeCancellationSource = false;
|
||||
|
||||
lock (_sync)
|
||||
{
|
||||
entry.ListenerCount--;
|
||||
|
||||
if (entry.ListenerCount == 0)
|
||||
{
|
||||
if (!entry.Completed)
|
||||
{
|
||||
// Remove the entry before canceling it. A caller arriving
|
||||
// after this point must create a new physical request
|
||||
// instead of joining one that is being canceled.
|
||||
RemoveEntry(entry);
|
||||
|
||||
entry.CancellationInProgress = true;
|
||||
cancelRequest = true;
|
||||
}
|
||||
else if (!entry.Disposed)
|
||||
{
|
||||
entry.Disposed = true;
|
||||
disposeCancellationSource = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cancelRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
entry.CancellationSource.Cancel();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Cancellation callbacks are external to the coalescer and
|
||||
// must not cause an exception to escape the library.
|
||||
_logger.LogWarning(
|
||||
exception,
|
||||
"Error canceling in-flight request {Method} {Url}",
|
||||
entry.Key.Method,
|
||||
entry.Key.Url);
|
||||
}
|
||||
finally
|
||||
{
|
||||
CompleteCancellation(entry);
|
||||
}
|
||||
}
|
||||
else if (disposeCancellationSource)
|
||||
{
|
||||
entry.CancellationSource.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void CompleteCancellation(RequestEntry entry)
|
||||
{
|
||||
var disposeCancellationSource = false;
|
||||
|
||||
lock (_sync)
|
||||
{
|
||||
entry.CancellationInProgress = false;
|
||||
|
||||
if (entry.Completed
|
||||
&& entry.ListenerCount == 0
|
||||
&& !entry.Disposed)
|
||||
{
|
||||
entry.Disposed = true;
|
||||
disposeCancellationSource = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (disposeCancellationSource)
|
||||
entry.CancellationSource.Dispose();
|
||||
}
|
||||
|
||||
private void CompleteRequest(RequestEntry entry)
|
||||
{
|
||||
var disposeCancellationSource = false;
|
||||
|
||||
lock (_sync)
|
||||
{
|
||||
entry.Completed = true;
|
||||
|
||||
// Only remove this specific entry. If all listeners canceled,
|
||||
// a replacement request may already have been created for the
|
||||
// same key.
|
||||
RemoveEntry(entry);
|
||||
|
||||
if (entry.ListenerCount == 0
|
||||
&& !entry.CancellationInProgress
|
||||
&& !entry.Disposed)
|
||||
{
|
||||
entry.Disposed = true;
|
||||
disposeCancellationSource = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (disposeCancellationSource)
|
||||
entry.CancellationSource.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove an entry when it is still the current entry for its key.
|
||||
/// Must only be called while holding <see cref="_sync"/>.
|
||||
/// </summary>
|
||||
private void RemoveEntry(RequestEntry entry)
|
||||
{
|
||||
if (_requests.TryGetValue(entry.Key, out var current)
|
||||
&& ReferenceEquals(current, entry))
|
||||
{
|
||||
_requests.Remove(entry.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Key used to identify identical requests for coalescing
|
||||
/// </summary>
|
||||
/// <param name="Method">Request method</param>
|
||||
/// <param name="Url">Request URL</param>
|
||||
/// <param name="Parameters">Request parameter string</param>
|
||||
/// <param name="ResponseType">Response type</param>
|
||||
public sealed record RequestCoalescingKey(
|
||||
string Method,
|
||||
string Url,
|
||||
string? Parameters,
|
||||
Type ResponseType);
|
||||
}
|
||||
@@ -101,6 +101,11 @@ namespace CryptoExchange.Net.Objects
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether concurrent identical requests should be prevented from sharing the same request/response
|
||||
/// </summary>
|
||||
public bool PreventRequestCoalescing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
|
||||
@@ -53,6 +53,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <param name="tryParseOnNonSuccess">Try parse the response even when status is not success</param>
|
||||
/// <param name="forcePathEndWithSlash">Force trailing `/`</param>
|
||||
/// <param name="identifier">Optional request identifier override</param>
|
||||
/// <param name="preventRequestCoalescing">Whether concurrent identical requests should be prevented from sharing the same request/response</param>
|
||||
/// <returns></returns>
|
||||
public RequestDefinition GetOrCreate(
|
||||
HttpMethod method,
|
||||
@@ -68,7 +69,8 @@ namespace CryptoExchange.Net.Objects
|
||||
bool? preventCaching = null,
|
||||
bool? tryParseOnNonSuccess = null,
|
||||
bool? forcePathEndWithSlash = null,
|
||||
string? identifier = null)
|
||||
string? identifier = null,
|
||||
bool? preventRequestCoalescing = null)
|
||||
{
|
||||
var identifierToUse = identifier ?? $"{path}{method.Method}{baseAddress}";
|
||||
if (!_definitions.TryGetValue(identifierToUse, out var def))
|
||||
@@ -85,6 +87,7 @@ namespace CryptoExchange.Net.Objects
|
||||
PreventCaching = preventCaching ?? false,
|
||||
TryParseOnNonSuccess = tryParseOnNonSuccess ?? false,
|
||||
ForcePathEndWithSlash = forcePathEndWithSlash ?? false,
|
||||
PreventRequestCoalescing = preventRequestCoalescing ?? false,
|
||||
};
|
||||
_definitions.TryAdd(identifierToUse, def);
|
||||
}
|
||||
|
||||
@@ -165,7 +165,10 @@ namespace CryptoExchange.Net.Objects.Sockets
|
||||
{
|
||||
StreamId = StreamId,
|
||||
UpdateType = UpdateType,
|
||||
Symbol = Symbol
|
||||
Symbol = Symbol,
|
||||
DataTime = DataTime,
|
||||
DataTimeLocal = DataTimeLocal,
|
||||
SequenceNumber = SequenceNumber
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Catalog of Shared API capability references.
|
||||
/// </summary>
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Asset capabilities.
|
||||
/// </summary>
|
||||
public static class Assets
|
||||
{
|
||||
/// <summary>
|
||||
/// Get asset capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetAsset, IGetAssetRest> GetAsset { get; } = new();
|
||||
/// <summary>
|
||||
/// Get all assets capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetAllAssets, IGetAllAssetsRest> GetAllAssets { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Balance capabilities.
|
||||
/// </summary>
|
||||
public static class Balances
|
||||
{
|
||||
/// <summary>
|
||||
/// Get balances capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetBalances, IGetBalancesRest> GetBalances { get; } = new();
|
||||
/// <summary>
|
||||
/// Subscribe to balance updates capability.
|
||||
/// </summary>
|
||||
public static SharedCapabilityReference<ISubscribeBalancesSocket> SubscribeBalances { get; } = new();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Deposit capabilities.
|
||||
/// </summary>
|
||||
public static class Deposits
|
||||
{
|
||||
/// <summary>
|
||||
/// Get deposit addresses capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetDepositAddresses, IGetDepositAddressesRest> GetDepositAddresses { get; } = new();
|
||||
/// <summary>
|
||||
/// Get deposit history capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetDepositHistory, IGetDepositHistoryRest> GetDepositHistory { get; } = new();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Fee capabilities.
|
||||
/// </summary>
|
||||
public static class Fees
|
||||
{
|
||||
/// <summary>
|
||||
/// Get fees capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetFees, IGetFeesRest> GetFees { get; } = new();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Funding capabilities.
|
||||
/// </summary>
|
||||
public static class Funding
|
||||
{
|
||||
/// <summary>
|
||||
/// Get current funding information capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetFundingInfo, IGetFundingInfoRest> GetFundingInfo { get; } = new();
|
||||
/// <summary>
|
||||
/// Get funding rate history capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetFundingRateHistory, IGetFundingRateHistoryRest> GetFundingRateHistory { get; } = new();
|
||||
/// <summary>
|
||||
/// Get user funding history capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetUserFundingHistory, IGetUserFundingHistoryRest> GetUserFundingHistory { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Index price capabilities.
|
||||
/// </summary>
|
||||
public static class IndexPrices
|
||||
{
|
||||
/// <summary>
|
||||
/// Get an index price capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetIndexPrice, IGetIndexPriceRest> GetIndexPrice { get; } = new();
|
||||
/// <summary>
|
||||
/// Get all index prices capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetAllIndexPrices, IGetAllIndexPricesRest> GetAllIndexPrices { get; } = new();
|
||||
/// <summary>
|
||||
/// Subscribe to index price updates capability.
|
||||
/// </summary>
|
||||
public static SharedCapabilityReference<ISubscribeIndexPriceSocket> SubscribeIndexPrice { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Kline capabilities.
|
||||
/// </summary>
|
||||
public static class Klines
|
||||
{
|
||||
/// <summary>
|
||||
/// Get klines capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetKlines, IGetKlinesRest> GetKlines { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get mark price klines capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetMarkPriceKlines, IGetMarkPriceKlinesRest> GetMarkPriceKlines { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get index price klines capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetIndexPriceKlines, IGetIndexPriceKlinesRest> GetIndexPriceKlines { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to kline updates capability.
|
||||
/// </summary>
|
||||
public static SharedCapabilityReference<ISubscribeKlinesSocket> SubscribeKlines { get; } = new();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Ledger capabilities.
|
||||
/// </summary>
|
||||
public static class Ledger
|
||||
{
|
||||
/// <summary>
|
||||
/// Get ledger entries capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetLedger, IGetLedgerRest> GetLedger { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Leverage capabilities.
|
||||
/// </summary>
|
||||
public static class Leverage
|
||||
{
|
||||
/// <summary>
|
||||
/// Get leverage capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetLeverage, IGetLeverageRest> GetLeverage { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Set leverage capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<ISetLeverage, ISetLeverageRest> SetLeverage { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get leverage tiers capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetLeverageTiers, IGetLeverageTiersRest> GetLeverageTiers { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Mark price capabilities.
|
||||
/// </summary>
|
||||
public static class MarkPrices
|
||||
{
|
||||
/// <summary>
|
||||
/// Get a mark price capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetMarkPrice, IGetMarkPriceRest> GetMarkPrice { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get all mark prices capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetAllMarkPrices, IGetAllMarkPricesRest> GetAllMarkPrices { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to mark price updates capability.
|
||||
/// </summary>
|
||||
public static SharedCapabilityReference<ISubscribeMarkPriceSocket> SubscribeMarkPrice { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Open interest capabilities.
|
||||
/// </summary>
|
||||
public static class OpenInterest
|
||||
{
|
||||
/// <summary>
|
||||
/// Get open interest capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetOpenInterest, IGetOpenInterestRest> GetOpenInterest { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Order book capabilities.
|
||||
/// </summary>
|
||||
public static class OrderBooks
|
||||
{
|
||||
/// <summary>
|
||||
/// Get an order book capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetOrderBook, IGetOrderBookRest> GetOrderBook { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get a book ticker capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetBookTicker, IGetBookTickerRest> GetBookTicker { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to order book updates capability.
|
||||
/// </summary>
|
||||
public static SharedCapabilityReference<ISubscribeOrderBookSocket> SubscribeOrderBook { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to incremental order book updates capability.
|
||||
/// </summary>
|
||||
public static SharedCapabilityReference<ISubscribeIncrementalOrderBookSocket> SubscribeIncrementalOrderBook { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Order capabilities.
|
||||
/// </summary>
|
||||
public static class Orders
|
||||
{
|
||||
/// <summary>
|
||||
/// Spot order capabilities.
|
||||
/// </summary>
|
||||
public static class Spot
|
||||
{
|
||||
/// <summary>
|
||||
/// Place a spot order capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<IPlaceSpotOrder, IPlaceSpotOrderRest, IPlaceSpotOrderSocket> PlaceOrder { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Place multiple spot orders capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<IPlaceMultipleSpotOrders, IPlaceMultipleSpotOrdersRest, IPlaceMultipleSpotOrdersSocket> PlaceMultipleOrders { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Edit a spot order capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<IEditSpotOrder, IEditSpotOrderRest, IEditSpotOrderSocket> EditOrder { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Edit a spot order by client order id capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<IEditSpotOrderByClientOrderId, IEditSpotOrderByClientOrderIdRest, IEditSpotOrderByClientOrderIdSocket> EditOrderByClientOrderId { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Cancel a spot order capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<ICancelSpotOrder, ICancelSpotOrderRest, ICancelSpotOrderSocket> CancelOrder { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Cancel a spot order by client order id capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<ICancelSpotOrderByClientOrderId, ICancelSpotOrderByClientOrderIdRest, ICancelSpotOrderByClientOrderIdSocket> CancelOrderByClientOrderId { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Cancel all spot orders capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<ICancelAllSpotOrders, ICancelAllSpotOrdersRest, ICancelAllSpotOrdersSocket> CancelAllOrders { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Cancel all spot orders for a symbol capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<ICancelAllSpotSymbolOrders, ICancelAllSpotSymbolOrdersRest, ICancelAllSpotSymbolOrdersSocket> CancelAllSymbolOrders { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get a spot order capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetSpotOrder, IGetSpotOrderRest> GetOrder { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get a spot order by client order id capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetSpotOrderByClientOrderId, IGetSpotOrderByClientOrderIdRest> GetOrderByClientOrderId { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get open spot orders capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetOpenSpotOrders, IGetOpenSpotOrdersRest> GetOpenOrders { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get closed spot orders capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetClosedSpotOrders, IGetClosedSpotOrdersRest> GetClosedOrders { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to spot order updates capability.
|
||||
/// </summary>
|
||||
public static SharedCapabilityReference<ISubscribeSpotOrdersSocket> SubscribeOrders { get; } = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Futures order capabilities.
|
||||
/// </summary>
|
||||
public static class Futures
|
||||
{
|
||||
/// <summary>
|
||||
/// Place a futures order capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<IPlaceFuturesOrder, IPlaceFuturesOrderRest, IPlaceFuturesOrderSocket> PlaceOrder { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Place multiple futures orders capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<IPlaceMultipleFuturesOrders, IPlaceMultipleFuturesOrdersRest, IPlaceMultipleFuturesOrdersSocket> PlaceMultipleOrders { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Edit a futures order capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<IEditFuturesOrder, IEditFuturesOrderRest, IEditFuturesOrderSocket> EditOrder { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Edit a futures order by client order id capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<IEditFuturesOrderByClientOrderId, IEditFuturesOrderByClientOrderIdRest, IEditFuturesOrderByClientOrderIdSocket> EditOrderByClientOrderId { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Cancel a futures order capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<ICancelFuturesOrder, ICancelFuturesOrderRest, ICancelFuturesOrderSocket> CancelOrder { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Cancel a futures order by client order id capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<ICancelFuturesOrderByClientOrderId, ICancelFuturesOrderByClientOrderIdRest, ICancelFuturesOrderByClientOrderIdSocket> CancelOrderByClientOrderId { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Cancel all futures orders capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<ICancelAllFuturesOrders, ICancelAllFuturesOrdersRest, ICancelAllFuturesOrdersSocket> CancelAllOrders { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Cancel all futures orders for a symbol capability.
|
||||
/// </summary>
|
||||
public static SharedRestSocketCapability<ICancelAllFuturesSymbolOrders, ICancelAllFuturesSymbolOrdersRest, ICancelAllFuturesSymbolOrdersSocket> CancelAllSymbolOrders { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get a futures order capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetFuturesOrder, IGetFuturesOrderRest> GetOrder { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get a futures order by client order id capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetFuturesOrderByClientOrderId, IGetFuturesOrderByClientOrderIdRest> GetOrderByClientOrderId { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get open futures orders capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetOpenFuturesOrders, IGetOpenFuturesOrdersRest> GetOpenOrders { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get closed futures orders capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetClosedFuturesOrders, IGetClosedFuturesOrdersRest> GetClosedOrders { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to futures order updates capability.
|
||||
/// </summary>
|
||||
public static SharedCapabilityReference<ISubscribeFuturesOrdersSocket> SubscribeOrders { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Position mode capabilities.
|
||||
/// </summary>
|
||||
public static class PositionMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Get position mode capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetPositionMode, IGetPositionModeRest> GetPositionMode { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Set position mode capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<ISetPositionMode, ISetPositionModeRest> SetPositionMode { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Position capabilities.
|
||||
/// </summary>
|
||||
public static class Positions
|
||||
{
|
||||
/// <summary>
|
||||
/// Get positions capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetPositions, IGetPositionsRest> GetPositions { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get position history capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetPositionHistory, IGetPositionHistoryRest> GetPositionHistory { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Close a full position capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<ICloseFullPosition, ICloseFullPositionRest> CloseFullPosition { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to position updates capability.
|
||||
/// </summary>
|
||||
public static SharedCapabilityReference<ISubscribePositionsSocket> SubscribePositions { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Symbol capabilities.
|
||||
/// </summary>
|
||||
public static class Symbols
|
||||
{
|
||||
/// <summary>
|
||||
/// Get spot symbols capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetSpotSymbols, IGetSpotSymbolsRest> GetSpotSymbols { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get futures symbols capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetFuturesSymbols, IGetFuturesSymbolsRest> GetFuturesSymbols { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Ticker capabilities.
|
||||
/// </summary>
|
||||
public static class Tickers
|
||||
{
|
||||
/// <summary>
|
||||
/// Get a ticker capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetTicker, IGetTickerRest> GetTicker { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get all tickers capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetAllTickers, IGetAllTickersRest> GetAllTickers { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to ticker updates capability.
|
||||
/// </summary>
|
||||
public static SharedCapabilityReference<ISubscribeTickerSocket> SubscribeTicker { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to all ticker updates capability.
|
||||
/// </summary>
|
||||
public static SharedCapabilityReference<ISubscribeAllTickersSocket> SubscribeAllTickers { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to book ticker updates capability.
|
||||
/// </summary>
|
||||
public static SharedCapabilityReference<ISubscribeBookTickerSocket> SubscribeBookTicker { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Take profit and stop loss capabilities.
|
||||
/// </summary>
|
||||
public static class TpSl
|
||||
{
|
||||
/// <summary>
|
||||
/// Set futures take profit or stop loss capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<ISetFuturesTpSl, ISetFuturesTpSlRest> SetFuturesTpSl { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Cancel futures take profit or stop loss capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<ICancelFuturesTpSl, ICancelFuturesTpSlRest> CancelFuturesTpSl { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Public trade capabilities.
|
||||
/// </summary>
|
||||
public static class Trades
|
||||
{
|
||||
/// <summary>
|
||||
/// Get recent trades capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetRecentTrades, IGetRecentTradesRest> GetRecentTrades { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get trade history capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetTradeHistory, IGetTradeHistoryRest> GetTradeHistory { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to trade updates capability.
|
||||
/// </summary>
|
||||
public static SharedCapabilityReference<ISubscribeTradesSocket> SubscribeTrades { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Transfer capabilities.
|
||||
/// </summary>
|
||||
public static class Transfers
|
||||
{
|
||||
/// <summary>
|
||||
/// Transfer assets capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<ITransfer, ITransferRest> Transfer { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get transfer history capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetTransferHistory, IGetTransferHistoryRest> GetTransferHistory { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Trigger order capabilities.
|
||||
/// </summary>
|
||||
public static class TriggerOrders
|
||||
{
|
||||
/// <summary>
|
||||
/// Spot trigger order capabilities.
|
||||
/// </summary>
|
||||
public static class Spot
|
||||
{
|
||||
/// <summary>
|
||||
/// Place a spot trigger order capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IPlaceSpotTriggerOrder, IPlaceSpotTriggerOrderRest> PlaceOrder { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get a spot trigger order capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetSpotTriggerOrder, IGetSpotTriggerOrderRest> GetOrder { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Cancel a spot trigger order capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<ICancelSpotTriggerOrder, ICancelSpotTriggerOrderRest> CancelOrder { get; } = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Futures trigger order capabilities.
|
||||
/// </summary>
|
||||
public static class Futures
|
||||
{
|
||||
/// <summary>
|
||||
/// Place a futures trigger order capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IPlaceFuturesTriggerOrder, IPlaceFuturesTriggerOrderRest> PlaceOrder { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get a futures trigger order capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetFuturesTriggerOrder, IGetFuturesTriggerOrderRest> GetOrder { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Cancel a futures trigger order capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<ICancelFuturesTriggerOrder, ICancelFuturesTriggerOrderRest> CancelOrder { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// User trade capabilities.
|
||||
/// </summary>
|
||||
public static class UserTrades
|
||||
{
|
||||
/// <summary>
|
||||
/// Get trades for a spot order capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetSpotOrderTrades, IGetSpotOrderTradesRest> GetSpotOrderTrades { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get spot user trade history capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetSpotUserTradeHistory, IGetSpotUserTradeHistoryRest> GetSpotTradeHistory { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get trades for a futures order capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetFuturesOrderTrades, IGetFuturesOrderTradesRest> GetFuturesOrderTrades { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get futures user trade history capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetFuturesUserTradeHistory, IGetFuturesUserTradeHistoryRest> GetFuturesTradeHistory { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to user trade updates capability.
|
||||
/// </summary>
|
||||
public static SharedCapabilityReference<ISubscribeUserTradesSocket> SubscribeUserTrades { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
public static partial class SharedCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Withdrawal capabilities.
|
||||
/// </summary>
|
||||
public static class Withdrawals
|
||||
{
|
||||
/// <summary>
|
||||
/// Withdraw assets capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IWithdraw, IWithdrawRest> Withdraw { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get withdrawal history capability.
|
||||
/// </summary>
|
||||
public static SharedRestCapability<IGetWithdrawalHistory, IGetWithdrawalHistoryRest> GetWithdrawalHistory { get; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Strongly typed reference to a Shared API capability.
|
||||
/// </summary>
|
||||
public class SharedCapabilityReference<T>
|
||||
where T : ISharedApiCapability
|
||||
{
|
||||
/// <summary>
|
||||
/// Capability interface type.
|
||||
/// </summary>
|
||||
public Type CapabilityType => typeof(T);
|
||||
|
||||
internal SharedCapabilityReference()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString() => typeof(T).Name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Capability lookup result
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Capability type</typeparam>
|
||||
public class SharedCapabilityResolution<T>
|
||||
where T : ISharedApiCapability
|
||||
{
|
||||
/// <summary>
|
||||
/// The exchange name
|
||||
/// </summary>
|
||||
public string Exchange => Capability.Exchange;
|
||||
|
||||
/// <summary>
|
||||
/// The transport type
|
||||
/// </summary>
|
||||
public SharedTransport Transport => Capability.Transport;
|
||||
|
||||
/// <summary>
|
||||
/// The capability
|
||||
/// </summary>
|
||||
public T Capability { get; }
|
||||
/// <summary>
|
||||
/// The capability options
|
||||
/// </summary>
|
||||
public CapabilityOptions Options { get; }
|
||||
|
||||
internal SharedCapabilityResolution(
|
||||
T capability,
|
||||
CapabilityOptions options)
|
||||
{
|
||||
Capability = capability;
|
||||
Options = options;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// References for a capability available through REST.
|
||||
/// </summary>
|
||||
public class SharedRestCapability<TCapability, TRest>
|
||||
: SharedCapabilityReference<TCapability>
|
||||
where TCapability : ISharedApiCapability
|
||||
where TRest : TCapability, ISharedRest
|
||||
{
|
||||
/// <summary>
|
||||
/// Transport-agnostic capability.
|
||||
/// </summary>
|
||||
public SharedCapabilityReference<TCapability> Any { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// REST capability.
|
||||
/// </summary>
|
||||
public SharedCapabilityReference<TRest> Rest { get; } = new();
|
||||
|
||||
internal SharedRestCapability()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// References for a capability available through REST and WebSocket.
|
||||
/// </summary>
|
||||
public class SharedRestSocketCapability<TCapability, TRest, TSocket>
|
||||
: SharedCapabilityReference<TCapability>
|
||||
where TCapability : ISharedApiCapability
|
||||
where TRest : TCapability, ISharedRest
|
||||
where TSocket : TCapability, ISharedSocket
|
||||
{
|
||||
/// <summary>
|
||||
/// REST capability.
|
||||
/// </summary>
|
||||
public SharedCapabilityReference<TRest> Rest { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// WebSocket capability.
|
||||
/// </summary>
|
||||
public SharedCapabilityReference<TSocket> Socket { get; } = new();
|
||||
|
||||
internal SharedRestSocketCapability()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Ledger entry type
|
||||
/// </summary>
|
||||
public enum SharedLedgerEntryType
|
||||
{
|
||||
/// <summary>
|
||||
/// Trade execution
|
||||
/// </summary>
|
||||
Trade,
|
||||
/// <summary>
|
||||
/// Withdrawal
|
||||
/// </summary>
|
||||
Withdrawal,
|
||||
/// <summary>
|
||||
/// Deposit
|
||||
/// </summary>
|
||||
Deposit,
|
||||
/// <summary>
|
||||
/// Transfer
|
||||
/// </summary>
|
||||
Transfer,
|
||||
/// <summary>
|
||||
/// Fee payment
|
||||
/// </summary>
|
||||
Fee,
|
||||
/// <summary>
|
||||
/// Funding fee payment
|
||||
/// </summary>
|
||||
FundingFee,
|
||||
/// <summary>
|
||||
/// Rebate
|
||||
/// </summary>
|
||||
Rebate,
|
||||
|
||||
/// <summary>
|
||||
/// Other or unknown
|
||||
/// </summary>
|
||||
Unknown
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of updates the incremental order book subscription produces
|
||||
/// </summary>
|
||||
public enum SharedOrderBookSubscriptionType
|
||||
{
|
||||
/// <summary>
|
||||
/// Subscription produces an initial snapshot update, followed by incremental change updates
|
||||
/// </summary>
|
||||
SnapshotThenIncremental,
|
||||
/// <summary>
|
||||
/// Subscription produces only incremental change updates
|
||||
/// </summary>
|
||||
OnlyIncremental
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of transport used for the shared API
|
||||
/// </summary>
|
||||
public enum SharedTransport
|
||||
{
|
||||
/// <summary>
|
||||
/// REST transport
|
||||
/// </summary>
|
||||
Rest,
|
||||
/// <summary>
|
||||
/// WebSocket transport
|
||||
/// </summary>
|
||||
Socket
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// A shared/common client interface
|
||||
/// </summary>
|
||||
public interface ISharedClient : ISharedApi
|
||||
{
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -7,7 +7,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <summary>
|
||||
/// Options for canceling a futures order
|
||||
/// </summary>
|
||||
public class CancelFuturesOrderSocketOptions : EndpointOptions<CancelOrderRequest, IFuturesOrderManagementSocketClient>
|
||||
public class CancelFuturesOrderSocketOptions : CancelFuturesOrderOptions
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Cancel a futures order over a socket connection";
|
||||
@@ -15,7 +15,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public CancelFuturesOrderSocketOptions(string exchange, bool authenticated) : base(exchange, authenticated, nameof(IFuturesOrderManagementSocketClient.CancelFuturesOrderAsync))
|
||||
public CancelFuturesOrderSocketOptions(string exchange, bool authenticated) : base(exchange, authenticated)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for canceling a spot order
|
||||
/// </summary>
|
||||
public class CancelSpotOrderSocketOptions : CancelSpotOrderOptions
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Cancel a spot order over a socket connection";
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public CancelSpotOrderSocketOptions(string exchange, bool authenticated) : base(exchange, authenticated)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for closing position
|
||||
/// </summary>
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
public class ClosePositionOptions : EndpointOptions
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
{
|
||||
private static PropertyInfo[] _requestProperties = typeof(ClosePositionRequest).GetProperties();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Close an open futures position";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type CapabilityType => typeof(IFuturesOrderRestClient);
|
||||
|
||||
private static readonly RequestParameterDescription[] _defaultParameterRules = new[]
|
||||
{
|
||||
RequestParameterRule<ClosePositionRequest>.Required(x => x.Symbol, "The symbol of the position to close", new SharedSymbol(TradingMode.PerpetualLinear, "ETH", "USDT")),
|
||||
RequestParameterRule<ClosePositionRequest>.Required(x => x.PositionMode, "The current position mode of the account", SharedPositionMode.OneWay),
|
||||
RequestParameterRule<ClosePositionRequest>.Optional(x => x.PositionSide, "The side of the position to close", SharedPositionSide.Long),
|
||||
RequestParameterRule<ClosePositionRequest>.Optional(x => x.MarginMode, "The margin mode of the position", SharedMarginMode.Cross),
|
||||
RequestParameterRule<ClosePositionRequest>.Optional(x => x.Quantity, "The quantity of the position to close", 1m),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public ClosePositionOptions(string exchange, bool authenticated) : base(exchange, nameof(IFuturesOrderRestClient.ClosePositionAsync), true, _defaultParameterRules, SharedTradingModeSets.Futures)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate request
|
||||
/// </summary>
|
||||
public Error? ValidateRequest(ClosePositionRequest request, IFuturesOrderRestClient client)
|
||||
{
|
||||
if (NeedsAuthentication && !client.Authenticated)
|
||||
return new NoApiCredentialsError();
|
||||
|
||||
foreach (var param in RequestParameterRules)
|
||||
{
|
||||
var property = _requestProperties.Single(x => x.Name == param.Name);
|
||||
var value = property.GetValue(request);
|
||||
|
||||
if (param.Support == RequestParameterSupport.Required)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return ArgumentError.Invalid(
|
||||
param.Name,
|
||||
$"Request parameter `{param.Name}` for exchange `{Exchange}` is required and should be provided. Example: {param.ExampleValue}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (request is SharedSymbolRequest symbolsRequest)
|
||||
{
|
||||
if (symbolsRequest.Symbols != null)
|
||||
{
|
||||
if (!SupportsMultipleSymbols)
|
||||
return ArgumentError.Invalid(nameof(SharedSymbolRequest.Symbols), $"Only a single symbol parameter is allowed, multiple symbols are not supported");
|
||||
|
||||
if (symbolsRequest.Symbols.Length > MaxSymbolCount)
|
||||
return ArgumentError.Invalid(nameof(SharedSymbolRequest.Symbols), $"Max number of symbols is {MaxSymbolCount} but {symbolsRequest.Symbols.Length} were passed");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ValidateRequest(request.ExchangeParameters, request.TradingMode, client.SupportedTradingModes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for placing a new futures order
|
||||
/// </summary>
|
||||
public class PlaceFuturesOrderSocketOptions : PlaceFuturesOrderOptions
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Place a new futures order over a socket connection";
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public PlaceFuturesOrderSocketOptions(string exchange, bool supportsTpSl) : base(exchange, supportsTpSl)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for placing a new spot order
|
||||
/// </summary>
|
||||
public class PlaceSpotOrderSocketOptions : PlaceSpotOrderOptions
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Place a new spot order over a socket connection";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public PlaceSpotOrderSocketOptions(string exchange) : base(exchange)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Funding rate request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetFundingRateHistoryOptions GetFundingRateHistoryOptions { get; }
|
||||
+2
-2
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Futures get order by client order id request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetFuturesOrderByClientOrderIdOptions GetFuturesOrderByClientOrderIdOptions { get; }
|
||||
@@ -25,7 +25,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Futures cancel order by client order id request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
CancelFuturesOrderByClientOrderIdOptions CancelFuturesOrderByClientOrderIdOptions { get; }
|
||||
+10
-10
@@ -38,7 +38,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Futures place order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
PlaceFuturesOrderOptions PlaceFuturesOrderOptions { get; }
|
||||
@@ -52,7 +52,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Futures get order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetFuturesOrderOptions GetFuturesOrderOptions { get; }
|
||||
@@ -65,7 +65,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Futures get open orders request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetOpenFuturesOrdersOptions GetOpenFuturesOrdersOptions { get; }
|
||||
@@ -78,7 +78,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Spot get closed orders request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetFuturesClosedOrdersOptions GetClosedFuturesOrdersOptions { get; }
|
||||
@@ -93,7 +93,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Futures get order trades request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetFuturesOrderTradesOptions GetFuturesOrderTradesOptions { get; }
|
||||
@@ -106,10 +106,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Futures user trades request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetFuturesUserTradesOptions GetFuturesUserTradesOptions { get; }
|
||||
GetFuturesUserTradeHistoryOptions GetFuturesUserTradesOptions { get; }
|
||||
/// <summary>
|
||||
/// Get futures user trade records, see <see cref="GetFuturesUserTradesOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||
/// The result is paginated, if there are more results to be retrieved, the `NextPageRequest` property of the result will contain the pagination request to be used for the next request to continue pagination.
|
||||
@@ -121,7 +121,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Futures cancel order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
CancelFuturesOrderOptions CancelFuturesOrderOptions { get; }
|
||||
@@ -134,7 +134,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Positions request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetPositionsOptions GetPositionsOptions { get; }
|
||||
@@ -147,7 +147,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Close position order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
ClosePositionOptions ClosePositionOptions { get; }
|
||||
+1
-1
@@ -16,7 +16,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Futures symbol request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetFuturesSymbolsOptions GetFuturesSymbolsOptions { get; }
|
||||
+4
-4
@@ -11,10 +11,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Futures get ticker request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetFuturesTickerOptions GetFuturesTickerOptions { get; }
|
||||
GetTickerOptions GetFuturesTickerOptions { get; }
|
||||
/// <summary>
|
||||
/// Get ticker info for a specific futures symbol, see <see cref="GetFuturesTickerOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||
/// </summary>
|
||||
@@ -24,10 +24,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Futures get tickers request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetFuturesTickersOptions GetFuturesTickersOptions { get; }
|
||||
GetAllTickersOptions GetFuturesTickersOptions { get; }
|
||||
/// <summary>
|
||||
/// Get ticker info for all futures symbols, see <see cref="GetFuturesTickersOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||
/// </summary>
|
||||
+2
-2
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Set take profit and/or stop loss options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
SetFuturesTpSlOptions SetFuturesTpSlOptions { get; }
|
||||
@@ -25,7 +25,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Cancel a take profit and/or stop loss options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
CancelFuturesTpSlOptions CancelFuturesTpSlOptions { get; }
|
||||
+3
-3
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Place spot trigger order options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
PlaceFuturesTriggerOrderOptions PlaceFuturesTriggerOrderOptions { get; }
|
||||
@@ -26,7 +26,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Get trigger order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetFuturesTriggerOrderOptions GetFuturesTriggerOrderOptions { get; }
|
||||
@@ -39,7 +39,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Cancel trigger order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
CancelFuturesTriggerOrderOptions CancelFuturesTriggerOrderOptions { get; }
|
||||
+1
-1
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Index price klines request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetIndexPriceKlinesOptions GetIndexPriceKlinesOptions { get; }
|
||||
+2
-2
@@ -16,7 +16,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Leverage request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetLeverageOptions GetLeverageOptions { get; }
|
||||
@@ -29,7 +29,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Leverage set request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
SetLeverageOptions SetLeverageOptions { get; }
|
||||
+1
-1
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Mark price klines request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetMarkPriceKlinesOptions GetMarkPriceKlinesOptions { get; }
|
||||
+1
-1
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Open interest request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetOpenInterestOptions GetOpenInterestOptions { get; }
|
||||
+1
-1
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Position history request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetPositionHistoryOptions GetPositionHistoryOptions { get; }
|
||||
+2
-2
@@ -16,7 +16,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Position mode request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetPositionModeOptions GetPositionModeOptions { get; }
|
||||
@@ -29,7 +29,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Position mode set request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
SetPositionModeOptions SetPositionModeOptions { get; }
|
||||
+3
-3
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Asset request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetAssetOptions GetAssetOptions { get; }
|
||||
@@ -25,10 +25,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Assets request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetAssetsOptions GetAssetsOptions { get; }
|
||||
GetAllAssetsOptions GetAssetsOptions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get info on all assets the exchange supports, see <see cref="GetAssetsOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||
+1
-1
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Balances request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetBalancesOptions GetBalancesOptions { get; }
|
||||
+1
-1
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Book ticker request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetBookTickerOptions GetBookTickerOptions { get; }
|
||||
+3
-3
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Deposit addresses request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetDepositAddressesOptions GetDepositAddressesOptions { get; }
|
||||
@@ -26,10 +26,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Deposits request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetDepositsOptions GetDepositsOptions { get; }
|
||||
GetDepositHistoryOptions GetDepositsOptions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get deposit records, see <see cref="GetDepositsOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||
+1
-1
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Fee request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetFeeOptions GetFeeOptions { get; }
|
||||
+1
-1
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Kline request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetKlinesOptions GetKlinesOptions { get; }
|
||||
+1
-1
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Order book request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetOrderBookOptions GetOrderBookOptions { get; }
|
||||
+1
-1
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Recent trades request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetRecentTradesOptions GetRecentTradesOptions { get; }
|
||||
+1
-1
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Trade history request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetTradeHistoryOptions GetTradeHistoryOptions { get; }
|
||||
+2
-2
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Transfer request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
TransferOptions TransferOptions { get; }
|
||||
@@ -23,4 +23,4 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <param name="ct">Cancellation token</param>
|
||||
Task<HttpResult<SharedId>> TransferAsync(TransferRequest request, CancellationToken ct = default);
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -1,17 +1,20 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Client for requesting to withdraw funds from the exchange
|
||||
/// Client for withdrawing funds
|
||||
/// </summary>
|
||||
public interface IWithdrawRestClient : ISharedClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Withdraw request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
WithdrawOptions WithdrawOptions { get; }
|
||||
@@ -24,4 +27,4 @@ namespace CryptoExchange.Net.SharedApis
|
||||
/// <returns></returns>
|
||||
Task<HttpResult<SharedId>> WithdrawAsync(WithdrawRequest request, CancellationToken ct = default);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -11,10 +11,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Withdrawal records request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetWithdrawalsOptions GetWithdrawalsOptions { get; }
|
||||
GetWithdrawalHistoryOptions GetWithdrawalsOptions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get withdrawal records, see <see cref="GetWithdrawalsOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||
+2
-2
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Spot get order by client order id request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetSpotOrderByClientOrderIdOptions GetSpotOrderByClientOrderIdOptions { get; }
|
||||
@@ -25,7 +25,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Spot cancel order by client order id request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
CancelSpotOrderByClientOrderIdOptions CancelSpotOrderByClientOrderIdOptions { get; }
|
||||
+8
-8
@@ -38,7 +38,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Spot place order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
PlaceSpotOrderOptions PlaceSpotOrderOptions { get; }
|
||||
@@ -51,7 +51,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Spot get order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetSpotOrderOptions GetSpotOrderOptions { get; }
|
||||
@@ -64,7 +64,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Spot get open orders request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetOpenSpotOrdersOptions GetOpenSpotOrdersOptions { get; }
|
||||
@@ -77,7 +77,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Spot get closed orders request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetSpotClosedOrdersOptions GetClosedSpotOrdersOptions { get; }
|
||||
@@ -92,7 +92,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Spot get order trades request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetSpotOrderTradesOptions GetSpotOrderTradesOptions { get; }
|
||||
@@ -106,10 +106,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Spot user trades request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetSpotUserTradesOptions GetSpotUserTradesOptions { get; }
|
||||
GetSpotUserTradeHistoryOptions GetSpotUserTradesOptions { get; }
|
||||
/// <summary>
|
||||
/// Get spot user trade records, see <see cref="GetSpotUserTradesOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||
/// The result is paginated, if there are more results to be retrieved, the `NextPageRequest` property of the result will contain the pagination request to be used for the next request to continue pagination.
|
||||
@@ -121,7 +121,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Spot cancel order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
CancelSpotOrderOptions CancelSpotOrderOptions { get; }
|
||||
+1
-1
@@ -16,7 +16,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Spot symbols request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetSpotSymbolsOptions GetSpotSymbolsOptions { get; }
|
||||
+4
-4
@@ -11,10 +11,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Spot ticker request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetSpotTickerOptions GetSpotTickerOptions { get; }
|
||||
GetTickerOptions GetSpotTickerOptions { get; }
|
||||
/// <summary>
|
||||
/// Get ticker for a specific spot symbol, see <see cref="GetSpotTickerOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||
/// </summary>
|
||||
@@ -23,10 +23,10 @@ namespace CryptoExchange.Net.SharedApis
|
||||
Task<HttpResult<SharedSpotTicker>> GetSpotTickerAsync(GetTickerRequest request, CancellationToken ct = default);
|
||||
/// <summary>
|
||||
/// Spot tickers request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetSpotTickersOptions GetSpotTickersOptions { get; }
|
||||
GetAllTickersOptions GetSpotTickersOptions { get; }
|
||||
/// <summary>
|
||||
/// Get tickers for all spot symbols, see <see cref="GetSpotTickersOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||
/// </summary>
|
||||
+3
-3
@@ -11,7 +11,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Place spot trigger order options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
PlaceSpotTriggerOrderOptions PlaceSpotTriggerOrderOptions { get; }
|
||||
@@ -26,7 +26,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Get trigger order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
GetSpotTriggerOrderOptions GetSpotTriggerOrderOptions { get; }
|
||||
@@ -39,7 +39,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Cancel trigger order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
CancelSpotTriggerOrderOptions CancelSpotTriggerOrderOptions { get; }
|
||||
+2
-2
@@ -38,7 +38,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Futures place order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
PlaceFuturesOrderSocketOptions PlaceFuturesOrderOptions { get; }
|
||||
@@ -52,7 +52,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Futures cancel order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
CancelFuturesOrderSocketOptions CancelFuturesOrderOptions { get; }
|
||||
+2
-2
@@ -38,7 +38,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Spot place order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
PlaceSpotOrderSocketOptions PlaceSpotOrderOptions { get; }
|
||||
@@ -51,7 +51,7 @@ namespace CryptoExchange.Net.SharedApis
|
||||
|
||||
/// <summary>
|
||||
/// Spot cancel order request options.<br />
|
||||
/// Use <see cref="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Use <see cref="CapabilityOptions.RequiredExchangeParameters"/> and <see cref="CapabilityOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||
/// </summary>
|
||||
CancelSpotOrderSocketOptions CancelSpotOrderOptions { get; }
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for canceling a futures order by client order id
|
||||
/// </summary>
|
||||
public class CancelFuturesOrderByClientOrderIdOptions : EndpointOptions<CancelOrderRequest, IFuturesOrderClientIdRestClient>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Cancel a futures order by its client order id";
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public CancelFuturesOrderByClientOrderIdOptions(string exchange, bool authenticated) : base(exchange, authenticated, nameof(IFuturesOrderClientIdRestClient.CancelFuturesOrderByClientOrderIdAsync))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for canceling a futures order
|
||||
/// </summary>
|
||||
public class CancelFuturesOrderOptions : EndpointOptions<CancelOrderRequest, IFuturesOrderRestClient>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Cancel a futures order";
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public CancelFuturesOrderOptions(string exchange, bool authenticated) : base(exchange, authenticated, nameof(IFuturesOrderRestClient.CancelFuturesOrderAsync))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for canceling a TP/SL
|
||||
/// </summary>
|
||||
public class CancelFuturesTpSlOptions : EndpointOptions<CancelTpSlRequest, IFuturesTpSlRestClient>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Cancel a take profit or stop loss order for a futures position";
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public CancelFuturesTpSlOptions(string exchange, bool authenticated) : base(exchange, authenticated, nameof(IFuturesTpSlRestClient.CancelFuturesTpSlAsync))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for canceling spot trigger order
|
||||
/// </summary>
|
||||
public class CancelFuturesTriggerOrderOptions : EndpointOptions<CancelOrderRequest, IFuturesTriggerOrderRestClient>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Cancel a futures trigger order";
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public CancelFuturesTriggerOrderOptions(string exchange, bool authenticated) : base(exchange, authenticated, nameof(IFuturesTriggerOrderRestClient.CancelFuturesTriggerOrderAsync))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for canceling a spot order
|
||||
/// </summary>
|
||||
public class CancelSpotOrderByClientOrderIdOptions : EndpointOptions<CancelOrderRequest, ISpotOrderClientIdRestClient>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Cancel a spot order by its client order id";
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public CancelSpotOrderByClientOrderIdOptions(string exchange, bool authenticated) : base(exchange, authenticated, nameof(ISpotOrderClientIdRestClient.CancelSpotOrderByClientOrderIdAsync))
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Error? ValidateRequest(CancelOrderRequest request, ISpotOrderClientIdRestClient client)
|
||||
{
|
||||
if (request.Symbol!.TradingMode != TradingMode.Spot)
|
||||
return ArgumentError.Invalid("TradingMode", $"TradingMode.{request.Symbol!.TradingMode} is not supported, should be Spot");
|
||||
|
||||
return base.ValidateRequest(request, client);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for canceling a spot order
|
||||
/// </summary>
|
||||
public class CancelSpotOrderOptions : EndpointOptions<CancelOrderRequest, ISpotOrderRestClient>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Cancel a spot order";
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public CancelSpotOrderOptions(string exchange, bool authenticated) : base(exchange, authenticated, nameof(ISpotOrderRestClient.CancelSpotOrderAsync))
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Error? ValidateRequest(CancelOrderRequest request, ISpotOrderRestClient client)
|
||||
{
|
||||
if (request.Symbol!.TradingMode != TradingMode.Spot)
|
||||
return ArgumentError.Invalid("TradingMode", $"TradingMode.{request.Symbol!.TradingMode} is not supported, should be Spot");
|
||||
|
||||
return base.ValidateRequest(request, client);
|
||||
}
|
||||
}
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for canceling a spot order
|
||||
/// </summary>
|
||||
public class CancelSpotOrderSocketOptions : EndpointOptions<CancelOrderRequest, ISpotOrderManagementSocketClient>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Cancel a spot order over a socket connection";
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public CancelSpotOrderSocketOptions(string exchange, bool authenticated) : base(exchange, authenticated, nameof(ISpotOrderManagementSocketClient.CancelSpotOrderAsync))
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Error? ValidateRequest(CancelOrderRequest request, ISpotOrderManagementSocketClient client)
|
||||
{
|
||||
if (request.Symbol!.TradingMode != TradingMode.Spot)
|
||||
return ArgumentError.Invalid("TradingMode", $"TradingMode.{request.Symbol!.TradingMode} is not supported, should be Spot");
|
||||
|
||||
return base.ValidateRequest(request, client);
|
||||
}
|
||||
}
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.SharedApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for requesting spot trigger order
|
||||
/// </summary>
|
||||
public class CancelSpotTriggerOrderOptions : EndpointOptions<CancelOrderRequest, ISpotTriggerOrderRestClient>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Cancel a spot trigger order";
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public CancelSpotTriggerOrderOptions(string exchange, bool authenticated) : base(exchange, authenticated, nameof(ISpotTriggerOrderRestClient.CancelSpotTriggerOrderAsync))
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Error? ValidateRequest(CancelOrderRequest request, ISpotTriggerOrderRestClient client)
|
||||
{
|
||||
if (request.Symbol!.TradingMode != TradingMode.Spot)
|
||||
return ArgumentError.Invalid("TradingMode", $"TradingMode.{request.Symbol!.TradingMode} is not supported, should be Spot");
|
||||
|
||||
return base.ValidateRequest(request, client);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user