mirror of
https://github.com/JKorf/CryptoExchange.Net.git
synced 2026-10-18 17:11:02 +00:00
Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3dd68dcad4 | |||
| ff43d202d4 | |||
| d1947e643b | |||
| 6fec65cd6a | |||
| 053bcf6ecc | |||
| 6957ba44f5 | |||
| c1af97dd4a | |||
| ecfe3cf392 | |||
| ac1e9cf2ab | |||
| 4987e6be70 | |||
| 9100c0d7f3 | |||
| 5b1ae30e4b | |||
| 36a06e8a9a | |||
| e7eb559074 | |||
| 79e2efec70 | |||
| c8c6d14329 | |||
| b8bd30a09d | |||
| c2b58ab19a | |||
| 90a031c595 | |||
| 860d753ad6 | |||
| e16c91792c | |||
| a3d95da9fa | |||
| 907399b878 | |||
| 9eab0d967e | |||
| 0dee68e8ae | |||
| d838d3377f | |||
| 2141ad9061 | |||
| 9be8798ccf | |||
| 4803ed91cd | |||
| 20bddd5c37 | |||
| 0e75ddb3d0 | |||
| 0e5b46002c | |||
| 8f7c71f9ce | |||
| 73377fbb87 | |||
| 3a00d6371a | |||
| caf6d36bcd | |||
| e078a373da | |||
| 007743f5a1 | |||
| d06f891cee | |||
| 8dcbb687f5 | |||
| fcb36f7ee0 | |||
| 3cffd67518 | |||
| ecd00ea707 | |||
| 38a7b981ce | |||
| c41cc3c4c7 | |||
| 4accc8039b | |||
| 87c86ec0c0 | |||
| d9850da282 | |||
| c4a8b02054 | |||
| 34b7258496 | |||
| 69099922c9 | |||
| 64c1cd5fa8 | |||
| 936ac6640b | |||
| 68ad9ae114 | |||
| 6238c17471 | |||
| 52e6fbfe47 | |||
| 4129622d71 | |||
| 95e0aefb9f | |||
| dd1cefdc90 |
@@ -30,6 +30,22 @@ var ticker = await binance.GetSpotTickerAsync(new GetTickerRequest(symbol));
|
|||||||
|
|
||||||
`SharedSymbol(TradingMode.Spot, "BTC", "USDT")` is portable. Each library translates to its native format internally. Don't pass raw strings like `"BTCUSDT"` to shared methods.
|
`SharedSymbol(TradingMode.Spot, "BTC", "USDT")` is portable. Each library translates to its native format internally. Don't pass raw strings like `"BTCUSDT"` to shared methods.
|
||||||
|
|
||||||
|
## Symbol metadata and catalogs
|
||||||
|
|
||||||
|
In 12.2.0, `SharedSpotSymbol` and `SharedFuturesSymbol` include `DisplayName` and base/quote asset classification through `SharedAssetType` (`Crypto`, `Fiat`, `TradFi`) and `SharedAssetSubType` (`StableCoin`, `Equity`, `Commodity`). Pass the matching base/quote filters to `GetSymbolsRequest` when discovery should return only a class of markets.
|
||||||
|
|
||||||
|
After calling `GetSpotSymbolsAsync`, `ISpotSymbolRestClient.SpotSymbolCatalog` maps asset and symbol names to shared metadata. `IFuturesSymbolRestClient.FuturesSymbolCatalog` works the same way after `GetFuturesSymbolsAsync`. Treat either property as unavailable before its corresponding request has populated the cache.
|
||||||
|
|
||||||
|
When implementing an exchange library, use `LibraryHelpers.IsStableCoin`, `IsCommodity`, and `IsEquity` only as best-effort classifiers and supply exchange-specific additions where needed.
|
||||||
|
|
||||||
|
## Shared market-data quantities
|
||||||
|
|
||||||
|
In 12.4.0, use `SharedOrderQuantity`-valued `Volumes` on shared spot/futures tickers and klines, and `Quantities` on shared trades. The scalar `Volume`, `QuoteVolume`, and `Quantity` members are obsolete.
|
||||||
|
|
||||||
|
## WebSocket order commands
|
||||||
|
|
||||||
|
In 12.5.0, `ISpotOrderManagementSocketClient` and `IFuturesOrderManagementSocketClient` optionally provide place/cancel order commands over WebSocket. Their methods return `QueryResult<SharedId>`, not `WebSocketResult<UpdateSubscription>`. Check whether the exchange implements the interface.
|
||||||
|
|
||||||
## Result pattern
|
## Result pattern
|
||||||
|
|
||||||
REST methods return `HttpResult<T>` and websocket subscription methods return `WebSocketResult<UpdateSubscription>`. Always check `.Success`. `.Exchange` property identifies which exchange responded — useful for logging.
|
REST methods return `HttpResult<T>` and websocket subscription methods return `WebSocketResult<UpdateSubscription>`. Always check `.Success`. `.Exchange` property identifies which exchange responded — useful for logging.
|
||||||
@@ -37,7 +53,7 @@ REST methods return `HttpResult<T>` and websocket subscription methods return `W
|
|||||||
## Available shared interfaces
|
## Available shared interfaces
|
||||||
|
|
||||||
- REST tickers/symbols/orderbook/klines/trades, orders (spot/futures, regular/trigger/TP-SL), balances, positions, fees, deposits/withdrawals, transfers
|
- REST tickers/symbols/orderbook/klines/trades, orders (spot/futures, regular/trigger/TP-SL), balances, positions, fees, deposits/withdrawals, transfers
|
||||||
- WebSocket tickers, book tickers, order book, trades, klines, user data
|
- WebSocket tickers, book tickers, order book, trades, klines, user data, and optional spot/futures order management
|
||||||
|
|
||||||
Each exchange documents which it implements. Not every exchange supports every operation.
|
Each exchange documents which it implements. Not every exchange supports every operation.
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,20 @@ var ticker = await binance.GetSpotTickerAsync(new GetTickerRequest(symbol));
|
|||||||
|
|
||||||
Same code works on every exchange that implements the interface. Use `Task.WhenAll` for concurrent multi-exchange calls.
|
Same code works on every exchange that implements the interface. Use `Task.WhenAll` for concurrent multi-exchange calls.
|
||||||
|
|
||||||
|
## Shared symbol metadata
|
||||||
|
|
||||||
|
CryptoExchange.Net 12.2.0 classifies the base and quote sides of `SharedSpotSymbol` and `SharedFuturesSymbol` with `SharedAssetType` (`Crypto`, `Fiat`, `TradFi`) and optional `SharedAssetSubType` (`StableCoin`, `Equity`, `Commodity`). The models also expose `DisplayName`. Use the corresponding base/quote fields on `GetSymbolsRequest` to filter symbol discovery.
|
||||||
|
|
||||||
|
`ISpotSymbolRestClient.SpotSymbolCatalog` is populated by `GetSpotSymbolsAsync`; `IFuturesSymbolRestClient.FuturesSymbolCatalog` is populated by `GetFuturesSymbolsAsync`. Do not assume a catalog is available before that request. For exchange-library implementations, `LibraryHelpers.IsStableCoin`, `IsCommodity`, and `IsEquity` offer best-effort classification and can be extended with exchange-specific values.
|
||||||
|
|
||||||
|
## Shared market-data quantities
|
||||||
|
|
||||||
|
CryptoExchange.Net 12.4.0 uses `SharedOrderQuantity` for market-data quantities. Prefer `Volumes` on `SharedSpotTicker`, `SharedFuturesTicker`, and `SharedKline`, and `Quantities` on `SharedTrade`; the scalar `Volume`, `QuoteVolume`, and `Quantity` members are obsolete.
|
||||||
|
|
||||||
|
## WebSocket order commands
|
||||||
|
|
||||||
|
CryptoExchange.Net 12.5.0 adds optional `ISpotOrderManagementSocketClient` and `IFuturesOrderManagementSocketClient` interfaces for placing and canceling orders over WebSocket. These command methods return `QueryResult<SharedId>` rather than a subscription result. Check exchange support before relying on either interface.
|
||||||
|
|
||||||
## Single-exchange code uses the exchange's own client
|
## Single-exchange code uses the exchange's own client
|
||||||
|
|
||||||
For Binance-only code, use `BinanceRestClient` directly (see Binance.Net repo `AGENTS.md`). SharedApis is for portability — use it when you need that.
|
For Binance-only code, use `BinanceRestClient` directly (see Binance.Net repo `AGENTS.md`). SharedApis is for portability — use it when you need that.
|
||||||
@@ -35,7 +49,7 @@ REST methods return `HttpResult<T>` and websocket subscription methods return `W
|
|||||||
## Available shared interfaces
|
## Available shared interfaces
|
||||||
|
|
||||||
REST: tickers, symbols, orderbook, klines, trades, orders (spot/futures, trigger, TP-SL), balances, positions, fees, deposits/withdrawals, transfers.
|
REST: tickers, symbols, orderbook, klines, trades, orders (spot/futures, trigger, TP-SL), balances, positions, fees, deposits/withdrawals, transfers.
|
||||||
WebSocket: tickers, book tickers, orderbook, trades, klines, user data.
|
WebSocket: tickers, book tickers, orderbook, trades, klines, user data, and optional spot/futures order management.
|
||||||
|
|
||||||
Each exchange library implements a subset. Check exchange docs for support matrix.
|
Each exchange library implements a subset. Check exchange docs for support matrix.
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,32 @@ var btcusdtPerp = new SharedSymbol(TradingMode.PerpetualLinear, "BTC", "USDT");
|
|||||||
|
|
||||||
For exchanges that use exotic asset names, see the AssetAliases configuration.
|
For exchanges that use exotic asset names, see the AssetAliases configuration.
|
||||||
|
|
||||||
|
## Symbol Metadata and Asset Classification
|
||||||
|
|
||||||
|
Since CryptoExchange.Net 12.2.0, shared symbol responses describe both sides of a market with `BaseAssetType`, `BaseAssetSubType`, `QuoteAssetType`, and `QuoteAssetSubType`. `SharedAssetType` distinguishes `Crypto`, `Fiat`, and `TradFi`; `SharedAssetSubType` distinguishes `StableCoin`, `Equity`, and `Commodity`. `SharedSpotSymbol` and `SharedFuturesSymbol` also expose `DisplayName`.
|
||||||
|
|
||||||
|
The same fields on `GetSymbolsRequest` filter spot or futures symbol discovery:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
var request = new GetSymbolsRequest(
|
||||||
|
baseAssetType: SharedAssetType.Crypto,
|
||||||
|
quoteAssetSubType: SharedAssetSubType.StableCoin);
|
||||||
|
|
||||||
|
var result = await symbolClient.GetSpotSymbolsAsync(request);
|
||||||
|
```
|
||||||
|
|
||||||
|
After calling `GetSpotSymbolsAsync` or `GetFuturesSymbolsAsync`, use the client's `SpotSymbolCatalog` or `FuturesSymbolCatalog` to look up normalized asset and symbol metadata by name. The catalog is unavailable until the corresponding symbol request has populated the cache.
|
||||||
|
|
||||||
|
For exchange-library implementations, `LibraryHelpers.IsStableCoin`, `IsCommodity`, and `IsEquity` provide best-effort classification of known assets and accept exchange-specific additions. These helpers are heuristics, not an exhaustive source of truth.
|
||||||
|
|
||||||
|
## Shared Market-Data Quantities
|
||||||
|
|
||||||
|
Since CryptoExchange.Net 12.4.0, shared market-data models use `SharedOrderQuantity` so base-asset, quote-asset, and contract quantities remain explicit. Read `SharedSpotTicker.Volumes`, `SharedFuturesTicker.Volumes`, and `SharedKline.Volumes`; read `SharedTrade.Quantities`. The former scalar `Volume`, `QuoteVolume`, and `Quantity` members are obsolete.
|
||||||
|
|
||||||
|
## WebSocket Order Management
|
||||||
|
|
||||||
|
Since CryptoExchange.Net 12.5.0, exchanges can implement `ISpotOrderManagementSocketClient` and `IFuturesOrderManagementSocketClient` to place and cancel orders over WebSocket. These are command interfaces, not subscription interfaces: `Place*OrderAsync` and `Cancel*OrderAsync` return `QueryResult<SharedId>`. Check exchange support before using them.
|
||||||
|
|
||||||
## Available Shared Interfaces
|
## Available Shared Interfaces
|
||||||
|
|
||||||
**REST:**
|
**REST:**
|
||||||
@@ -80,6 +106,7 @@ For exchanges that use exotic asset names, see the AssetAliases configuration.
|
|||||||
- `ITickerSocketClient`, `IBookTickerSocketClient`
|
- `ITickerSocketClient`, `IBookTickerSocketClient`
|
||||||
- `IOrderBookSocketClient`, `ITradeSocketClient`, `IKlineSocketClient`
|
- `IOrderBookSocketClient`, `ITradeSocketClient`, `IKlineSocketClient`
|
||||||
- `IUserTradeSocketClient`, `ISpotOrderSocketClient`, `IFuturesOrderSocketClient`, `IPositionSocketClient`, `IBalanceSocketClient`
|
- `IUserTradeSocketClient`, `ISpotOrderSocketClient`, `IFuturesOrderSocketClient`, `IPositionSocketClient`, `IBalanceSocketClient`
|
||||||
|
- Order commands: `ISpotOrderManagementSocketClient`, `IFuturesOrderManagementSocketClient`
|
||||||
|
|
||||||
Each exchange documents which interfaces it implements (some exchanges don't support every operation).
|
Each exchange documents which interfaces it implements (some exchanges don't support every operation).
|
||||||
|
|
||||||
|
|||||||
@@ -96,23 +96,20 @@ namespace CryptoExchange.Net.UnitTests
|
|||||||
waiters.Add(evnt.WaitAsync());
|
waiters.Add(evnt.WaitAsync());
|
||||||
}
|
}
|
||||||
|
|
||||||
List<bool>? results = null;
|
var remaining = waiters.ToList();
|
||||||
var resultsWaiter = Task.Run(async () =>
|
|
||||||
{
|
|
||||||
await Task.WhenAll(waiters);
|
|
||||||
results = waiters.Select(w => w.Result).ToList();
|
|
||||||
});
|
|
||||||
|
|
||||||
for(var i = 1; i <= 10; i++)
|
for (var i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
evnt.Set();
|
evnt.Set();
|
||||||
await Task.Delay(1); // Wait for the continuation.
|
|
||||||
Assert.That(10 - i == waiters.Count(w => w.Status != TaskStatus.RanToCompletion));
|
var completed = await Task.WhenAny(remaining);
|
||||||
|
Assert.That(await completed, Is.True);
|
||||||
|
|
||||||
|
remaining.Remove(completed);
|
||||||
|
Assert.That(remaining.Count(w => w.IsCompleted), Is.Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
await resultsWaiter;
|
Assert.That(remaining, Is.Empty);
|
||||||
|
|
||||||
Assert.That(10 == results?.Count(r => r));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -138,6 +138,68 @@ namespace CryptoExchange.Net.UnitTests.ClientTests
|
|||||||
Assert.That(socket2.Connected == false);
|
Assert.That(socket2.Connected == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase()]
|
||||||
|
public async Task BatchedSubscription_Should_NotExceedIndividualCombineTarget()
|
||||||
|
{
|
||||||
|
// arrange
|
||||||
|
var client = new TestSocketClient(options =>
|
||||||
|
{
|
||||||
|
options.SocketSubscriptionsCombineTarget = 10;
|
||||||
|
options.SocketIndividualSubscriptionCombineTarget = 10;
|
||||||
|
});
|
||||||
|
TestHelpers.ConfigureSocketClient(client, "wss://localhost");
|
||||||
|
|
||||||
|
// act
|
||||||
|
await client.ApiClient1.SubscribeToUpdatesAsync<TestObject>(x => { }, false, default, individualSubscriptionCount: 6);
|
||||||
|
TestHelpers.ConfigureSocketClient(client, "wss://localhost");
|
||||||
|
await client.ApiClient1.SubscribeToUpdatesAsync<TestObject>(x => { }, false, default, individualSubscriptionCount: 6);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
Assert.That(client.ApiClient1._socketConnections.Count == 2);
|
||||||
|
Assert.That(client.ApiClient1._socketConnections.Values.All(connection => connection.Subscriptions.Sum(subscription => subscription.IndividualSubscriptionCount) <= 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase()]
|
||||||
|
public async Task BatchedSubscription_FullIndividualConnection_Should_NotPreventEligibleConnectionReuse()
|
||||||
|
{
|
||||||
|
// arrange
|
||||||
|
var client = new TestSocketClient(options =>
|
||||||
|
{
|
||||||
|
options.SocketSubscriptionsCombineTarget = 5;
|
||||||
|
options.SocketIndividualSubscriptionCombineTarget = 10;
|
||||||
|
});
|
||||||
|
TestHelpers.ConfigureSocketClient(client, "wss://localhost");
|
||||||
|
await client.ApiClient1.SubscribeToUpdatesAsync<TestObject>(x => { }, false, default);
|
||||||
|
await client.ApiClient1.SubscribeToUpdatesAsync<TestObject>(x => { }, false, default);
|
||||||
|
|
||||||
|
TestHelpers.ConfigureSocketClient(client, "wss://localhost");
|
||||||
|
await client.ApiClient1.SubscribeToUpdatesAsync<TestObject>(x => { }, false, default, individualSubscriptionCount: 10);
|
||||||
|
|
||||||
|
TestHelpers.ConfigureSocketClient(client, "wss://localhost");
|
||||||
|
|
||||||
|
// act
|
||||||
|
await client.ApiClient1.SubscribeToUpdatesAsync<TestObject>(x => { }, false, default);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
Assert.That(
|
||||||
|
client.ApiClient1._socketConnections.Count,
|
||||||
|
Is.EqualTo(2),
|
||||||
|
"The eligible connection should be reused instead of opening a new connection after selecting a full individual-subscription connection");
|
||||||
|
|
||||||
|
var fullConnection = client.ApiClient1._socketConnections.Values
|
||||||
|
.Single(connection => connection.Subscriptions.Sum(subscription => subscription.IndividualSubscriptionCount) == 10);
|
||||||
|
Assert.That(
|
||||||
|
fullConnection.UserSubscriptionCount,
|
||||||
|
Is.EqualTo(1),
|
||||||
|
"The full connection should not receive the normal subscription");
|
||||||
|
|
||||||
|
var eligibleConnection = client.ApiClient1._socketConnections.Values.Single(connection => connection != fullConnection);
|
||||||
|
Assert.That(
|
||||||
|
eligibleConnection.UserSubscriptionCount,
|
||||||
|
Is.EqualTo(3),
|
||||||
|
"The existing eligible connection should receive the normal subscription");
|
||||||
|
}
|
||||||
|
|
||||||
[TestCase()]
|
[TestCase()]
|
||||||
public async Task ErrorResponse_ShouldNot_ConfirmSubscription()
|
public async Task ErrorResponse_ShouldNot_ConfirmSubscription()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,6 +25,17 @@ namespace CryptoExchange.Net.UnitTests.ConverterTests
|
|||||||
Assert.That(output!.Value == expected);
|
Assert.That(output!.Value == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase(1, true)]
|
||||||
|
[TestCase(2, true)]
|
||||||
|
[TestCase(0, false)]
|
||||||
|
[TestCase(-1, false)]
|
||||||
|
public void TestBoolConverterInts(int value, bool? expected)
|
||||||
|
{
|
||||||
|
var val = $"{value}";
|
||||||
|
var output = JsonSerializer.Deserialize<STJBoolObject>($"{{ \"Value\": {val} }}", SerializerOptions.WithConverters(new TestSerializerContext()));
|
||||||
|
Assert.That(output!.Value == expected);
|
||||||
|
}
|
||||||
|
|
||||||
[TestCase("1", true)]
|
[TestCase("1", true)]
|
||||||
[TestCase("true", true)]
|
[TestCase("true", true)]
|
||||||
[TestCase("yes", true)]
|
[TestCase("yes", true)]
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ namespace CryptoExchange.Net.UnitTests.ConverterTests
|
|||||||
[TestCase("1620777600000")]
|
[TestCase("1620777600000")]
|
||||||
[TestCase("2021-05-12T00:00:00.000Z")]
|
[TestCase("2021-05-12T00:00:00.000Z")]
|
||||||
[TestCase("2021-05-12T00:00:00.000000000Z")]
|
[TestCase("2021-05-12T00:00:00.000000000Z")]
|
||||||
|
[TestCase("2021-05-12 00:00:00.000000+00:00:00")]
|
||||||
[TestCase("0.000000", true)]
|
[TestCase("0.000000", true)]
|
||||||
[TestCase("0", true)]
|
[TestCase("0", true)]
|
||||||
[TestCase("", true)]
|
[TestCase("", true)]
|
||||||
|
|||||||
@@ -36,9 +36,13 @@ namespace CryptoExchange.Net.UnitTests.Implementations
|
|||||||
protected override TestAuthenticationProvider CreateAuthenticationProvider(TestCredentials credentials) =>
|
protected override TestAuthenticationProvider CreateAuthenticationProvider(TestCredentials credentials) =>
|
||||||
new TestAuthenticationProvider(credentials);
|
new TestAuthenticationProvider(credentials);
|
||||||
|
|
||||||
public async Task<WebSocketResult<UpdateSubscription>> SubscribeToUpdatesAsync<T>(Action<DataEvent<T>> handler, bool subQuery, CancellationToken ct)
|
public async Task<WebSocketResult<UpdateSubscription>> SubscribeToUpdatesAsync<T>(Action<DataEvent<T>> handler, bool subQuery, CancellationToken ct, int individualSubscriptionCount = 1)
|
||||||
{
|
{
|
||||||
return await base.SubscribeAsync(new TestSubscription<T>(_logger, handler, subQuery, false), ct);
|
var subscription = new TestSubscription<T>(_logger, handler, subQuery, false)
|
||||||
|
{
|
||||||
|
IndividualSubscriptionCount = individualSubscriptionCount
|
||||||
|
};
|
||||||
|
return await base.SubscribeAsync(subscription, ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using CryptoExchange.Net.Objects.Errors;
|
||||||
|
using CryptoExchange.Net.Objects.Sockets;
|
||||||
|
using CryptoExchange.Net.Sockets.Default;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.UnitTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class ManualUpdateSubscriptionTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void Constructor_Should_CreateSubscribedVirtualSubscription()
|
||||||
|
{
|
||||||
|
var controller = new ManualUpdateSubscription(socketId: 12);
|
||||||
|
|
||||||
|
Assert.That(controller.Subscription.SocketId, Is.EqualTo(12));
|
||||||
|
Assert.That(controller.Subscription.Id, Is.GreaterThan(0));
|
||||||
|
Assert.That(controller.Subscription.SocketStatus, Is.EqualTo(SocketStatus.Connected));
|
||||||
|
Assert.That(controller.Subscription.SubscriptionStatus, Is.EqualTo(SubscriptionStatus.Subscribed));
|
||||||
|
Assert.That(controller.Subscription.LastReceiveTime, Is.Null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void StateChanges_Should_BeVisibleOnSubscription()
|
||||||
|
{
|
||||||
|
var controller = new ManualUpdateSubscription();
|
||||||
|
var timestamp = new DateTime(2026, 8, 5, 12, 0, 0, DateTimeKind.Utc);
|
||||||
|
var statuses = new List<SubscriptionStatus>();
|
||||||
|
controller.Subscription.SubscriptionStatusChanged += statuses.Add;
|
||||||
|
|
||||||
|
controller.SetLastReceiveTime(timestamp);
|
||||||
|
controller.SetSocketStatus(SocketStatus.Reconnecting);
|
||||||
|
controller.SetSubscriptionStatus(SubscriptionStatus.Subscribing);
|
||||||
|
controller.SetSubscriptionStatus(SubscriptionStatus.Subscribed);
|
||||||
|
|
||||||
|
Assert.That(controller.Subscription.LastReceiveTime, Is.EqualTo(timestamp));
|
||||||
|
Assert.That(controller.Subscription.SocketStatus, Is.EqualTo(SocketStatus.Reconnecting));
|
||||||
|
Assert.That(controller.Subscription.SubscriptionStatus, Is.EqualTo(SubscriptionStatus.Subscribed));
|
||||||
|
Assert.That(statuses, Is.EqualTo(new[]
|
||||||
|
{
|
||||||
|
SubscriptionStatus.Subscribing,
|
||||||
|
SubscriptionStatus.Subscribed
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void LifecycleMethods_Should_InvokeSubscriptionEvents()
|
||||||
|
{
|
||||||
|
var controller = new ManualUpdateSubscription();
|
||||||
|
var error = new ServerError("Test error", ErrorInfo.Unknown);
|
||||||
|
var exception = new InvalidOperationException("Test exception");
|
||||||
|
var disconnectedPeriod = TimeSpan.FromMinutes(2);
|
||||||
|
var lost = 0;
|
||||||
|
var restored = TimeSpan.Zero;
|
||||||
|
Error? resubscribeError = null;
|
||||||
|
var paused = 0;
|
||||||
|
var unpaused = 0;
|
||||||
|
Exception? receivedException = null;
|
||||||
|
|
||||||
|
controller.Subscription.ConnectionLost += () => lost++;
|
||||||
|
controller.Subscription.ConnectionRestored += x => restored = x;
|
||||||
|
controller.Subscription.ResubscribingFailed += x => resubscribeError = x;
|
||||||
|
controller.Subscription.ActivityPaused += () => paused++;
|
||||||
|
controller.Subscription.ActivityUnpaused += () => unpaused++;
|
||||||
|
controller.Subscription.Exception += x => receivedException = x;
|
||||||
|
|
||||||
|
controller.InvokeConnectionLost();
|
||||||
|
controller.InvokeConnectionRestored(disconnectedPeriod);
|
||||||
|
controller.InvokeResubscribingFailed(error);
|
||||||
|
controller.InvokeActivityPaused();
|
||||||
|
controller.InvokeActivityUnpaused();
|
||||||
|
controller.InvokeException(exception);
|
||||||
|
|
||||||
|
Assert.That(lost, Is.EqualTo(1));
|
||||||
|
Assert.That(restored, Is.EqualTo(disconnectedPeriod));
|
||||||
|
Assert.That(resubscribeError, Is.SameAs(error));
|
||||||
|
Assert.That(paused, Is.EqualTo(1));
|
||||||
|
Assert.That(unpaused, Is.EqualTo(1));
|
||||||
|
Assert.That(receivedException, Is.SameAs(exception));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void InvokeConnectionClosed_Should_CloseAndOnlyInvokeOnce()
|
||||||
|
{
|
||||||
|
var controller = new ManualUpdateSubscription();
|
||||||
|
var closed = 0;
|
||||||
|
controller.Subscription.ConnectionClosed += () => closed++;
|
||||||
|
|
||||||
|
controller.InvokeConnectionClosed();
|
||||||
|
controller.InvokeConnectionClosed();
|
||||||
|
|
||||||
|
Assert.That(closed, Is.EqualTo(1));
|
||||||
|
Assert.That(controller.Subscription.SocketStatus, Is.EqualTo(SocketStatus.Closed));
|
||||||
|
Assert.That(controller.Subscription.SubscriptionStatus, Is.EqualTo(SubscriptionStatus.Closed));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task SubscriptionOperations_Should_InvokeCallbacks()
|
||||||
|
{
|
||||||
|
var closes = 0;
|
||||||
|
var reconnects = 0;
|
||||||
|
var resubscribes = 0;
|
||||||
|
var controller = new ManualUpdateSubscription(
|
||||||
|
closeAsync: () =>
|
||||||
|
{
|
||||||
|
closes++;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
},
|
||||||
|
reconnectAsync: () =>
|
||||||
|
{
|
||||||
|
reconnects++;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
},
|
||||||
|
resubscribeAsync: () =>
|
||||||
|
{
|
||||||
|
resubscribes++;
|
||||||
|
return Task.FromResult(CallResult.Ok());
|
||||||
|
});
|
||||||
|
|
||||||
|
await controller.Subscription.ReconnectAsync();
|
||||||
|
var resubscribeResult = await controller.Subscription.ResubscribeAsync();
|
||||||
|
await controller.Subscription.CloseAsync();
|
||||||
|
await controller.Subscription.CloseAsync();
|
||||||
|
|
||||||
|
Assert.That(reconnects, Is.EqualTo(1));
|
||||||
|
Assert.That(resubscribes, Is.EqualTo(1));
|
||||||
|
Assert.That(resubscribeResult.Success, Is.True);
|
||||||
|
Assert.That(closes, Is.EqualTo(1));
|
||||||
|
Assert.That(controller.Subscription.SubscriptionStatus, Is.EqualTo(SubscriptionStatus.Closed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -156,8 +156,9 @@ namespace CryptoExchange.Net.UnitTests.SocketRoutingTests
|
|||||||
MessageRouter = messageRouter;
|
MessageRouter = messageRouter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CS0067 // The event is never used, but it's required by the interface
|
||||||
public event Action? OnMessageRouterUpdated;
|
public event Action? OnMessageRouterUpdated;
|
||||||
|
#pragma warning restore CS0067
|
||||||
public bool Handle(string typeIdentifier, string? topicFilter, SocketConnection socketConnection, DateTime receiveTime, string? originalData, object result)
|
public bool Handle(string typeIdentifier, string? topicFilter, SocketConnection socketConnection, DateTime receiveTime, string? originalData, object result)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
string? cacheKey = null;
|
string? cacheKey = null;
|
||||||
if (ShouldCache(definition))
|
if (ShouldCache(definition))
|
||||||
{
|
{
|
||||||
cacheKey = definition.FullUrl + definition + uriParameters?.ToFormData();
|
cacheKey = GetCacheKey(definition, uriParameters);
|
||||||
_logger.CheckingCache(cacheKey);
|
_logger.CheckingCache(cacheKey);
|
||||||
var cachedValue = _cache.Get(cacheKey, ClientOptions.CachingMaxAge);
|
var cachedValue = _cache.Get(cacheKey, ClientOptions.CachingMaxAge);
|
||||||
if (cachedValue != null)
|
if (cachedValue != null)
|
||||||
@@ -800,6 +800,13 @@ namespace CryptoExchange.Net.Clients
|
|||||||
&& definition.Method == HttpMethod.Get
|
&& definition.Method == HttpMethod.Get
|
||||||
&& !definition.PreventCaching;
|
&& !definition.PreventCaching;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Produce a unique cache key for the request based on the request definition and parameters.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual string GetCacheKey(RequestDefinition definition, Parameters? parameters)
|
||||||
|
{
|
||||||
|
return definition.FullUrl + definition + parameters?.ToFormData();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual void SetOptions(UpdateOptions options)
|
public virtual void SetOptions(UpdateOptions options)
|
||||||
@@ -889,6 +896,12 @@ namespace CryptoExchange.Net.Clients
|
|||||||
|
|
||||||
ApiCredentials = (TApiCredentials?)options.ApiCredentials?.Copy() ?? ApiCredentials;
|
ApiCredentials = (TApiCredentials?)options.ApiCredentials?.Copy() ?? ApiCredentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override string GetCacheKey(RequestDefinition definition, Parameters? parameters)
|
||||||
|
{
|
||||||
|
return definition.FullUrl + definition + parameters?.ToFormData() + GetAuthenticationProvider()?.Key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -97,6 +97,11 @@ namespace CryptoExchange.Net.Clients
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected bool AllowTopicsOnTheSameConnection { get; set; } = true;
|
protected bool AllowTopicsOnTheSameConnection { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to allow usage of a current public WebSocket connection for an authenticated request
|
||||||
|
/// </summary>
|
||||||
|
protected bool UsePublicConnectionForAuth { get; set; } = false;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public double IncomingKbps
|
public double IncomingKbps
|
||||||
{
|
{
|
||||||
@@ -625,6 +630,21 @@ namespace CryptoExchange.Net.Clients
|
|||||||
return Task.FromResult(CallResult.Ok());
|
return Task.FromResult(CallResult.Ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the connection can be used for a new subscription or query with the provided parameters
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connection">The connection to check</param>
|
||||||
|
/// <param name="address">The address set by the request</param>
|
||||||
|
/// <param name="authenticated">Whether the request needs an authenticated connection</param>
|
||||||
|
/// <param name="topic">Topic of the request</param>
|
||||||
|
/// <returns>True if connection can be used</returns>
|
||||||
|
protected virtual bool ConnectionCanBeUsedFor(SocketConnection connection, string address, bool authenticated, string? topic = null)
|
||||||
|
{
|
||||||
|
return connection.ConnectionUriString.Equals(address.TrimEnd('/'), StringComparison.Ordinal)
|
||||||
|
&& connection.ApiClient.ClientName.Equals(ClientName, StringComparison.Ordinal)
|
||||||
|
&& (AllowTopicsOnTheSameConnection || !connection.Topics.Contains(topic));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a connection for a new subscription or query. Can be an existing if there are open position or a new one.
|
/// Gets a connection for a new subscription or query. Can be an existing if there are open position or a new one.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -643,10 +663,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
string? topic = null,
|
string? topic = null,
|
||||||
int individualSubscriptionCount = 1)
|
int individualSubscriptionCount = 1)
|
||||||
{
|
{
|
||||||
var socketQuery = _socketConnections.Where(s => s.Value.ConnectionUriString.Equals(address.TrimEnd('/'), StringComparison.Ordinal)
|
var socketQuery = _socketConnections.Where(s => ConnectionCanBeUsedFor(s.Value, address, authenticated, topic)).Select(x => x.Value); // Don't ToList this so the query is executed again when called
|
||||||
&& s.Value.ApiClient.ClientName.Equals(ClientName, StringComparison.Ordinal)
|
|
||||||
&& (AllowTopicsOnTheSameConnection || !s.Value.Topics.Contains(topic)))
|
|
||||||
.Select(x => x.Value); // Don't ToList this so the query is executed again when called
|
|
||||||
|
|
||||||
// If all current socket connections are reconnecting or resubscribing wait for that to finish as we can probably use the existing connection
|
// If all current socket connections are reconnecting or resubscribing wait for that to finish as we can probably use the existing connection
|
||||||
var delayStart = DateTime.UtcNow;
|
var delayStart = DateTime.UtcNow;
|
||||||
@@ -676,49 +693,32 @@ namespace CryptoExchange.Net.Clients
|
|||||||
_logger.WaitedForReconnectingSocket((long)(DateTime.UtcNow - delayStart).TotalMilliseconds);
|
_logger.WaitedForReconnectingSocket((long)(DateTime.UtcNow - delayStart).TotalMilliseconds);
|
||||||
|
|
||||||
socketQuery = socketQuery.Where(s => (s.Status == SocketStatus.None || s.Status == SocketStatus.Connected)
|
socketQuery = socketQuery.Where(s => (s.Status == SocketStatus.None || s.Status == SocketStatus.Connected)
|
||||||
&& (s.Authenticated == authenticated || !authenticated)
|
&& (s.Authenticated == authenticated || !authenticated || UsePublicConnectionForAuth)
|
||||||
&& s.Connected).ToList();
|
&& s.Connected).ToList();
|
||||||
|
|
||||||
SocketConnection? connection;
|
bool maxConnectionsReached = _socketConnections.Count >= (ApiOptions.MaxSocketConnections ?? ClientOptions.MaxSocketConnections);
|
||||||
if (!dedicatedRequestConnection)
|
SocketConnection? connection = null;
|
||||||
{
|
if (dedicatedRequestConnection)
|
||||||
connection = socketQuery
|
|
||||||
.Where(s => !s.DedicatedRequestConnection.IsDedicatedRequestConnection)
|
|
||||||
.OrderBy(s => s.UserSubscriptionCount)
|
|
||||||
.FirstOrDefault();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
connection = socketQuery.Where(s => s.DedicatedRequestConnection.IsDedicatedRequestConnection).FirstOrDefault();
|
connection = socketQuery.Where(s => s.DedicatedRequestConnection.IsDedicatedRequestConnection).FirstOrDefault();
|
||||||
if (connection != null && !connection.DedicatedRequestConnection.Authenticated)
|
if (connection != null && !connection.DedicatedRequestConnection.Authenticated)
|
||||||
// Mark dedicated request connection as authenticated if the request is authenticated
|
// Mark dedicated request connection as authenticated if the request is authenticated
|
||||||
connection.DedicatedRequestConnection.Authenticated = authenticated;
|
connection.DedicatedRequestConnection.Authenticated = authenticated;
|
||||||
|
}
|
||||||
|
|
||||||
if (connection == null)
|
if (connection == null)
|
||||||
// Fall back to an existing connection if there is no dedicated request connection available
|
{
|
||||||
connection = socketQuery.OrderBy(s => s.UserSubscriptionCount).FirstOrDefault();
|
// Use an eligible non-dedicated connection for subscriptions, or as fallback when no dedicated request connection is available
|
||||||
|
connection = socketQuery
|
||||||
|
.Where(s => !s.DedicatedRequestConnection.IsDedicatedRequestConnection)
|
||||||
|
.Where(s => IsConnectionEligible(s, individualSubscriptionCount, maxConnectionsReached))
|
||||||
|
.OrderBy(s => s.UserSubscriptionCount)
|
||||||
|
.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool maxConnectionsReached = _socketConnections.Count >= (ApiOptions.MaxSocketConnections ?? ClientOptions.MaxSocketConnections);
|
|
||||||
if (connection != null)
|
if (connection != null)
|
||||||
{
|
|
||||||
bool lessThanBatchSubCombineTarget = connection.UserSubscriptionCount < ClientOptions.SocketSubscriptionsCombineTarget;
|
|
||||||
bool lessThanIndividualSubCombineTarget = connection.Subscriptions.Sum(x => x.IndividualSubscriptionCount) < ClientOptions.SocketIndividualSubscriptionCombineTarget;
|
|
||||||
|
|
||||||
if ((lessThanBatchSubCombineTarget && lessThanIndividualSubCombineTarget)
|
|
||||||
|| maxConnectionsReached)
|
|
||||||
{
|
|
||||||
// Use existing socket if it has less than target connections OR it has the least connections and we can't make new
|
|
||||||
// If there is a max subscriptions per connection limit also only use existing if the new subscription doesn't go over the limit
|
|
||||||
if (MaxIndividualSubscriptionsPerConnection == null)
|
|
||||||
return CallResult.Ok(connection);
|
return CallResult.Ok(connection);
|
||||||
|
|
||||||
var currentCount = connection.Subscriptions.Sum(x => x.IndividualSubscriptionCount);
|
|
||||||
if (currentCount + individualSubscriptionCount <= MaxIndividualSubscriptionsPerConnection)
|
|
||||||
return CallResult.Ok(connection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxConnectionsReached)
|
if (maxConnectionsReached)
|
||||||
return CallResult.Fail<SocketConnection>(new InvalidOperationError("Max amount of socket connections reached"));
|
return CallResult.Fail<SocketConnection>(new InvalidOperationError("Max amount of socket connections reached"));
|
||||||
|
|
||||||
@@ -784,6 +784,23 @@ namespace CryptoExchange.Net.Clients
|
|||||||
return CallResult.Ok(socketConnection);
|
return CallResult.Ok(socketConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsConnectionEligible(SocketConnection socketConnection, int individualSubscriptionCount, bool maxConnectionsReached)
|
||||||
|
{
|
||||||
|
var currentIndividualSubscriptionCount = socketConnection.Subscriptions.Sum(x => x.IndividualSubscriptionCount);
|
||||||
|
bool lessThanBatchSubCombineTarget = socketConnection.UserSubscriptionCount < ClientOptions.SocketSubscriptionsCombineTarget;
|
||||||
|
// Include the incoming batch so batched subscriptions cannot overshoot the configured socket target.
|
||||||
|
bool lessThanIndividualSubCombineTarget = currentIndividualSubscriptionCount + individualSubscriptionCount <= ClientOptions.SocketIndividualSubscriptionCombineTarget;
|
||||||
|
|
||||||
|
if ((!lessThanBatchSubCombineTarget || !lessThanIndividualSubCombineTarget)
|
||||||
|
&& !maxConnectionsReached)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MaxIndividualSubscriptionsPerConnection == null
|
||||||
|
|| currentIndividualSubscriptionCount + individualSubscriptionCount <= MaxIndividualSubscriptionsPerConnection;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Process an unhandled message
|
/// Process an unhandled message
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -14,21 +14,19 @@ using System.Text;
|
|||||||
namespace CryptoExchange.Net.Clients
|
namespace CryptoExchange.Net.Clients
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public abstract class UserClientProvider<TRestClient, TSocketClient, TRestOptions, TSocketOptions, TCredentials, TEnvironment>
|
public abstract class UserClientProvider<TRestClient, TRestOptions, TCredentials, TEnvironment>
|
||||||
where TRestClient : IRestClient<TCredentials>
|
where TRestClient : IRestClient<TCredentials>
|
||||||
where TSocketClient : ISocketClient<TCredentials>
|
|
||||||
where TRestOptions : RestExchangeOptions<TEnvironment, TCredentials>, new()
|
where TRestOptions : RestExchangeOptions<TEnvironment, TCredentials>, new()
|
||||||
where TSocketOptions : SocketExchangeOptions<TEnvironment, TCredentials>, new()
|
|
||||||
where TCredentials : ApiCredentials
|
where TCredentials : ApiCredentials
|
||||||
where TEnvironment : TradeEnvironment
|
where TEnvironment : TradeEnvironment
|
||||||
{
|
{
|
||||||
private ConcurrentDictionary<string, TRestClient> _restClients = new ConcurrentDictionary<string, TRestClient>();
|
private ConcurrentDictionary<string, TRestClient> _restClients = new ConcurrentDictionary<string, TRestClient>();
|
||||||
private ConcurrentDictionary<string, TSocketClient> _socketClients = new ConcurrentDictionary<string, TSocketClient>();
|
|
||||||
|
|
||||||
private readonly IOptions<TRestOptions> _restOptions;
|
private readonly IOptions<TRestOptions> _restOptions;
|
||||||
private readonly IOptions<TSocketOptions> _socketOptions;
|
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly ILoggerFactory? _loggerFactory;
|
/// <summary>
|
||||||
|
/// Logger factory
|
||||||
|
/// </summary>
|
||||||
|
protected readonly ILoggerFactory? _loggerFactory;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public abstract string ExchangeName { get; }
|
public abstract string ExchangeName { get; }
|
||||||
@@ -39,17 +37,14 @@ namespace CryptoExchange.Net.Clients
|
|||||||
public UserClientProvider(
|
public UserClientProvider(
|
||||||
HttpClient? httpClient,
|
HttpClient? httpClient,
|
||||||
ILoggerFactory? loggerFactory,
|
ILoggerFactory? loggerFactory,
|
||||||
IOptions<TRestOptions> restOptions,
|
IOptions<TRestOptions> restOptions)
|
||||||
IOptions<TSocketOptions> socketOptions)
|
|
||||||
{
|
{
|
||||||
_httpClient = httpClient ?? new HttpClient();
|
_httpClient = httpClient ?? new HttpClient();
|
||||||
_httpClient.Timeout = restOptions.Value.RequestTimeout;
|
_httpClient.Timeout = restOptions.Value.RequestTimeout;
|
||||||
_loggerFactory = loggerFactory;
|
_loggerFactory = loggerFactory;
|
||||||
_restOptions = restOptions;
|
_restOptions = restOptions;
|
||||||
_socketOptions = socketOptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private IOptions<TRestOptions> SetRestEnvironment(IOptions<TRestOptions> options, TEnvironment? environment)
|
private IOptions<TRestOptions> SetRestEnvironment(IOptions<TRestOptions> options, TEnvironment? environment)
|
||||||
{
|
{
|
||||||
if (environment == null)
|
if (environment == null)
|
||||||
@@ -61,22 +56,10 @@ namespace CryptoExchange.Net.Clients
|
|||||||
return Options.Create(newRestClientOptions);
|
return Options.Create(newRestClientOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IOptions<TSocketOptions> SetSocketEnvironment(IOptions<TSocketOptions> options, TEnvironment? environment)
|
|
||||||
{
|
|
||||||
if (environment == null)
|
|
||||||
return options;
|
|
||||||
|
|
||||||
var newSocketClientOptions = new TSocketOptions();
|
|
||||||
options.Value.Set(newSocketClientOptions);
|
|
||||||
newSocketClientOptions.Environment = environment;
|
|
||||||
return Options.Create(newSocketClientOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void InitializeUserClient(string userIdentifier, TCredentials credentials, TEnvironment? environment = null)
|
public virtual void InitializeUserClient(string userIdentifier, TCredentials credentials, TEnvironment? environment = null)
|
||||||
{
|
{
|
||||||
CreateRestClient(userIdentifier, credentials, environment);
|
CreateRestClient(userIdentifier, credentials, environment);
|
||||||
CreateSocketClient(userIdentifier, credentials, environment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -88,15 +71,6 @@ namespace CryptoExchange.Net.Clients
|
|||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public TSocketClient GetSocketClient(string userIdentifier, TCredentials? credentials = null, TEnvironment? environment = null)
|
|
||||||
{
|
|
||||||
if (!_socketClients.TryGetValue(userIdentifier, out var client) || client.Disposed)
|
|
||||||
client = CreateSocketClient(userIdentifier, credentials, environment);
|
|
||||||
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TRestClient CreateRestClient(string userIdentifier, TCredentials? credentials, TEnvironment? environment)
|
private TRestClient CreateRestClient(string userIdentifier, TCredentials? credentials, TEnvironment? environment)
|
||||||
{
|
{
|
||||||
var clientRestOptions = SetRestEnvironment(_restOptions, environment);
|
var clientRestOptions = SetRestEnvironment(_restOptions, environment);
|
||||||
@@ -109,6 +83,94 @@ namespace CryptoExchange.Net.Clients
|
|||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new instance of the rest client
|
||||||
|
/// </summary>
|
||||||
|
protected abstract TRestClient ConstructRestClient(
|
||||||
|
HttpClient client,
|
||||||
|
ILoggerFactory? loggerFactory,
|
||||||
|
IOptions<TRestOptions> options);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual void ClearUserClients(string userIdentifier)
|
||||||
|
{
|
||||||
|
_restClients.TryRemove(userIdentifier, out var restClient);
|
||||||
|
restClient?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual void Clear()
|
||||||
|
{
|
||||||
|
foreach (var client in _restClients.Values)
|
||||||
|
client.Dispose();
|
||||||
|
_restClients.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies the provided options delegate to a new instance of the specified type.
|
||||||
|
/// </summary>
|
||||||
|
protected static T ApplyOptionsDelegate<T>(Action<T>? del) where T : new()
|
||||||
|
{
|
||||||
|
var opts = new T();
|
||||||
|
del?.Invoke(opts);
|
||||||
|
return opts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public abstract class UserClientProvider<TRestClient, TSocketClient, TRestOptions, TSocketOptions, TCredentials, TEnvironment>
|
||||||
|
: UserClientProvider<TRestClient, TRestOptions, TCredentials, TEnvironment>
|
||||||
|
where TRestClient : IRestClient<TCredentials>
|
||||||
|
where TSocketClient : ISocketClient<TCredentials>
|
||||||
|
where TRestOptions : RestExchangeOptions<TEnvironment, TCredentials>, new()
|
||||||
|
where TSocketOptions : SocketExchangeOptions<TEnvironment, TCredentials>, new()
|
||||||
|
where TCredentials : ApiCredentials
|
||||||
|
where TEnvironment : TradeEnvironment
|
||||||
|
{
|
||||||
|
private ConcurrentDictionary<string, TSocketClient> _socketClients = new ConcurrentDictionary<string, TSocketClient>();
|
||||||
|
private readonly IOptions<TSocketOptions> _socketOptions;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ctor
|
||||||
|
/// </summary>
|
||||||
|
public UserClientProvider(
|
||||||
|
HttpClient? httpClient,
|
||||||
|
ILoggerFactory? loggerFactory,
|
||||||
|
IOptions<TRestOptions> restOptions,
|
||||||
|
IOptions<TSocketOptions> socketOptions)
|
||||||
|
: base(httpClient, loggerFactory, restOptions)
|
||||||
|
{
|
||||||
|
_socketOptions = socketOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IOptions<TSocketOptions> SetSocketEnvironment(IOptions<TSocketOptions> options, TEnvironment? environment)
|
||||||
|
{
|
||||||
|
if (environment == null)
|
||||||
|
return options;
|
||||||
|
|
||||||
|
var newSocketClientOptions = new TSocketOptions();
|
||||||
|
options.Value.Set(newSocketClientOptions);
|
||||||
|
newSocketClientOptions.Environment = environment;
|
||||||
|
return Options.Create(newSocketClientOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void InitializeUserClient(string userIdentifier, TCredentials credentials, TEnvironment? environment = null)
|
||||||
|
{
|
||||||
|
base.InitializeUserClient(userIdentifier, credentials, environment);
|
||||||
|
CreateSocketClient(userIdentifier, credentials, environment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public TSocketClient GetSocketClient(string userIdentifier, TCredentials? credentials = null, TEnvironment? environment = null)
|
||||||
|
{
|
||||||
|
if (!_socketClients.TryGetValue(userIdentifier, out var client) || client.Disposed)
|
||||||
|
client = CreateSocketClient(userIdentifier, credentials, environment);
|
||||||
|
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
private TSocketClient CreateSocketClient(string userIdentifier, TCredentials? credentials, TEnvironment? environment)
|
private TSocketClient CreateSocketClient(string userIdentifier, TCredentials? credentials, TEnvironment? environment)
|
||||||
{
|
{
|
||||||
var clientSocketOptions = SetSocketEnvironment(_socketOptions, environment);
|
var clientSocketOptions = SetSocketEnvironment(_socketOptions, environment);
|
||||||
@@ -121,15 +183,6 @@ namespace CryptoExchange.Net.Clients
|
|||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new instance of the rest client
|
|
||||||
/// </summary>
|
|
||||||
protected abstract TRestClient ConstructRestClient(
|
|
||||||
HttpClient client,
|
|
||||||
ILoggerFactory? loggerFactory,
|
|
||||||
IOptions<TRestOptions> options);
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs a new instance of the socket client
|
/// Constructs a new instance of the socket client
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -137,36 +190,23 @@ namespace CryptoExchange.Net.Clients
|
|||||||
ILoggerFactory? loggerFactory,
|
ILoggerFactory? loggerFactory,
|
||||||
IOptions<TSocketOptions> options);
|
IOptions<TSocketOptions> options);
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void ClearUserClients(string userIdentifier)
|
public override void ClearUserClients(string userIdentifier)
|
||||||
{
|
{
|
||||||
_restClients.TryRemove(userIdentifier, out var restClient);
|
base.ClearUserClients(userIdentifier);
|
||||||
|
|
||||||
_socketClients.TryRemove(userIdentifier, out var socketClient);
|
_socketClients.TryRemove(userIdentifier, out var socketClient);
|
||||||
restClient?.Dispose();
|
|
||||||
socketClient?.Dispose();
|
socketClient?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Clear()
|
public override void Clear()
|
||||||
{
|
{
|
||||||
foreach (var client in _restClients.Values)
|
base.Clear();
|
||||||
client.Dispose();
|
|
||||||
_restClients.Clear();
|
|
||||||
|
|
||||||
foreach (var client in _socketClients.Values)
|
foreach (var client in _socketClients.Values)
|
||||||
client.Dispose();
|
client.Dispose();
|
||||||
_socketClients.Clear();
|
_socketClients.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Applies the provided options delegate to a new instance of the specified type.
|
|
||||||
/// </summary>
|
|
||||||
protected static T ApplyOptionsDelegate<T>(Action<T>? del) where T : new()
|
|
||||||
{
|
|
||||||
var opts = new T();
|
|
||||||
del?.Invoke(opts);
|
|
||||||
return opts;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
if (reader.TokenType == JsonTokenType.Number)
|
if (reader.TokenType == JsonTokenType.Number)
|
||||||
{
|
{
|
||||||
var number = reader.GetInt16();
|
var number = reader.GetInt16();
|
||||||
if (number > 1)
|
if (number >= 1)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -198,6 +198,9 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
return new DateTime(year, month, day, 0, 0, 0, DateTimeKind.Utc);
|
return new DateTime(year, month, day, 0, 0, 0, DateTimeKind.Utc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stringValue.EndsWith("+00:00:00"))
|
||||||
|
return DateTime.Parse(stringValue.Substring(0, stringValue.Length - 9), CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal);
|
||||||
|
|
||||||
return DateTime.Parse(stringValue, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal);
|
return DateTime.Parse(stringValue, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -88,7 +88,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson.MessageHandlers
|
|||||||
stream.Seek(0, SeekOrigin.Begin);
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
var written = new StreamReader(stream).ReadBlock(dataSnippet, 0, _errorResponseSnippetLimit);
|
var written = new StreamReader(stream).ReadBlock(dataSnippet, 0, _errorResponseSnippetLimit);
|
||||||
var data = new string(dataSnippet, 0, written);
|
var data = new string(dataSnippet, 0, written);
|
||||||
errorMsg += $": {data}";
|
errorMsg += $": {(string.IsNullOrEmpty(data) ? "(empty)" : data)}";
|
||||||
if (data.Length == _errorResponseSnippetLimit)
|
if (data.Length == _errorResponseSnippetLimit)
|
||||||
errorMsg += " (truncated)";
|
errorMsg += " (truncated)";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
<PackageId>CryptoExchange.Net</PackageId>
|
<PackageId>CryptoExchange.Net</PackageId>
|
||||||
<Authors>JKorf</Authors>
|
<Authors>JKorf</Authors>
|
||||||
<Description>CryptoExchange.Net is a base library which is used to implement different cryptocurrency (exchange) API's. It provides a standardized way of implementing different API's, which results in a very similar experience for users of the API implementations.</Description>
|
<Description>CryptoExchange.Net is a base library which is used to implement different cryptocurrency (exchange) API's. It provides a standardized way of implementing different API's, which results in a very similar experience for users of the API implementations.</Description>
|
||||||
<PackageVersion>12.0.0</PackageVersion>
|
<PackageVersion>12.5.0</PackageVersion>
|
||||||
<AssemblyVersion>12.0.0</AssemblyVersion>
|
<AssemblyVersion>12.5.0</AssemblyVersion>
|
||||||
<FileVersion>12.0.0</FileVersion>
|
<FileVersion>12.5.0</FileVersion>
|
||||||
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
||||||
<PackageTags>OKX;OKX.Net;Mexc;Mexc.Net;Kucoin;Kucoin.Net;Kraken;Kraken.Net;Huobi;Huobi.Net;CoinEx;CoinEx.Net;Bybit;Bybit.Net;Bitget;Bitget.Net;Bitfinex;Bitfinex.Net;Binance;Binance.Net;CryptoCurrency;CryptoCurrency Exchange;CryptoExchange.Net</PackageTags>
|
<PackageTags>OKX;OKX.Net;Mexc;Mexc.Net;Kucoin;Kucoin.Net;Kraken;Kraken.Net;Huobi;Huobi.Net;CoinEx;CoinEx.Net;Bybit;Bybit.Net;Bitget;Bitget.Net;Bitfinex;Bitfinex.Net;Binance;Binance.Net;CryptoCurrency;CryptoCurrency Exchange;CryptoExchange.Net</PackageTags>
|
||||||
<RepositoryType>git</RepositoryType>
|
<RepositoryType>git</RepositoryType>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace CryptoExchange.Net
|
|||||||
if (keyedCache != null && DateTime.UtcNow - keyedCache.UpdateTime < TimeSpan.FromMinutes(60))
|
if (keyedCache != null && DateTime.UtcNow - keyedCache.UpdateTime < TimeSpan.FromMinutes(60))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
exchangeInfo.Set(key, new ExchangeInfo(DateTime.UtcNow, updateData.ToDictionary(x => x.Name, x => x.SharedSymbol)));
|
exchangeInfo.Set(key, new ExchangeInfo(DateTime.UtcNow, updateData.ToDictionary(x => x.Name, x => x)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -118,6 +118,22 @@ namespace CryptoExchange.Net
|
|||||||
return exchangeInfo.ParseSymbol(key, symbolName);
|
return exchangeInfo.ParseSymbol(key, symbolName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a symbol catalog for a specific exchange(topic) and environment. Only available if <see cref="UpdateSymbolInfo(string, string, string?, SharedSpotSymbol[])"/> has been called previously.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="exchange">Exchange name</param>
|
||||||
|
/// <param name="topicId">Id for the provided data</param>
|
||||||
|
/// <param name="environmentName">Trade environment</param>
|
||||||
|
/// <param name="key">Additional data set identification key</param>
|
||||||
|
public static SharedSymbolCatalog? GetSymbolCatalog(string exchange, string topicId, string environmentName, string? key)
|
||||||
|
{
|
||||||
|
var id = topicId + environmentName;
|
||||||
|
if (!_symbolInfos.TryGetValue(id, out var exchangeInfo))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return exchangeInfo.GetSymbolCatalog(exchange, key);
|
||||||
|
}
|
||||||
|
|
||||||
class ExchangeKeyedCache
|
class ExchangeKeyedCache
|
||||||
{
|
{
|
||||||
private ExchangeInfo? _noKeyCache;
|
private ExchangeInfo? _noKeyCache;
|
||||||
@@ -163,7 +179,7 @@ namespace CryptoExchange.Net
|
|||||||
|
|
||||||
public SharedSymbol? ParseSymbol(string? key, string symbolName)
|
public SharedSymbol? ParseSymbol(string? key, string symbolName)
|
||||||
{
|
{
|
||||||
SharedSymbol? symbolInfo = null;
|
SharedSpotSymbol? symbolInfo = null;
|
||||||
if (key == null)
|
if (key == null)
|
||||||
{
|
{
|
||||||
if (_noKeyCache != null)
|
if (_noKeyCache != null)
|
||||||
@@ -173,7 +189,7 @@ namespace CryptoExchange.Net
|
|||||||
|
|
||||||
return new SharedSymbol(symbolInfo.TradingMode, symbolInfo.BaseAsset, symbolInfo.QuoteAsset, symbolName)
|
return new SharedSymbol(symbolInfo.TradingMode, symbolInfo.BaseAsset, symbolInfo.QuoteAsset, symbolName)
|
||||||
{
|
{
|
||||||
DeliverTime = symbolInfo.DeliverTime
|
DeliverTime = (symbolInfo as SharedFuturesSymbol)?.DeliveryTime
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +199,7 @@ namespace CryptoExchange.Net
|
|||||||
{
|
{
|
||||||
return new SharedSymbol(symbolInfo.TradingMode, symbolInfo.BaseAsset, symbolInfo.QuoteAsset, symbolName)
|
return new SharedSymbol(symbolInfo.TradingMode, symbolInfo.BaseAsset, symbolInfo.QuoteAsset, symbolName)
|
||||||
{
|
{
|
||||||
DeliverTime = symbolInfo.DeliverTime
|
DeliverTime = (symbolInfo as SharedFuturesSymbol)?.DeliveryTime
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,7 +215,7 @@ namespace CryptoExchange.Net
|
|||||||
{
|
{
|
||||||
return new SharedSymbol(symbolInfo.TradingMode, symbolInfo.BaseAsset, symbolInfo.QuoteAsset, symbolName)
|
return new SharedSymbol(symbolInfo.TradingMode, symbolInfo.BaseAsset, symbolInfo.QuoteAsset, symbolName)
|
||||||
{
|
{
|
||||||
DeliverTime = symbolInfo.DeliverTime
|
DeliverTime = (symbolInfo as SharedFuturesSymbol)?.DeliveryTime
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +281,7 @@ namespace CryptoExchange.Net
|
|||||||
{
|
{
|
||||||
return _noKeyCache.Symbols
|
return _noKeyCache.Symbols
|
||||||
.Where(x => x.Value.BaseAsset.Equals(baseAsset, StringComparison.InvariantCultureIgnoreCase))
|
.Where(x => x.Value.BaseAsset.Equals(baseAsset, StringComparison.InvariantCultureIgnoreCase))
|
||||||
.Select(x => x.Value)
|
.Select(x => x.Value.SharedSymbol)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +290,7 @@ namespace CryptoExchange.Net
|
|||||||
{
|
{
|
||||||
result.AddRange(cache.Symbols
|
result.AddRange(cache.Symbols
|
||||||
.Where(x => x.Value.BaseAsset.Equals(baseAsset, StringComparison.InvariantCultureIgnoreCase))
|
.Where(x => x.Value.BaseAsset.Equals(baseAsset, StringComparison.InvariantCultureIgnoreCase))
|
||||||
.Select(x => x.Value));
|
.Select(x => x.Value.SharedSymbol));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.ToArray();
|
return result.ToArray();
|
||||||
@@ -286,18 +302,63 @@ namespace CryptoExchange.Net
|
|||||||
|
|
||||||
return exchangeInfo.Symbols
|
return exchangeInfo.Symbols
|
||||||
.Where(x => x.Value.BaseAsset.Equals(baseAsset, StringComparison.InvariantCultureIgnoreCase))
|
.Where(x => x.Value.BaseAsset.Equals(baseAsset, StringComparison.InvariantCultureIgnoreCase))
|
||||||
.Select(x => x.Value)
|
.Select(x => x.Value.SharedSymbol)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal SharedSymbolCatalog? GetSymbolCatalog(string exchange, string? key)
|
||||||
|
{
|
||||||
|
IEnumerable<SharedSpotSymbol> cachedSymbols;
|
||||||
|
if (key == null)
|
||||||
|
{
|
||||||
|
if (_noKeyCache != null)
|
||||||
|
cachedSymbols = _noKeyCache.Symbols.Values;
|
||||||
|
else
|
||||||
|
cachedSymbols = _keyedCache.Values.SelectMany(x => x.Symbols.Values);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!_keyedCache.TryGetValue(key, out var exchangeInfo) || exchangeInfo == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
cachedSymbols = exchangeInfo.Symbols.Values;
|
||||||
|
}
|
||||||
|
|
||||||
|
var assets = new Dictionary<string, SharedAssetInfo>();
|
||||||
|
var symbols = new Dictionary<string, SharedSpotSymbol>();
|
||||||
|
foreach (var symbol in cachedSymbols)
|
||||||
|
{
|
||||||
|
if (!assets.TryGetValue(symbol.BaseAsset, out var baseAssetInfo))
|
||||||
|
{
|
||||||
|
baseAssetInfo = new SharedAssetInfo(symbol.BaseAsset, symbol.BaseAssetType, symbol.BaseAssetSubType);
|
||||||
|
assets.Add(symbol.BaseAsset, baseAssetInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!assets.TryGetValue(symbol.QuoteAsset, out var quoteAssetInfo))
|
||||||
|
{
|
||||||
|
quoteAssetInfo = new SharedAssetInfo(symbol.QuoteAsset, symbol.QuoteAssetType, symbol.QuoteAssetSubType);
|
||||||
|
assets.Add(symbol.QuoteAsset, quoteAssetInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbols.Add(symbol.Name, symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SharedSymbolCatalog
|
||||||
|
{
|
||||||
|
Exchange = exchange,
|
||||||
|
Assets = assets,
|
||||||
|
Symbols = symbols
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ExchangeInfo
|
class ExchangeInfo
|
||||||
{
|
{
|
||||||
public DateTime UpdateTime { get; set; }
|
public DateTime UpdateTime { get; set; }
|
||||||
public Dictionary<string, SharedSymbol> Symbols { get; set; }
|
public Dictionary<string, SharedSpotSymbol> Symbols { get; set; }
|
||||||
|
|
||||||
public ExchangeInfo(DateTime updateTime, Dictionary<string, SharedSymbol> symbols)
|
public ExchangeInfo(DateTime updateTime, Dictionary<string, SharedSpotSymbol> symbols)
|
||||||
{
|
{
|
||||||
UpdateTime = updateTime;
|
UpdateTime = updateTime;
|
||||||
Symbols = symbols;
|
Symbols = symbols;
|
||||||
|
|||||||
@@ -461,11 +461,15 @@ namespace CryptoExchange.Net
|
|||||||
|
|
||||||
if (typeof(ISpotOrderSocketClient).IsAssignableFrom(typeof(T)))
|
if (typeof(ISpotOrderSocketClient).IsAssignableFrom(typeof(T)))
|
||||||
services.AddTransient(x => (ISpotOrderSocketClient)client(x)!);
|
services.AddTransient(x => (ISpotOrderSocketClient)client(x)!);
|
||||||
|
if (typeof(ISpotOrderManagementSocketClient).IsAssignableFrom(typeof(T)))
|
||||||
|
services.AddTransient(x => (ISpotOrderManagementSocketClient)client(x)!);
|
||||||
|
|
||||||
if (typeof(IFuturesOrderSocketClient).IsAssignableFrom(typeof(T)))
|
if (typeof(IFuturesOrderSocketClient).IsAssignableFrom(typeof(T)))
|
||||||
services.AddTransient(x => (IFuturesOrderSocketClient)client(x)!);
|
services.AddTransient(x => (IFuturesOrderSocketClient)client(x)!);
|
||||||
if (typeof(IPositionSocketClient).IsAssignableFrom(typeof(T)))
|
if (typeof(IPositionSocketClient).IsAssignableFrom(typeof(T)))
|
||||||
services.AddTransient(x => (IPositionSocketClient)client(x)!);
|
services.AddTransient(x => (IPositionSocketClient)client(x)!);
|
||||||
|
if (typeof(IFuturesOrderManagementSocketClient).IsAssignableFrom(typeof(T)))
|
||||||
|
services.AddTransient(x => (IFuturesOrderManagementSocketClient)client(x)!);
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,9 @@ namespace CryptoExchange.Net.Interfaces
|
|||||||
/// <param name="interval">Kline interval</param>
|
/// <param name="interval">Kline interval</param>
|
||||||
/// <param name="limit">The max amount of klines to retain</param>
|
/// <param name="limit">The max amount of klines to retain</param>
|
||||||
/// <param name="period">The max period the data should be retained</param>
|
/// <param name="period">The max period the data should be retained</param>
|
||||||
|
/// <param name="exchangeParameters">Exchange parameters</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IKlineTracker CreateKlineTracker(SharedSymbol symbol, SharedKlineInterval interval, int? limit = null, TimeSpan? period = null);
|
IKlineTracker CreateKlineTracker(SharedSymbol symbol, SharedKlineInterval interval, int? limit = null, TimeSpan? period = null, ExchangeParameters? exchangeParameters = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the factory supports creating a TradeTracker instance for this symbol
|
/// Whether the factory supports creating a TradeTracker instance for this symbol
|
||||||
@@ -39,7 +40,8 @@ namespace CryptoExchange.Net.Interfaces
|
|||||||
/// <param name="symbol">The symbol</param>
|
/// <param name="symbol">The symbol</param>
|
||||||
/// <param name="limit">The max amount of trades to retain</param>
|
/// <param name="limit">The max amount of trades to retain</param>
|
||||||
/// <param name="period">The max period the data should be retained</param>
|
/// <param name="period">The max period the data should be retained</param>
|
||||||
|
/// <param name="exchangeParameters">Exchange parameters</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
ITradeTracker CreateTradeTracker(SharedSymbol symbol, int? limit = null, TimeSpan? period = null);
|
ITradeTracker CreateTradeTracker(SharedSymbol symbol, int? limit = null, TimeSpan? period = null, ExchangeParameters? exchangeParameters = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ using CryptoExchange.Net.Objects.Options;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO.Pipelines;
|
||||||
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
|
||||||
@@ -14,6 +16,61 @@ namespace CryptoExchange.Net
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class LibraryHelpers
|
public static class LibraryHelpers
|
||||||
{
|
{
|
||||||
|
private static readonly HashSet<string> _stableCoins = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
// USD
|
||||||
|
"USDT", "USDC", "DAI", "FDUSD", "USDE", "TUSD", "USDP", "PYUSD", "GUSD",
|
||||||
|
"USDD", "LUSD", "USDJ", "SUSD", "ZUSD", "BUSD", "USTC", "USDX", "USDK",
|
||||||
|
"CUSD", "USD1", "USD0", "XUSD", "BFUSD", "USDS", "RLUSD", "OUSD", "USDH",
|
||||||
|
"APXUSD", "USDQ", "USDPT", "FIDD", "AUSD",
|
||||||
|
// EUR
|
||||||
|
"EURS", "EURC", "EURI", "EURT", "AGEUR", "CEUR", "AEUR", "EURQ", "EUROP",
|
||||||
|
// Other
|
||||||
|
"CNYT", // CNY
|
||||||
|
"CREAL", "BRL1", // BRL
|
||||||
|
"XSGD", // SGD
|
||||||
|
"GYEN", // JPY
|
||||||
|
"KGST", // KGS
|
||||||
|
"QCAD", // CAD
|
||||||
|
"TGBP", // GBP
|
||||||
|
"AUDX", // AUD
|
||||||
|
"MXNB", // MXN
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly HashSet<string> _commodities = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
// Metals
|
||||||
|
"XAU", "XAUT", "XAG", "XPT", "XPD", "COPPER", "PAXG", "XNI", "XCU", "XAL", "GOLD", "SILVER",
|
||||||
|
// Energy
|
||||||
|
"BZ", "NATGAS", "NGAS", "CL", "XTI", "UKOIL", "USOIL", "BRENTOIL"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly HashSet<string> _stocks = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
// Top stocks, will need to update periodically
|
||||||
|
"AAAU", "AADR", "AAPL", "ACWI", "ACWX", "AGG", "AMD", "AMLP", "AMZN", "ARKF",
|
||||||
|
"ARKG", "ARKK", "ARKQ", "ARKW", "AVGO", "BA", "BABA", "BND", "BNDX", "BOTZ",
|
||||||
|
"CIBR", "COIN", "DIA", "DIVB", "DVY", "EEM", "EFA", "EFAV", "ESGU", "EWG",
|
||||||
|
"EWJ", "EWT", "EWU", "EWW", "EWY", "EWZ", "FDN", "FEZ", "GLDM", "GOOGL",
|
||||||
|
"HDV", "HOOD", "HYG", "IAU", "IBB", "ICLN", "IEFA", "IEMG", "IGSB", "IJH",
|
||||||
|
"IJR", "INTC", "ITOT", "IUSB", "IUSG", "IUSV", "IWM", "IWO", "IWR", "IYR",
|
||||||
|
"JETS", "JPM", "LIT", "MCHI", "META", "MGK", "MSTR", "MTUM", "MU", "NET",
|
||||||
|
"NFLX", "NOBL", "NVDA", "OIH", "ORCL", "PAVE", "PBW", "PLTR", "QQQ", "QQQM",
|
||||||
|
"SCHB", "SCHD", "SCHF", "SCHG", "SCHH", "SCHV", "SCHX", "SKHY", "SPCX", "SPCXD",
|
||||||
|
"SPLG", "SPY", "SPYG", "SPYV", "SQQQ", "TSLA", "TSM", "TQQQ", "USMV", "VBR",
|
||||||
|
"VCIT", "VCSH", "VEA", "VEU", "VGIT", "VGK", "VGT", "VHT", "VIG", "VNQ",
|
||||||
|
"VOO", "VOT", "VTI", "VTV", "VUG", "VXUS", "XBI", "XLC", "XLE", "XLF",
|
||||||
|
"XLI", "XLK", "XLP", "XLU", "XLV", "XLY", "CSCO", "UBER", "MRVL", "RKLB",
|
||||||
|
"COHR", "SOXL", "HD", "DIS", "CBRS", "V", "BRKB", "FLNC", "LLY", "COST",
|
||||||
|
"ARM", "BMNR", "NBIS", "ASML", "AAOI", "GLW", "SHLD", "BE", "QNTX", "IBM",
|
||||||
|
"AMAT", "NOK", "ASTS", "BBX", "SLX", "SKHYNIX", "SAMSUNG", "HYUNDAI", "NVO",
|
||||||
|
"IREN", "ONDS", "CRM" , "VRT", "ZEST", "BTW", "HPE", "AXTI", "BX", "CRWD",
|
||||||
|
"CRDO", "NOW", "ZM", "DKNG", "RIVN", "URNM", "EBAY", "ADBE", "UVXY", "RDW",
|
||||||
|
"CIEN","PANW", "WIN", "PAYP", "HIMS", "CRWV", "QCOM", "LITE", "DRAM", "ANTHROPIC",
|
||||||
|
"OPENAI", "USAR", "BILL", "SNDK", "NASDAQ100", "SPX500", "BSB", "CRCL", "STRC",
|
||||||
|
"MSFT", "WDC"
|
||||||
|
};
|
||||||
|
|
||||||
private static ILogger? _staticLogger;
|
private static ILogger? _staticLogger;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Static logger
|
/// Static logger
|
||||||
@@ -105,6 +162,67 @@ namespace CryptoExchange.Net
|
|||||||
return _defaultClientReferences.TryGetValue(key, out var id) ? id : throw new KeyNotFoundException($"{exchange} not found in configuration");
|
return _defaultClientReferences.TryGetValue(key, out var id) ? id : throw new KeyNotFoundException($"{exchange} not found in configuration");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether an asset is a known stablecoin. Note that this is not definitive, only large known stocks are checked
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="asset">Asset name</param>
|
||||||
|
/// <param name="additionalStableCoins">Additional stablecoin names for the specific exchange</param>
|
||||||
|
public static bool IsStableCoin(string asset, params HashSet<string> additionalStableCoins)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(asset))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return _stableCoins.Contains(asset) || (additionalStableCoins != null && additionalStableCoins.Contains(asset, StringComparer.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether an asset is a known commodity. Note that this is not definitive, only large known stocks are checked
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="asset">Asset name</param>
|
||||||
|
/// <param name="additionalCommodities">Additional commodity names for the specific exchange</param>
|
||||||
|
public static bool IsCommodity(string asset, params HashSet<string> additionalCommodities)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(asset))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return _commodities.Contains(asset) || (additionalCommodities != null && additionalCommodities.Contains(asset, StringComparer.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether an asset is a known stock. Note that this is not definitive, only large known stocks are checked
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="asset">Asset name</param>
|
||||||
|
/// <param name="additionalStocks">Additional stock names for the specific exchange</param>
|
||||||
|
public static bool IsEquity(string asset, params HashSet<string> additionalStocks)
|
||||||
|
=> IsEquity(asset, [], additionalStocks);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether an asset is a known stock.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="asset">Asset name</param>
|
||||||
|
/// <param name="potentialSuffixes">Suffixes to check, for example when `X` is a potential suffix both `TSLA` and `TSLAX` will be checked</param>
|
||||||
|
/// <param name="additionalStocks">Additional stock names for the specific exchange</param>
|
||||||
|
public static bool IsEquity(string asset, string[] potentialSuffixes, params HashSet<string> additionalStocks)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(asset))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_stocks.Contains(asset) || (additionalStocks != null && additionalStocks.Contains(asset, StringComparer.OrdinalIgnoreCase)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
foreach (var suffix in potentialSuffixes)
|
||||||
|
{
|
||||||
|
if (!asset.EndsWith(suffix))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var suffixAsset = asset.Substring(0, asset.Length - suffix.Length);
|
||||||
|
if (_stocks.Contains(suffixAsset) || (additionalStocks != null && additionalStocks.Contains(suffixAsset, StringComparer.OrdinalIgnoreCase)))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new HttpMessageHandler instance
|
/// Create a new HttpMessageHandler instance
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
_receivedMessageNotMatchedToAnyListener = LoggerMessage.Define<int, string, string, string>(
|
_receivedMessageNotMatchedToAnyListener = LoggerMessage.Define<int, string, string, string>(
|
||||||
LogLevel.Warning,
|
LogLevel.Warning,
|
||||||
new EventId(2029, "ReceivedMessageNotMatchedToAnyListener"),
|
new EventId(2029, "ReceivedMessageNotMatchedToAnyListener"),
|
||||||
"[Sckt {SocketId}] received message not matched to any listener. TypeIdentifier: {TypeIdentifier}, ListenId: {ListenId}, current listeners: [{ListenIds}]");
|
"[Sckt {SocketId}] received message not matched to any listener. TypeIdentifier: {TypeIdentifier}, TopicFilter: {ListenId}, registered TopicFilters for type: [{TopicFilters}]");
|
||||||
|
|
||||||
_failedToParse = LoggerMessage.Define<int, string>(
|
_failedToParse = LoggerMessage.Define<int, string>(
|
||||||
LogLevel.Warning,
|
LogLevel.Warning,
|
||||||
@@ -326,9 +326,9 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
_sendingData(logger, socketId, requestId, data, null);
|
_sendingData(logger, socketId, requestId, data, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ReceivedMessageNotMatchedToAnyListener(this ILogger logger, int socketId, string typeIdentifier, string listenId, string listenIds)
|
public static void ReceivedMessageNotMatchedToAnyListener(this ILogger logger, int socketId, string typeIdentifier, string topicFilter, string topicFilters)
|
||||||
{
|
{
|
||||||
_receivedMessageNotMatchedToAnyListener(logger, socketId, typeIdentifier, listenId, listenIds, null);
|
_receivedMessageNotMatchedToAnyListener(logger, socketId, typeIdentifier, topicFilter, topicFilters, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendingByteData(this ILogger logger, int socketId, int requestId, int length)
|
public static void SendingByteData(this ILogger logger, int socketId, int requestId, int length)
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ namespace CryptoExchange.Net.Objects
|
|||||||
/// Add key as comma separated values
|
/// Add key as comma separated values
|
||||||
/// </summary>
|
/// </summary>
|
||||||
#if NET5_0_OR_GREATER
|
#if NET5_0_OR_GREATER
|
||||||
public void AddCommaSeparated<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicFields)] T>(string key, IEnumerable<T> values)
|
public void AddCommaSeparated<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicFields)] T>(string key, IEnumerable<T>? values)
|
||||||
#else
|
#else
|
||||||
public void AddCommaSeparated<T>(string key, IEnumerable<T>? values)
|
public void AddCommaSeparated<T>(string key, IEnumerable<T>? values)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@@ -8,8 +9,11 @@ namespace CryptoExchange.Net.Objects;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Call result
|
/// Call result
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[DebuggerDisplay("{DebugView,nq}")]
|
||||||
public record CallResult : ICallResult
|
public record CallResult : ICallResult
|
||||||
{
|
{
|
||||||
|
private string DebugView => Success ? "Success" : $"Error: {Error}";
|
||||||
|
|
||||||
private static CallResult _successResult = new CallResult();
|
private static CallResult _successResult = new CallResult();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using CryptoExchange.Net.SharedApis;
|
using CryptoExchange.Net.SharedApis;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
@@ -12,8 +13,11 @@ namespace CryptoExchange.Net.Objects;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// HTTP call result
|
/// HTTP call result
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[DebuggerDisplay("{DebugView,nq}")]
|
||||||
public record HttpResult : IHttpResult
|
public record HttpResult : IHttpResult
|
||||||
{
|
{
|
||||||
|
private string DebugView => $"[Req {RequestId}] " + (Success ? "Success" : $"Error: {Error}");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new success HTTP result
|
/// Create a new success HTTP result
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -251,8 +255,32 @@ public record HttpResult : IHttpResult
|
|||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
[DebuggerDisplay("{DebugView,nq}")]
|
||||||
public record HttpResult<T> : HttpResult, IHttpResult<T>
|
public record HttpResult<T> : HttpResult, IHttpResult<T>
|
||||||
{
|
{
|
||||||
|
private string DebugView
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var result = new StringBuilder($"[Req {RequestId}] " + (Success ? "Success" : $"Error: {Error}"));
|
||||||
|
if (Data != null)
|
||||||
|
{
|
||||||
|
result.Append(", ");
|
||||||
|
var typeName = typeof(T).Name;
|
||||||
|
if (Data is Array ar)
|
||||||
|
{
|
||||||
|
result.Append($"{ar.Length} {typeName.Substring(0, typeName.Length - 2)}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.Append(typeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@@ -8,8 +9,11 @@ namespace CryptoExchange.Net.Objects;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// WebSocket call result
|
/// WebSocket call result
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[DebuggerDisplay("{DebugView,nq}")]
|
||||||
public record WebSocketResult : IWebSocketResult
|
public record WebSocketResult : IWebSocketResult
|
||||||
{
|
{
|
||||||
|
private string DebugView => $"[Sckt {ConnectionId}] " + (RequestId == null ? "" : $"[Req {RequestId}] ") + (Success ? "Success" : $"Error: {Error}");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -183,7 +187,7 @@ public record WebSocketResult<T> : WebSocketResult, IWebSocketResult<T>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public record QueryResult : WebSocketResult
|
public record QueryResult : WebSocketResult, IQueryResult
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
@@ -208,6 +212,8 @@ public record QueryResult : WebSocketResult
|
|||||||
Url = result.Url,
|
Url = result.Url,
|
||||||
RequestId = result.RequestId,
|
RequestId = result.RequestId,
|
||||||
ResponseTime = result.ResponseTime,
|
ResponseTime = result.ResponseTime,
|
||||||
|
OriginalData = result.OriginalData,
|
||||||
|
RequestBody = result.RequestBody
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -288,6 +294,9 @@ public record QueryResult : WebSocketResult
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string? RequestBody { get; init; }
|
public string? RequestBody { get; init; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string? OriginalData { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -314,7 +323,4 @@ public record QueryResult<T> : QueryResult, IQueryResult<T>
|
|||||||
public new bool Success => Error == null;
|
public new bool Success => Error == null;
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public T? Data { get; set; }
|
public T? Data { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string? OriginalData { get; init; }
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,209 @@
|
|||||||
|
using CryptoExchange.Net.Sockets;
|
||||||
|
using CryptoExchange.Net.Sockets.Default;
|
||||||
|
using CryptoExchange.Net.Sockets.Default.Routing;
|
||||||
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.Objects.Sockets
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Controller for an update subscription which isn't backed by a websocket connection. Can be used for testing.
|
||||||
|
/// </summary>
|
||||||
|
public class ManualUpdateSubscription
|
||||||
|
{
|
||||||
|
private readonly Func<Task> _closeAsync;
|
||||||
|
private readonly Func<Task> _reconnectAsync;
|
||||||
|
private readonly Func<Task<CallResult>> _resubscribeAsync;
|
||||||
|
private readonly ManualSubscription _manualSubscription;
|
||||||
|
private int _closedEventInvoked;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The update subscription
|
||||||
|
/// </summary>
|
||||||
|
public UpdateSubscription Subscription { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The virtual socket id
|
||||||
|
/// </summary>
|
||||||
|
public int SocketId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The last timestamp anything was received by the subscription
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? LastReceiveTime { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current virtual websocket status
|
||||||
|
/// </summary>
|
||||||
|
public SocketStatus SocketStatus { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a manually controlled update subscription
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="socketId">The virtual socket id</param>
|
||||||
|
/// <param name="closeAsync">Callback when the subscription is closed</param>
|
||||||
|
/// <param name="reconnectAsync">Callback when a reconnect is requested</param>
|
||||||
|
/// <param name="resubscribeAsync">Callback when a resubscribe is requested</param>
|
||||||
|
public ManualUpdateSubscription(
|
||||||
|
int socketId = 0,
|
||||||
|
Func<Task>? closeAsync = null,
|
||||||
|
Func<Task>? reconnectAsync = null,
|
||||||
|
Func<Task<CallResult>>? resubscribeAsync = null)
|
||||||
|
{
|
||||||
|
SocketId = socketId;
|
||||||
|
SocketStatus = SocketStatus.Connected;
|
||||||
|
_closeAsync = closeAsync ?? (() => Task.CompletedTask);
|
||||||
|
_reconnectAsync = reconnectAsync ?? (() => Task.CompletedTask);
|
||||||
|
_resubscribeAsync = resubscribeAsync ?? (() => Task.FromResult(CallResult.Ok()));
|
||||||
|
|
||||||
|
_manualSubscription = new ManualSubscription();
|
||||||
|
_manualSubscription.Status = SubscriptionStatus.Subscribed;
|
||||||
|
Subscription = new UpdateSubscription(this, _manualSubscription);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the last timestamp anything was received by the subscription
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="timestamp">The receive timestamp</param>
|
||||||
|
public void SetLastReceiveTime(DateTime? timestamp)
|
||||||
|
{
|
||||||
|
LastReceiveTime = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the virtual websocket status
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="status">The status</param>
|
||||||
|
public void SetSocketStatus(SocketStatus status)
|
||||||
|
{
|
||||||
|
SocketStatus = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the subscription status
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="status">The status</param>
|
||||||
|
public void SetSubscriptionStatus(SubscriptionStatus status)
|
||||||
|
{
|
||||||
|
_manualSubscription.Status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoke the connection lost event
|
||||||
|
/// </summary>
|
||||||
|
public void InvokeConnectionLost()
|
||||||
|
{
|
||||||
|
Subscription.HandleConnectionLostEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoke the connection restored event
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disconnectedPeriod">The period the connection was disconnected</param>
|
||||||
|
public void InvokeConnectionRestored(TimeSpan disconnectedPeriod)
|
||||||
|
{
|
||||||
|
Subscription.HandleConnectionRestoredEvent(disconnectedPeriod);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoke the connection closed event
|
||||||
|
/// </summary>
|
||||||
|
public void InvokeConnectionClosed()
|
||||||
|
{
|
||||||
|
if (Interlocked.Exchange(ref _closedEventInvoked, 1) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SocketStatus = SocketStatus.Closed;
|
||||||
|
_manualSubscription.Status = SubscriptionStatus.Closed;
|
||||||
|
Subscription.HandleConnectionClosedEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoke the resubscribing failed event
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="error">The resubscribe error</param>
|
||||||
|
public void InvokeResubscribingFailed(Error error)
|
||||||
|
{
|
||||||
|
if (error == null)
|
||||||
|
throw new ArgumentNullException(nameof(error));
|
||||||
|
|
||||||
|
Subscription.HandleResubscribeFailedEvent(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoke the activity paused event
|
||||||
|
/// </summary>
|
||||||
|
public void InvokeActivityPaused()
|
||||||
|
{
|
||||||
|
Subscription.HandlePausedEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoke the activity unpaused event
|
||||||
|
/// </summary>
|
||||||
|
public void InvokeActivityUnpaused()
|
||||||
|
{
|
||||||
|
Subscription.HandleUnpausedEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoke the exception event
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="exception">The exception</param>
|
||||||
|
public void InvokeException(Exception exception)
|
||||||
|
{
|
||||||
|
if (exception == null)
|
||||||
|
throw new ArgumentNullException(nameof(exception));
|
||||||
|
|
||||||
|
_manualSubscription.InvokeExceptionHandler(exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal async Task CloseAsync()
|
||||||
|
{
|
||||||
|
if (_manualSubscription.Status == SubscriptionStatus.Closed
|
||||||
|
|| _manualSubscription.Status == SubscriptionStatus.Closing)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_manualSubscription.Status = SubscriptionStatus.Closing;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _closeAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_manualSubscription.Status = SubscriptionStatus.Closed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Task ReconnectAsync()
|
||||||
|
{
|
||||||
|
return _reconnectAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Task<CallResult> ResubscribeAsync()
|
||||||
|
{
|
||||||
|
return _resubscribeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ManualSubscription : Subscription
|
||||||
|
{
|
||||||
|
public ManualSubscription()
|
||||||
|
: base(NullLogger.Instance, false)
|
||||||
|
{
|
||||||
|
MessageRouter = MessageRouter.Create();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Query? GetSubQuery(SocketConnection connection)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Query? GetUnsubQuery(SocketConnection connection)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,8 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class UpdateSubscription
|
public class UpdateSubscription
|
||||||
{
|
{
|
||||||
private readonly SocketConnection _connection;
|
private readonly SocketConnection? _connection;
|
||||||
|
private readonly ManualUpdateSubscription? _manualSubscription;
|
||||||
internal readonly Subscription _subscription;
|
internal readonly Subscription _subscription;
|
||||||
|
|
||||||
#if NET9_0_OR_GREATER
|
#if NET9_0_OR_GREATER
|
||||||
@@ -102,7 +103,7 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The id of the socket
|
/// The id of the socket
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int SocketId => _connection.SocketId;
|
public int SocketId => _connection?.SocketId ?? _manualSubscription!.SocketId;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The id of the subscription
|
/// The id of the subscription
|
||||||
@@ -112,12 +113,12 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The last timestamp anything was received from the server
|
/// The last timestamp anything was received from the server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? LastReceiveTime => _connection.LastReceiveTime;
|
public DateTime? LastReceiveTime => _connection?.LastReceiveTime ?? _manualSubscription!.LastReceiveTime;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current websocket status
|
/// The current websocket status
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SocketStatus SocketStatus => _connection.Status;
|
public SocketStatus SocketStatus => _connection?.Status ?? _manualSubscription!.SocketStatus;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current subscription status
|
/// The current subscription status
|
||||||
@@ -143,6 +144,18 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
_subscription.StatusChanged += (x) => SubscriptionStatusChanged?.Invoke(x);
|
_subscription.StatusChanged += (x) => SubscriptionStatusChanged?.Invoke(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ctor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="manualSubscription">The manual subscription for controlling events and data</param>
|
||||||
|
/// <param name="subscription">The subscription</param>
|
||||||
|
internal UpdateSubscription(ManualUpdateSubscription manualSubscription, Subscription subscription)
|
||||||
|
{
|
||||||
|
_manualSubscription = manualSubscription;
|
||||||
|
_subscription = subscription;
|
||||||
|
_subscription.StatusChanged += (x) => SubscriptionStatusChanged?.Invoke(x);
|
||||||
|
}
|
||||||
|
|
||||||
private void UnsubscribeConnectionEvents()
|
private void UnsubscribeConnectionEvents()
|
||||||
{
|
{
|
||||||
lock (_eventLock)
|
lock (_eventLock)
|
||||||
@@ -150,22 +163,26 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
if (!_connectionEventsSubscribed)
|
if (!_connectionEventsSubscribed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (_connection != null)
|
||||||
|
{
|
||||||
_connection.ConnectionClosed -= HandleConnectionClosedEvent;
|
_connection.ConnectionClosed -= HandleConnectionClosedEvent;
|
||||||
_connection.ConnectionLost -= HandleConnectionLostEvent;
|
_connection.ConnectionLost -= HandleConnectionLostEvent;
|
||||||
_connection.ConnectionRestored -= HandleConnectionRestoredEvent;
|
_connection.ConnectionRestored -= HandleConnectionRestoredEvent;
|
||||||
_connection.ResubscribingFailed -= HandleResubscribeFailedEvent;
|
_connection.ResubscribingFailed -= HandleResubscribeFailedEvent;
|
||||||
_connection.ActivityPaused -= HandlePausedEvent;
|
_connection.ActivityPaused -= HandlePausedEvent;
|
||||||
_connection.ActivityUnpaused -= HandleUnpausedEvent;
|
_connection.ActivityUnpaused -= HandleUnpausedEvent;
|
||||||
|
}
|
||||||
|
|
||||||
_connectionEventsSubscribed = false;
|
_connectionEventsSubscribed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleConnectionClosedEvent()
|
internal void HandleConnectionClosedEvent()
|
||||||
{
|
{
|
||||||
UnsubscribeConnectionEvents();
|
UnsubscribeConnectionEvents();
|
||||||
|
|
||||||
// If we're not the subscription closing this connection don't bother emitting
|
// If we're not the subscription closing this connection don't bother emitting
|
||||||
if (!_subscription.IsClosingConnection)
|
if (_connection != null && !_subscription.IsClosingConnection)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
List<Action> handlers;
|
List<Action> handlers;
|
||||||
@@ -176,7 +193,7 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleConnectionLostEvent()
|
internal void HandleConnectionLostEvent()
|
||||||
{
|
{
|
||||||
if (!_subscription.Active)
|
if (!_subscription.Active)
|
||||||
{
|
{
|
||||||
@@ -192,7 +209,7 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleConnectionRestoredEvent(TimeSpan period)
|
internal void HandleConnectionRestoredEvent(TimeSpan period)
|
||||||
{
|
{
|
||||||
if (!_subscription.Active)
|
if (!_subscription.Active)
|
||||||
{
|
{
|
||||||
@@ -208,7 +225,7 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
callback(period);
|
callback(period);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleResubscribeFailedEvent(Error error)
|
internal void HandleResubscribeFailedEvent(Error error)
|
||||||
{
|
{
|
||||||
if (!_subscription.Active)
|
if (!_subscription.Active)
|
||||||
{
|
{
|
||||||
@@ -224,7 +241,7 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
callback(error);
|
callback(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandlePausedEvent()
|
internal void HandlePausedEvent()
|
||||||
{
|
{
|
||||||
if (!_subscription.Active)
|
if (!_subscription.Active)
|
||||||
{
|
{
|
||||||
@@ -240,7 +257,7 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleUnpausedEvent()
|
internal void HandleUnpausedEvent()
|
||||||
{
|
{
|
||||||
if (!_subscription.Active)
|
if (!_subscription.Active)
|
||||||
{
|
{
|
||||||
@@ -262,7 +279,10 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task CloseAsync()
|
public Task CloseAsync()
|
||||||
{
|
{
|
||||||
|
if (_connection != null)
|
||||||
return _connection.CloseAsync(_subscription);
|
return _connection.CloseAsync(_subscription);
|
||||||
|
|
||||||
|
return _manualSubscription!.CloseAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -271,7 +291,10 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task ReconnectAsync()
|
public Task ReconnectAsync()
|
||||||
{
|
{
|
||||||
|
if (_connection != null)
|
||||||
return _connection.TriggerReconnectAsync();
|
return _connection.TriggerReconnectAsync();
|
||||||
|
|
||||||
|
return _manualSubscription!.ReconnectAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -279,8 +302,14 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
internal async Task UnsubscribeAsync()
|
internal async Task UnsubscribeAsync()
|
||||||
|
{
|
||||||
|
if (_connection != null)
|
||||||
{
|
{
|
||||||
await _connection.UnsubscribeAsync(_subscription).ConfigureAwait(false);
|
await _connection.UnsubscribeAsync(_subscription).ConfigureAwait(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _manualSubscription!.CloseAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -289,7 +318,10 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
internal async Task<CallResult> ResubscribeAsync()
|
internal async Task<CallResult> ResubscribeAsync()
|
||||||
{
|
{
|
||||||
|
if (_connection != null)
|
||||||
return await _connection.ResubscribeAsync(_subscription).ConfigureAwait(false);
|
return await _connection.ResubscribeAsync(_subscription).ConfigureAwait(false);
|
||||||
|
|
||||||
|
return await _manualSubscription!.ResubscribeAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -289,6 +289,7 @@ namespace CryptoExchange.Net.OrderBook
|
|||||||
if (!startResult.Success)
|
if (!startResult.Success)
|
||||||
{
|
{
|
||||||
Status = OrderBookStatus.Disconnected;
|
Status = OrderBookStatus.Disconnected;
|
||||||
|
_queueEvent.Set();
|
||||||
return CallResult.Fail(startResult.Error!);
|
return CallResult.Fail(startResult.Error!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Asset type
|
||||||
|
/// </summary>
|
||||||
|
public enum SharedAssetType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Unknown or unspecified asset type
|
||||||
|
/// </summary>
|
||||||
|
Unspecified,
|
||||||
|
/// <summary>
|
||||||
|
/// Cryptocurrency asset type
|
||||||
|
/// </summary>
|
||||||
|
Crypto,
|
||||||
|
/// <summary>
|
||||||
|
/// Fiat currency asset type
|
||||||
|
/// </summary>
|
||||||
|
Fiat,
|
||||||
|
/// <summary>
|
||||||
|
/// Traditional finance asset type
|
||||||
|
/// </summary>
|
||||||
|
TradFi
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Asset sub type
|
||||||
|
/// </summary>
|
||||||
|
public enum SharedAssetSubType
|
||||||
|
{
|
||||||
|
// --- Crypto sub types ---
|
||||||
|
/// <summary>
|
||||||
|
/// Stable coin, can be for different fiat currencies
|
||||||
|
/// </summary>
|
||||||
|
StableCoin,
|
||||||
|
|
||||||
|
// --- TradFi sub types ---
|
||||||
|
/// <summary>
|
||||||
|
/// Equity, can be stocks, ETFs, or indices
|
||||||
|
/// </summary>
|
||||||
|
Equity,
|
||||||
|
/// <summary>
|
||||||
|
/// Commodity, can be oil, gas, metals, etc.
|
||||||
|
/// </summary>
|
||||||
|
Commodity
|
||||||
|
}
|
||||||
|
}
|
||||||
-39
@@ -1,39 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using System.Threading;
|
|
||||||
using CryptoExchange.Net.Objects;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Client for managing futures orders using a client order id
|
|
||||||
/// </summary>
|
|
||||||
public interface IFuturesOrderClientIdRestClient : ISharedClient
|
|
||||||
{
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetFuturesOrderByClientOrderIdOptions GetFuturesOrderByClientOrderIdOptions { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get info on a specific futures order using a client order id, see <see cref="GetFuturesOrderByClientOrderIdOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedFuturesOrder>> GetFuturesOrderByClientOrderIdAsync(GetOrderRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
CancelFuturesOrderByClientOrderIdOptions CancelFuturesOrderByClientOrderIdOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Cancel a futures order using client order id, see <see cref="CancelFuturesOrderByClientOrderIdOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedId>> CancelFuturesOrderByClientOrderIdAsync(CancelOrderRequest request, CancellationToken ct = default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Client for placing and managing futures orders
|
|
||||||
/// </summary>
|
|
||||||
public interface IFuturesOrderRestClient : ISharedClient
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// How the trading fee is deducted
|
|
||||||
/// </summary>
|
|
||||||
SharedFeeDeductionType FuturesFeeDeductionType { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// How the asset is determined in which the trading fee is paid
|
|
||||||
/// </summary>
|
|
||||||
SharedFeeAssetType FuturesFeeAssetType { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Supported order types for futures orders
|
|
||||||
/// </summary>
|
|
||||||
SharedOrderType[] FuturesSupportedOrderTypes { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Supported time in force types for futures orders
|
|
||||||
/// </summary>
|
|
||||||
SharedTimeInForce[] FuturesSupportedTimeInForce { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Supported quantity types for futures orders
|
|
||||||
/// </summary>
|
|
||||||
SharedQuantitySupport FuturesSupportedOrderQuantity { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generate a new random client order id
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
string GenerateClientOrderId();
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
PlaceFuturesOrderOptions PlaceFuturesOrderOptions { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Place a new futures order, see <see cref="PlaceFuturesOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedId>> PlaceFuturesOrderAsync(PlaceFuturesOrderRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetFuturesOrderOptions GetFuturesOrderOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Get info on a specific futures order, see <see cref="GetFuturesOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedFuturesOrder>> GetFuturesOrderAsync(GetOrderRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetOpenFuturesOrdersOptions GetOpenFuturesOrdersOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Get info on a open futures orders, see <see cref="GetOpenFuturesOrdersOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedFuturesOrder[]>> GetOpenFuturesOrdersAsync(GetOpenOrdersRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetFuturesClosedOrdersOptions GetClosedFuturesOrdersOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Get info on closed futures orders, see <see cref="GetClosedFuturesOrdersOptions"/> 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.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedFuturesOrder[]>> GetClosedFuturesOrdersAsync(GetClosedOrdersRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetFuturesOrderTradesOptions GetFuturesOrderTradesOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Get trades for a specific futures order, see <see cref="GetFuturesOrderTradesOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedUserTrade[]>> GetFuturesOrderTradesAsync(GetOrderTradesRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetFuturesUserTradesOptions 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.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedUserTrade[]>> GetFuturesUserTradesAsync(GetUserTradesRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
CancelFuturesOrderOptions CancelFuturesOrderOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Cancel a futures order, see <see cref="CancelFuturesOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedId>> CancelFuturesOrderAsync(CancelOrderRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetPositionsOptions GetPositionsOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Get open position info, see <see cref="GetPositionsOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedPosition[]>> GetPositionsAsync(GetPositionsRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
ClosePositionOptions ClosePositionOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Close a currently open position, see <see cref="ClosePositionOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<HttpResult<SharedId>> ClosePositionAsync(ClosePositionRequest request, CancellationToken ct = default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Client for requesting ticker info for futures symbols
|
|
||||||
/// </summary>
|
|
||||||
public interface IFuturesTickerRestClient : ISharedClient
|
|
||||||
{
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetFuturesTickerOptions 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>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedFuturesTicker>> GetFuturesTickerAsync(GetTickerRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetFuturesTickersOptions 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>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedFuturesTicker[]>> GetFuturesTickersAsync(GetTickersRequest request, CancellationToken ct = default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using System.Threading;
|
|
||||||
using CryptoExchange.Net.Objects;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Take profit / Stop loss client
|
|
||||||
/// </summary>
|
|
||||||
public interface IFuturesTpSlRestClient : ISharedClient
|
|
||||||
{
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
SetFuturesTpSlOptions SetFuturesTpSlOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Set a take profit and/or stop loss for an open position, see <see cref="SetFuturesTpSlOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<HttpResult<SharedId>> SetFuturesTpSlAsync(SetTpSlRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
CancelFuturesTpSlOptions CancelFuturesTpSlOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Cancel an active take profit and/or stop loss for an open position, see <see cref="CancelFuturesTpSlOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<HttpResult<bool>> CancelFuturesTpSlAsync(CancelTpSlRequest request, CancellationToken ct = default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-53
@@ -1,53 +0,0 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Client for placing trigger orders
|
|
||||||
/// </summary>
|
|
||||||
public interface IFuturesTriggerOrderRestClient : ISharedClient
|
|
||||||
{
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
PlaceFuturesTriggerOrderOptions PlaceFuturesTriggerOrderOptions { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Place a new trigger order, see <see cref="PlaceFuturesTriggerOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<HttpResult<SharedId>> PlaceFuturesTriggerOrderAsync(PlaceFuturesTriggerOrderRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetFuturesTriggerOrderOptions GetFuturesTriggerOrderOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Get info on a specific trigger order, see <see cref="GetFuturesTriggerOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedFuturesTriggerOrder>> GetFuturesTriggerOrderAsync(GetOrderRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
CancelFuturesTriggerOrderOptions CancelFuturesTriggerOrderOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Cancel a trigger order, see <see cref="CancelFuturesTriggerOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedId>> CancelFuturesTriggerOrderAsync(CancelOrderRequest request, CancellationToken ct = default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Client for requesting asset info
|
|
||||||
/// </summary>
|
|
||||||
public interface IAssetsRestClient : ISharedClient
|
|
||||||
{
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetAssetOptions GetAssetOptions { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get info on a specific asset, see <see cref="GetAssetOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedAsset>> GetAssetAsync(GetAssetRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetAssetsOptions 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 />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedAsset[]>> GetAssetsAsync(GetAssetsRequest request, CancellationToken ct = default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Client for requesting deposit addresses and deposit records
|
|
||||||
/// </summary>
|
|
||||||
public interface IDepositRestClient : ISharedClient
|
|
||||||
{
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetDepositAddressesOptions GetDepositAddressesOptions { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get deposit addresses for an asset, see <see cref="GetDepositAddressesOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<HttpResult<SharedDepositAddress[]>> GetDepositAddressesAsync(GetDepositAddressesRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetDepositsOptions GetDepositsOptions { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get deposit records, see <see cref="GetDepositsOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<HttpResult<SharedDeposit[]>> GetDepositsAsync(GetDepositsRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for request funding rate records
|
||||||
|
/// </summary>
|
||||||
|
public interface IFundingRateRestClient : IGetFundingRateHistoryRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Threading;
|
||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for managing futures orders using a client order id
|
||||||
|
/// </summary>
|
||||||
|
public interface IFuturesOrderClientIdRestClient :
|
||||||
|
IGetFuturesOrderByClientOrderIdRestClient,
|
||||||
|
ICancelFuturesOrderByClientOrderIdRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for placing and managing futures orders
|
||||||
|
/// </summary>
|
||||||
|
public interface IFuturesOrderRestClient :
|
||||||
|
IPlaceFuturesOrderRestClient,
|
||||||
|
IGetFuturesOrderRestClient,
|
||||||
|
IGetOpenFuturesOrdersRestClient,
|
||||||
|
IGetClosedFuturesOrdersRestClient,
|
||||||
|
IGetFuturesOrderTradesRestClient,
|
||||||
|
IGetFuturesUserTradesRestClient,
|
||||||
|
ICancelFuturesOrderRestClient,
|
||||||
|
IGetPositionsRestClient,
|
||||||
|
IClosePositionRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for request futures symbol info
|
||||||
|
/// </summary>
|
||||||
|
public interface IFuturesSymbolRestClient : IGetFuturesSymbolsRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for requesting ticker info for futures symbols
|
||||||
|
/// </summary>
|
||||||
|
public interface IFuturesTickerRestClient :
|
||||||
|
IGetFuturesTickerRestClient,
|
||||||
|
IGetAllFuturesTickersRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Threading;
|
||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Take profit / Stop loss client
|
||||||
|
/// </summary>
|
||||||
|
public interface IFuturesTpSlRestClient :
|
||||||
|
ISetFuturesTpSlRestClient,
|
||||||
|
ICancelFuturesTpSlRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for placing trigger orders
|
||||||
|
/// </summary>
|
||||||
|
public interface IFuturesTriggerOrderRestClient :
|
||||||
|
IPlaceFuturesTriggerOrderRestClient,
|
||||||
|
IGetFuturesTriggerOrderRestClient,
|
||||||
|
ICancelFuturesTriggerOrderRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for getting the index price klines for a symbol
|
||||||
|
/// </summary>
|
||||||
|
public interface IIndexPriceKlineRestClient : IGetIndexPriceKlinesRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for managing the leverage of a symbol
|
||||||
|
/// </summary>
|
||||||
|
public interface ILeverageRestClient :
|
||||||
|
IGetLeverageRestClient,
|
||||||
|
ISetLeverageRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for getting the mark price klines for a symbol
|
||||||
|
/// </summary>
|
||||||
|
public interface IMarkPriceKlineRestClient : IGetMarkPriceKlinesRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for getting the open interest for a symbol
|
||||||
|
/// </summary>
|
||||||
|
public interface IOpenInterestRestClient : IGetOpenInterestRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for getting position history
|
||||||
|
/// </summary>
|
||||||
|
public interface IPositionHistoryRestClient : IGetPositionHistoryRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for managing the position mode setting
|
||||||
|
/// </summary>
|
||||||
|
public interface IPositionModeRestClient :
|
||||||
|
IGetPositionModeRestClient,
|
||||||
|
ISetPositionModeRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for requesting asset info
|
||||||
|
/// </summary>
|
||||||
|
public interface IAssetsRestClient :
|
||||||
|
IGetAssetRestClient,
|
||||||
|
IGetAllAssetsRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for requesting user balance info
|
||||||
|
/// </summary>
|
||||||
|
public interface IBalanceRestClient : IGetBalancesRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for retrieving the current best bid/ask price
|
||||||
|
/// </summary>
|
||||||
|
public interface IBookTickerRestClient : IGetBookTickerRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for requesting deposit addresses and deposit records
|
||||||
|
/// </summary>
|
||||||
|
public interface IDepositRestClient :
|
||||||
|
IGetDepositAddressesRestClient,
|
||||||
|
IGetDepositHistoryRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Threading;
|
||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for requesting user trading fees
|
||||||
|
/// </summary>
|
||||||
|
public interface IFeeRestClient : IGetFeesRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for requesting kline/candlestick data
|
||||||
|
/// </summary>
|
||||||
|
public interface IKlineRestClient : IGetKlinesRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for retrieving the order book for a symbol
|
||||||
|
/// </summary>
|
||||||
|
public interface IOrderBookRestClient : IGetOrderBookRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for retrieving the most recent public trades
|
||||||
|
/// </summary>
|
||||||
|
public interface IRecentTradeRestClient : IGetRecentTradesRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for retrieving trading history
|
||||||
|
/// </summary>
|
||||||
|
public interface ITradeHistoryRestClient : IGetTradeHistoryRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for retrieving withdrawal records
|
||||||
|
/// </summary>
|
||||||
|
public interface IWithdrawalRestClient : IGetWithdrawalHistoryRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Threading;
|
||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for managing spot orders using a client order id
|
||||||
|
/// </summary>
|
||||||
|
public interface ISpotOrderClientIdRestClient :
|
||||||
|
ICancelSpotOrderByClientOrderIdRestClient,
|
||||||
|
IGetSpotOrderByClientOrderIdRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using CryptoExchange.Net.SharedApis.Interfaces.Rest.V2.SpotUserTrades;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for placing and managing spot orders
|
||||||
|
/// </summary>
|
||||||
|
public interface ISpotOrderRestClient :
|
||||||
|
IPlaceSpotOrderRestClient,
|
||||||
|
ICancelSpotOrderRestClient,
|
||||||
|
IGetSpotOrderRestClient,
|
||||||
|
IGetOpenSpotOrdersRestClient,
|
||||||
|
IGetClosedSpotOrdersRestClient,
|
||||||
|
IGetSpotOrderTradesRestClient,
|
||||||
|
IGetSpotUserTradeHistoryRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for requesting spot symbols
|
||||||
|
/// </summary>
|
||||||
|
public interface ISpotSymbolRestClient : IGetSpotSymbolsRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using CryptoExchange.Net.SharedApis.Interfaces.Rest.V2.Spot.Tickers;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for requesting spot tickers
|
||||||
|
/// </summary>
|
||||||
|
public interface ISpotTickerRestClient :
|
||||||
|
IGetSpotTickerRestClient,
|
||||||
|
IGetAllSpotTickersRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Client for placing trigger orders
|
||||||
|
/// </summary>
|
||||||
|
public interface ISpotTriggerOrderRestClient :
|
||||||
|
IPlaceSpotTriggerOrderRestClient,
|
||||||
|
IGetSpotTriggerOrderRestClient,
|
||||||
|
ICancelSpotTriggerOrderRestClient
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using System.Threading;
|
|
||||||
using CryptoExchange.Net.Objects;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Client for managing spot orders using a client order id
|
|
||||||
/// </summary>
|
|
||||||
public interface ISpotOrderClientIdRestClient : ISharedClient
|
|
||||||
{
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetSpotOrderByClientOrderIdOptions GetSpotOrderByClientOrderIdOptions { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get info on a specific spot order using a client order id, see <see cref="GetSpotOrderByClientOrderIdOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedSpotOrder>> GetSpotOrderByClientOrderIdAsync(GetOrderRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
CancelSpotOrderByClientOrderIdOptions CancelSpotOrderByClientOrderIdOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Cancel a spot order using client order id, see <see cref="CancelSpotOrderByClientOrderIdOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedId>> CancelSpotOrderByClientOrderIdAsync(CancelOrderRequest request, CancellationToken ct = default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Client for placing and managing spot orders
|
|
||||||
/// </summary>
|
|
||||||
public interface ISpotOrderRestClient : ISharedClient
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// How the trading fee is deducted
|
|
||||||
/// </summary>
|
|
||||||
SharedFeeDeductionType SpotFeeDeductionType { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// How the asset is determined in which the trading fee is paid
|
|
||||||
/// </summary>
|
|
||||||
SharedFeeAssetType SpotFeeAssetType { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Supported order types for spot orders
|
|
||||||
/// </summary>
|
|
||||||
SharedOrderType[] SpotSupportedOrderTypes { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Supported time in force types for placing spot orders
|
|
||||||
/// </summary>
|
|
||||||
SharedTimeInForce[] SpotSupportedTimeInForce { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Supported quantity types for placing spot orders
|
|
||||||
/// </summary>
|
|
||||||
SharedQuantitySupport SpotSupportedOrderQuantity { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generate a new random client order id
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
string GenerateClientOrderId();
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
PlaceSpotOrderOptions PlaceSpotOrderOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Place a new spot order, see <see cref="PlaceSpotOrderOptions"/> 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.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedId>> PlaceSpotOrderAsync(PlaceSpotOrderRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetSpotOrderOptions GetSpotOrderOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Get info on a specific spot order, see <see cref="GetSpotOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedSpotOrder>> GetSpotOrderAsync(GetOrderRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetOpenSpotOrdersOptions GetOpenSpotOrdersOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Get info on a open spot orders, see <see cref="GetOpenSpotOrdersOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedSpotOrder[]>> GetOpenSpotOrdersAsync(GetOpenOrdersRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetSpotClosedOrdersOptions GetClosedSpotOrdersOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Get info on closed spot orders, see <see cref="GetClosedSpotOrdersOptions"/> 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.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedSpotOrder[]>> GetClosedSpotOrdersAsync(GetClosedOrdersRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetSpotOrderTradesOptions GetSpotOrderTradesOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Get trades for a specific spot order, see <see cref="GetSpotOrderTradesOptions"/> 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.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedUserTrade[]>> GetSpotOrderTradesAsync(GetOrderTradesRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetSpotUserTradesOptions 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.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedUserTrade[]>> GetSpotUserTradesAsync(GetUserTradesRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
CancelSpotOrderOptions CancelSpotOrderOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Cancel a spot order, see <see cref="CancelSpotOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedId>> CancelSpotOrderAsync(CancelOrderRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Client for requesting spot tickers
|
|
||||||
/// </summary>
|
|
||||||
public interface ISpotTickerRestClient : ISharedClient
|
|
||||||
{
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetSpotTickerOptions 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>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetSpotTickersOptions GetSpotTickersOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Get tickers for all spot symbols, see <see cref="GetSpotTickersOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedSpotTicker[]>> GetSpotTickersAsync(GetTickersRequest request, CancellationToken ct = default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Client for placing trigger orders
|
|
||||||
/// </summary>
|
|
||||||
public interface ISpotTriggerOrderRestClient : ISharedClient
|
|
||||||
{
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
PlaceSpotTriggerOrderOptions PlaceSpotTriggerOrderOptions { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Place a new trigger order, see <see cref="PlaceSpotTriggerOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<HttpResult<SharedId>> PlaceSpotTriggerOrderAsync(PlaceSpotTriggerOrderRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetSpotTriggerOrderOptions GetSpotTriggerOrderOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Get info on a specific trigger order, see <see cref="GetSpotTriggerOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedSpotTriggerOrder>> GetSpotTriggerOrderAsync(GetOrderRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
CancelSpotTriggerOrderOptions CancelSpotTriggerOrderOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Cancel a trigger order, see <see cref="CancelSpotTriggerOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedId>> CancelSpotTriggerOrderAsync(CancelOrderRequest request, CancellationToken ct = default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IGetAllAssetsRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
GetAssetsOptions 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 />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedAsset[]>> GetAssetsAsync(GetAssetsRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IGetAssetRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
GetAssetOptions GetAssetOptions { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get info on a specific asset, see <see cref="GetAssetOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedAsset>> GetAssetAsync(GetAssetRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-4
@@ -1,13 +1,13 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
namespace CryptoExchange.Net.SharedApis
|
||||||
{
|
{
|
||||||
/// <summary>
|
public interface IGetBalancesRestClient : ISharedClient
|
||||||
/// Client for requesting user balance info
|
|
||||||
/// </summary>
|
|
||||||
public interface IBalanceRestClient : ISharedClient
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Balances request options.<br />
|
/// Balances request options.<br />
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IGetDepositAddressesRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
GetDepositAddressesOptions GetDepositAddressesOptions { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get deposit addresses for an asset, see <see cref="GetDepositAddressesOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<HttpResult<SharedDepositAddress[]>> GetDepositAddressesAsync(GetDepositAddressesRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IGetDepositHistoryRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
GetDepositHistoryOptions GetDepositHistoryOptions { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get deposit records, see <see cref="GetDepositHistoryOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<HttpResult<SharedDeposit[]>> GetDepositHistoryAsync(GetDepositsRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-6
@@ -1,13 +1,13 @@
|
|||||||
using System.Threading.Tasks;
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using CryptoExchange.Net.Objects;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
namespace CryptoExchange.Net.SharedApis
|
||||||
{
|
{
|
||||||
/// <summary>
|
public interface IGetFeesRestClient : ISharedClient
|
||||||
/// Client for requesting user trading fees
|
|
||||||
/// </summary>
|
|
||||||
public interface IFeeRestClient : ISharedClient
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fee request options.<br />
|
/// Fee request options.<br />
|
||||||
+4
-4
@@ -1,13 +1,13 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
namespace CryptoExchange.Net.SharedApis
|
||||||
{
|
{
|
||||||
/// <summary>
|
public interface IGetFundingRateHistoryRestClient : ISharedClient
|
||||||
/// Client for request funding rate records
|
|
||||||
/// </summary>
|
|
||||||
public interface IFundingRateRestClient : ISharedClient
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Funding rate request options.<br />
|
/// Funding rate request options.<br />
|
||||||
+4
-4
@@ -1,13 +1,13 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
namespace CryptoExchange.Net.SharedApis
|
||||||
{
|
{
|
||||||
/// <summary>
|
public interface IGetIndexPriceKlinesRestClient : ISharedClient
|
||||||
/// Client for getting the index price klines for a symbol
|
|
||||||
/// </summary>
|
|
||||||
public interface IIndexPriceKlineRestClient : ISharedClient
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Index price klines request options.<br />
|
/// Index price klines request options.<br />
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IGetLeverageRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
GetLeverageOptions GetLeverageOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Get the current leverage setting for a symbol, see <see cref="GetLeverageOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedLeverage>> GetLeverageAsync(GetLeverageRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-18
@@ -1,32 +1,19 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
namespace CryptoExchange.Net.SharedApis
|
||||||
{
|
{
|
||||||
/// <summary>
|
public interface ISetLeverageRestClient : ISharedClient
|
||||||
/// Client for managing the leverage of a symbol
|
|
||||||
/// </summary>
|
|
||||||
public interface ILeverageRestClient : ISharedClient
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How the leverage setting is configured on the exchange
|
/// How the leverage setting is configured on the exchange
|
||||||
/// </summary>
|
/// </summary>
|
||||||
SharedLeverageSettingMode LeverageSettingType { get; }
|
SharedLeverageSettingMode LeverageSettingType { get; }
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetLeverageOptions GetLeverageOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Get the current leverage setting for a symbol, see <see cref="GetLeverageOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedLeverage>> GetLeverageAsync(GetLeverageRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Leverage set request options.<br />
|
/// 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="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||||
@@ -39,6 +26,5 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <param name="request">Request info</param>
|
/// <param name="request">Request info</param>
|
||||||
/// <param name="ct">Cancellation token</param>
|
/// <param name="ct">Cancellation token</param>
|
||||||
Task<HttpResult<SharedLeverage>> SetLeverageAsync(SetLeverageRequest request, CancellationToken ct = default);
|
Task<HttpResult<SharedLeverage>> SetLeverageAsync(SetLeverageRequest request, CancellationToken ct = default);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-4
@@ -1,13 +1,13 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
namespace CryptoExchange.Net.SharedApis
|
||||||
{
|
{
|
||||||
/// <summary>
|
public interface IGetMarkPriceKlinesRestClient : ISharedClient
|
||||||
/// Client for getting the mark price klines for a symbol
|
|
||||||
/// </summary>
|
|
||||||
public interface IMarkPriceKlineRestClient : ISharedClient
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Mark price klines request options.<br />
|
/// Mark price klines request options.<br />
|
||||||
+5
-4
@@ -1,14 +1,15 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
namespace CryptoExchange.Net.SharedApis
|
||||||
{
|
{
|
||||||
/// <summary>
|
public interface IGetOpenInterestRestClient : ISharedClient
|
||||||
/// Client for getting the open interest for a symbol
|
|
||||||
/// </summary>
|
|
||||||
public interface IOpenInterestRestClient : ISharedClient
|
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Open interest request options.<br />
|
/// 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="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface ICancelFuturesOrderByClientOrderIdRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
CancelFuturesOrderByClientOrderIdOptions CancelFuturesOrderByClientOrderIdOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Cancel a futures order using client order id, see <see cref="CancelFuturesOrderByClientOrderIdOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedId>> CancelFuturesOrderByClientOrderIdAsync(CancelOrderRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface ICancelFuturesOrderRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
CancelFuturesOrderOptions CancelFuturesOrderOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Cancel a futures order, see <see cref="CancelFuturesOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedId>> CancelFuturesOrderAsync(CancelOrderRequest request, CancellationToken ct = default);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IPlaceFuturesOrderRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// How the trading fee is deducted
|
||||||
|
/// </summary>
|
||||||
|
SharedFeeDeductionType FuturesFeeDeductionType { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// How the asset is determined in which the trading fee is paid
|
||||||
|
/// </summary>
|
||||||
|
SharedFeeAssetType FuturesFeeAssetType { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Supported order types for futures orders
|
||||||
|
/// </summary>
|
||||||
|
SharedOrderType[] FuturesSupportedOrderTypes { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Supported time in force types for futures orders
|
||||||
|
/// </summary>
|
||||||
|
SharedTimeInForce[] FuturesSupportedTimeInForce { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Supported quantity types for futures orders
|
||||||
|
/// </summary>
|
||||||
|
SharedQuantitySupport FuturesSupportedOrderQuantity { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate a new random client order id
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
string GenerateClientOrderId();
|
||||||
|
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
PlaceFuturesOrderOptions PlaceFuturesOrderOptions { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Place a new futures order, see <see cref="PlaceFuturesOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedId>> PlaceFuturesOrderAsync(PlaceFuturesOrderRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IGetClosedFuturesOrdersRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
GetFuturesClosedOrdersOptions GetClosedFuturesOrdersOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Get info on closed futures orders, see <see cref="GetClosedFuturesOrdersOptions"/> 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.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="nextPageToken">The pagination request from the previous request result `NextPageRequest` property to continue pagination</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedFuturesOrder[]>> GetClosedFuturesOrdersAsync(GetClosedOrdersRequest request, PageRequest? nextPageToken = null, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IGetFuturesOrderByClientOrderIdRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
GetFuturesOrderByClientOrderIdOptions GetFuturesOrderByClientOrderIdOptions { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get info on a specific futures order using a client order id, see <see cref="GetFuturesOrderByClientOrderIdOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedFuturesOrder>> GetFuturesOrderByClientOrderIdAsync(GetOrderRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IGetFuturesOrderRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
GetFuturesOrderOptions GetFuturesOrderOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Get info on a specific futures order, see <see cref="GetFuturesOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedFuturesOrder>> GetFuturesOrderAsync(GetOrderRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IGetOpenFuturesOrdersRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
GetOpenFuturesOrdersOptions GetOpenFuturesOrdersOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Get info on a open futures orders, see <see cref="GetOpenFuturesOrdersOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedFuturesOrder[]>> GetOpenFuturesOrdersAsync(GetOpenOrdersRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IGetPositionModeRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
GetPositionModeOptions GetPositionModeOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Get the current position mode setting, see <see cref="GetPositionModeOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedPositionModeResult>> GetPositionModeAsync(GetPositionModeRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-17
@@ -1,32 +1,19 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
namespace CryptoExchange.Net.SharedApis
|
||||||
{
|
{
|
||||||
/// <summary>
|
public interface ISetPositionModeRestClient : ISharedClient
|
||||||
/// Client for managing the position mode setting
|
|
||||||
/// </summary>
|
|
||||||
public interface IPositionModeRestClient : ISharedClient
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How the exchange handles setting the position mode
|
/// How the exchange handles setting the position mode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
SharedPositionModeSelection PositionModeSettingType { get; }
|
SharedPositionModeSelection PositionModeSettingType { get; }
|
||||||
|
|
||||||
/// <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 />
|
|
||||||
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
|
||||||
/// </summary>
|
|
||||||
GetPositionModeOptions GetPositionModeOptions { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Get the current position mode setting, see <see cref="GetPositionModeOptions"/> for request options and exchange specific required/optional parameters. <br />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">Request info</param>
|
|
||||||
/// <param name="ct">Cancellation token</param>
|
|
||||||
Task<HttpResult<SharedPositionModeResult>> GetPositionModeAsync(GetPositionModeRequest request, CancellationToken ct = default);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Position mode set request options.<br />
|
/// 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="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IClosePositionRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
ClosePositionOptions ClosePositionOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Close a currently open position, see <see cref="ClosePositionOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<HttpResult<SharedId>> ClosePositionAsync(ClosePositionRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-4
@@ -1,13 +1,13 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
namespace CryptoExchange.Net.SharedApis
|
||||||
{
|
{
|
||||||
/// <summary>
|
public interface IGetPositionHistoryRestClient : ISharedClient
|
||||||
/// Client for getting position history
|
|
||||||
/// </summary>
|
|
||||||
public interface IPositionHistoryRestClient : ISharedClient
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Position history request options.<br />
|
/// Position history request options.<br />
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IGetPositionsRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
GetPositionsOptions GetPositionsOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Get open position info, see <see cref="GetPositionsOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedPosition[]>> GetPositionsAsync(GetPositionsRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
-4
@@ -1,14 +1,19 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.SharedApis
|
namespace CryptoExchange.Net.SharedApis
|
||||||
{
|
{
|
||||||
/// <summary>
|
public interface IGetFuturesSymbolsRestClient : ISharedClient
|
||||||
/// Client for request futures symbol info
|
|
||||||
/// </summary>
|
|
||||||
public interface IFuturesSymbolRestClient : ISharedClient
|
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Get the futures symbol catalog. Only available if <see cref="GetFuturesSymbolsAsync(GetSymbolsRequest, CancellationToken)"/> has been called previously.
|
||||||
|
/// </summary>
|
||||||
|
SharedSymbolCatalog? FuturesSymbolCatalog { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Futures symbol request options.<br />
|
/// 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="EndpointOptions.RequiredExchangeParameters"/> and <see cref="EndpointOptions.OptionalExchangeParameters"/> to check for required and optional parameters for the request. <br />
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IGetAllFuturesTickersRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
GetFuturesTickersOptions 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>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedFuturesTicker[]>> GetFuturesTickersAsync(GetTickersRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IGetFuturesTickerRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
GetFuturesTickerOptions 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>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedFuturesTicker>> GetFuturesTickerAsync(GetTickerRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface ICancelFuturesTpSlRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
CancelFuturesTpSlOptions CancelFuturesTpSlOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Cancel an active take profit and/or stop loss for an open position, see <see cref="CancelFuturesTpSlOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<HttpResult<bool>> CancelFuturesTpSlAsync(CancelTpSlRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface ISetFuturesTpSlRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
SetFuturesTpSlOptions SetFuturesTpSlOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Set a take profit and/or stop loss for an open position, see <see cref="SetFuturesTpSlOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<HttpResult<SharedId>> SetFuturesTpSlAsync(SetTpSlRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface ICancelFuturesTriggerOrderRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
CancelFuturesTriggerOrderOptions CancelFuturesTriggerOrderOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Cancel a trigger order, see <see cref="CancelFuturesTriggerOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedId>> CancelFuturesTriggerOrderAsync(CancelOrderRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.SharedApis
|
||||||
|
{
|
||||||
|
public interface IGetFuturesTriggerOrderRestClient : ISharedClient
|
||||||
|
{
|
||||||
|
/// <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 />
|
||||||
|
/// Exchange specific parameters can be added to the request via the `ExchangeParameters` property of the request object.
|
||||||
|
/// </summary>
|
||||||
|
GetFuturesTriggerOrderOptions GetFuturesTriggerOrderOptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Get info on a specific trigger order, see <see cref="GetFuturesTriggerOrderOptions"/> for request options and exchange specific required/optional parameters. <br />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Request info</param>
|
||||||
|
/// <param name="ct">Cancellation token</param>
|
||||||
|
Task<HttpResult<SharedFuturesTriggerOrder>> GetFuturesTriggerOrderAsync(GetOrderRequest request, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user