mirror of
https://github.com/JKorf/CryptoExchange.Net.git
synced 2026-08-11 16:32:57 +00:00
Squashed commit of the following:
commit9450d447b9Author: Jkorf <jankorf91@gmail.com> Date: Fri Feb 18 11:05:46 2022 +0100 Updated version commitbc0b55f337Author: Jkorf <jankorf91@gmail.com> Date: Fri Feb 18 10:09:26 2022 +0100 Added clientOrderId parameter to common clients commit31111006c7Author: Jkorf <jankorf91@gmail.com> Date: Thu Feb 17 16:32:53 2022 +0100 Update SpotClient.razor commite7400ce334Author: Jkorf <jankorf91@gmail.com> Date: Thu Feb 17 16:10:49 2022 +0100 Made some names more generic commit9bdef400daAuthor: Jkorf <jankorf91@gmail.com> Date: Tue Feb 15 11:38:41 2022 +0100 Updated vesrion commit3b80a945eeAuthor: Jkorf <jankorf91@gmail.com> Date: Tue Feb 15 11:34:50 2022 +0100 docs commit0268e211e9Author: Jkorf <jankorf91@gmail.com> Date: Tue Feb 15 09:56:45 2022 +0100 Immediate initial reconnect attempt when connection is lost commit6eb43c5218Author: Jkorf <jankorf91@gmail.com> Date: Fri Feb 11 13:59:05 2022 +0100 Re-added recalculation interval commit1df63ab60cAuthor: Jkorf <jankorf91@gmail.com> Date: Wed Feb 9 14:32:00 2022 +0100 Updated version commit9461b57daaAuthor: Jkorf <jankorf91@gmail.com> Date: Wed Feb 9 13:37:12 2022 +0100 Fix for time offset calculation not updating when offset is < 500ms commit105547d6b1Author: Jan Korf <jankorf91@gmail.com> Date: Sat Feb 5 21:05:10 2022 +0100 Updated version commit379ded6832Author: Jan Korf <jankorf91@gmail.com> Date: Sat Feb 5 20:29:57 2022 +0100 Fixed tests commitb18204a52dAuthor: Jan Korf <jankorf91@gmail.com> Date: Sat Feb 5 20:28:08 2022 +0100 Added CancellationToken support on Common client interface and SymbolOrderBook, improved SymbolOrderBook start/stop robustness commitbaa23c2eccAuthor: Jan Korf <jankorf91@gmail.com> Date: Sat Feb 5 14:56:32 2022 +0100 Added GetSubscriptionByRequest method on socket connection commit7aad9482a5Author: Jkorf <jankorf91@gmail.com> Date: Wed Feb 2 10:57:06 2022 +0100 Updated version commit6e4d9d225eAuthor: Jkorf <jankorf91@gmail.com> Date: Wed Feb 2 09:42:22 2022 +0100 Fixed exception when deserializing non-nullable datetime value '0' in .net framework commitfd1a2bbda9Author: Jkorf <jankorf91@gmail.com> Date: Tue Jan 25 13:19:10 2022 +0100 Updated version commit2ece04dd58Author: Jkorf <jankorf91@gmail.com> Date: Tue Jan 25 13:17:25 2022 +0100 Refactored use of AutoResetEvent to AsyncResetEvent in SymbolOrderBook commit893d0c723dAuthor: Jkorf <jankorf91@gmail.com> Date: Tue Jan 25 13:01:21 2022 +0100 Fixed DateTime converter for nanosecond times in string format commit2c43ee7554Author: Jkorf <jankorf91@gmail.com> Date: Mon Jan 24 15:56:24 2022 +0100 Updated version version; fixed dependencies commit100a34d1a0Author: Jkorf <jankorf91@gmail.com> Date: Mon Jan 24 14:37:15 2022 +0100 Updated version commitbb1071472fAuthor: Jkorf <jankorf91@gmail.com> Date: Mon Jan 24 14:31:57 2022 +0100 Re-added Common prefix for common enums to avoid conflicts with library namespaces commit37b1d18104Author: Jkorf <jankorf91@gmail.com> Date: Fri Jan 21 15:25:33 2022 +0100 Updated version commit325389cdf8Author: Jan Korf <jankorf91@gmail.com> Date: Thu Jan 20 21:08:51 2022 +0100 Added FTX to console example commit3e23882572Author: Jkorf <jankorf91@gmail.com> Date: Thu Jan 20 16:21:42 2022 +0100 Replaced Debug.WriteLine with Trace.WriteLine commit3cf5480cadAuthor: Jan Korf <jankorf91@gmail.com> Date: Wed Jan 19 22:07:22 2022 +0100 Example commitfe31cf156dAuthor: Jkorf <jankorf91@gmail.com> Date: Wed Jan 19 16:35:08 2022 +0100 Examples commit7427914cb7Author: Jkorf <jankorf91@gmail.com> Date: Tue Jan 18 16:46:43 2022 +0100 Update index.md commit1bc6225814Author: Jkorf <jankorf91@gmail.com> Date: Tue Jan 18 16:45:10 2022 +0100 docs commit259fe6bfd1Author: Jkorf <jankorf91@gmail.com> Date: Tue Jan 18 14:25:20 2022 +0100 Update index.md commit5f9c075ac7Author: Jkorf <jankorf91@gmail.com> Date: Tue Jan 18 14:22:33 2022 +0100 Update index.md commita26514016aAuthor: Jkorf <jankorf91@gmail.com> Date: Tue Jan 18 14:13:35 2022 +0100 Update index.md commit01a97412bfAuthor: Jkorf <jankorf91@gmail.com> Date: Tue Jan 18 14:12:02 2022 +0100 docs commit24b503ca8cAuthor: Jkorf <jankorf91@gmail.com> Date: Tue Jan 18 13:42:12 2022 +0100 docs commit008b15b055Author: Jkorf <jankorf91@gmail.com> Date: Tue Jan 18 13:32:55 2022 +0100 docs commit66fce6cb84Author: Jan Korf <jankorf91@gmail.com> Date: Mon Jan 17 21:31:53 2022 +0100 docs commit0f65701f90Author: Jan Korf <jankorf91@gmail.com> Date: Mon Jan 17 21:25:33 2022 +0100 docs commitf7a405a2e6Author: Jkorf <jankorf91@gmail.com> Date: Mon Jan 17 16:32:50 2022 +0100 docs commit55284c0549Author: Jkorf <jankorf91@gmail.com> Date: Mon Jan 17 15:51:03 2022 +0100 docs commit5bfbcca25bAuthor: Jkorf <jankorf91@gmail.com> Date: Mon Jan 17 14:04:08 2022 +0100 docs commitcdbc0ba215Author: Jkorf <jankorf91@gmail.com> Date: Mon Jan 17 13:58:51 2022 +0100 docs commite33e7c6775Author: Jkorf <jankorf91@gmail.com> Date: Mon Jan 17 13:47:58 2022 +0100 docs commitb65669659dAuthor: Jkorf <jankorf91@gmail.com> Date: Mon Jan 17 13:44:45 2022 +0100 docs commite51b863242Merge:dbfe34f088f35dAuthor: Jkorf <jankorf91@gmail.com> Date: Mon Jan 17 13:36:51 2022 +0100 Merge branch 'feature/new-cc' of https://github.com/JKorf/CryptoExchange.Net into feature/new-cc commitdbfe34f534Author: Jkorf <jankorf91@gmail.com> Date: Mon Jan 17 13:35:46 2022 +0100 Docs commit088f35d420Author: Jan Korf <jankorf91@gmail.com> Date: Mon Jan 17 13:34:40 2022 +0100 Set theme jekyll-theme-cayman commite77add4d1cAuthor: Jan Korf <jankorf91@gmail.com> Date: Sat Jan 15 15:26:38 2022 +0100 Updated version commita37a2d6e31Author: Jan Korf <jankorf91@gmail.com> Date: Sat Jan 15 15:23:52 2022 +0100 Added CallResult tests, fixed response time not set commit8f6e853e13Author: Jkorf <jankorf91@gmail.com> Date: Fri Jan 14 16:47:49 2022 +0100 Added Request info and ResponseTime to WebCallResult, refactored CallResult ctors commitc6bf0d67a4Author: Jkorf <jankorf91@gmail.com> Date: Fri Jan 7 16:30:02 2022 +0100 Fix typo commit996f3c2cedAuthor: Jkorf <jankorf91@gmail.com> Date: Fri Jan 7 16:23:42 2022 +0100 Some options logging commitfb9e9f9aa6Author: Jkorf <jankorf91@gmail.com> Date: Fri Jan 7 15:10:27 2022 +0100 Updated version commit52ebacaa21Author: Jkorf <jankorf91@gmail.com> Date: Fri Jan 7 15:05:51 2022 +0100 Fixed symbol order book tostring not locking thread, Potential fix for request timeout showing unclear message commit6b45859934Author: Jkorf <jankorf91@gmail.com> Date: Mon Jan 3 14:08:35 2022 +0100 Updated example commitebe332b724Author: Jkorf <jankorf91@gmail.com> Date: Mon Jan 3 12:05:47 2022 +0100 Updated version commit8c24b46fb3Author: Jkorf <jankorf91@gmail.com> Date: Mon Jan 3 11:33:07 2022 +0100 Fixed typo Comon -> Common commit7a195f662cAuthor: Jkorf <jankorf91@gmail.com> Date: Mon Jan 3 09:37:50 2022 +0100 Updated example, removed global.json commit120132c45bAuthor: Jan Korf <jankorf91@gmail.com> Date: Sat Jan 1 20:30:35 2022 +0100 Reverted conditional refs commitb3b4ed3f3fAuthor: Jan Korf <jankorf91@gmail.com> Date: Sat Jan 1 19:45:59 2022 +0100 Updated version commitf4b4c93e64Author: Jan Korf <jankorf91@gmail.com> Date: Sat Jan 1 19:40:50 2022 +0100 Added new shared interface implementation commitf8c3b37cdfAuthor: Jan Korf <jankorf91@gmail.com> Date: Tue Dec 28 14:14:15 2021 +0100 wip example commit0117737dfaAuthor: Jan Korf <jankorf91@gmail.com> Date: Tue Dec 28 14:13:14 2021 +0100 Added conditional refs for Microsoft.Extensions, added DependencyInjection.Abstractions to support extension method on IServiceCollection commit02c1f874e1Author: Jan Korf <jankorf91@gmail.com> Date: Mon Dec 27 15:32:07 2021 +0100 Updated version commitb212842ec8Author: Jan Korf <jankorf91@gmail.com> Date: Mon Dec 27 15:27:14 2021 +0100 Added ExchangeName to IExchangeClient interface commitc96e75d6c3Author: Jkorf <jankorf91@gmail.com> Date: Tue Dec 21 16:22:51 2021 +0100 Updated version commitc62fbda3d7Author: Jkorf <jankorf91@gmail.com> Date: Fri Dec 17 14:17:30 2021 +0100 Added ApiClients list for managing api credentials, requests made and dispose commit04b43257a5Author: Jkorf <jankorf91@gmail.com> Date: Thu Dec 16 16:17:26 2021 +0100 Update .gitignore commit8ba0ded16dAuthor: Jkorf <jankorf91@gmail.com> Date: Mon Dec 13 12:57:31 2021 +0100 Fixed api credentials getting disposed, fixed DateTimeConverter losing precision commit5c665ad54cAuthor: Jkorf <jankorf91@gmail.com> Date: Fri Dec 10 16:35:42 2021 +0100 Refactoring and comments commitb7cd6a866aAuthor: Jan Korf <jankorf91@gmail.com> Date: Wed Dec 8 21:49:25 2021 +0100 Auth work commitc2105fe690Author: Jkorf <jankorf91@gmail.com> Date: Wed Dec 8 16:20:44 2021 +0100 Wip, support for time syncing, refactoring authentication commit8b479547abAuthor: Jkorf <jankorf91@gmail.com> Date: Tue Dec 7 15:47:55 2021 +0100 Fixed release name commit2ab032b871Author: Jkorf <jankorf91@gmail.com> Date: Tue Dec 7 15:47:14 2021 +0100 Updated version commit48baaeb2d8Author: Jkorf <jankorf91@gmail.com> Date: Mon Dec 6 16:18:18 2021 +0100 Added periodic identifier commit60ec18919aAuthor: Jan Korf <jankorf91@gmail.com> Date: Sun Dec 5 17:26:55 2021 +0100 Added quotes to log commit0818c6277bAuthor: Jkorf <jankorf91@gmail.com> Date: Fri Dec 3 16:23:05 2021 +0100 Small changes commit6d0120d564Author: Jkorf <jankorf91@gmail.com> Date: Wed Dec 1 16:26:34 2021 +0100 Comments, fix test commit3c3b5639f5Author: Jkorf <jankorf91@gmail.com> Date: Wed Dec 1 13:31:54 2021 +0100 Refactor clients/options commit49de7e89ccAuthor: Jkorf <jankorf91@gmail.com> Date: Tue Nov 30 10:31:45 2021 +0100 Disposable changes, fixed tests commit69a6fabb79Author: Jkorf <jankorf91@gmail.com> Date: Mon Nov 29 16:43:27 2021 +0100 Restruct commit9a266e44ceAuthor: Jkorf <jankorf91@gmail.com> Date: Fri Nov 26 09:32:26 2021 +0100 Added enum converter commit78f81393a4Author: Jkorf <jankorf91@gmail.com> Date: Thu Nov 25 10:25:56 2021 +0100 Removed old timestamp converters commit9ebe5de825Author: Jan Korf <jankorf91@gmail.com> Date: Wed Nov 24 19:32:37 2021 +0100 Added AppendPath method commit8b619e82f2Author: Jkorf <jankorf91@gmail.com> Date: Wed Nov 24 16:39:14 2021 +0100 Added DateTimeConverter as replacement for individual converters, fix for not closing socket when auth fails commit7ac7a11dfeAuthor: Jkorf <jankorf91@gmail.com> Date: Wed Nov 17 10:23:01 2021 +0100 Resolved some code issues commit3784b0c62bAuthor: Jkorf <jankorf91@gmail.com> Date: Mon Nov 15 16:36:30 2021 +0100 Ratelimiter rework commitcb1826da7aAuthor: Jkorf <jankorf91@gmail.com> Date: Fri Nov 12 09:40:42 2021 +0100 Documentation commitf7445543f2Author: Jkorf <jankorf91@gmail.com> Date: Wed Nov 10 16:44:46 2021 +0100 Exposed order book id commit6c3462403fAuthor: Jkorf <jankorf91@gmail.com> Date: Wed Nov 10 13:18:52 2021 +0100 Fixed tests commitf83127590aAuthor: Jkorf <jankorf91@gmail.com> Date: Wed Nov 3 08:27:03 2021 +0100 wip commit23bbf0ef88Author: Jkorf <jankorf91@gmail.com> Date: Wed Oct 27 12:57:23 2021 +0200 Added cancellation token support for socket subscriptions commitb7f1619aecMerge:6ce6a46f6af235Author: Jkorf <jankorf91@gmail.com> Date: Tue Oct 26 15:39:52 2021 +0200 Merge branch 'master' of https://github.com/JKorf/CryptoExchange.Net commit6ce6a46ca3Author: Jkorf <jankorf91@gmail.com> Date: Tue Oct 26 15:39:50 2021 +0200 Some renames
This commit is contained in:
+191
@@ -0,0 +1,191 @@
|
||||
---
|
||||
title: General usage
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
## How to use the library
|
||||
|
||||
Each implementation generally provides two different clients, which will be the access point for the API's. First of the rest client, which is typically available via [ExchangeName]Client, and a socket client, which is generally named [ExchangeName]SocketClient. For example `BinanceClient` and `BinanceSocketClient`.
|
||||
|
||||
## Rest client
|
||||
The rest client gives access to the Rest endpoint of the API. Rest endpoints are accessed by sending an HTTP request and receiving a response. The client is split in different sub-clients, which are named API Clients. These API clients are then again split in different topics. Typically a Rest client will look like this:
|
||||
|
||||
- KucoinClient
|
||||
- SpotApi
|
||||
- Account
|
||||
- ExchangeData
|
||||
- Trading
|
||||
- FuturesApi
|
||||
- Account
|
||||
- ExchangeData
|
||||
- Trading
|
||||
|
||||
This rest client has 2 different API clients, the `SpotApi` and the `FuturesApi`, each offering their own set of endpoints.
|
||||
*Requesting ticker info on the spot API*
|
||||
```csharp
|
||||
var client = new KucoinClient();
|
||||
var tickersResult = kucoinClient.SpotApi.ExchangeData.GetTickersAsync();
|
||||
```
|
||||
|
||||
Structuring the client like this should make it easier to find endpoints and allows for separate options and functionality for different API clients. For example, some API's have totally separate API's for futures, with different base addresses and different API credentials, while other API's have implemented this in the same API. Either way, this structure can facilitate a similar interface.
|
||||
|
||||
### Rest API client
|
||||
The Api clients are parts of the total API with a common identifier. In the previous Kucoin example, it separates the Spot and the Futures API. This again is then separated into topics. Most Rest clients implement the following structure:
|
||||
|
||||
**Account**
|
||||
Endpoints related to the user account. This can for example be endpoints for accessing account settings, or getting account balances. The endpoints in this topic will require API credentials to be provided in the client options.
|
||||
|
||||
**ExchangeData**
|
||||
Endpoints related to exchange data. Exchange data can be tied to the exchange, for example retrieving the symbols supported by the exchange and what the trading rules are, or can be more general market endpoints, such as getting the most recent trades for a symbol.
|
||||
These endpoints generally don't require API credentials as they are publicly available.
|
||||
|
||||
**Trading**
|
||||
Endpoints related to trading. These are endpoints for placing and retrieving orders and retrieving trades made by the user. The endpoints in this topic will require API credentials to be provided in the client options.
|
||||
|
||||
### Processing request responses
|
||||
Each request will return a WebCallResult<T> with the following properties:
|
||||
`ResponseHeaders`: The headers returned from the server
|
||||
`ResponseStatusCode`: The status code as returned by the server
|
||||
`Success`: Whether or not the call was successful. If successful the `Data` property will contain the resulting data, if not successful the `Error` property will contain more details about what the issue was
|
||||
`Error`: Details on what went wrong with a call. Only filled when `Success` == `false`
|
||||
`Data`: Data returned by the server
|
||||
|
||||
When processing the result of a call it should always be checked for success. Not doing so will result in `NullReference` exceptions.
|
||||
|
||||
*Check call result*
|
||||
```csharp
|
||||
var callResult = await kucoinClient.SpotApi.ExchangeData.GetTickersAsync();
|
||||
if(!callResult.Success)
|
||||
{
|
||||
Console.WriteLine("Request failed: " + callResult.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("Result: " + callResult.Data);
|
||||
```
|
||||
|
||||
## Socket client
|
||||
The socket client gives access to the websocket API of an exchange. Websocket API's offer streams to which updates are pushed to which a client can listen. Some exchanges also offer some degree of functionality by allowing clients to give commands via the websocket, but most exchanges only allow this via the Rest API.
|
||||
Just like the Rest client is divided in Rest Api clients, the Socket client is divided into Socket Api clients, each with their own range of API functionality. Socket Api clients are generally not divided into topics since the number of methods isn't as big as with the Rest client. To use the Kucoin client as example again, it looks like this:
|
||||
|
||||
```csharp
|
||||
|
||||
- KucoinSocketClient
|
||||
- SpotStreams
|
||||
- FuturesStreams
|
||||
|
||||
```
|
||||
*Subscribing to updates for all tickers on the Spot Api*
|
||||
```csharp
|
||||
var subscribeResult = kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(DataHandler);
|
||||
```
|
||||
|
||||
Subscribe methods require a data handler parameter, which is the method which will be called when an update is received from the server. This can be the name of a method or a lambda expression.
|
||||
|
||||
*Method reference*
|
||||
```csharp
|
||||
await kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(DataHandler);
|
||||
|
||||
private static void DataHandler(DataEvent<KucoinStreamTick> updateData)
|
||||
{
|
||||
// Process updateData
|
||||
}
|
||||
```
|
||||
|
||||
*Lambda*
|
||||
```csharp
|
||||
await kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(updateData =>
|
||||
{
|
||||
// Process updateData
|
||||
});
|
||||
```
|
||||
|
||||
All updates are wrapped in a `DataEvent<>` object, which contain a `Timestamp`, `OriginalData`, `Topic`, and a `Data` property. The `Timestamp` is the timestamp when the data was received (not send!). `OriginalData` will contain the originally received data if this has been enabled in the client options. `Topic` will contain the topic of the update, which is typically the symbol or asset the update is for. The `Data` property contains the received update data.
|
||||
|
||||
*[WARNING] Do not use `using` statements in combination with constructing a `SocketClient`. Doing so will dispose the `SocketClient` instance when the subscription is done, which will result in the connection getting closed. Instead assign the socket client to a variable outside of the method scope.*
|
||||
|
||||
### Processing subscribe responses
|
||||
Subscribing to a stream will return a `CallResult<UpdateSubscription>` object. This should be checked for success the same was as the [rest client](#processing-request-responses). The `UpdateSubscription` object can be used to listen for connection events of the socket connection.
|
||||
```csharp
|
||||
|
||||
var subscriptionResult = await kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(DataHandler);
|
||||
if(!subscriptionResult.Success)
|
||||
{
|
||||
Console.WriteLine("Failed to connect: " + subscriptionResult.Error);
|
||||
return;
|
||||
}
|
||||
subscriptionResult.Data.ConnectionLost += () =>
|
||||
{
|
||||
Console.WriteLine("Connection lost");
|
||||
};
|
||||
subscriptionResult.Data.ConnectionRestored += (time) =>
|
||||
{
|
||||
Console.WriteLine("Connection restored");
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
### Unsubscribing
|
||||
When no longer interested in specific updates there are a few ways to unsubscribe.
|
||||
|
||||
**Close subscription**
|
||||
Subscribing to an update stream will respond with an `UpdateSubscription` object. You can call the `CloseAsync()` method on this to no longer receive updates from that subscription:
|
||||
```csharp
|
||||
var subscriptionResult = await kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(DataHandler);
|
||||
await subscriptionResult.Data.CloseAsync();
|
||||
```
|
||||
|
||||
**Cancellation token**
|
||||
Passing in a `CancellationToken` as parameter in the subscribe method will allow you to cancel subscriptions by canceling the token. This can be useful when you need to cancel some streams but not others. In this example, both `BTC-USDT` and `ETH-USDT` streams get canceled, while the `KCS-USDT` stream remains active.
|
||||
```csharp
|
||||
var cts = new CancellationTokenSource();
|
||||
var subscriptionResult1 = await kucoinSocketClient.SpotStreams.SubscribeToTickerUpdatesAsync("BTC-USDT", DataHandler, cts.Token);
|
||||
var subscriptionResult2 = await kucoinSocketClient.SpotStreams.SubscribeToTickerUpdatesAsync("ETH-USDT", DataHandler, cts.Token);
|
||||
var subscriptionResult3 = await kucoinSocketClient.SpotStreams.SubscribeToTickerUpdatesAsync("KCS-USDT", DataHandler);
|
||||
Console.ReadLine();
|
||||
cts.Cancel();
|
||||
```
|
||||
|
||||
**Client unsubscribe**
|
||||
Subscriptions can also be closed by calling the `UnsubscribeAsync` method on the client, while providing either the `UpdateSubscription` object or the subscription id:
|
||||
```csharp
|
||||
var subscriptionResult = await kucoinSocketClient.SpotStreams.SubscribeToTickerUpdatesAsync("BTC-USDT", DataHandler);
|
||||
await kucoinSocketClient.UnsubscribeAsync(subscriptionResult.Data);
|
||||
// OR
|
||||
await kucoinSocketClient.UnsubscribeAsync(subscriptionResult.Data.Id);
|
||||
```
|
||||
|
||||
When you need to unsubscribe all current subscriptions on a client you can call `UnsubscribeAllAsync` on the client to unsubscribe all streams and close all connections.
|
||||
|
||||
|
||||
## Dependency injection
|
||||
Each library offers a `Add[Library]` extension method for `IServiceCollection`, which allows you to add the clients to the service collection. It also provides a callback for setting the client options. See this example for adding the `BinanceClient`:
|
||||
```csharp
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddBinance((restClientOptions, socketClientOptions) => {
|
||||
restClientOptions.ApiCredentials = new ApiCredentials("KEY", "SECRET");
|
||||
restClientOptions.LogLevel = LogLevel.Trace;
|
||||
|
||||
socketClientOptions.ApiCredentials = new ApiCredentials("KEY", "SECRET");
|
||||
});
|
||||
}
|
||||
```
|
||||
Doing client registration this way will add the `IBinanceClient` as a transient service, and the `IBinanceSocketClient` as a scoped service.
|
||||
|
||||
Alternatively, the clients can be registered manually:
|
||||
```csharp
|
||||
BinanceClient.SetDefaultOptions(new BinanceClientOptions
|
||||
{
|
||||
ApiCredentials = new ApiCredentials("KEY", "SECRET"),
|
||||
LogLevel = LogLevel.Trace
|
||||
});
|
||||
|
||||
BinanceSocketClient.SetDefaultOptions(new BinanceSocketClientOptions
|
||||
{
|
||||
ApiCredentials = new ApiCredentials("KEY", "SECRET"),
|
||||
});
|
||||
|
||||
services.AddTransient<IBinanceClient, BinanceClient>();
|
||||
services.AddScoped<IBinanceSocketClient, BinanceSocketClient>();
|
||||
```
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
---
|
||||
title: FAQ
|
||||
nav_order: 11
|
||||
---
|
||||
|
||||
## Frequently asked questions
|
||||
|
||||
### I occasionally get a NullReferenceException, what's wrong?
|
||||
You probably don't check the result status of a call and just assume the data is always there. `NullReferenceExecption`s will happen when you have code like this `var symbol = client.GetTickersAync().Result.Data.Symbol` because the `Data` property is null when the call fails. Instead check if the call is successful like this:
|
||||
```csharp
|
||||
var tickerResult = await client.GetTickersAync();
|
||||
if(!tickerResult.Success)
|
||||
{
|
||||
// Handle error
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle result, it is now safe to access the Data property
|
||||
var symbol = tickerResult.Data.Symbol;
|
||||
}
|
||||
```
|
||||
|
||||
### The socket client stops sending updates after a little while
|
||||
You probably didn't keep a reference to the socket client and it got disposed.
|
||||
Instead of subscribing like this:
|
||||
```csharp
|
||||
private void SomeMethod()
|
||||
{
|
||||
var socketClient = new BinanceSocketClient();
|
||||
socketClient.Spot.SubscribeToOrderBookUpdates("BTCUSDT", data => {
|
||||
// Handle data
|
||||
});
|
||||
}
|
||||
```
|
||||
Subscribe like this:
|
||||
```csharp
|
||||
private BinanceSocketClient _socketClient = new BinanceSocketClient();
|
||||
|
||||
// .. rest of the class
|
||||
|
||||
private void SomeMethod()
|
||||
{
|
||||
_socketClient.Spot.SubscribeToOrderBookUpdates("BTCUSDT", data => {
|
||||
// Handle data
|
||||
});
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Can I use the TestNet/US/other API with this library
|
||||
Yes, generally these are all supported and can be configured by setting the BaseAddress in the client options. Some known API addresses should be available in the [Exchange]ApiAddresses class. For example:
|
||||
```csharp
|
||||
var client = new BinanceClient(new BinanceClientOptions
|
||||
{
|
||||
SpotApiOptions = new BinanceApiClientOptions
|
||||
{
|
||||
BaseAddress = BinanceApiAddresses.TestNet.RestClientAddress
|
||||
},
|
||||
UsdFuturesApiOptions = new BinanceApiClientOptions
|
||||
{
|
||||
BaseAddress = BinanceApiAddresses.TestNet.UsdFuturesRestClientAddress
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: Glossary
|
||||
nav_order: 10
|
||||
---
|
||||
## Terms and definitions
|
||||
|
||||
|Definition|Synonyms|Meaning|
|
||||
|----------|--------|-------|
|
||||
|Symbol|Market|An asset pair, for example `BTC-ETH`|
|
||||
|Asset|Currency, Coin|A coin for which you can hold balance and which makes up Symbols. For example both `BTC`, `ETH` or `USD`|
|
||||
|Trade|Execution, fill|The (partial) execution of an order. Orders can have multiple trades|
|
||||
|Quantity|Amount, Size|The amount of asset|
|
||||
|Fee|Commission|The fee paid for an order or trade|
|
||||
|Kline|Candlestick, OHLC|K-line data, used for candlestick charts. Contains Open/High/Low/Close/Volume|
|
||||
|KlineInterval|The time period of a single kline|
|
||||
|Open order|Active order, Unexecuted order|An order which has not yet been fully filled|
|
||||
|Closed order|Completed order, executed order|An order which is no longer active. Can be canceled or fully filled|
|
||||
|Network|Chain|The network of an asset. For example `ETH` allows multiple networks like `ERC20` and `BEP2`|
|
||||
|Order book|Market depth|A list of (the top rows of) the current best bids and asks|
|
||||
|Ticker|Stats|Statistics over the last 24 hours|
|
||||
|Client implementation|Library|An implementation of the `CrytpoExchange.Net` library. For example `Binance.Net` or `FTX.Net`|
|
||||
|
||||
### Other naming conventions
|
||||
#### PlaceOrderAsync
|
||||
Methods for creating an order are always named `PlaceOrderAsync`, with and optional additional name for the type of order, for example `PlaceMarginOrderAsync`.
|
||||
|
||||
#### GetOrdersAsync/GetOpenOrdersAsync/GetClosedOrdersAsync
|
||||
`GetOpenOrdersAsync` only retrieves orders which are still active, `GetClosedOrdersAsync` only retrieves orders which are canceled/closed. `GetOrdersAsync` retrieves both open and closed orders.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: Creating an implementation
|
||||
nav_order: 8
|
||||
---
|
||||
|
||||
TODO
|
||||
@@ -0,0 +1,145 @@
|
||||
---
|
||||
title: Common interfaces
|
||||
nav_order: 5
|
||||
---
|
||||
|
||||
## Shared interfaces
|
||||
Clients have a common interface implementation to allow a shared code base to use the same functionality for different exchanges. The interface is implemented at the `API` level, for example:
|
||||
```csharp
|
||||
var binanceClient = new BinanceClient();
|
||||
ISpotClient spotClient = binanceClient.SpotApi.CommonSpotClient;
|
||||
IFuturesClient futuresClient = binanceClient.UsdFuturesApi.CommonFuturesClient;
|
||||
```
|
||||
|
||||
For examples on this see the Examples folder.
|
||||
|
||||
## ISpotClient
|
||||
The `ISpotClient` interface is implemented on Spot API clients. The interface exposes basic functionality like retrieving market data and managing orders. The `ISpotClient` interface will be available via the `CommonSpotClient` property on the Api client.
|
||||
The spot client has the following members:
|
||||
|
||||
*Properties*
|
||||
```csharp
|
||||
// The name of the exchange this client interacts with
|
||||
string ExchangeName { get; }
|
||||
```
|
||||
|
||||
*Events*
|
||||
```csharp
|
||||
// Event when placing an order with this ISpotClient. Note that this is not an event handler listening on the exchange, just an event handler for when the `PlaceOrderAsync` method is called.
|
||||
event Action<OrderId> OnOrderPlaced;
|
||||
// Event when canceling an order with this ISpotClient. Note that this is not an event handler listening on the exchange, just an event handler for when the `CancelOrderAsync` method is called.
|
||||
event Action<OrderId> OnOrderCanceled;
|
||||
|
||||
```
|
||||
|
||||
*Methods*
|
||||
```csharp
|
||||
// Retrieve the name of a symbol based on 2 assets. This will format them in the way the exchange expects them. For example BTC, USDT will return BTCUSDT on Binance and BTC-USDT on Kucoin
|
||||
string GetSymbolName(string baseAsset, string quoteAsset);
|
||||
|
||||
// Get a list of symbols (trading pairs) on the exchange
|
||||
Task<WebCallResult<IEnumerable<Symbol>>> GetSymbolsAsync();
|
||||
|
||||
// Get the ticker (24 hour stats) for a symbol
|
||||
Task<WebCallResult<Ticker>> GetTickerAsync(string symbol);
|
||||
|
||||
// Get a list of tickers for all symbols
|
||||
Task<WebCallResult<IEnumerable<Ticker>>> GetTickersAsync();
|
||||
|
||||
// Get a list klines (candlesticks) for a symbol
|
||||
Task<WebCallResult<IEnumerable<Kline>>> GetKlinesAsync(string symbol, TimeSpan timespan, DateTime? startTime = null, DateTime? endTime = null, int? limit = null);
|
||||
|
||||
// Get the order book for a symbol
|
||||
Task<WebCallResult<OrderBook>> GetOrderBookAsync(string symbol);
|
||||
|
||||
// Get a list of most recent trades
|
||||
Task<WebCallResult<IEnumerable<Trade>>> GetRecentTradesAsync(string symbol);
|
||||
|
||||
// Get balances
|
||||
Task<WebCallResult<IEnumerable<Balance>>> GetBalancesAsync(string? accountId = null);
|
||||
|
||||
// Place an order
|
||||
Task<WebCallResult<OrderId>> PlaceOrderAsync(string symbol, CommonOrderSide side, CommonOrderType type, decimal quantity, decimal? price = null, string? accountId = null);
|
||||
|
||||
// Get order by order id
|
||||
Task<WebCallResult<Order>> GetOrderAsync(string orderId, string? symbol = null);
|
||||
|
||||
// Get the trades for an order
|
||||
Task<WebCallResult<IEnumerable<UserTrade>>> GetOrderTradesAsync(string orderId, string? symbol = null);
|
||||
|
||||
// Get a list of open orders. Some exchanges require a symbol
|
||||
Task<WebCallResult<IEnumerable<Order>>> GetOpenOrdersAsync(string? symbol = null);
|
||||
|
||||
// Get a list of closed orders. Some exchanges require a symbol
|
||||
Task<WebCallResult<IEnumerable<Order>>> GetClosedOrdersAsync(string? symbol = null);
|
||||
|
||||
// Cancel an active order
|
||||
Task<WebCallResult<OrderId>> CancelOrderAsync(string orderId, string? symbol = null);
|
||||
```
|
||||
|
||||
## IFuturesClient
|
||||
The `IFuturesClient` interface is implemented on Futures API clients. The interface exposes basic functionality like retrieving market data and managing orders. The `IFuturesClient` interface will be available via the `CommonFuturesClient` property on the Api client.
|
||||
The spot client has the following members:
|
||||
|
||||
*Properties*
|
||||
```csharp
|
||||
// The name of the exchange this client interacts with
|
||||
string ExchangeName { get; }
|
||||
```
|
||||
|
||||
*Events*
|
||||
```csharp
|
||||
// Event when placing an order with this ISpotClient. Note that this is not an event handler listening on the exchange, just an event handler for when the `PlaceOrderAsync` method is called.
|
||||
event Action<OrderId> OnOrderPlaced;
|
||||
// Event when canceling an order with this ISpotClient. Note that this is not an event handler listening on the exchange, just an event handler for when the `CancelOrderAsync` method is called.
|
||||
event Action<OrderId> OnOrderCanceled;
|
||||
|
||||
```
|
||||
|
||||
*Methods*
|
||||
```csharp
|
||||
// Retrieve the name of a symbol based on 2 assets. This will format them in the way the exchange expects them. For example BTC, USDT will return BTCUSDT on Binance and BTC-USDT on Kucoin
|
||||
string GetSymbolName(string baseAsset, string quoteAsset);
|
||||
|
||||
// Get a list of symbols (trading pairs) on the exchange
|
||||
Task<WebCallResult<IEnumerable<Symbol>>> GetSymbolsAsync();
|
||||
|
||||
// Get the ticker (24 hour stats) for a symbol
|
||||
Task<WebCallResult<Ticker>> GetTickerAsync(string symbol);
|
||||
|
||||
// Get a list of tickers for all symbols
|
||||
Task<WebCallResult<IEnumerable<Ticker>>> GetTickersAsync();
|
||||
|
||||
// Get a list klines (candlesticks) for a symbol
|
||||
Task<WebCallResult<IEnumerable<Kline>>> GetKlinesAsync(string symbol, TimeSpan timespan, DateTime? startTime = null, DateTime? endTime = null, int? limit = null);
|
||||
|
||||
// Get the order book for a symbol
|
||||
Task<WebCallResult<OrderBook>> GetOrderBookAsync(string symbol);
|
||||
|
||||
// Get a list of most recent trades
|
||||
Task<WebCallResult<IEnumerable<Trade>>> GetRecentTradesAsync(string symbol);
|
||||
|
||||
// Get balances
|
||||
Task<WebCallResult<IEnumerable<Balance>>> GetBalancesAsync(string? accountId = null);
|
||||
|
||||
// Get current open positions
|
||||
Task<WebCallResult<IEnumerable<Position>>> GetPositionsAsync();
|
||||
|
||||
// Place an order
|
||||
Task<WebCallResult<OrderId>> PlaceOrderAsync(string symbol, CommonOrderSide side, CommonOrderType type, decimal quantity, decimal? price = null, int? leverage = null, string? accountId = null);
|
||||
|
||||
// Get order by order id
|
||||
Task<WebCallResult<Order>> GetOrderAsync(string orderId, string? symbol = null);
|
||||
|
||||
// Get the trades for an order
|
||||
Task<WebCallResult<IEnumerable<UserTrade>>> GetOrderTradesAsync(string orderId, string? symbol = null);
|
||||
|
||||
// Get a list of open orders. Some exchanges require a symbol
|
||||
Task<WebCallResult<IEnumerable<Order>>> GetOpenOrdersAsync(string? symbol = null);
|
||||
|
||||
// Get a list of closed orders. Some exchanges require a symbol
|
||||
Task<WebCallResult<IEnumerable<Order>>> GetClosedOrdersAsync(string? symbol = null);
|
||||
|
||||
// Cancel an active order
|
||||
Task<WebCallResult<OrderId>> CancelOrderAsync(string orderId, string? symbol = null);
|
||||
```
|
||||
+325
@@ -0,0 +1,325 @@
|
||||
---
|
||||
title: Log config
|
||||
nav_order: 4
|
||||
---
|
||||
|
||||
## Configuring logging
|
||||
The library offers extensive logging, for which you can supply your own logging implementation. The logging can be configured via the client options (see [Client options](https://github.com/JKorf/CryptoExchange.Net/wiki/Options)). The examples here are using the `BinanceClient` but they should be the same for each implementation.
|
||||
|
||||
Logging is based on the `Microsoft.Extensions.Logging.ILogger` interface. This should provide ease of use when connecting the library logging to your existing logging implementation.
|
||||
|
||||
## Serilog
|
||||
To make the CryptoExchange.Net logging write to the Serilog logger you can use the following methods, depending on the type of project you're using. The following examples assume that the `Serilog.Sinks.Console` package is already installed.
|
||||
|
||||
### Dotnet hosting
|
||||
|
||||
With for example an ASP.Net Core or Blazor project the logging can be added to the dependency container, which you can then use to inject it into the client. Make sure to install the `Serilog.AspNetCore` package (https://github.com/serilog/serilog-aspnetcore).
|
||||
|
||||
<Details>
|
||||
<Summary>
|
||||
Using ILogger injection
|
||||
|
||||
</Summary>
|
||||
<BlockQuote>
|
||||
Adding `UseSerilog()` in the `CreateHostBuilder` will add the Serilog logging implementation as an ILogger which you can inject into implementations.
|
||||
|
||||
*Configuring Serilog as ILogger:*
|
||||
```csharp
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Debug()
|
||||
.WriteTo.Console()
|
||||
.CreateLogger();
|
||||
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.UseSerilog()
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
|
||||
*Injecting ILogger:*
|
||||
```csharp
|
||||
|
||||
public class BinanceDataProvider
|
||||
{
|
||||
BinanceClient _client;
|
||||
|
||||
public BinanceDataProvider(ILogger<BinanceDataProvider> logger)
|
||||
{
|
||||
_client = new BinanceClient(new BinanceClientOptions
|
||||
{
|
||||
LogLevel = LogLevel.Trace,
|
||||
LogWriters = new List<ILogger> { logger }
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</BlockQuote>
|
||||
</Details>
|
||||
|
||||
<Details>
|
||||
<Summary>
|
||||
Using Add[Library] extension method
|
||||
|
||||
</Summary>
|
||||
<BlockQuote>
|
||||
When using the `Add[Library]` extension method, for instance `AddBinance()`, there is a small issue that there is no available `ILogger<>` yet when adding the library. This can be solved as follows:
|
||||
|
||||
*Configuring Serilog as ILogger:*
|
||||
```csharp
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Debug()
|
||||
.WriteTo.Console()
|
||||
.CreateLogger();
|
||||
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup(
|
||||
context => new Startup(context.Configuration, LoggerFactory.Create(config => config.AddSerilog()) )); // <- this allows us to use ILoggerFactory in the Startup.cs
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
|
||||
*Injecting ILogger:*
|
||||
```csharp
|
||||
|
||||
public class Startup
|
||||
{
|
||||
private ILoggerFactory _loggerFactory;
|
||||
|
||||
public Startup(IConfiguration configuration, ILoggerFactory loggerFactory)
|
||||
{
|
||||
Configuration = configuration;
|
||||
_loggerFactory = loggerFactory;
|
||||
}
|
||||
|
||||
/* .. rest of class .. */
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddBinance((restClientOptions, socketClientOptions) => {
|
||||
// Point the logging to use the ILogger configuration
|
||||
restClientOptions.LogWriters = new List<ILogger> { _loggerFactory.CreateLogger<IBinanceClient>() };
|
||||
});
|
||||
|
||||
// Rest of service registrations
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</BlockQuote>
|
||||
</Details>
|
||||
|
||||
### Console application
|
||||
If you don't have a dependency injection service available because you are for example working on a simple console application you can use a slightly different approach.
|
||||
|
||||
*Configuring Serilog as ILogger:*
|
||||
```csharp
|
||||
var serilogLogger = new LoggerConfiguration()
|
||||
.MinimumLevel.Debug()
|
||||
.WriteTo.Console()
|
||||
.CreateLogger();
|
||||
|
||||
var loggerFactory = (ILoggerFactory)new LoggerFactory();
|
||||
loggerFactory.AddSerilog(serilogLogger);
|
||||
|
||||
```
|
||||
|
||||
*Injecting ILogger:*
|
||||
```csharp
|
||||
|
||||
var client = new BinanceClient(new BinanceClientOptions
|
||||
{
|
||||
LogLevel = LogLevel.Trace,
|
||||
LogWriters = new List<ILogger> { loggerFactory.CreateLogger("") }
|
||||
});
|
||||
```
|
||||
|
||||
The `BinanceClient` will now write the logging it produces to the Serilog logger.
|
||||
|
||||
## Log4Net
|
||||
|
||||
To make the CryptoExchange.Net logging write to the Log4Net logge with for example an ASP.Net Core or Blazor project the logging can be added to the dependency container, which you can then use to inject it into the client you're using. Make sure to install the `Microsoft.Extensions.Logging.Log4Net.AspNetCore` package (https://github.com/huorswords/Microsoft.Extensions.Logging.Log4Net.AspNetCore).
|
||||
Adding `AddLog4Net()` in the `ConfigureLogging` call will add the Log4Net implementation as an ILogger which you can inject into implementations. Make sure you have a log4net.config configuration file in your project.
|
||||
|
||||
*Configuring Log4Net as ILogger:*
|
||||
```csharp
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.ConfigureLogging(logging =>
|
||||
{
|
||||
logging.AddLog4Net();
|
||||
logging.SetMinimumLevel(LogLevel.Trace);
|
||||
});
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
```
|
||||
|
||||
*Injecting ILogger:*
|
||||
```csharp
|
||||
|
||||
public class BinanceDataProvider
|
||||
{
|
||||
BinanceClient _client;
|
||||
|
||||
public BinanceDataProvider(ILogger<BinanceDataProvider> logger)
|
||||
{
|
||||
_client = new BinanceClient(new BinanceClientOptions
|
||||
{
|
||||
LogLevel = LogLevel.Trace,
|
||||
LogWriters = new List<ILogger> { logger }
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
If you don't have the Dotnet dependency container available you'll need to provide your own ILogger implementation. See [Custom logger](#custom-logger).
|
||||
|
||||
## NLog
|
||||
To make the CryptoExchange.Net logging write to the NLog logger you can use the following ways, depending on the type of project you're using.
|
||||
|
||||
### Dotnet hosting
|
||||
|
||||
With for example an ASP.Net Core or Blazor project the logging can be added to the dependency container, which you can then use to inject it into the client you're using. Make sure to install the `NLog.Web.AspNetCore` package (https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-5).
|
||||
Adding `UseNLog()` to the `CreateHostBuilder()` method will add the NLog implementation as an ILogger which you can inject into implementations. Make sure you have a nlog.config configuration file in your project.
|
||||
|
||||
*Configuring NLog as ILogger:*
|
||||
```csharp
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
})
|
||||
.ConfigureLogging(logging =>
|
||||
{
|
||||
logging.ClearProviders();
|
||||
logging.SetMinimumLevel(LogLevel.Trace);
|
||||
})
|
||||
.UseNLog();
|
||||
```
|
||||
|
||||
*Injecting ILogger:*
|
||||
```csharp
|
||||
|
||||
public class BinanceDataProvider
|
||||
{
|
||||
BinanceClient _client;
|
||||
|
||||
public BinanceDataProvider(ILogger<BinanceDataProvider> logger)
|
||||
{
|
||||
_client = new BinanceClient(new BinanceClientOptions
|
||||
{
|
||||
LogLevel = LogLevel.Trace,
|
||||
LogWriters = new List<ILogger> { logger }
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
If you don't have the Dotnet dependency container available you'll need to provide your own ILogger implementation. See [Custom logger](#custom-logger).
|
||||
|
||||
## Custom logger
|
||||
If you're using a different framework or for some other reason these methods don't work for you you can create a custom ILogger implementation to receive the logging. All you need to do is create an implementation of the ILogger interface and provide that to the client.
|
||||
|
||||
*A simple console logging implementation (note that the ConsoleLogger is already available in the CryptoExchange.Net library)*:
|
||||
```csharp
|
||||
|
||||
public class ConsoleLogger : ILogger
|
||||
{
|
||||
public IDisposable BeginScope<TState>(TState state) => null;
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel) => true;
|
||||
|
||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
|
||||
{
|
||||
var logMessage = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff} | {logLevel} | {formatter(state, exception)}";
|
||||
Console.WriteLine(logMessage);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
*Injecting the console logging implementation:*
|
||||
```csharp
|
||||
|
||||
var client = new BinanceClient(new BinanceClientOptions
|
||||
{
|
||||
LogLevel = LogLevel.Trace,
|
||||
LogWriters = new List<ILogger> { new ConsoleLogger() }
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
## Provide logging for issues
|
||||
A big debugging tool when opening an issue on Github is providing logging of what data caused the issue. This can be provided two ways, via the `OriginalData` property of the call result or data event, or collecting the Trace logging.
|
||||
### OriginalData
|
||||
This is only useful when there is an issue in deserialization. So either a call result is giving a Deserialization error, or the result has a value that is unexpected. If that is the issue, please provide the original data that is received so the deserialization issue can be resolved based on the received data.
|
||||
By default the `OriginalData` property in the `WebCallResult`/`DataEvent` object is not filled as saving the original data has a (very small) performance penalty. To save the original data in the `OriginalData` property the `OutputOriginalData` option should be set to `true` in the client options.
|
||||
*Enabled output data*
|
||||
```csharp
|
||||
var client = new BinanceClient(new BinanceClientOptions
|
||||
{
|
||||
OutputOriginalData = true
|
||||
});
|
||||
```
|
||||
|
||||
*Accessing original data*
|
||||
```csharp
|
||||
// Rest request
|
||||
var tickerResult = client.SpotApi.ExchangeData.GetTickersAsync();
|
||||
var originallyRecievedData = tickerResult.OriginalData;
|
||||
|
||||
// Socket update
|
||||
client.SpotStreams.SubscribeToAllTickerUpdatesAsync(update => {
|
||||
var originallyRecievedData = update.OriginalData;
|
||||
});
|
||||
```
|
||||
|
||||
### Trace logging
|
||||
Trace logging, which is the most verbose log level, can be enabled in the client options.
|
||||
*Enabled output data*
|
||||
```csharp
|
||||
var client = new BinanceClient(new BinanceClientOptions
|
||||
{
|
||||
LogLevel = LogLevel.Trace
|
||||
});
|
||||
```
|
||||
After enabling trace logging all data send to/received from the server is written to the log writers. By default this is written to the output window in Visual Studio via Debug.WriteLine, though this might be different depending on how you configured your logging.
|
||||
Output data will look something like this:
|
||||
```
|
||||
2021-12-17 10:40:42:296 | Debug | Binance | Client configuration: LogLevel: Trace, Writers: 1, OutputOriginalData: False, Proxy: -, AutoReconnect: True, ReconnectInterval: 00:00:05, MaxReconnectTries: , MaxResubscribeTries: 5, MaxConcurrentResubscriptionsPerSocket: 5, SocketResponseTimeout: 00:00:10, SocketNoDataTimeout: 00:00:00, SocketSubscriptionsCombineTarget: , CryptoExchange.Net: v5.0.0.0, Binance.Net: v8.0.0.0
|
||||
2021-12-17 10:40:42:410 | Debug | Binance | [15] Creating request for https://api.binance.com/api/v3/ticker/24hr
|
||||
2021-12-17 10:40:42:439 | Debug | Binance | [15] Sending GET request to https://api.binance.com/api/v3/ticker/24hr?symbol=BTCUSDT with headers Accept=[application/json], X-MBX-APIKEY=[XXX]
|
||||
2021-12-17 10:40:43:024 | Debug | Binance | [15] Response received in 571ms: {"symbol":"BTCUSDT","priceChange":"-1726.47000000","priceChangePercent":"-3.531","weightedAvgPrice":"48061.51544204","prevClosePrice":"48901.44000000","lastPrice":"47174.97000000","lastQty":"0.00352000","bidPrice":"47174.96000000","bidQty":"0.65849000","askPrice":"47174.97000000","askQty":"0.13802000","openPrice":"48901.44000000","highPrice":"49436.43000000","lowPrice":"46749.55000000","volume":"33136.69765000","quoteVolume":"1592599905.80360790","openTime":1639647642763,"closeTime":1639734042763,"firstId":1191596486,"lastId":1192649611,"count":1053126}
|
||||
```
|
||||
When opening an issue, please provide this logging when available.
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
title: Migrate v4 to v5
|
||||
nav_order: 9
|
||||
---
|
||||
|
||||
## Migrating from version 4 to version 5
|
||||
When updating your code from version 4 implementations to version 5 implementations you will encounter a fair bit of breaking changes. Here is the general outline for changes made in the CryptoExchange.Net library. For more specific changes for each library visit the library migration guide.
|
||||
|
||||
*NOTE when updating it is not possible to have some client implementations use a V4 version and some clients a V5. When updating all libraries should be migrated*
|
||||
|
||||
## Client structure
|
||||
The client structure has been changed to make clients more consistent across different implementations. Clients using V4 either had `client.Method()`, `client.[Api].Method()` or `client.[Api].[Topic].Method()`.
|
||||
|
||||
This has been unified to be `client.[Api]Api.[Topic].Method()`:
|
||||
`bittrexClient.GetTickersAsync()` -> `bittrexClient.SpotApi.ExchangeData.GetTickersAsync()`
|
||||
`kucoinClient.Spot.GetTickersAsync()` -> `kucoinClient.SpotApi.ExchangeData.GetTickersAsync()`
|
||||
`binanceClient.Spot.Market.GetTickersAsync()` -> `binanceClient.SpotApi.ExchangeData.GetTickersAsync()`
|
||||
|
||||
Socket clients are restructured as `client.[Api]Streams.Method()`:
|
||||
`bittrexClient.SpotStreams.SubscribeToTickerUpdatesAsync()`
|
||||
`kucoinClient.SpotStreams.SubscribeToTickerUpdatesAsync()`
|
||||
`binanceClient.SpotStreams.SubscribeToAllTickerUpdatesAsync()`
|
||||
|
||||
|
||||
## Options structure
|
||||
The options have been changed in 2 categories, options for the whole client, and options only for a specific sub Api. Some options might no longer be available on the base level and should be set on the Api options instead, for example the `BaseAddress`.
|
||||
The following example sets some basic options, and specifically overwrites the USD futures Api options to use the test net address and different Api credentials:
|
||||
*V4*
|
||||
```csharp
|
||||
var binanceClient = new BinanceClient(new BinanceApiClientOptions{
|
||||
LogLevel = LogLevel.Trace,
|
||||
RequestTimeout = TimeSpan.FromSeconds(60),
|
||||
ApiCredentials = new ApiCredentials("API KEY", "API SECRET"),
|
||||
BaseAddressUsdtFutures = new ApiCredentials("OTHER API KEY ONLY FOR USD FUTURES", "OTHER API SECRET ONLY FOR USD FUTURES")
|
||||
// No way to set separate credentials for the futures API
|
||||
});
|
||||
```
|
||||
|
||||
*V5*
|
||||
```csharp
|
||||
var binanceClient = new BinanceClient(new BinanceClientOptions()
|
||||
{
|
||||
// Client options
|
||||
LogLevel = LogLevel.Trace,
|
||||
RequestTimeout = TimeSpan.FromSeconds(60),
|
||||
ApiCredentials = new ApiCredentials("API KEY", "API SECRET"),
|
||||
|
||||
// Set options specifically for the USD futures API
|
||||
UsdFuturesApiOptions = new BinanceApiClientOptions
|
||||
{
|
||||
BaseAddress = BinanceApiAddresses.TestNet.UsdFuturesRestClientAddress,
|
||||
ApiCredentials = new ApiCredentials("OTHER API KEY ONLY FOR USD FUTURES", "OTHER API SECRET ONLY FOR USD FUTURES")
|
||||
}
|
||||
});
|
||||
```
|
||||
See [Client options](https://github.com/JKorf/CryptoExchange.Net/wiki/Options) for more details on the specific options.
|
||||
|
||||
## IExchangeClient
|
||||
The `IExchangeClient` has been replaced by the `ISpotClient` and `IFuturesClient`. Where previously the `IExchangeClient` was implemented on the base client level, the `ISpotClient`/`IFuturesClient` have been implemented on the sub-Api level.
|
||||
This, in combination with the client restructuring, allows for more logically implemented interfaces, see this example:
|
||||
*V4*
|
||||
```csharp
|
||||
var spotClients = new [] {
|
||||
(IExhangeClient)binanceClient,
|
||||
(IExchangeClient)bittrexClient,
|
||||
(IExchangeClient)kucoinClient.Spot
|
||||
};
|
||||
|
||||
// There was no common implementation for futures client
|
||||
```
|
||||
|
||||
*V5*
|
||||
```csharp
|
||||
var spotClients = new [] {
|
||||
binanceClient.SpotApi.CommonSpotClient,
|
||||
bittrexClient.SpotApi.CommonSpotClient,
|
||||
kucoinClient.SpotApi.CommonSpotClient
|
||||
};
|
||||
|
||||
var futuresClients = new [] {
|
||||
binanceClient.UsdFuturesApi.CommonFuturesClient,
|
||||
kucoinClient.FuturesApi.CommonFuturesClient
|
||||
};
|
||||
```
|
||||
|
||||
Where the IExchangeClient was returning interfaces which were implemented by models from the exchange, the `ISpotClient`/`IFuturesClient` returns actual objects defined in the `CryptoExchange.Net` library. This shifts the responsibility of parsing
|
||||
the library model to a shared model from the model class to the client class, which makes more sense and removes the need for separate library models to implement the same mapping logic. It also removes the need for the `Common` prefix on properties:
|
||||
*V4*
|
||||
```csharp
|
||||
var kline = await ((IExhangeClient)binanceClient).GetKlinesAysnc(/*params*/);
|
||||
var closePrice = kline.CommonClose;
|
||||
```
|
||||
|
||||
*V5*
|
||||
```csharp
|
||||
var kline = await binanceClient.SpotApi.ComonSpotClient.GetKlinesAysnc(/*params*/);
|
||||
var closePrice = kline.ClosePrice;
|
||||
```
|
||||
|
||||
For more details on the interfaces see [Common interfaces](interfaces.html)
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
---
|
||||
title: Client options
|
||||
nav_order: 3
|
||||
---
|
||||
|
||||
## Setting client options
|
||||
|
||||
Each implementation can be configured using client options. There are 2 ways to provide these, either via `[client].SetDefaultOptions([options]);`, or in the constructor of the client. The examples here use the `BinanceClient`, but usage is the same for each client.
|
||||
|
||||
*Set the default options to use for new clients*
|
||||
```csharp
|
||||
|
||||
BinanceClient.SetDefaultOptions(new BinanceClientOptions
|
||||
{
|
||||
LogLevel = LogLevel.Trace,
|
||||
ApiCredentials = new ApiCredentials("KEY", "SECRET")
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
*Set the options to use for a single new client*
|
||||
```csharp
|
||||
|
||||
var client = new BinanceClient(new BinanceClientOptions
|
||||
{
|
||||
LogLevel = LogLevel.Trace,
|
||||
ApiCredentials = new ApiCredentials("KEY", "SECRET")
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
When calling `SetDefaultOptions` each client created after that will use the options that were set, unless the specific option is overriden in the options that were provided to the client. Consider the following example:
|
||||
```csharp
|
||||
|
||||
BinanceClient.SetDefaultOptions(new BinanceClientOptions
|
||||
{
|
||||
LogLevel = LogLevel.Trace,
|
||||
OutputOriginalData = true
|
||||
});
|
||||
|
||||
var client = new BinanceClient(new BinanceClientOptions
|
||||
{
|
||||
LogLevel = LogLevel.Debug,
|
||||
ApiCredentials = new ApiCredentials("KEY", "SECRET")
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
The client instance will have the following options:
|
||||
`LogLevel = Debug`
|
||||
`OutputOriginalData = true`
|
||||
`ApiCredentials = set`
|
||||
|
||||
## Api options
|
||||
The options are divided in two categories. The basic options, which will apply to everything the client does, and the Api options, which is limited to the specific API client (see [Clients](https://github.com/JKorf/CryptoExchange.Net/wiki/Clients)).
|
||||
|
||||
```csharp
|
||||
|
||||
var client = new BinanceClient(new BinanceClientOptions
|
||||
{
|
||||
LogLevel = LogLevel.Debug,
|
||||
ApiCredentials = new ApiCredentials("GENERAL-KEY", "GENERAL-SECRET"),
|
||||
SpotApiOptions = new BinanceApiClientOptions
|
||||
{
|
||||
ApiCredentials = new ApiCredentials("SPOT-KEY", "SPOT-SECRET") ,
|
||||
BaseAddress = BinanceApiAddresses.Us.RestClientAddress
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
The options provided in the SpotApiOptions are only applied to the SpotApi (`client.SpotApi.XXX` endpoints), while the base options are applied to everything. This means that the spot endpoints will use the "SPOT-KEY" credentials, while all other endpoints (`client.UsdFuturesApi.XXX` / `client.CoinFuturesApi.XXX`) will use the "GENERAL-KEY" credentials.
|
||||
|
||||
## CryptoExchange.Net options definitions
|
||||
All clients have access to the following options, specific implementations might have additional options.
|
||||
|
||||
**Base client options**
|
||||
|
||||
|Option|Description|Default|
|
||||
|------|-----------|-------|
|
||||
|`LogWriters`| A list of `ILogger`s to handle log messages. | `new List<ILogger> { new DebugLogger() }` |
|
||||
|`LogLevel`| The minimum log level before passing messages to the `LogWriters`. Messages with a more verbose level than the one specified here will be ignored. Setting this to `null` will pass all messages to the `LogWriters`.| `LogLevel.Information`
|
||||
|`OutputOriginalData`|If set to `true` the originally received Json data will be output as well as the deserialized object. For `RestClient` calls the data will be in the `WebCallResult<T>.OriginalData` property, for `SocketClient` subscriptions the data will be available in the `DataEvent<T>.OriginalData` property when receiving an update. | `false`
|
||||
|`ApiCredentials`| The API credentials to use for accessing protected endpoints. Typically a key/secret combination. Note that this is a `default` value for all API clients, and can be overridden per API client. See the `Base Api client options`| `null`
|
||||
|`Proxy`|The proxy to use for connecting to the API.| `null`
|
||||
|
||||
**Rest client options (extension of base client options)**
|
||||
|
||||
|Option|Description|Default|
|
||||
|------|-----------|-------|
|
||||
|`RequestTimeout`|The time out to use for requests.|`TimeSpan.FromSeconds(30)`|
|
||||
|`HttpClient`|The `HttpClient` instance to use for making requests. When creating multiple `RestClient` instances a single `HttpClient` should be provided to prevent each client instance from creating its own. *[WARNING] When providing the `HttpClient` instance in the options both the `RequestTimeout` and `Proxy` client options will be ignored and should be set on the provided `HttpClient` instance.*| `null` |
|
||||
|
||||
**Socket client options (extension of base client options)**
|
||||
|
||||
|Option|Description|Default|
|
||||
|------|-----------|-------|
|
||||
|`AutoReconnect`|Whether or not the socket should automatically reconnect when disconnected.|`true`
|
||||
|`ReconnectInterval`|The time to wait between connection tries when reconnecting.|`TimeSpan.FromSeconds(5)`
|
||||
|`SocketResponseTimeout`|The time in which a response is expected on a request before giving a timeout.|`TimeSpan.FromSeconds(10)`
|
||||
|`SocketNoDataTimeout`|If no data is received after this timespan then assume the connection is dropped. This is mainly used for API's which have some sort of ping/keepalive system. For example; the Bitfinex API will sent a heartbeat message every 15 seconds, so the `SocketNoDataTimeout` could be set to 20 seconds. On API's without such a mechanism this might not work because there just might not be any update while still being fully connected. | `default(TimeSpan)` (no timeout)
|
||||
|`SocketSubscriptionsCombineTarget`|The amount of subscriptions that should be made on a single socket connection. Not all exchanges support multiple subscriptions on a single socket. Setting this to a higher number increases subscription speed because not every subscription needs to connect to the server, but having more subscriptions on a single connection will also increase the amount of traffic on that single connection, potentially leading to issues.| Depends on implementation
|
||||
|`MaxReconnectTries`|The maximum amount of tries for reconnecting|`null` (infinite)
|
||||
|`MaxResubscribeTries`|The maximum amount of tries for resubscribing after successfully reconnecting the socket|5
|
||||
|`MaxConcurrentResubscriptionsPerSocket`|The maximum number of concurrent resubscriptions per socket when resubscribing after reconnecting|5
|
||||
|
||||
**Base Api client options**
|
||||
|
||||
|Option|Description|Default|
|
||||
|------|-----------|-------|
|
||||
|`ApiCredentials`|The API credentials to use for this specific API client. Will override any credentials provided in the base client options|
|
||||
|`BaseAddress`|The base address to the API. All calls to the API will use this base address as basis for the endpoints. This allows for swapping to test API's or swapping to a different cluster for example. Available base addresses are defined in the [Library]ApiAddresses helper class, for example `KucoinApiAddresses`|Depends on implementation
|
||||
|
||||
**Options for Rest Api Client (extension of base api client options)**
|
||||
|
||||
|Option|Description|Default|
|
||||
|------|-----------|-------|
|
||||
|`RateLimiters`|A list of `IRateLimiter`s to use.|`new List<IRateLimiter>()`|
|
||||
|`RateLimitingBehaviour`|What should happen when a rate limit is reached.|`RateLimitingBehaviour.Wait`|
|
||||
|
||||
**Options for Socket Api Client (extension of base api client options)**
|
||||
There are currently no specific options for socket API clients, the base API options are still available.
|
||||
@@ -0,0 +1,57 @@
|
||||
---
|
||||
title: Order books
|
||||
nav_order: 6
|
||||
---
|
||||
|
||||
## Locally synced order book
|
||||
Each implementation provides an order book implementation. These implementations will provide a client side order book and will take care of synchronization with the server, and will handle reconnecting and resynchronizing in case of a dropped connection.
|
||||
Order book implementations are named as `[ExchangeName][Type]SymbolOrderBook`, for example `BinanceSpotSymbolOrderBook`.
|
||||
|
||||
## Usage
|
||||
Start the book synchronization by calling the `StartAsync` method. This returns a success state whether the book is successfully synchronized and started. You can listen to the `OnStatusChange` event to be notified of when the status of a book changes. Note that the order book is only synchronized with the server when the state is `Synced`.
|
||||
|
||||
*Start an order book and print the top 3 rows*
|
||||
```csharp
|
||||
|
||||
var book = new BinanceSpotSymbolOrderBook("BTCUSDT");
|
||||
book.OnStatusChange += (oldState, newState) => Console.WriteLine($"State changed from {oldState} to {newState}");
|
||||
var startResult = await book.StartAsync();
|
||||
if (!startResult.Success)
|
||||
{
|
||||
Console.WriteLine("Failed to start order book: " + startResult.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
Console.WriteLine(book.ToString(3);
|
||||
await Task.Delay(500);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Accessing bids/asks
|
||||
You can access the current Bid/Ask lists using the responding properties:
|
||||
`var currentBidList = book.Bids;`
|
||||
`var currentAskList = book.Asks;`
|
||||
|
||||
Note that these will return copies of the internally synced lists when accessing the properties, and when accessing them in sequence like above does mean that the lists may not be in sync with eachother since they're accessed at different points in time.
|
||||
When you need both lists in sync you should access the `Book` property.
|
||||
`var (currentBidList, currentAskList) = book.Book;`
|
||||
|
||||
Because copies of the lists are made when accessing the bids/asks properties the performance impact should be considered. When only the current best ask/bid info is needed you can access the `BestOffers` property.
|
||||
`var (bestBid, bestAsk) = book.BestOffers;`
|
||||
|
||||
### Events
|
||||
The following events are available on the symbol order book:
|
||||
`book.OnStatusChange`: The book has changed state. This happens during connecting, the connection was lost or the order book was detected to be out of sync. The asks/bids are only the actual with the server when state is `Synced`.
|
||||
`book.OnOrderBookUpdate`: The book has changed, the arguments contain the changed entries.
|
||||
`book.OnBestOffersChanged`: The best offer (best bid, best ask) has changed.
|
||||
|
||||
```csharp
|
||||
|
||||
book.OnStatusChange += (oldStatus, newStatus) => { Console.WriteLine($"State changed from {oldStatus} to {newStatus}"); };
|
||||
book.OnOrderBookUpdate += (bidsAsks) => { Console.WriteLine($"Order book changed: {bidsAsks.Asks.Count()} asks, {bidsAsks.Bids.Count()} bids"); };
|
||||
book.OnBestOffersChanged += (bestOffer) => { Console.WriteLine($"Best offer changed, best bid: {bestOffer.BestBid.Price}, best ask: {bestOffer.BestAsk.Price}"); };
|
||||
|
||||
```
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
title: Rate limiting
|
||||
nav_order: 7
|
||||
---
|
||||
|
||||
## Rate limiting
|
||||
The library has build in rate limiting. These rate limits can be configured per client. Some client implementations where the exchange has clear rate limits will also have a default rate limiter already set up.
|
||||
Rate limiting is configured in the client options, and can be set on a specific client or for all clients by either providing it in the constructor for a client, or by using the `SetDefaultOptions` on a client.
|
||||
|
||||
What to do when a limit is reached can be configured with the `RateLimitingBehaviour` client options, which has 2 possible options. Setting it to `Fail` will cause a request to fail without sending it. Setting it to `Wait` will cause the request to wait until the request can be send in accordance to the rate limiter.
|
||||
|
||||
A rate limiter can be configured in the options like so:
|
||||
```csharp
|
||||
new ClientOptions
|
||||
{
|
||||
RateLimitingBehaviour = RateLimitingBehaviour.Wait,
|
||||
RateLimiters = new List<IRateLimiter>
|
||||
{
|
||||
new RateLimiter()
|
||||
.AddTotalRateLimit(50, TimeSpan.FromSeconds(10))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This will add a rate limiter for 50 requests per 10 seconds.
|
||||
A rate limiter can have multiple limits:
|
||||
```csharp
|
||||
new RateLimiter()
|
||||
.AddTotalRateLimit(50, TimeSpan.FromSeconds(10))
|
||||
.AddEndpointLimit("/api/order", 10, TimeSpan.FromSeconds(2))
|
||||
```
|
||||
This adds another limit of 10 requests per 2 seconds in addition to the 50 requests per 10 seconds limit.
|
||||
These are the available rate limit configurations:
|
||||
|
||||
### AddTotalRateLimit
|
||||
|Parameter|Description|
|
||||
|---------|-----------|
|
||||
|limit|The request weight limit per time period. Note that requests can have a weight specified. Default requests will have a weight of 1|
|
||||
|perTimePeriod|The time period over which the limit is enforced|
|
||||
|
||||
A rate limit for the total amount of requests for all requests send from the client.
|
||||
|
||||
### AddEndpointLimit
|
||||
|Parameter|Description|
|
||||
|---------|-----------|
|
||||
|endpoint|The endpoint this limit is for|
|
||||
|limit|The request weight limit per time period. Note that requests can have a weight specified. Default requests will have a weight of 1|
|
||||
|perTimePeriod|The time period over which the limit is enforced|
|
||||
|method|The HTTP method this limit is for. Defaults to all methods|
|
||||
|excludeFromOtherRateLimits|When set to true requests to this endpoint won't be counted for other configured rate limits|
|
||||
|
||||
A rate limit for all requests send to a specific endpoint. Requests that do not fully match the endpoint will not be counted to this limit.
|
||||
|
||||
### AddPartialEndpointLimit
|
||||
|Parameter|Description|
|
||||
|---------|-----------|
|
||||
|endpoint|The partial endpoint this limit is for. Partial means that a request will match this limiter when a part of the request URI path matches this endpoint|
|
||||
|limit|The request weight limit per time period. Note that requests can have a weight specified. Default requests will have a weight of 1|
|
||||
|perTimePeriod|The time period over which the limit is enforced|
|
||||
|method|The HTTP method this limit is for. Defaults to all methods|
|
||||
|countPerEndpoint|Whether all requests matching the endpoint pattern should be combined for this limit or each endpoint has its own limit|
|
||||
|ignoreOtherRateLimits|When set to true requests to this endpoint won't be counted for other configured rate limits|
|
||||
|
||||
A rate limit for a partial endpoint. Requests will be counted towards this limit if the request path contains the endpoint. For example request `/api/v2/test` will match when the partial endpoint limit is set for `/api/v2`.
|
||||
|
||||
### AddApiKeyLimit
|
||||
|Parameter|Description|
|
||||
|---------|-----------|
|
||||
|limit|The request weight limit per time period. Note that requests can have a weight specified. Default requests will have a weight of 1|
|
||||
|perTimePeriod|The time period over which the limit is enforced|
|
||||
|onlyForSignedRequests|Whether this rate limit should only be counter for signed/authenticated requests|
|
||||
|excludeFromTotalRateLimit|Whether requests counted for this rate limited should not be counted towards the total rate limit|
|
||||
|
||||
A rate limit for an API key. Requests with the same API key will be grouped and limited.
|
||||
@@ -0,0 +1,2 @@
|
||||
remote_theme: pmarsceill/just-the-docs
|
||||
markdown: GFM
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
title: Home
|
||||
nav_order: 1
|
||||
---
|
||||
|
||||
  
|
||||
|
||||
The CryptoExchange.Net library is a base package for exchange API implementations. It offers base classes for creating clients for exchange API's. Basing exchange implementation on the common CryptoExchange.Net library allows for ease of implementation for new exchanges, as only the endpoints and models have to implemented, but not all systems around requests and connections, and it makes it easier for users to implement a new library in their code base as all base principles and configuration are the same for different exchanges.
|
||||
|
||||
**Implementations by me**
|
||||
These will always be on the latest CryptoExchange.Net version and the latest versions will always work together
|
||||
|
||||
||Exchange|Documentation|
|
||||
|-|-|-|
|
||||
|<a href="https://github.com/JKorf/Binance.Net"><img src="https://github.com/JKorf/Binance.Net/blob/master/Binance.Net/Icon/icon.png?raw=true"></a>|Binance|https://jkorf.github.io/Binance.Net/|
|
||||
|<a href="https://github.com/JKorf/Bitfinex.Net"><img src="https://github.com/JKorf/Bitfinex.Net/blob/master/Bitfinex.Net/Icon/icon.png?raw=true"></a>|Bitfinex|https://jkorf.github.io/Bitfinex.Net/|
|
||||
|<a href="https://github.com/JKorf/Bittrex.Net"><img src="https://github.com/JKorf/Bittrex.Net/blob/master/Bittrex.Net/Icon/icon.png?raw=true"></a>|Bittrex|https://jkorf.github.io/Bittrex.Net/|
|
||||
|<a href="https://github.com/JKorf/Bybit.Net"><img src="https://github.com/JKorf/Bybit.Net/blob/main/ByBit.Net/Icon/icon.png?raw=true"></a>|Bybit|https://jkorf.github.io/Bybit.Net/|
|
||||
|<a href="https://github.com/JKorf/CoinEx.Net"><img src="https://github.com/JKorf/CoinEx.Net/blob/master/CoinEx.Net/Icon/icon.png?raw=true"></a>|CoinEx|https://jkorf.github.io/CoinEx.Net/|
|
||||
|<a href="https://github.com/JKorf/FTX.Net"><img src="https://github.com/JKorf/FTX.Net/blob/main/FTX.Net/Icon/icon.png?raw=true"></a>|FTX|https://jkorf.github.io/FTX.Net/|
|
||||
|<a href="https://github.com/JKorf/Huobi.Net"><img src="https://github.com/JKorf/Huobi.Net/blob/master/Huobi.Net/Icon/icon.png?raw=true"></a>|Huobi|https://jkorf.github.io/Huobi.Net/|
|
||||
|<a href="https://github.com/JKorf/Kraken.Net"><img src="https://github.com/JKorf/Kraken.Net/blob/master/Kraken.Net/Icon/icon.png?raw=true"></a>|Kraken|https://jkorf.github.io/Kraken.Net/|
|
||||
|<a href="https://github.com/JKorf/Kucoin.Net"><img src="https://github.com/JKorf/Kucoin.Net/blob/master/Kucoin.Net/Icon/icon.png?raw=true"></a>|Kucoin|https://jkorf.github.io/Kucoin.Net/|
|
||||
|
||||
**Implementations by third parties**
|
||||
These might not be compatible with other libraries, make sure to check the CryptoExchange.Net version.
|
||||
|
||||
||Exchange|
|
||||
|-|-|
|
||||
|<a href="https://github.com/Zaliro/Switcheo.Net"><img src="https://github.com/Zaliro/Switcheo.Net/blob/master/Resources/switcheo-coin.png?raw=true"></a>|Switcheo|
|
||||
|<a href="https://github.com/ridicoulous/LiquidQuoine.Net"><img src="https://github.com/ridicoulous/LiquidQuoine.Net/blob/master/Resources/icon.png?raw=true"></a>|Liquid|
|
||||
|<a href="https://github.com/ridicoulous/Bitmex.Net"><img src="https://github.com/ridicoulous/Bitmex.Net/blob/master/Bitmex.Net/Icon/icon.png?raw=true"></a>|Bitmex|
|
||||
|<a href="https://github.com/intelligences/HitBTC.Net"><img src="https://github.com/intelligences/HitBTC.Net/blob/master/src/HitBTC.Net/Icon/icon.png?raw=true"></a>|HitBTC|
|
||||
|<a href="https://github.com/EricGarnier/LiveCoin.Net"><img src="https://github.com/EricGarnier/LiveCoin.Net/blob/master/LiveCoin.Net/Icon/icon.png?raw=true"></a>|LiveCoin|
|
||||
|<a href="https://github.com/burakoner/OKEx.Net"><img src="https://github.com/burakoner/OKEx.Net/blob/master/Okex.Net/Icon/icon.png?raw=true"></a>|OKEx|
|
||||
|<a href="https://github.com/burakoner/Chiliz.Net"><img src="https://github.com/burakoner/Chiliz.Net/blob/master/Chiliz.Net/Icon/icon.png?raw=true"></a>|Chiliz|
|
||||
|<a href="https://github.com/burakoner/BtcTurk.Net"><img src="https://github.com/burakoner/BtcTurk.Net/blob/master/BtcTurk.Net/Icon/icon.png?raw=true"></a>|BtcTurk|
|
||||
|<a href="https://github.com/burakoner/Thodex.Net"><img src="https://github.com/burakoner/Thodex.Net/blob/master/Thodex.Net/Icon/icon.png?raw=true"></a>|Thodex|
|
||||
|<a href="https://github.com/d-ugarov/Exante.Net"><img src="https://github.com/d-ugarov/Exante.Net/blob/master/Exante.Net/Icon/icon.png?raw=true"></a>|Exante|
|
||||
|<a href="https://github.com/rodrigobelo/wootrade-dotnet"><img src="https://github.com/rodrigobelo/wootrade-dotnet/blob/main/wootrade-dotnet-icon.png?raw=true"></a>|Wootrade|
|
||||
|
||||
## Discord
|
||||
A Discord server is available [here](https://discord.gg/MSpeEtSY8t). Feel free to join for discussion and/or questions around the CryptoExchange.Net and implementation libraries.
|
||||
|
||||
## Donate / Sponsor
|
||||
I develop and maintain this package on my own for free in my spare time. Donations are greatly appreciated. If you prefer to donate any other currency please contact me.
|
||||
|
||||
**Btc**: 12KwZk3r2Y3JZ2uMULcjqqBvXmpDwjhhQS
|
||||
**Eth**: 0x069176ca1a4b1d6e0b7901a6bc0dbf3bb0bf5cc2
|
||||
**Nano**: xrb_1ocs3hbp561ef76eoctjwg85w5ugr8wgimkj8mfhoyqbx4s1pbc74zggw7gs
|
||||
|
||||
Alternatively, sponsor me on Github using [Github Sponsors](https://github.com/sponsors/JKorf)
|
||||
Reference in New Issue
Block a user