1
0
mirror of https://github.com/JKorf/CryptoExchange.Net.git synced 2026-10-04 02:11:11 +00:00
This commit is contained in:
Jkorf
2026-09-23 10:16:15 +02:00
parent bda81d8170
commit a8517d2c76
2 changed files with 470 additions and 0 deletions
+147
View File
@@ -0,0 +1,147 @@
# CryptoExchange.Net Shared API V2 map
This is a compact map for choosing Shared API V2 types. All listed types are in `CryptoExchange.Net.SharedApis`. Exchange libraries implement subsets; the map describes available abstractions, not guaranteed exchange support.
## Entry points
| Need | Use |
| --- | --- |
| Known exchange and API surface | Its typed `.SharedApi` property |
| Runtime selection within one exchange | Exchange-wide `I[Exchange]SharedApiClient` |
| Strongly typed runtime lookup key | `SharedCapabilities` |
| One preferred match | `GetCapability(...)` |
| Every matching surface/transport in one exchange | `GetCapabilities(...)` |
| V1 compatibility during migration | `.SharedClient` |
Prefer a direct typed `.SharedApi` when the API surface is known. Dynamic lookup returns `SharedCapabilityResolution<T>?`; handle `null`.
```csharp
IGetTickerRest ticker = restClient.SpotApi.SharedApi;
var result = await ticker.GetTickerAsync(request);
```
```csharp
var match = sharedClient.GetCapability(
SharedCapabilities.Tickers.GetTicker.Rest,
TradingMode.Spot);
```
## Interface suffixes and results
| Interface shape | Transport | Typical result |
| --- | --- | --- |
| Operation with no suffix, e.g. `IPlaceSpotOrder` | selected/preferred | `IExchangeCallResult<T>` |
| `...Rest` | REST | `HttpResult<T>` |
| socket command, e.g. `IPlaceSpotOrderSocket` | WebSocket | `QueryResult<T>` |
| subscription, e.g. `ISubscribeTickerSocket` | WebSocket | `WebSocketResult<UpdateSubscription>` |
When a `SharedCapabilities` entry supports multiple transports, use the base entry for preferred transport, `.Rest` for REST, or `.Socket` for socket. Exchange-wide preferred transport normally defaults to REST.
## Market data
| Operation | Capability interface | Lookup reference |
| --- | --- | --- |
| Get one ticker | `IGetTickerRest` | `SharedCapabilities.Tickers.GetTicker.Rest` |
| Get all tickers | `IGetAllTickersRest` | `SharedCapabilities.Tickers.GetAllTickers.Rest` |
| Subscribe to one ticker | `ISubscribeTickerSocket` | `SharedCapabilities.Tickers.SubscribeTicker` |
| Subscribe to all tickers | `ISubscribeAllTickersSocket` | `SharedCapabilities.Tickers.SubscribeAllTickers` |
| Subscribe to book ticker | `ISubscribeBookTickerSocket` | `SharedCapabilities.Tickers.SubscribeBookTicker` |
| Get order book | `IGetOrderBookRest` | `SharedCapabilities.OrderBooks.GetOrderBook.Rest` |
| Get book ticker | `IGetBookTickerRest` | `SharedCapabilities.OrderBooks.GetBookTicker.Rest` |
| Subscribe to order book | `ISubscribeOrderBookSocket` | `SharedCapabilities.OrderBooks.SubscribeOrderBook` |
| Subscribe to incremental book | `ISubscribeIncrementalOrderBookSocket` | `SharedCapabilities.OrderBooks.SubscribeIncrementalOrderBook` |
| Get klines | `IGetKlinesRest` | `SharedCapabilities.Klines.GetKlines.Rest` |
| Subscribe to klines | `ISubscribeKlinesSocket` | `SharedCapabilities.Klines.SubscribeKlines` |
| Get recent trades | `IGetRecentTradesRest` | `SharedCapabilities.Trades.GetRecentTrades.Rest` |
| Subscribe to trades | `ISubscribeTradesSocket` | `SharedCapabilities.Trades.SubscribeTrades` |
| Get spot symbols | `IGetSpotSymbolsRest` | `SharedCapabilities.Symbols.GetSpotSymbols.Rest` |
| Get futures symbols | `IGetFuturesSymbolsRest` | `SharedCapabilities.Symbols.GetFuturesSymbols.Rest` |
Ticker V2 methods are `GetTickerAsync` and `GetAllTickersAsync`; both use `SharedTicker` for spot and futures. Use separate mark-price, index-price, funding, or open-interest capabilities for derivatives-specific data.
## Spot orders
| Operation | Capability family | Lookup reference |
| --- | --- | --- |
| Place | `IPlaceSpotOrder`, `IPlaceSpotOrderRest`, `IPlaceSpotOrderSocket` | `SharedCapabilities.Orders.Spot.PlaceOrder[.Rest/.Socket]` |
| Edit | `IEditSpotOrder`, `IEditSpotOrderRest`, `IEditSpotOrderSocket` | `SharedCapabilities.Orders.Spot.EditOrder[.Rest/.Socket]` |
| Cancel | `ICancelSpotOrder`, `ICancelSpotOrderRest`, `ICancelSpotOrderSocket` | `SharedCapabilities.Orders.Spot.CancelOrder[.Rest/.Socket]` |
| Get one | `IGetSpotOrderRest` | `SharedCapabilities.Orders.Spot.GetOrder.Rest` |
| Get open | `IGetOpenSpotOrdersRest` | `SharedCapabilities.Orders.Spot.GetOpenOrders.Rest` |
| Get closed | `IGetClosedSpotOrdersRest` | `SharedCapabilities.Orders.Spot.GetClosedOrders.Rest` |
| Subscribe to updates | `ISubscribeSpotOrdersSocket` | `SharedCapabilities.Orders.Spot.SubscribeOrders` |
Client-order-id variants exist for edit, cancel, and get. Batch placement and cancel-all capabilities also exist; resolve them only when the application needs those operations and the exchange supports them.
## Futures orders
| Operation | Capability family | Lookup reference |
| --- | --- | --- |
| Place | `IPlaceFuturesOrder`, `IPlaceFuturesOrderRest`, `IPlaceFuturesOrderSocket` | `SharedCapabilities.Orders.Futures.PlaceOrder[.Rest/.Socket]` |
| Edit | `IEditFuturesOrder`, `IEditFuturesOrderRest`, `IEditFuturesOrderSocket` | `SharedCapabilities.Orders.Futures.EditOrder[.Rest/.Socket]` |
| Cancel | `ICancelFuturesOrder`, `ICancelFuturesOrderRest`, `ICancelFuturesOrderSocket` | `SharedCapabilities.Orders.Futures.CancelOrder[.Rest/.Socket]` |
| Get one | `IGetFuturesOrderRest` | `SharedCapabilities.Orders.Futures.GetOrder.Rest` |
| Get open | `IGetOpenFuturesOrdersRest` | `SharedCapabilities.Orders.Futures.GetOpenOrders.Rest` |
| Get closed | `IGetClosedFuturesOrdersRest` | `SharedCapabilities.Orders.Futures.GetClosedOrders.Rest` |
| Subscribe to updates | `ISubscribeFuturesOrdersSocket` | `SharedCapabilities.Orders.Futures.SubscribeOrders` |
Specify `TradingMode.PerpetualLinear`, `PerpetualInverse`, or the appropriate delivery mode when multiple futures APIs can match.
## Account and derivatives
Use the following capability families for common account workflows:
| Area | Common interfaces |
| --- | --- |
| Balances | `IGetBalancesRest`, `ISubscribeBalancesSocket` |
| Positions | `IGetPositionsRest`, `ISubscribePositionsSocket`, `IGetPositionHistoryRest` |
| User trades | `IGetSpotUserTradeHistoryRest`, `IGetFuturesUserTradeHistoryRest`, `ISubscribeUserTradesSocket` |
| Fees | `IGetFeesRest` |
| Deposits | `IGetDepositAddressesRest`, `IGetDepositHistoryRest` |
| Withdrawals | `IWithdrawRest`, `IGetWithdrawalHistoryRest` |
| Transfers | `ITransferRest`, `IGetTransferHistoryRest` |
| Leverage | `IGetLeverageRest`, `ISetLeverageRest`, `IGetLeverageTiersRest` |
| Funding | `IGetFundingInfoRest`, `IGetFundingRateHistoryRest`, `IGetUserFundingHistoryRest` |
| Mark/index data | `IGetMarkPriceRest`, `IGetIndexPriceRest` and their all-market/subscription variants |
| Open interest | `IGetOpenInterestRest` |
The `SharedCapabilities` catalog groups these under matching plural categories such as `Balances`, `Positions`, `Funding`, `Leverage`, `MarkPrices`, and `IndexPrices`.
## Parameter support map
Every successful runtime resolution includes `Options`:
| Property | Meaning |
| --- | --- |
| `RequestParameterRules` | Shared request fields that are required, optional, or unsupported |
| `ExchangeParameterRules` | Exchange-specific fields accepted through `ExchangeParameters` |
| `SupportedTradingModes` | Modes supported by this capability implementation |
| `NeedsAuthentication` | Whether credentials are required |
Capability presence is not proof that all properties on its request model are accepted. Inspect rules for dynamically generated requests.
## Common V1 to V2 mappings
| V1 call | V2 capability call |
| --- | --- |
| `ISpotTickerRestClient.GetSpotTickerAsync` | `IGetTickerRest.GetTickerAsync` |
| `ISpotTickerRestClient.GetSpotTickersAsync` | `IGetAllTickersRest.GetAllTickersAsync` |
| `ISpotOrderRestClient.PlaceSpotOrderAsync` | `IPlaceSpotOrderRest.PlaceSpotOrderAsync` |
| `ISpotOrderRestClient.CancelSpotOrderAsync` | `ICancelSpotOrderRest.CancelSpotOrderAsync` |
| `IFuturesOrderRestClient.PlaceFuturesOrderAsync` | `IPlaceFuturesOrderRest.PlaceFuturesOrderAsync` |
| `IFuturesOrderRestClient.CancelFuturesOrderAsync` | `ICancelFuturesOrderRest.CancelFuturesOrderAsync` |
| `IFuturesOrderRestClient.GetPositionsAsync` | `IGetPositionsRest.GetPositionsAsync` |
V1 uses `.SharedClient`; V2 uses `.SharedApi`. Migrate operation by operation.
## Selection checklist
1. Use the exchange-native API if portability is unnecessary.
2. For portable code, identify the single operation capability required.
3. Use the typed `.SharedApi` directly when the surface is known.
4. Otherwise resolve through the exchange-wide shared client and handle `null`.
5. Specify trading mode and transport when ambiguity matters.
6. Inspect parameter rules for dynamic requests.
7. Check `Success` before using `Data`.
For migration edge cases and CryptoClients.Net cross-exchange lookup, see `SHARED_API_V2_MIGRATION.md`.
+323
View File
@@ -0,0 +1,323 @@
# CryptoExchange.Net — full AI context
Library: CryptoExchange.Net
Library version: 13.0.0
CryptoExchange.Net package version: 13.0.0
Language: C#/.NET
Targets: netstandard2.0, netstandard2.1, net8.0, net9.0, net10.0
## Purpose
CryptoExchange.Net is the base library used by 28+ exchange-specific clients. It provides shared REST and WebSocket infrastructure, authentication and result conventions, rate limiting, order-book support, and exchange-agnostic Shared APIs.
CryptoExchange.Net does not provide exchange endpoints by itself. Install the exchange libraries required by the application, such as Binance.Net, Bybit.Net, JK.OKX.Net, Kraken.Net, or Coinbase.Net. Install `CryptoClients.Net` when one package should provide the full exchange bundle.
Use an exchange's native API for code tied to that exchange. Use Shared API V2 for portable code that performs the same operation against multiple exchanges.
## Shared API V2 mental model
Shared API V2 models each operation as a fine-grained capability. A typed exchange API surface exposes implemented capabilities through `.SharedApi`. Examples include:
- `IGetTickerRest`
- `IGetOrderBookRest`
- `IGetKlinesRest`
- `IPlaceSpotOrderRest`
- `ICancelFuturesOrderRest`
- `ISubscribeTickerSocket`
- `ISubscribeTradesSocket`
This replaces the V1 assumption that one broad interface represents a complete feature group. An exchange may support order placement without editing, or REST placement without socket placement. Write services against only the capabilities they require.
V1 aggregate interfaces remain available through `.SharedClient` for incremental migration. Use `.SharedApi` for new code.
## Installation
Install only the exchange packages needed:
```bash
dotnet add package Binance.Net
dotnet add package JK.OKX.Net
dotnet add package Bybit.Net
```
Or install the combined package:
```bash
dotnet add package CryptoClients.Net
```
Do not add CryptoExchange.Net alone and expect to create an exchange client.
## Direct typed capability usage
When the exchange and API surface are known, assign `.SharedApi` to the operation interface. The API surface's compile-time type exposes only the capabilities implemented there.
```csharp
using Binance.Net.Clients;
using OKX.Net.Clients;
using CryptoExchange.Net.SharedApis;
IGetTickerRest binance = new BinanceRestClient().SpotApi.SharedApi;
IGetTickerRest okx = new OKXRestClient().UnifiedApi.SharedApi;
var symbol = new SharedSymbol(TradingMode.Spot, "BTC", "USDT");
var result = await binance.GetTickerAsync(new GetTickerRequest(symbol));
if (!result.Success)
{
Console.WriteLine($"[{result.Exchange}] {result.Error}");
return;
}
Console.WriteLine($"[{result.Exchange}] {result.Data!.LastPrice}");
```
Use `SharedSymbol` rather than exchange-native strings. Each exchange implementation converts base asset, quote asset, and trading mode into its own symbol format.
Common trading modes include `Spot`, `PerpetualLinear`, and `PerpetualInverse`. Use the mode that corresponds to the intended exchange API surface.
## Multi-exchange concurrency
Shared capabilities allow uniform concurrent calls:
```csharp
var clients = new IGetTickerRest[]
{
new BinanceRestClient().SpotApi.SharedApi,
new OKXRestClient().UnifiedApi.SharedApi,
new BybitRestClient().V5Api.SharedApi,
};
var symbol = new SharedSymbol(TradingMode.Spot, "BTC", "USDT");
var tasks = clients.Select(client =>
client.GetTickerAsync(new GetTickerRequest(symbol)));
var results = await Task.WhenAll(tasks);
foreach (var ticker in results.Where(x => x.Success))
Console.WriteLine($"{ticker.Exchange}: {ticker.Data!.LastPrice}");
```
Independent requests should normally run concurrently. Reuse long-lived clients or dependency-injected clients instead of creating clients for each request.
## Dynamic capability resolution
Each exchange library registers an exchange-wide `I[Exchange]SharedApiClient`. Use this client when the API surface, trading mode, or transport is selected at runtime.
`SharedCapabilities` is a catalog of strongly typed references. A reference identifies the interface to find; it does not guarantee support and does not perform an exchange request.
```csharp
var resolution = sharedClient.GetCapability(
SharedCapabilities.Orders.Futures.PlaceOrder.Rest,
TradingMode.PerpetualLinear);
if (resolution is null)
{
Console.WriteLine("Futures REST placement is unavailable.");
return;
}
var result = await resolution.Capability.PlaceFuturesOrderAsync(request);
```
`GetCapability` returns one `SharedCapabilityResolution<T>` or `null`. The resolution exposes:
- `Capability`: the callable typed interface.
- `Options`: capability metadata and request rules.
- `Exchange`: the exchange name.
- `Transport`: REST or socket.
`GetCapabilities` returns every matching implementation on that exchange-wide client. Pass a `TradingMode` when an exchange can expose multiple matching API surfaces, especially separate linear and inverse futures APIs.
Use the typed `.SharedApi` property when the desired surface is already known. Use dynamic resolution only when the choice or support is genuinely runtime-dependent.
## Transport selection
Some operations have transport-agnostic, REST-specific, and socket-specific variants. Order placement is representative:
- `IPlaceSpotOrder`: transport-agnostic, returns `IExchangeCallResult<SharedId>`.
- `IPlaceSpotOrderRest`: REST-specific, returns `HttpResult<SharedId>`.
- `IPlaceSpotOrderSocket`: socket-specific, returns `QueryResult<SharedId>`.
Subscription interfaces such as `ISubscribeTickerSocket` return `WebSocketResult<UpdateSubscription>`.
Use a capability reference without a suffix when either transport is acceptable:
```csharp
var preferred = sharedClient.GetCapability(
SharedCapabilities.Orders.Spot.PlaceOrder);
```
Use `.Rest` or `.Socket` when the transport or concrete result type matters:
```csharp
var rest = sharedClient.GetCapability(
SharedCapabilities.Orders.Spot.PlaceOrder.Rest);
var socket = sharedClient.GetCapability(
SharedCapabilities.Orders.Spot.PlaceOrder.Socket);
```
Exchange-wide transport-agnostic lookup follows the configured `SharedApi.PreferredTransport`, which normally defaults to REST. Do not rely on that preference when application semantics require a particular transport.
## Result handling
All result types expose `Success`, `Data`, and `Error`. Check `Success` before reading `Data`.
- REST capability: `HttpResult<T>`
- socket command capability: `QueryResult<T>`
- socket subscription capability: `WebSocketResult<UpdateSubscription>`
- transport-agnostic capability: `IExchangeCallResult<T>`
Shared results carry the exchange name, which should be included in logs and aggregation records.
```csharp
if (!result.Success)
{
logger.LogWarning(
"{Exchange} ticker request failed: {Error}",
result.Exchange,
result.Error);
return;
}
```
## Request parameter discovery
A capability can exist even when an exchange does not accept every property on the shared request. Inspect the selected capability's `Options` before building fully dynamic requests:
- `RequestParameterRules`: each shared request field is `Required`, `Optional`, or `NotSupported`.
- `ExchangeParameterRules`: exchange-specific required or optional parameters supplied through the request's `ExchangeParameters`.
- `SupportedTradingModes`: modes supported by this particular implementation.
```csharp
var placement = sharedClient.GetCapability(
SharedCapabilities.Orders.Futures.PlaceOrder.Rest,
TradingMode.PerpetualLinear);
var leverageRule = placement?.Options.RequestParameterRules
.FirstOrDefault(rule =>
rule.Name == nameof(PlaceFuturesOrderRequest.Leverage));
if (leverageRule?.Support == RequestParameterSupport.NotSupported)
Console.WriteLine("Set leverage with a separate capability.");
```
Do not infer field support from the request model alone. Handle a missing capability, unsupported trading mode, required field, and required exchange parameter before submitting a trading request.
## Dependency injection
Each exchange library provides a `services.Add[Exchange](...)` extension. Registration includes native clients, V1 shared facades, V2 operation capabilities, and the exchange-wide shared client.
Direct capability injection is appropriate when one implementation is intended:
```csharp
public sealed class TickerService
{
private readonly IGetTickerRest _ticker;
public TickerService(IGetTickerRest ticker)
=> _ticker = ticker;
public Task<HttpResult<SharedTicker>> GetAsync(
SharedSymbol symbol,
CancellationToken ct = default)
=> _ticker.GetTickerAsync(new GetTickerRequest(symbol), ct);
}
```
If multiple exchanges or multiple API surfaces register the same capability interface, inject the exchange-specific shared client and select a typed API property or use `GetCapability`. Resolving one unqualified capability does not express which registered implementation is desired.
`CryptoClients.Net` registers `IExchangeSharedApiClient` for V2 lookup across exchanges. Its `GetCapabilities` returns one preferred matching implementation per exchange, while `GetImplementations` returns every matching transport and API surface.
## Common capability families
Frequently used market-data capabilities:
- Tickers: `IGetTickerRest`, `IGetAllTickersRest`, `ISubscribeTickerSocket`, `ISubscribeAllTickersSocket`, `ISubscribeBookTickerSocket`.
- Order books: `IGetOrderBookRest`, `IGetBookTickerRest`, `ISubscribeOrderBookSocket`, `ISubscribeIncrementalOrderBookSocket`.
- Klines and trades: `IGetKlinesRest`, `ISubscribeKlinesSocket`, `IGetRecentTradesRest`, `ISubscribeTradesSocket`.
- Symbols: `IGetSpotSymbolsRest`, `IGetFuturesSymbolsRest`.
Frequently used trading and account capabilities:
- Spot and futures order placement, editing, cancellation, retrieval, open/closed orders, and order-update subscriptions.
- Balances, positions, user trades, fees, deposits, withdrawals, and transfers.
- Funding, open interest, leverage, mark price, and index price operations for derivatives.
Use `docs/ai-api-map.md` or the typed API surface for names. Do not assume every exchange implements every family.
## V2 ticker behavior
V2 uses `GetTickerAsync` and `GetAllTickersAsync` for both spot and futures and returns `SharedTicker`. Futures-specific mark price, index price, and funding data have separate capabilities rather than being assumed to exist on the common ticker.
```csharp
IGetTickerRest ticker = restClient.SpotApi.SharedApi;
var result = await ticker.GetTickerAsync(
new GetTickerRequest(
new SharedSymbol(TradingMode.Spot, "ETH", "USDT")));
```
## Order and subscription behavior
V2 exposes REST and socket order commands under the same operation capability when both are supported. Choose the transport-specific interface when the caller needs `HttpResult<T>` or `QueryResult<T>`.
Order-update subscriptions use `SharedSpotOrderUpdate` and `SharedFuturesOrderUpdate`. REST order retrieval returns `SharedSpotOrder` or `SharedFuturesOrder`. Keep update-only stream semantics out of ordinary order snapshots.
`ICloseFullPosition` closes the entire position and has no quantity parameter. It is not a replacement for partial close logic; use a suitable order capability when an exchange supports partial reduction.
## V1 migration essentials
V1 remains available through `.SharedClient`; V2 is exposed through `.SharedApi`. Both are views over the exchange API, so migration can happen operation by operation.
```csharp
var symbol = new SharedSymbol(TradingMode.Spot, "BTC", "USDT");
var request = new GetTickerRequest(symbol);
// V1 compatibility facade
var oldResult = await restClient.SpotApi.SharedClient
.GetSpotTickerAsync(request);
// V2 capability
var newResult = await restClient.SpotApi.SharedApi
.GetTickerAsync(request);
```
Representative mappings:
- `ISpotTickerRestClient.GetSpotTickerAsync` -> `IGetTickerRest.GetTickerAsync`
- `ISpotOrderRestClient.PlaceSpotOrderAsync` -> `IPlaceSpotOrderRest.PlaceSpotOrderAsync`
- `ISpotOrderRestClient.CancelSpotOrderAsync` -> `ICancelSpotOrderRest.CancelSpotOrderAsync`
- `IFuturesOrderRestClient.PlaceFuturesOrderAsync` -> `IPlaceFuturesOrderRest.PlaceFuturesOrderAsync`
- `IFuturesOrderRestClient.GetPositionsAsync` -> `IGetPositionsRest.GetPositionsAsync`
Transport-agnostic V2 methods return `IExchangeCallResult<T>`. Select `...Rest` or `...Socket` if old code depends on a concrete transport result. See `docs/SHARED_API_V2_MIGRATION.md` for detailed migration examples and CryptoClients.Net behavior.
## Code-generation rules
- Use `.SharedApi` and fine-grained V2 interfaces for new portable code.
- Use `.SharedClient` only when maintaining or incrementally migrating V1 code.
- Use `SharedSymbol` instead of native symbol strings.
- Resolve capability support rather than assuming it.
- Inspect capability options when requests are generated dynamically.
- Select REST or socket explicitly when transport semantics matter.
- Check `Success` before accessing `Data`.
- Reuse clients through DI and keep calls asynchronous.
- Run independent exchange calls concurrently.
- Keep exchange-native models out of cross-exchange service contracts.
## Implementing an exchange library
Exchange implementations derive from the shared REST and socket client bases, provide their authentication and option types, and expose typed Shared API classes. Implement the fine-grained capability interfaces actually supported by each API surface and publish accurate `CapabilityOptions`, including trading modes and request/exchange parameter rules. Register the Shared APIs and exchange-wide shared client in the exchange library's DI extension.
Use established exchange libraries as references. Do not advertise a capability merely because a similar native endpoint exists; its shared request and result semantics must be implemented correctly.
## References
- Source: https://github.com/JKorf/CryptoExchange.Net
- Documentation: https://cryptoexchange.jkorf.dev/
- Shared API V2 migration: https://github.com/JKorf/CryptoExchange.Net/blob/master/docs/SHARED_API_V2_MIGRATION.md
- AI API map: https://github.com/JKorf/CryptoExchange.Net/blob/master/docs/ai-api-map.md
- CryptoClients.Net: https://github.com/JKorf/CryptoClients.Net
- CryptoManager.Net: https://github.com/JKorf/CryptoManager.Net
- NuGet: https://www.nuget.org/packages/CryptoExchange.Net
- Discord: https://discord.gg/MSpeEtSY8t