1
0
mirror of https://github.com/JKorf/CryptoExchange.Net.git synced 2026-08-11 08:22:53 +00:00
Files
CryptoExchange.Net/AGENTS.md
T
2026-07-28 12:45:36 +02:00

9.3 KiB

name, description
name description
cryptoexchange-net Use CryptoExchange.Net abstractions when generating C#/.NET code that needs to work across MULTIPLE cryptocurrency exchanges (Binance + Bybit + OKX + Kraken + Coinbase + ...) — for arbitrage, best-execution routing, multi-exchange portfolio dashboards, exchange-agnostic trading bots, or comparison tools. Triggers on requests mentioning multi-exchange, cross-exchange, arbitrage, exchange-agnostic, or unified crypto API in C#. Also triggers when the user is implementing a new exchange library following the CryptoExchange.Net pattern.

CryptoExchange.Net Skill

When to use

CryptoExchange.Net is the base library powering 28+ exchange-specific libraries (Binance.Net, Bybit.Net, OKX.Net, Kraken.Net, Coinbase.Net, etc.). You don't install it directly — you install the exchange libraries, which depend on it.

Three usage modes:

  1. You target ONE exchange → use that exchange's library directly (e.g., Binance.Net), see its CLAUDE.md.
  2. You target MULTIPLE exchanges → install each library you need + use CryptoExchange.Net.SharedApis interfaces — write code once, runs against any exchange. This is the main use case for this skill.
  3. You want ALL exchanges in one package → install CryptoClients.Net, get ExchangeRestClient and ExchangeSocketClient with everything bundled.

Installation

For a multi-exchange project:

dotnet add package Binance.Net
dotnet add package JK.OKX.Net
dotnet add package Bybit.Net
# ... etc

Or the bundle:

dotnet add package CryptoClients.Net

Core Pattern: Shared Interfaces

Every exchange library exposes .SharedClient properties on its API surfaces. These implement the same interfaces from CryptoExchange.Net.SharedApis.

using Binance.Net.Clients;
using OKX.Net.Clients;
using Bybit.Net.Clients;
using CryptoExchange.Net.SharedApis;

// All three implement ISpotTickerRestClient
ISpotTickerRestClient binance = new BinanceRestClient().SpotApi.SharedClient;
ISpotTickerRestClient okx     = new OKXRestClient().UnifiedApi.SharedClient;
ISpotTickerRestClient bybit   = new BybitRestClient().V5Api.SharedClient;

// Single agnostic call — works against any of them
var symbol = new SharedSymbol(TradingMode.Spot, "BTC", "USDT");
var ticker = await binance.GetSpotTickerAsync(new GetTickerRequest(symbol));
// ticker.Data.LastPrice, ticker.Data.HighPrice, etc. — same model regardless of exchange

Core Pattern: SharedSymbol

Different exchanges format symbols differently — Binance uses BTCUSDT, OKX uses BTC-USDT, others may have other formats. SharedSymbol normalizes this:

var btcusdt = new SharedSymbol(TradingMode.Spot, "BTC", "USDT");
// Each exchange library translates SharedSymbol → its native format internally.

// For futures:
var btcusdtPerp = new SharedSymbol(TradingMode.PerpetualLinear, "BTC", "USDT");

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:

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.

Available Shared Interfaces

REST:

  • Market data: ISpotTickerRestClient, IBookTickerRestClient, ISpotSymbolRestClient, IFuturesSymbolRestClient, IOrderBookRestClient, IRecentTradeRestClient, IKlineRestClient
  • Orders: ISpotOrderRestClient, IFuturesOrderRestClient, ISpotOrderClientIdRestClient, IFuturesOrderClientIdRestClient, ISpotTriggerOrderRestClient, IFuturesTriggerOrderRestClient, IFuturesTpSlRestClient
  • Account: IBalanceRestClient, IPositionRestClient, IFeeRestClient, ITransferRestClient, IDepositRestClient, IWithdrawalRestClient

WebSocket:

  • ITickerSocketClient, IBookTickerSocketClient
  • IOrderBookSocketClient, ITradeSocketClient, IKlineSocketClient
  • IUserTradeSocketClient, ISpotOrderSocketClient, IFuturesOrderSocketClient, IPositionSocketClient, IBalanceSocketClient

Each exchange documents which interfaces it implements (some exchanges don't support every operation).

Core Pattern: Result Handling

Same as exchange-specific libraries: REST calls return HttpResult<T> and websocket subscription calls return WebSocketResult<UpdateSubscription>, both with .Success, .Data, and .Error. Always check .Success first.

var result = await sharedClient.GetSpotTickerAsync(new GetTickerRequest(symbol));
if (!result.Success)
{
    Console.WriteLine($"[{sharedClient.Exchange}] Error: {result.Error}");
    return;
}
Console.WriteLine($"[{sharedClient.Exchange}] {result.Data.LastPrice}");

.Exchange property on every shared client tells you which exchange you're talking to — useful for logging.

Core Pattern: Multi-Exchange Aggregation

var clients = new ISpotTickerRestClient[]
{
    new BinanceRestClient().SpotApi.SharedClient,
    new OKXRestClient().UnifiedApi.SharedClient,
    new BybitRestClient().V5Api.SharedClient,
};

var symbol = new SharedSymbol(TradingMode.Spot, "BTC", "USDT");

// Fetch concurrently from all exchanges
var tasks = clients.Select(c => c.GetSpotTickerAsync(new GetTickerRequest(symbol))).ToArray();
var results = await Task.WhenAll(tasks);

for (int i = 0; i < clients.Length; i++)
{
    if (results[i].Success)
        Console.WriteLine($"{clients[i].Exchange}: {results[i].Data!.LastPrice}");
}

Per-Exchange Setup

Each exchange library has its own credentials class and options. See each library's CLAUDE.md for specifics. The pattern is consistent: XxxRestClient(options => { options.ApiCredentials = new XxxCredentials(...); }).

Dependency Injection

Each exchange library has its own services.AddXxx(...) extension. They all share the same option-builder pattern. Register only the ones you use:

services.AddBinance(restOpts => { /*...*/ }, socketOpts => { /*...*/ });
services.AddOKX(restOpts => { /*...*/ }, socketOpts => { /*...*/ });
// Inject IBinanceRestClient, IOKXRestClient, etc.

For one-package access: services.AddCryptoClients(...) from CryptoClients.Net.

Common Pitfalls — AVOID

  • Do NOT install CryptoExchange.Net and try to call exchange APIs directly — it's a base abstraction; you need an exchange library.
  • Do NOT try to use one exchange's models with another's client — use the SharedApis types (SharedSymbol, SharedSpotTicker, SharedSpotOrder, etc.) for cross-exchange code.
  • Do NOT block on async operations — use await throughout. Task.WhenAll for parallelism across exchanges.
  • Do NOT assume every exchange supports every operation — check exchange docs or the library's implementation. Operations may return errors like "not supported on this exchange".
  • Do NOT instantiate clients per-request — reuse via DI.
  • Do NOT iterate exchanges sequentially when concurrency is fine — use Task.WhenAll for ~Nx speedup.

Implementing a New Exchange Library

If you're building a NEW exchange wrapper following the CryptoExchange.Net pattern (rare but valuable):

  • Inherit from RestApiClient and SocketApiClient base classes
  • Define your own XxxCredentials extending ApiCredentials (or use ApiCredentials directly)
  • Implement AuthenticationProvider for the exchange's signing scheme
  • Implement the relevant Shared* interfaces on your API client classes for cross-exchange support
  • Follow the same XxxRestOptions / XxxSocketOptions pattern

See existing libraries (Binance.Net, Bybit.Net) as reference implementations.

Reference