-
var client = new HuobiRestClient();
+
+
var client = new GateIoRestClient();
+var tickersResult = await client.SpotApi.ExchangeData.GetTickersAsync();
+if (!tickersResult.Success)
+{
+ // Handle error, tickersResult.Error contains more information
+}
+else
+{
+ // Handle data, tickersResult.Data will contain the actual data
+}
+
+
+
var client = new HTXRestClient();
var tickersResult = await client.SpotApi.ExchangeData.GetTickersAsync();
if (!tickersResult.Success)
{
@@ -1120,6 +1245,9 @@ else
Bitget
+
+ BitMart
+
Bybit
@@ -1127,7 +1255,10 @@ else
Coinex
- Huobi
+ GateIo
+
+
+ HTX
Kraken
@@ -1196,6 +1327,17 @@ if (!subscribeResult.Success)
{
// Handle error, subscribeResult.Error contains more information on why the subscription failed
}
+// Subscribing was successfull, the data will now be streamed into the data handler
+
+
+
var client = new BitMartSocketClient();
+var subscribeResult = await client.SpotApi.SubscribeToTickerUpdatesAsync("ETH_USDT", update => {
+ // Handle the data update, update.Data will contain the actual data
+});
+if (!subscribeResult.Success)
+{
+ // Handle error, subscribeResult.Error contains more information on why the subscription failed
+}
// Subscribing was successfull, the data will now be streamed into the data handler
@@ -1220,8 +1362,19 @@ if (!subscribeResult.Success)
}
// Subscribing was successfull, the data will now be streamed into the data handler
-
-
var client = new HuobiSocketClient();
+
+
var client = new GateIoSocketClient();
+var subscribeResult = await client.SpotApi.SubscribeToTickerUpdatesAsync("ETH_USDT", update => {
+ // Handle the data update, update.Data will contain the actual data
+});
+if (!subscribeResult.Success)
+{
+ // Handle error, subscribeResult.Error contains more information on why the subscription failed
+}
+// Subscribing was successfull, the data will now be streamed into the data handler
+
+
+
var client = new HTXSocketClient();
var subscribeResult = await client.SpotApi.SubscribeToTickerUpdatesAsync(update => {
// Handle the data update, update.Data will contain the actual data
});
@@ -1388,42 +1541,404 @@ await client.UnsubscribeAllAsync();
-
- Common Clients
- The CryptoClients.Net library exposes two client classes. These clients aim to make using the different API's easier.
+
+ Cross Exchange Development
- (I)ExchangeRestClient
- The IExchangeRestClient
(or ExchangeRestClient
when used directly) can be used to easily access REST clients for different API's.
-
-
- For example, using the Binance, Bybit and Kucoin API's can be done like this:
-
var exchangeRestClient = new ExchangeRestClient(); // Either construct it or inject the IExchangeRestClient into your service after having called 'AddCryptoClients()' during service regirations
-var binanceTicker = await exchangeRestClient.Binance.SpotApi.ExchangeData.GetTickersAsync();
-var bybitTicker = await exchangeRestClient.Bybit.V5Api.ExchangeData.GetTickers();
-var kucoinTicker = await exchangeRestClient.Kucoin.SpotApi.ExchangeData.GetTickers();
-
+ Unfortunately there is no standard for exchanges when it comes to the API's they offer. Altough most of them offer roughly the same functionality each of them is structured differently and expects+ differently named and formatted parameters.
+
+ With this in mind all exhange clients implement various ISharedClient
interfaces. These interfaces split the functionality from the exchange specifics allowing for a common implementation for multiple exchanges. Which interfaces are implemented for each exchange depends on what functionality the exchange API offers.
+
+ The ISharedClient
interfaces allow for functionality to be defined once for every exchange instead of (partially) having to implement it for each exchange
+
+ // Abstract out the exchange request by using the shared ticker interface
+public async Task GetTickerAsync(ISpotTickerRestClient client, SharedSymbol symbol)
+{
+ var result = await client.GetSpotTickerAsync(new GetTickerRequest(symbol));
+ return result.Data;
+}
+
+// Abstract out the exchange response by using the shared response model
+public bool CheckForTrigger(SharedSpotTicker ticker)
+{
+ return ticker.HighPrice - ticker.LastPrice > 10;
+}
+
+
+// Requesting the data from different exchanges
+var sharedSymbol = new SharedSymbol(TradingMode.Spot, "ETH", "USDT");
+var lastBybitTicker = await GetTickerAsync(bybitResClient.V5Api.SharedClient, sharedSymbol);
+var lastGateIoTicker = await GetTickerAsync(gateioRestClient.SpotApi.SharedClient, sharedSymbol);
+var lastBinanceTicker = await GetTickerAsync(binanceRestClient.SpotApi.SharedClient, sharedSymbol);
+
+// Checking response with different exchange responses
+var bybitTriggered = CheckForTrigger(lastBybitTicker);
+var gateioTriggered = CheckForTrigger(lastGateIoTicker);
+var binanceTriggered = CheckForTrigger(lastBinanceTicker);
+
+ See CryptoExchange.Net examples for an example of how to use this.
+
+ Shared clients for all exchanges:
+
+
+
+
+
// Spot API common functionality rest client
+var spotSharedRestClients = binanceRestClient.SpotApi.SharedClient;
+
+// Spot API common functionality socket client
+var spotSharedSocketClient = binanceSocketClient.SpotApi.SharedClient;
+
+// USD-M Futures API common functionality rest client
+var usdFuturesSharedRestClient = binanceRestClient.UsdFuturesApi.SharedClient;
+
+// USD-M Futures API common functionality socket client
+var usdFuturesSharedSocketClient = binanceSocketClient.UsdFuturesApi.SharedClient;
+
+// Coin-M Futures API common functionality rest client
+var coinFuturesSharedRestClient = binanceRestClient.CoinFuturesApi.SharedClient;
+
+// Coin-M Futures API common functionality socket client
+var coinFuturesSharedSocketClient = binanceSocketClient.CoinFuturesApi.SharedClient;
+
+
+
// Spot API common functionality rest client
+var spotSharedRestClients = bingXRestClient.SpotApi.SharedClient;
+
+// Spot API common functionality socket client
+var spotSharedSocketClient = bingXSocketClient.SpotApi.SharedClient;
+
+// Perpetual Futures API common functionality rest client
+var usdFuturesSharedRestClient = bingXRestClient.PerpetualFuturesApi.SharedClient;
+
+// Perpetual Futures API common functionality socket client
+var usdFuturesSharedSocketClient = bingXSocketClient.PerpetualFuturesApi.SharedClient;
+
+
+
// Spot API common functionality rest client
+var spotSharedRestClients = bitfinexRestClient.SpotApi.SharedClient;
+
+// Spot API common functionality socket client
+var spotSharedSocketClient = bitfinexSocketClient.SpotApi.SharedClient;
+
+
+
// Spot API common functionality rest client
+var spotSharedRestClients = bitgetRestClient.SpotApiV2.SharedClient;
+
+// Spot API common functionality socket client
+var spotSharedSocketClient = bitgetSocketClient.SpotApiV2.SharedClient;
+
+// Perpetual Futures API common functionality rest client
+var usdFuturesSharedRestClient = bitgetRestClient.FuturesApiV2.SharedClient;
+
+// Perpetual Futures API common functionality socket client
+var usdFuturesSharedSocketClient = bitgetSocketClient.FuturesApiV2.SharedClient;
+
+
+
// Spot API common functionality rest client
+var spotSharedRestClients = bitMartRestClient.SpotApi.SharedClient;
+
+// Spot API common functionality socket client
+var spotSharedSocketClient = bitMartSocketClient.SpotApi.SharedClient;
+
+// USD Futures API common functionality rest client
+var usdFuturesSharedRestClient = bitMartRestClient.UsdFuturesApi.SharedClient;
+
+// USD Futures API common functionality socket client
+var usdFuturesSharedSocketClient = bitMartSocketClient.UsdFuturesApi.SharedClient;
+
+
+
// Spot and Futures API common functionality rest client
+var spotSharedRestClients = bybitRestClient.V5Api.SharedClient;
+
+// Spot and Futures API common functionality socket client
+var spotSharedSocketClient = bybitSocketClient.V5SpotApi.SharedClient;
+
+// Linear Futures API common functionality socket client
+var linearFuturesSharedSocketClient = bybitSocketClient.V5LinearApi.SharedClient;
+
+// Inverse Futures API common functionality socket client
+var inverseFuturesspotSharedSocketClient = bybitSocketClient.V5InverseApi.SharedClient;
+
+// Private Futures API common functionality socket client
+var privateFuturesSharedSocketClient = bybitSocketClient.V5PrivateApi.SharedClient;
+
+
+
// Spot API common functionality rest client
+var spotSharedRestClients = coinExRestClient.SpotApiV2.SharedClient;
+
+// Spot API common functionality socket client
+var spotSharedSocketClient = coinExSocketClient.SpotApiV2.SharedClient;
+
+// Futures API common functionality rest client
+var usdFuturesSharedRestClient = coinExRestClient.FuturesApi.SharedClient;
+
+// Futures API common functionality socket client
+var usdFuturesSharedSocketClient = coinExSocketClient.FuturesApi.SharedClient;
+
+
+
// Spot API common functionality rest client
+var spotSharedRestClients = gateioRestClient.SpotApi.SharedClient;
+
+// Spot API common functionality socket client
+var spotSharedSocketClient = gateioSocketClient.SpotApi.SharedClient;
+
+// Perpetual Futures API common functionality rest client
+var perpFuturesSharedRestClient = gateioRestClient.PerpetualFuturesApi.SharedClient;
+
+// Perpetual Futures API common functionality socket client
+var perpFuturesSharedSocketClient = gateioSocketClient.PerpetualFuturesApi.SharedClient;
+
+
+
// Spot API common functionality rest client
+var spotSharedRestClients = htxRestClient.SpotApi.SharedClient;
+
+// Spot API common functionality socket client
+var spotSharedSocketClient = htxSocketClient.SpotApi.SharedClient;
+
+// USDT Futures API common functionality rest client
+var usdFuturesSharedRestClient = htxRestClient.UsdtFuturesApi.SharedClient;
+
+// USDT Futures API common functionality socket client
+var usdFuturesSharedSocketClient = htxSocketClient.UsdtFuturesApi.SharedClient;
+
+
+
// Spot API common functionality rest client
+var spotSharedRestClients = krakenRestClient.SpotApi.SharedClient;
+
+// Spot API common functionality socket client
+var spotSharedSocketClient = krakenSocketClient.SpotApi.SharedClient;
+
+// Futures API common functionality rest client
+var usdFuturesSharedRestClient = krakenRestClient.FuturesApi.SharedClient;
+
+// Futures API common functionality socket client
+var usdFuturesSharedSocketClient = krakenSocketClient.FuturesApi.SharedClient;
+
+
+
// Spot API common functionality rest client
+var spotSharedRestClients = kucoinRestClient.SpotApi.SharedClient;
+
+// Spot API common functionality socket client
+var spotSharedSocketClient = kucoinSocketClient.SpotApi.SharedClient;
+
+// Futures API common functionality rest client
+var usdFuturesSharedRestClient = kucoinRestClient.FuturesApi.SharedClient;
+
+// Futures API common functionality socket client
+var usdFuturesSharedSocketClient = kucoinSocketClient.FuturesApi.SharedClient;
+
+
+
// Spot API common functionality rest client
+var spotSharedRestClients = mexcRestClient.SpotApi.SharedClient;
+
+// Spot API common functionality socket client
+var spotSharedSocketClient = mexcSocketClient.SpotApi.SharedClient;
+
+
+
// Futures and Spot API common functionality rest client
+var spotSharedRestClients = okxRestClient.UnifiedApi.SharedClient;
+
+// Futures and Spot API common functionality socket client
+var spotSharedSocketClient = okxSocketClient.UnifiedApi.SharedClient;
+
+
+
+
TradingMode
+
The shared client interfaces and functionality work with the TradingMode
enum. This enums determines what part of the API a request targets. Many exchanges support multiple trading modes, which might be split over different sub-clients:
+
Console.WriteLine(string.Join(", ", binanceClient.UsdFuturesApi.SharedClient.SupportedTradingModes));
+// Output: DeliveryLinear, PerpetualLinear
+
+Console.WriteLine(string.Join(", ", binanceClient.CoinFuturesApi.SharedClient.SupportedTradingModes));
+// Output: DeliveryInverse, PerpetualInverse
+
+Console.WriteLine(string.Join(", ", binanceClient.SpotApi.SharedClient.SupportedTradingModes));
+// Output: Spot
-
(I)ExchangeSocketClient
- Similarly as the (I)ExchangeRestClient
this client allows you to access the different Websocket clients through a single access point.
-
-
For example accessing the Bitget, Kraken and OKX API's could be done like this:
-
var exchangeSocketClient = new ExchangeSocketClient(); // Either construct it or inject the IExchangeSocketClient into your service after having called 'AddCryptoClients()' during service regirations
-var bitgetSub = await exchangeSocketClient.Bitget.SpotApi.SubscribeToTickerUpdatesAsync("ETHUSDT", data => {});
-var krakenSub = await exchangeSocketClient.Kraken.SpotApi.SubscribeToTickerUpdatesAsync("ETH/USD", data => {});
-var okxSub = await exchangeSocketClient.OKX.UnifiedApi.ExchangeData.SubscribeToTickerUpdatesAsync("ETH-USDT", data => {});
-
+
+ Mode | Description |
+ TradingMode.Spot | Spot trading |
+ TradingMode.PerpetualLinear | Futures contract trading without delivery date using stablecoin as settlement |
+ TradingMode.DeliveryLinear | Futures contract trading with specific delivery date using stablecoin as settlement |
+ TradingMode.PerpetualInverse | Futures contract trading without delivery date using a crypto asset as settlement |
+ TradingMode.DeliveryInverse | Futures contract trading with specific delivery date using a crypto asset as settlement |
+
+
+
SharedSymbol
+
One of the main challenges of working with different exchanges is the different names and formats used for symbols. For example, the ETH/USDT spot trading pair is called ETHUSDT
on Binance, ETH-USDT
on Kucoin and ETH_USDT
on GateIo. With futures trading it's even worse, ranging from ETH-USD-SWAP
to ETHU24
+
+
To combat this problem the SharedSymbol
class was introduced. This class takes a TradingMode
, base asset name and quote asset name which are used to format the symbol according to the exchange it will be used by.
+
// Create a symbol reference for ETH/USDT spot trading
+var symbol1 = new SharedSymbol(TradingMode.Spot, "ETH", "USDT");
+
+// Create a symbol reference for BTC/USDC perpetual linear futures trading
+var symbol2 = new SharedSymbol(TradingMode.PerpetualLinear, "BTC", "USDC");
+
+// Create a symbol reference for BTC/USD perpetual inverse futures trading
+var symbol3 = new SharedSymbol(TradingMode.PerpetualInverse, "BTC", "USD");
+
+// Create a symbol reference for BTC/USDT linear futures trading with delivery on 27 Sept 2024
+var symbol4 = new SharedSymbol(TradingMode.DeliveryLinear, "BTC", "USDT", new DateTime(2024, 9, 27));
+
+// Create a symbol reference for ETH/USD inverse futures trading with delivery on 27 Sept 2024
+var symbol5 = new SharedSymbol(TradingMode.DeliveryLinear, "ETH", "USD", new DateTime(2024, 9, 27));
+
+
+
With the SharedSymbol
functionality available we can reference symbols without having to think about how the exchange expects a symbol.
+
var symbol = new SharedSymbol(TradingMode.Spot, "ETH", "USDT");
+
+var tickerMexcResult = await mexcSharedRestClients.GetSpotTickerAsync(new GetTickerRequest(symbol));
+Console.WriteLine($"{mexcSharedRestClients.Exchange} {tickerMexcResult.Data.Symbol} last price: {tickerMexcResult.Data.LastPrice}");
+// Output: Mexc ETHUSDT last price: 2614,67
+
+var tickerKucoinResult = await kucoinSharedRestClients.GetSpotTickerAsync(new GetTickerRequest(symbol));
+Console.WriteLine($"{kucoinSharedRestClients.Exchange} {tickerKucoinResult.Data.Symbol} last price: {tickerKucoinResult.Data.LastPrice}");
+// Output: Kucoin ETH-USDT last price: 2614,49
+
+
+
Some Rest history requests support pagination. These requests take a INextPageToken
as parameter and results include a NextPageToken
property on the result. These tokens can be used to automatically execute multiple paginated requests
+
+
var symbol = new SharedSymbol(TradingMode.PerpetualLinear, "ETH", "USDT");
+
+INextPageToken? nextToken = null;
+while (true)
+{
+ // Execute a request specifying the next page token which was returned from by the previous request (or null for the first request)
+ var pageResult = await client.GetClosedFuturesOrdersAsync(new GetClosedOrdersRequest(symbol, limit: 2), nextToken);
+
+ Console.WriteLine($"{pageResult.Data.Count()} items");
+
+ // If NextPagToken is null there is no next page available
+ if (pageResult.NextPageToken == null)
+ break;
+
+ // Store next page token for the next request
+ nextToken = pageResult.NextPageToken;
+}
+
+
Or simplify this by using the ExchangeHelpers.ExecutePages
helper function to stream each page as a result in the form of a IAsyncEnumerable
+
+
await foreach (var pageResult in ExchangeHelpers.ExecutePages(client.GetClosedFuturesOrdersAsync, new GetClosedOrdersRequest(symbol, limit: 2)))
+ Console.WriteLine($"{pageResult.Data.Count()} items");
+
+
Available Interfaces
+
+
Available REST shared interfaces
+
+ Interface | Description |
+ IAssetsRestClient | For requesting withdrawal and deposit info for assets |
+ IKlineRestClient | For requesting public kline/candlestick data |
+ IOrderBookRestClient | For requesting public order book data |
+ IRecentTradeRestClient | For requesting the most recent public trades for a symbol |
+ ITradeHistoryRestClient | For requesting historic public trade data for a symbol |
+ ISpotSymbolRestClient | For requesting Spot symbols info |
+ ISpotTickerRestClient | For requesting Spot ticker information |
+ IFundingRateRestClient | For requesting funding rate history for a Futures symbol |
+ IFuturesSymbolRestClient | For requesting Futures symbols info |
+ IFuturesTickerRestClient | For requesting Futures ticker information |
+ IIndexPriceKlineRestClient | For requesting index price kline history for a Futures symbol |
+ IMarkPriceKlineRestClient | For requesting mark price kline history for a Futures symbol |
+ IOpenInterestRestClient | For requesting the open interest for a Futures symbol |
+ IBalanceRestClient | For requesting user asset balances |
+ IDepositRestClient | For requesting user deposit history |
+ IListenKeyRestClient | For managing the user listen key which can be used for subscribing to user data streams |
+ IWithdrawalRestClient | For requesting user withdrawal history |
+ IWithdrawRestClient | For requesting to withdraw funds from the exchange |
+ ISpotOrderRestClient | For placing and managing Spot orders |
+ IFuturesOrderRestClient | For placing and managing Futures orders |
+ ILeverageRestClient | For managing leverage for a Futures symbol |
+ IPositionHistoryRestClient | For requesting the user position closing history |
+ IPositionModeRestClient | For managing the position mode for the user |
+
+
+
Available Socket shared interfaces
+
+ Interface | Description |
+ IBookTickerSocketClient | For subscribing to book ticker (best bid/ask) updates for a symbol |
+ IKlineSocketClient | For subscribing to kline/candlestick updates for a symbol |
+ IOrderBookSocketClient | For subscribing to order book snapshot updates for a symbol |
+ ITickerSocketClient | For subscribing to ticker updates for a symbol |
+ ITickersSocketClient | For subscribing to ticker updates for all symbols |
+ ITradeSocketClient | For subscribing to public trade updates for a symbol |
+ IBalanceSocketClient | For subscribing to user balance updates |
+ IUserTradeSocketClient | For subscribing to user trade updates |
+ ISpotOrderSocketClient | For subscribing to user Spot order updates |
+ IFuturesOrderSocketClient | For subscribing to user Futures order updates |
+ IPositionSocketClient | For subscribing to user position updates |
+
+
+
CryptoClients.Net
+
The CryptoClients.Net
library has some additional tools for dynamically accessing different exchanges. Both the (I)ExchangeRestClient
and (I)ExchangeSocketClient
expose methods for executing requests and subscriptions on dynamically selected exchanges.
+
+
Rest
+
var restClient = new ExchangeRestClient();
+var symbol = new SharedSymbol(TradingMode.Spot, "ETH", "USDT");
+
+// Get ticker results from Binance and Kucoin
+var tickers = await restClient.GetSpotTickerAsync(new GetTickerRequest(symbol), [Exchange.Binance, Exchange.Kucoin]);
+
+// Get ticker results for all exchanges
+var tickers = await restClient.GetSpotTickerAsync(new GetTickerRequest(symbol));
+
+
Socket
+
var socketClient = new ExchangeSocketClient();
+var symbol = new SharedSymbol(TradingMode.Spot, "ETH", "USDT");
+
+// Subscribe to ticker updates on Binance and Kucoin
+var tickers = await socketClient.SubscribeToTickerUpdatesAsync(new SubscribeTickerRequest(symbol), update =>
+{
+ Console.WriteLine($"{update.Exchange} update: {update.Data.LastPrice}");
+},
+[Exchange.Binance, Exchange.Kucoin]);
+
+// Subscribe to ticker updates on all exchanges
+var tickers = await socketClient.SubscribeToTickerUpdatesAsync(new SubscribeTickerRequest(symbol), update =>
+{
+ Console.WriteLine($"{update.Exchange} update: {update.Data.LastPrice}");
+});
-
ISpotClient
- The ISpotClient
is a REST API client interface implemented by each library which implements a Spot trading API. It provided a common way of doing basic operations on the Spot market, for example getting ticker or trade data, but also placing and retrieving orders. Because this interface is implemented for each exchange with a Spot market the interface is relatively basic, only exposing methods that are supported by all the APIs.
-
-
- The ISpotClient
is added to the service collection when using dependency injection. Alternatively it can be accessed for a specific client by calling the `CommonSpotClient` property on the Spot sub-API of a client:
-
var spotClient = restClient.SpotApi.CommonSpotClient;
-
-
-
+
@@ -1493,6 +2008,9 @@ options.ApiCredentials = new ApiCredentials("YOUR PUBLIC KEY", "YOUR PRIVATE KEY
Bitget
+
+ BitMart
+
Bybit
@@ -1503,7 +2021,10 @@ options.ApiCredentials = new ApiCredentials("YOUR PUBLIC KEY", "YOUR PRIVATE KEY
Coinex
- Huobi
+ GateIo
+
+
+ HTX
Kraken
@@ -1557,6 +2078,15 @@ options.ApiCredentials = new ApiCredentials("YOUR PUBLIC KEY", "YOUR PRIVATE KEY
builder.Services.AddBitget(
+ restOptions => {
+ restOptions.RequestTimeout = TimeSpan.FromSeconds(30);
+ },
+ socketOptions => {
+ socketOptions.RequestTimeout = TimeSpan.FromSeconds(10);
+ });
+
+
+
builder.Services.AddBitMart(
restOptions => {
restOptions.RequestTimeout = TimeSpan.FromSeconds(30);
},
@@ -1588,8 +2118,17 @@ options.ApiCredentials = new ApiCredentials("YOUR PUBLIC KEY", "YOUR PRIVATE KEY
socketOptions.RequestTimeout = TimeSpan.FromSeconds(10);
});
-
-
builder.Services.AddHuobi(
+
+
builder.Services.AddGateIo(
+ restOptions => {
+ restOptions.RequestTimeout = TimeSpan.FromSeconds(30);
+ },
+ socketOptions => {
+ socketOptions.RequestTimeout = TimeSpan.FromSeconds(10);
+ });
+
+
+
builder.Services.AddHTX(
restOptions => {
restOptions.RequestTimeout = TimeSpan.FromSeconds(30);
},
@@ -1655,6 +2194,9 @@ options.ApiCredentials = new ApiCredentials("YOUR PUBLIC KEY", "YOUR PRIVATE KEY
Bitget
+
+ BitMart
+
Bybit
@@ -1665,7 +2207,10 @@ options.ApiCredentials = new ApiCredentials("YOUR PUBLIC KEY", "YOUR PRIVATE KEY
Coinex
- Huobi
+ GateIo
+
+
+ HTX
Kraken
@@ -1707,6 +2252,12 @@ options.ApiCredentials = new ApiCredentials("YOUR PUBLIC KEY", "YOUR PRIVATE KEY
var client = new BitgetRestClient(opts =>
+{
+ opts.RequestTimeout = TimeSpan.FromSeconds(30);
+});
+
+
+
var client = new BitMartRestClient(opts =>
{
opts.RequestTimeout = TimeSpan.FromSeconds(30);
});
@@ -1729,8 +2280,14 @@ options.ApiCredentials = new ApiCredentials("YOUR PUBLIC KEY", "YOUR PRIVATE KEY
opts.RequestTimeout = TimeSpan.FromSeconds(30);
});
-
-
var client = new HuobiRestClient(opts =>
+
+
var client = new GateIoRestClient(opts =>
+{
+ opts.RequestTimeout = TimeSpan.FromSeconds(30);
+});
+
+
+
var client = new HTXRestClient(opts =>
{
opts.RequestTimeout = TimeSpan.FromSeconds(30);
});
@@ -1778,6 +2335,9 @@ options.ApiCredentials = new ApiCredentials("YOUR PUBLIC KEY", "YOUR PRIVATE KEY
Bitget
+
+ BitMart
+
Bybit
@@ -1788,7 +2348,10 @@ options.ApiCredentials = new ApiCredentials("YOUR PUBLIC KEY", "YOUR PRIVATE KEY
Coinex
- Huobi
+ GateIo
+
+
+ HTX
Kraken
@@ -1831,6 +2394,13 @@ var client = new BitfinexRestClient();
options.RequestTimeout = TimeSpan.FromSeconds(30);
});
var client = new BitgetRestClient();
+
+
+
BitMartRestClient.SetDefaultOptions(options =>
+{
+ options.RequestTimeout = TimeSpan.FromSeconds(30);
+});
+var client = new BitMartRestClient();
BybitRestClient.SetDefaultOptions(options =>
@@ -1853,12 +2423,19 @@ var client = new CoinGeckoRestClient();
});
var client = new CoinExRestClient();
-
-
HuobiRestClient.SetDefaultOptions(options =>
+
+
GateIoRestClient.SetDefaultOptions(options =>
{
options.RequestTimeout = TimeSpan.FromSeconds(30);
});
-var client = new HuobiRestClient();
+var client = new GateIoRestClient();
+
+
+
HTXRestClient.SetDefaultOptions(options =>
+{
+ options.RequestTimeout = TimeSpan.FromSeconds(30);
+});
+var client = new HTXRestClient();
KrakenRestClient.SetDefaultOptions(options =>
@@ -1998,13 +2575,13 @@ var client = new OKXRestClient();
Option | Description | Default value |
- AutoReconnect |
- Whether or not the socket should attempt to automatically reconnect when disconnected |
- true |
+ ReconnectPolicy |
+ The reconnect policy to execute when the connection is lost |
+ ReconnectPolicy.FixedDelay |
ReconnectInterval |
- The time to wait between connection tries when reconnecting |
+ The time to wait between connection tries when reconnecting, only applied when reconnect policy is FixedDelay |
TimeSpan.FromSeconds(5) |
@@ -2086,6 +2663,9 @@ var client = new OKXRestClient();
Bitget
+
+ BitMart
+
Bybit
@@ -2093,7 +2673,10 @@ var client = new OKXRestClient();
Coinex
- Huobi
+ GateIo
+
+
+ HTX
Kraken
@@ -2171,6 +2754,19 @@ if (!startResult.Success)
}
// Book has successfully started and synchronized
+// Once no longer needed you can stop the live sync functionality by calling StopAsync()
+await book.StopAsync();
+
+
+
+
var book = new BitMartSymbolOrderBook("ETH_USDT", Category.Spot);
+var startResult = await book.StartAsync();
+if (!startResult.Success)
+{
+ // Handle error, error info available in startResult.Error
+}
+// Book has successfully started and synchronized
+
// Once no longer needed you can stop the live sync functionality by calling StopAsync()
await book.StopAsync();
@@ -2201,8 +2797,21 @@ if (!startResult.Success)
await book.StopAsync();
-
-
var book = new HuobiSpotSymbolOrderBook("ethusdt");
+
+
var book = new GateIoSpotSymbolOrderBook("ETH_USDT");
+var startResult = await book.StartAsync();
+if (!startResult.Success)
+{
+ // Handle error, error info available in startResult.Error
+}
+// Book has successfully started and synchronized
+
+// Once no longer needed you can stop the live sync functionality by calling StopAsync()
+await book.StopAsync();
+
+
+
+
var book = new HTXSpotSymbolOrderBook("ethusdt");
var startResult = await book.StartAsync();
if (!startResult.Success)
{
@@ -2430,7 +3039,22 @@ var binanceClient = new BinanceRestClient(new HttpClient(), logFactory, options
CryptoClients
- Binance
+ Binance
+
+
+ BingX
+
+
+ Bitget
+
+
+ BitMart
+
+
+ GateIo
+
+
+ HTX
Kraken
@@ -2438,6 +3062,12 @@ var binanceClient = new BinanceRestClient(new HttpClient(), logFactory, options
Kucoin
+
+ Mexc
+
+
+ OKX
+
@@ -2464,6 +3094,76 @@ var binanceClient = new BinanceRestClient(new HttpClient(), logFactory, options
BinanceExchange.RateLimiter.RateLimitTriggered += (rateLimitEvent) => Console.WriteLine("Limit triggered: " + rateLimitEvent);
// Output: Limit triggered: RateLimitEvent { ApiLimit = Spot Socket, LimitDescription = Limit of 6000 per 00:01:00, RequestDefinition = GET 1, Host = wss://ws-api.binance.com, Current = 5752, RequestWeight = 250, Limit = 6000, TimePeriod = 00:01:00, DelayTime = 00:00:38.7784145, Behaviour = Wait }
+
+
+
+
services.AddBingX(x =>
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+}, x =>
+{
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+});
+
To be notified of when a rate limit is hit the static BingXExchange.RateLimiter
exposes an event which triggers when a rate limit is reached
+
BingXExchange.RateLimiter.RateLimitTriggered += (rateLimitEvent) => Console.WriteLine("Limit triggered: " + rateLimitEvent);
+
+
+
+
+
services.AddBitget(x =>
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+}, x =>
+{
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+});
+
To be notified of when a rate limit is hit the static BitgetExchange.RateLimiter
exposes an event which triggers when a rate limit is reached
+
BitgetExchange.RateLimiter.RateLimitTriggered += (rateLimitEvent) => Console.WriteLine("Limit triggered: " + rateLimitEvent);
+
+
+
+
+
services.AddBitMart(x =>
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+}, x =>
+{
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+});
+
To be notified of when a rate limit is hit the static BitMartExchange.RateLimiter
exposes an event which triggers when a rate limit is reached
+
BitMartExchange.RateLimiter.RateLimitTriggered += (rateLimitEvent) => Console.WriteLine("Limit triggered: " + rateLimitEvent);
+
+
+
+
+
services.AddGateIo(x =>
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+}, x =>
+{
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+});
+
To be notified of when a rate limit is hit the static GateIoExchange.RateLimiter
exposes an event which triggers when a rate limit is reached
+
GateIoExchange.RateLimiter.RateLimitTriggered += (rateLimitEvent) => Console.WriteLine("Limit triggered: " + rateLimitEvent);
+
+
+
+
+
services.AddHTX(x =>
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+}, x =>
+{
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+});
+
To be notified of when a rate limit is hit the static HTXExchange.RateLimiter
exposes an event which triggers when a rate limit is reached
+
HTXExchange.RateLimiter.RateLimitTriggered += (rateLimitEvent) => Console.WriteLine("Limit triggered: " + rateLimitEvent);
+
@@ -2500,6 +3200,34 @@ var binanceClient = new BinanceRestClient(new HttpClient(), logFactory, options
Kucoin applies different rate limits based on the account VIP level. By default the rate limit is set to the most conservative VIP0
tier. To change the rate limit tier call the Configure
method
KucoinExchange.RateLimiter.Configure(Kucoin.Net.Enums.VipLevel.Vip5);
+
+
services.AddMexc(x =>
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+}, x =>
+{
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+});
+
To be notified of when a rate limit is hit the static MexcExchange.RateLimiter
exposes an event which triggers when a rate limit is reached
+
MexcExchange.RateLimiter.RateLimitTriggered += (rateLimitEvent) => Console.WriteLine("Limit triggered: " + rateLimitEvent);
+
+
+
+
+
services.AddOKX(x =>
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+}, x =>
+{
+ x.RatelimiterEnabled = true;
+ x.RateLimitingBehaviour = RateLimitingBehaviour.Wait;
+});
+
To be notified of when a rate limit is hit the static OKXExchange.RateLimiter
exposes an event which triggers when a rate limit is reached
+
OKXExchange.RateLimiter.RateLimitTriggered += (rateLimitEvent) => Console.WriteLine("Limit triggered: " + rateLimitEvent);
+
+
+
@@ -2515,7 +3243,7 @@ var binanceClient = new BinanceRestClient(new HttpClient(), logFactory, options
Prevent rate limiting, the cache can be queried as many times as you like without having to worry about getting rate limited by the server
-Caching is only applied for successful GET requests as GET requests by definition should not change state. Other HTTP method (POST, DELETE, etc) generally do change state, so caching those call would prevent an action being executed.
+Caching is only applied for successful GET requests as GET requests by definition should not change state. Other HTTP methods (POST, DELETE, etc) generally do change state, so caching those call would prevent an action being executed.
@@ -2564,6 +3292,9 @@ var responseSource = result.DataSource;
Bitget
+
+ BitMart
+
Bybit
@@ -2571,7 +3302,10 @@ var responseSource = result.DataSource;
Coinex
- Huobi
+ GateIo
+
+
+ HTX
Kraken
@@ -2602,6 +3336,9 @@ await exchangeRestClient.Binance.SpotApi.ExchangeData.GetExchangeInfoAsync();
await bitgetClient.SpotApi.ExchangeData.GetSymbolsAsync();
+
+
+
await bitMartClient.SpotApi.ExchangeData.GetSymbolsAsync();
await bybitClient.V5Api.ExchangeData.GetSpotSymbolsAsync();
@@ -2609,8 +3346,11 @@ await exchangeRestClient.Binance.SpotApi.ExchangeData.GetExchangeInfoAsync();
await coinExClient.SpotApiV2.ExchangeData.GetSymbolsAsync();
-
-
await huobiClient.SpotApi.ExchangeData.GetSymbolsAsync();
+
+
await gateIoClient.SpotApi.ExchangeData.GetSymbolsAsync();
+
+
+
await htxClient.SpotApi.ExchangeData.GetSymbolsAsync();
await krakenClient.SpotApi.ExchangeData.GetSymbolsAsync();
@@ -2657,6 +3397,9 @@ await exchangeRestClient.Binance.SpotApi.ExchangeData.GetExchangeInfoAsync();
Bitget
+
+ BitMart
+
Bybit
@@ -2664,7 +3407,10 @@ await exchangeRestClient.Binance.SpotApi.ExchangeData.GetExchangeInfoAsync();Coinex
- Huobi
+ GateIo
+
+
+ HTX
Kraken
@@ -2695,6 +3441,9 @@ await exchangeRestClient.Binance.SpotApi.ExchangeData.GetTickerAsync(spotClient.
await bitgetClient.SpotApi.ExchangeData.GetTickerAsync("BTCUSDT_SPBL");
+
+
+
await bitMartClient.SpotApi.ExchangeData.GetTickerAsync("BTC_USDT");
await bybitClient.V5Api.ExchangeData.GetSpotTickersAsync("BTCUSDT");
@@ -2702,8 +3451,11 @@ await exchangeRestClient.Binance.SpotApi.ExchangeData.GetTickerAsync(spotClient.
await coinExClient.SpotApiV2.ExchangeData.GetTickersAsync(new[] { "BTCUSDT" });
-
-
await huobiClient.SpotApi.ExchangeData.GetTickerAsync("BTCUSDT");
+
+
await gateioClient.SpotApi.ExchangeData.GetTickersAsync("BTC_USDT");
+
+
+
await htxClient.SpotApi.ExchangeData.GetTickerAsync("BTCUSDT");
await krakenClient.SpotApi.ExchangeData.GetTickerAsync("BTCUSDT");
@@ -2750,6 +3502,9 @@ await exchangeRestClient.Binance.SpotApi.ExchangeData.GetTickerAsync(spotClient.
Bitget
+
+ BitMart
+
Bybit
@@ -2757,7 +3512,10 @@ await exchangeRestClient.Binance.SpotApi.ExchangeData.GetTickerAsync(spotClient.
Coinex
- Huobi
+ GateIo
+
+
+ HTX
Kraken
@@ -2788,6 +3546,9 @@ await exchangeRestClient.Binance.SpotApi.Account.GetBalancesAsync();
await bitgetClient.SpotApi.Account.GetBalancesAsync();
+
+
+
await bitMartClient.SpotApi.Account.GetSpotBalancesAsync();
await bybitClient.V5Api.Account.GetBalancesAsync(AccountType.Spot);
@@ -2795,12 +3556,15 @@ await exchangeRestClient.Binance.SpotApi.Account.GetBalancesAsync();
await coinExClient.SpotApiV2.Account.GetBalancesAsync();
-
+
+
await gateioClient.SpotApi.Account.GetBalancesAsync();
+
+
// Need an account id, you probably want to already have done this before placing the order
-var accounts = await huobiClient.SpotApi.Account.GetAccountsAsync();
+var accounts = await htxClient.SpotApi.Account.GetAccountsAsync();
var account = accounts.Data.Single(a => a.Type == AccountType.Spot);
-var result = await huobiClient.SpotApi.Account.GetBalancesAsync();
+var result = await htxClient.SpotApi.Account.GetBalancesAsync();
await krakenClient.SpotApi.Account.GetBalancesAsync();
@@ -2847,6 +3611,9 @@ var result = await huobiClient.SpotApi.Account.GetBalancesAsync();
Bitget
+
+ BitMart
+
Bybit
@@ -2854,7 +3621,10 @@ var result = await huobiClient.SpotApi.Account.GetBalancesAsync();
Coinex
- Huobi
+ GateIo
+
+
+ HTX
Kraken
@@ -2885,6 +3655,9 @@ await exchangeRestClient.Binance.SpotApi.Trading.PlaceOrderAsync("BTCUSDT", Orde
await bitgetClient.SpotApi.Trading.PlaceOrderAsync("BTCUSDT_SPBL", BitgetOrderSide.Buy, BitgetOrderType.Limit, 0.1m, timeInForce: BitgetTimeInForce.GoodTillCanceled, 50000);
+
+
+
await bitMartClient.SpotApi.Trading.PlaceOrderAsync("BTC_USDT", OrderSide.Buy, OrderType.Limit, 0.1m, price: 50000);
await bybitClient.V5Api.Trading.PlaceOrderAsync(Category.Spot, "BTCUSDT", OrderSide.Buy, NewOrderType.Limit, 0.1m, price: 50000);
@@ -2892,12 +3665,15 @@ await exchangeRestClient.Binance.SpotApi.Trading.PlaceOrderAsync("BTCUSDT", Orde
await coinExClient.SpotApiV2.Trading.PlaceOrderAsync("BTCUSDT", AccountType.Spot, OrderSide.Buy, OrderTypeV2.Limit, 0.1m, 50000);
-