From 8d45b4b069604bf5422456c98d0a8023424545cb Mon Sep 17 00:00:00 2001 From: JKorf Date: Thu, 8 Feb 2024 17:51:49 +0100 Subject: [PATCH] docs --- docs/Old/Clients.md | 171 ++++++++++++++++++++++++ docs/Old/FAQ.md | 60 +++++++++ docs/Old/Glossary.md | 28 ++++ docs/Old/Implementation.md | 6 + docs/Old/Interfaces.md | 145 ++++++++++++++++++++ docs/Old/Logging.md | 150 +++++++++++++++++++++ docs/Old/Migration Guide.md | 73 ++++++++++ docs/Old/Options.md | 133 ++++++++++++++++++ docs/Old/Orderbooks.md | 68 ++++++++++ docs/Old/RateLimiter.md | 74 ++++++++++ docs/Old/index.md | 65 +++++++++ docs/assets/images/BinanceInstall.png | Bin 0 -> 7861 bytes docs/assets/images/BitfinexInstall.png | Bin 0 -> 7945 bytes docs/assets/images/BitgetInstall.png | Bin 0 -> 7949 bytes docs/assets/images/BybitInstall.png | Bin 0 -> 8265 bytes docs/assets/images/CoinExInstall.png | Bin 0 -> 8234 bytes docs/assets/images/CoinGeckoInstall.png | Bin 0 -> 7409 bytes docs/assets/images/HuobiInstall.png | Bin 0 -> 7669 bytes docs/assets/images/KrakenInstall.png | Bin 0 -> 7833 bytes docs/assets/images/KucoinInstall.png | Bin 0 -> 7733 bytes docs/assets/images/MexcInstall.png | Bin 0 -> 7755 bytes docs/assets/images/OKXInstall.png | Bin 0 -> 7970 bytes docs/index.html | 148 ++++++++++++++++++-- 23 files changed, 1108 insertions(+), 13 deletions(-) create mode 100644 docs/Old/Clients.md create mode 100644 docs/Old/FAQ.md create mode 100644 docs/Old/Glossary.md create mode 100644 docs/Old/Implementation.md create mode 100644 docs/Old/Interfaces.md create mode 100644 docs/Old/Logging.md create mode 100644 docs/Old/Migration Guide.md create mode 100644 docs/Old/Options.md create mode 100644 docs/Old/Orderbooks.md create mode 100644 docs/Old/RateLimiter.md create mode 100644 docs/Old/index.md create mode 100644 docs/assets/images/BinanceInstall.png create mode 100644 docs/assets/images/BitfinexInstall.png create mode 100644 docs/assets/images/BitgetInstall.png create mode 100644 docs/assets/images/BybitInstall.png create mode 100644 docs/assets/images/CoinExInstall.png create mode 100644 docs/assets/images/CoinGeckoInstall.png create mode 100644 docs/assets/images/HuobiInstall.png create mode 100644 docs/assets/images/KrakenInstall.png create mode 100644 docs/assets/images/KucoinInstall.png create mode 100644 docs/assets/images/MexcInstall.png create mode 100644 docs/assets/images/OKXInstall.png diff --git a/docs/Old/Clients.md b/docs/Old/Clients.md new file mode 100644 index 0000000..a03786b --- /dev/null +++ b/docs/Old/Clients.md @@ -0,0 +1,171 @@ +--- +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 is the rest client, which is typically available via [ExchangeName]RestClient, and a socket client, which is generally named [ExchangeName]SocketClient. For example `BinanceRestClient` 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: + +- [ExchangeName]RestClient + - 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 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 with the following properties: +`RequestHeaders`: The headers send to the server in the request message +`RequestMethod`: The Http method of the request +`RequestUrl`: The url the request was send to +`ResponseLength`: The length in bytes of the response message +`ResponseTime`: The duration between sending the request and receiving the response +`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` +`OriginalData`: Will contain the originally received unparsed data if this has been enabled in the client options +`Data`: Data returned by the server, only available if `Success` == `true` + +When processing the result of a call it should always be checked for success. Not doing so will result in `NullReference` exceptions when the call fails for whatever reason. + +*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, and sometimes also allow request/response communication. +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 always 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 updateData) +{ + // Process updateData +} +``` + +*Lambda* +```csharp +await kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(updateData => +{ + // Process updateData +}); +``` + +All updates are wrapped in a `DataEvent<>` object, which contain the following properties: +`Timestamp`: The timestamp when the data was received (not send!) +`OriginalData`: Will contain the originally received unparsed 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 +`Data`: Contains the received update data. + +*[WARNING] Do not use `using` statements in combination with constructing a `SocketClient` without blocking the thread. 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` object. This should be checked for success the same way as a [rest request](#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. + + diff --git a/docs/Old/FAQ.md b/docs/Old/FAQ.md new file mode 100644 index 0000000..9087c13 --- /dev/null +++ b/docs/Old/FAQ.md @@ -0,0 +1,60 @@ +--- +title: FAQ +nav_order: 12 +--- + +## 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 Environment in the client options. Some known environments should be available in the [Exchange]Environment class. For example: +```csharp +var client = new BinanceRestClient(options => +{ + options.Environment = BinanceEnvironment.Testnet; +}); +``` + +### How are timezones handled / Timestamps are off by xx +Exchange API's treat all timestamps as UTC, both incoming and outgoing. The client libraries do no conversion so be sure to use UTC as well. \ No newline at end of file diff --git a/docs/Old/Glossary.md b/docs/Old/Glossary.md new file mode 100644 index 0000000..f8c38bc --- /dev/null +++ b/docs/Old/Glossary.md @@ -0,0 +1,28 @@ +--- +title: Glossary +nav_order: 11 +--- +## 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 `Bybit.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. \ No newline at end of file diff --git a/docs/Old/Implementation.md b/docs/Old/Implementation.md new file mode 100644 index 0000000..2a4acfd --- /dev/null +++ b/docs/Old/Implementation.md @@ -0,0 +1,6 @@ +--- +title: Creating an implementation +nav_order: 8 +--- + +TODO \ No newline at end of file diff --git a/docs/Old/Interfaces.md b/docs/Old/Interfaces.md new file mode 100644 index 0000000..dc76026 --- /dev/null +++ b/docs/Old/Interfaces.md @@ -0,0 +1,145 @@ +--- +title: Common interfaces +nav_order: 7 +--- + +## 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 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 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>> GetSymbolsAsync(); + +// Get the ticker (24 hour stats) for a symbol +Task> GetTickerAsync(string symbol); + +// Get a list of tickers for all symbols +Task>> GetTickersAsync(); + +// Get a list klines (candlesticks) for a symbol +Task>> GetKlinesAsync(string symbol, TimeSpan timespan, DateTime? startTime = null, DateTime? endTime = null, int? limit = null); + +// Get the order book for a symbol +Task> GetOrderBookAsync(string symbol); + +// Get a list of most recent trades +Task>> GetRecentTradesAsync(string symbol); + +// Get balances +Task>> GetBalancesAsync(string? accountId = null); + +// Place an order +Task> PlaceOrderAsync(string symbol, CommonOrderSide side, CommonOrderType type, decimal quantity, decimal? price = null, string? accountId = null); + +// Get order by order id +Task> GetOrderAsync(string orderId, string? symbol = null); + +// Get the trades for an order +Task>> GetOrderTradesAsync(string orderId, string? symbol = null); + +// Get a list of open orders. Some exchanges require a symbol +Task>> GetOpenOrdersAsync(string? symbol = null); + +// Get a list of closed orders. Some exchanges require a symbol +Task>> GetClosedOrdersAsync(string? symbol = null); + +// Cancel an active order +Task> 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 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 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>> GetSymbolsAsync(); + +// Get the ticker (24 hour stats) for a symbol +Task> GetTickerAsync(string symbol); + +// Get a list of tickers for all symbols +Task>> GetTickersAsync(); + +// Get a list klines (candlesticks) for a symbol +Task>> GetKlinesAsync(string symbol, TimeSpan timespan, DateTime? startTime = null, DateTime? endTime = null, int? limit = null); + +// Get the order book for a symbol +Task> GetOrderBookAsync(string symbol); + +// Get a list of most recent trades +Task>> GetRecentTradesAsync(string symbol); + +// Get balances +Task>> GetBalancesAsync(string? accountId = null); + +// Get current open positions +Task>> GetPositionsAsync(); + +// Place an order +Task> PlaceOrderAsync(string symbol, CommonOrderSide side, CommonOrderType type, decimal quantity, decimal? price = null, int? leverage = null, string? accountId = null); + +// Get order by order id +Task> GetOrderAsync(string orderId, string? symbol = null); + +// Get the trades for an order +Task>> GetOrderTradesAsync(string orderId, string? symbol = null); + +// Get a list of open orders. Some exchanges require a symbol +Task>> GetOpenOrdersAsync(string? symbol = null); + +// Get a list of closed orders. Some exchanges require a symbol +Task>> GetClosedOrdersAsync(string? symbol = null); + +// Cancel an active order +Task> CancelOrderAsync(string orderId, string? symbol = null); +``` \ No newline at end of file diff --git a/docs/Old/Logging.md b/docs/Old/Logging.md new file mode 100644 index 0000000..1f37bf5 --- /dev/null +++ b/docs/Old/Logging.md @@ -0,0 +1,150 @@ +--- +title: Logging +nav_order: 5 +--- + +## Configuring logging +The library offers extensive logging, which depends on the dotnet `Microsoft.Extensions.Logging.ILogger` interface. This should provide ease of use when connecting the library logging to your existing logging implementation. + +*Configure logging to write to the console* +```csharp +IServiceCollection services = new ServiceCollection(); +services + .AddBinance() + .AddLogging(options => + { + options.SetMinimumLevel(LogLevel.Trace); + options.AddConsole(); + }); +``` + +The library provides a TraceLogger ILogger implementation which writes log messages using `Trace.WriteLine`, but any other logging library can be used. + +*Configure logging to use trace logging* +```csharp +IServiceCollection serviceCollection = new ServiceCollection(); +serviceCollection.AddBinance() + .AddLogging(options => + { + options.SetMinimumLevel(LogLevel.Trace); + options.AddProvider(new TraceLoggerProvider()); + }); +``` + +### Using an external logging library and dotnet DI + +With for example an ASP.Net Core or Blazor project the logging can be configured by the dependency container, which can then automatically be used be the clients. +The next example shows how to use Serilog. This assumes the `Serilog.AspNetCore` package (https://github.com/serilog/serilog-aspnetcore) is installed. + +*Using serilog:* +```csharp +using Binance.Net; +using Serilog; + +Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .WriteTo.Console() + .CreateLogger(); + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddBinance(); +builder.Host.UseSerilog(); +var app = builder.Build(); + +// startup + +app.Run(); +``` + +### Logging without dotnet DI +If you don't have a dependency injection service available because you are for example working on a simple console application you have 2 options for logging. + +#### Create a ServiceCollection manually and get the client from the service provider + +```csharp +IServiceCollection serviceCollection = new ServiceCollection(); +serviceCollection.AddBinance(); +serviceCollection.AddLogging(options => +{ + options.SetMinimumLevel(LogLevel.Trace); + options.AddConsole(); +}).BuildServiceProvider(); + +var client = serviceCollection.GetRequiredService(); + +``` + +#### Create a LoggerFactory manually + +```csharp +var logFactory = new LoggerFactory(); +logFactory.AddProvider(new ConsoleLoggerProvider()); +var binanceClient = new BinanceRestClient(new HttpClient(), logFactory, options => { }); +``` + +## Providing 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(options => +{ + options.OutputOriginalData = true +}); +``` + +*Accessing original data* +```csharp +// Rest request +var tickerResult = await client.SpotApi.ExchangeData.GetTickersAsync(); +var originallyReceivedData = tickerResult.OriginalData; + +// Socket update +await client.SpotStreams.SubscribeToAllTickerUpdatesAsync(update => { + var originallyRecievedData = update.OriginalData; +}); +``` + +### Trace logging +Trace logging, which is the most verbose log level, will show everything the library does and includes the data that was send and received. +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. + +### Example of serilog config and minimal API's + +```csharp +using Binance.Net; +using Binance.Net.Interfaces.Clients; +using Serilog; + +Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .WriteTo.Console() + .CreateLogger(); + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddBinance(); +builder.Host.UseSerilog(); +var app = builder.Build(); + +// startup + +app.Urls.Add("http://localhost:3000"); + +app.MapGet("/price/{symbol}", async (string symbol) => +{ + var client = app.Services.GetRequiredService(); + var result = await client.SpotApi.ExchangeData.GetPriceAsync(symbol); + return result.Data.Price; +}); + +app.Run(); +``` \ No newline at end of file diff --git a/docs/Old/Migration Guide.md b/docs/Old/Migration Guide.md new file mode 100644 index 0000000..4b3b51b --- /dev/null +++ b/docs/Old/Migration Guide.md @@ -0,0 +1,73 @@ +--- +title: Migrate v5 to v6 +nav_order: 10 +--- + +## Migrating from version 5 to version 6 +When updating your code from version 5 implementations to version 6 implementations you will encounter some breaking changes. Here is the general outline of 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 V5 version and some clients a V6. When updating all libraries should be migrated* + +## Rest client name +To be more clear about different clients for different API's the rest client implementations have been renamed from [Exchange]Client to [Exchange]RestClient. This makes it more clear that it only implements the Rest API and the [Exchange]SocketClient the Socket API. + +## Options +Option parameters have been changed to a callback instead of an options object. This makes processing of the options easier and is in line with how dotnet handles option configurations. + +**BaseAddress** +The BaseAddress option has been replaced by the Environment option. The Environment options allows for selection/switching between different trade environments more easily. For example the environment can be switched between a testnet and live by changing only a single line instead of having to change all BaseAddresses. + +**LogLevel/LogWriters** +The logging options have been removed and are now inherited by the DI configuration. See [Logging](https://jkorf.github.io/CryptoExchange.Net/Logging.html) for more info. + +**HttpClient** +The HttpClient will now be received by the DI container instead of having to pass it manually. When not using DI it is still possible to provide a HttpClient, but it is now located in the client constructor. + +*V5* +```csharp +var client = new BinanceClient(new BinanceClientOptions(){ + OutputOriginalData = true, + SpotApiOptions = new RestApiOptions { + BaseAddress = BinanceApiAddresses.TestNet.RestClientAddress + } + // Other options +}); +``` + +*V6* +```csharp +var client = new BinanceClient(options => { + options.OutputOriginalData = true; + options.Environment = BinanceEnvironment.Testnet; + // Other options +}); +``` + +## Socket api name +As socket API's are often more than just streams to subscribe to the name of the socket API clients have been changed from [Topic]Streams to [Topic]Api which matches the rest API client names. For example `SpotStreams` has become `SpotApi`, so `binanceSocketClient.UsdFuturesStreams.SubscribeXXX` has become `binanceSocketClient.UsdFuturesApi.SubscribeXXX`. + +## Add[Exchange] extension method +With the change in options providing the DI extension methods for the IServiceCollection have also been changed slightly. Also the socket clients will now be registered as Singleton by default instead of Scoped. + +*V5* +```csharp +builder.Services.AddKucoin((restOpts, socketOpts) => +{ + restOpts.LogLevel = LogLevel.Debug; + restOpts.ApiCredentials = new KucoinApiCredentials("KEY", "SECRET", "PASS"); + socketOpts.LogLevel = LogLevel.Debug; + socketOpts.ApiCredentials = new KucoinApiCredentials("KEY", "SECRET", "PASS"); +}, ServiceLifetime.Singleton); +``` + +*V6* +```csharp +builder.Services.AddKucoin((restOpts) => +{ + restOpts.ApiCredentials = new KucoinApiCredentials("KEY", "SECRET", "PASS"); +}, +(socketOpts) => +{ + socketOpts.ApiCredentials = new KucoinApiCredentials("KEY", "SECRET", "PASS"); +}); +``` \ No newline at end of file diff --git a/docs/Old/Options.md b/docs/Old/Options.md new file mode 100644 index 0000000..e44ab9f --- /dev/null +++ b/docs/Old/Options.md @@ -0,0 +1,133 @@ +--- +title: Client options +nav_order: 4 +--- + +## 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(options => +{ + options.OutputOriginalData = true; + options.ApiCredentials = new ApiCredentials("KEY", "SECRET"); + // Override the api credentials for the Spot API + options.SpotOptions.ApiCredentials = new ApiCredentials("SPOT-KEY", "SPOT-SECRET"); +}); + +``` + +*Set the options to use for a single new client* +```csharp + +var client = new BinanceClient(options => +{ + options.OutputOriginalData = true; + options.ApiCredentials = new ApiCredentials("KEY", "SECRET"); + // Override the api credentials for the Spot API + options.SpotOptions.ApiCredentials = new ApiCredentials("SPOT-KEY", "SPOT-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(options => +{ + options.OutputOriginalData = true; +}); + +var client = new BinanceClient(options => +{ + options.OutputOriginalData = false; +}); + +``` + +The client instance will have the following options: +`OutputOriginalData = false` + +## 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://jkorf.github.io/CryptoExchange.Net/Clients.html)). + +```csharp + +var client = new BinanceRestClient(options => +{ + options.ApiCredentials = new ApiCredentials("GENERAL-KEY", "GENERAL-SECRET"), + options.SpotOptions.ApiCredentials = new ApiCredentials("SPOT-KEY", "SPOT-SECRET"); +}); + +``` + +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| +|------|-----------|-------| +|`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.OriginalData` property, for `SocketClient` subscriptions the data will be available in the `DataEvent.OriginalData` property when receiving an update. | `false` +|`ApiCredentials`| The API credentials to use for accessing protected endpoints. Can either be an API key/secret using Hmac encryption or an API key/private key using RSA encryption for exchanges that support that. See [Credentials](#credentials). 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` +|`RequestTimeout`|The timeout for client requests to the server| `TimeSpan.FromSeconds(20)` + +**Rest client options (extension of base client options)** + +|Option|Description|Default| +|------|-----------|-------| +|`AutoTimestamp`|Whether or not the library should attempt to sync the time between the client and server. If the time between server and client is not in sync authentication errors might occur. This option should be disabled when the client time sure is to be in sync.|`true`| +|`TimestampRecalculationInterval`|The interval of how often the time synchronization between client and server should be executed| `TimeSpan.FromHours(1)` +|`Environment`|The environment the library should talk to. Some exchanges have testnet/sandbox environments which can be used instead of the real exchange. The environment option can be used to switch between different trade environments|`Live environment` + +**Socket client options (extension of base client options)** + +|Option|Description|Default| +|------|-----------|-------| +|`AutoReconnect`|Whether or not the socket should attempt to 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 +|`MaxConcurrentResubscriptionsPerSocket`|The maximum number of concurrent resubscriptions per socket when resubscribing after reconnecting|5 +|`MaxSocketConnections`|The maximum amount of distinct socket connections|`null` +|`DelayAfterConnect`|The time to wait before sending messages after connecting to the server.|`TimeSpan.Zero` +|`Environment`|The environment the library should talk to. Some exchanges have testnet/sandbox environments which can be used instead of the real exchange. The environment option can be used to switch between different trade environments|`Live environment` + +**Base Api client options** + +|Option|Description|Default| +|------|-----------|-------| +|`ApiCredentials`|The API credentials to use for accessing protected endpoints. Can either be an API key/secret using Hmac encryption or an API key/private key using RSA encryption for exchanges that support that. See [Credentials](#credentials). Setting ApiCredentials on the Api Options will override any default ApiCredentials on the `Base client options`| `null` +|`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.OriginalData` property, for `SocketClient` subscriptions the data will be available in the `DataEvent.OriginalData` property when receiving an update.|False + +**Options for Rest Api Client (extension of base api client options)** + +|Option|Description|Default| +|------|-----------|-------| +|`RateLimiters`|A list of `IRateLimiter`s to use.|`new List()`| +|`RateLimitingBehaviour`|What should happen when a rate limit is reached.|`RateLimitingBehaviour.Wait`| +|`AutoTimestamp`|Whether or not the library should attempt to sync the time between the client and server. If the time between server and client is not in sync authentication errors might occur. This option should be disabled when the client time is sure to be in sync. Overrides the Rest client options `AutoTimestamp` option if set|`null`| +|`TimestampRecalculationInterval`|The interval of how often the time synchronization between client and server should be executed. Overrides the Rest client options `TimestampRecalculationInterval` option if set| `TimeSpan.FromHours(1)` + +**Options for Socket Api Client (extension of base api client options)** + +|Option|Description|Default| +|------|-----------|-------| +|`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. Overrides the Socket client options `SocketNoDataTimeout` option if set | `default(TimeSpan)` (no timeout) +|`MaxSocketConnections`|The maximum amount of distinct socket connections. Overrides the Socket client options `MaxSocketConnections` option if set |`null` + +## Credentials +Credentials are supported in 3 formats in the base library: + +|Type|Description|Example| +|----|-----------|-------| +|`Hmac`|An API key + secret combination. The API key is send with the request and the secret is used to sign requests. This is the default authentication method on all exchanges. |`options.ApiCredentials = new ApiCredentials("51231f76e-9c503548-8fabs3f-rfgf12mkl3", "556be32-d563ba53-faa2dfd-b3n5c", CredentialType.Hmac);`| +|`RsaPem`|An API key + a public and private key pair generated by the user. The public key is shared with the exchange, while the private key is used to sign requests. This CredentialType expects the private key to be in .pem format and is only supported in .netstandard2.1 due to limitations of the framework|`options.ApiCredentials = new ApiCredentials("432vpV8daAaXAF4Qg", ""-----BEGIN PRIVATE KEY-----[PRIVATEKEY]-----END PRIVATE KEY-----", CredentialType.RsaPem);`| +|`RsaXml`|An API key + a public and private key pair generated by the user. The public key is shared with the exchange, while the private key is used to sign requests. This CredentialType expects the private key to be in xml format and is supported in .netstandard2.0 and .netstandard2.1, but it might mean the private key needs to be converted from the original format to xml|`options.ApiCredentials = new ApiCredentials("432vpV8daAaXAF4Qg", "[PRIVATEKEY]", CredentialType.RsaXml);`| \ No newline at end of file diff --git a/docs/Old/Orderbooks.md b/docs/Old/Orderbooks.md new file mode 100644 index 0000000..a529bc9 --- /dev/null +++ b/docs/Old/Orderbooks.md @@ -0,0 +1,68 @@ +--- +title: Order books +nav_order: 6 +--- + +## Locally synced order book +Each exchange 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 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`. When the order book has been started and the state changes from `Synced` to `Reconnecting` the book will automatically reconnect and resync itself. + +*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.Clear(); + 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}"); }; + +``` + +### Order book factory + Each exchange implementation also provides an order book factory for creating ISymbolOrderBook instances. The naming convention for the factory is `[Exchange]OrderBookFactory`, for example `BinanceOrderBookFactory`. This type will be automatically added when using DI and can be used to facilitate easier testing. + + *Creating an order book using the order book factory* + ```csharp +var factory = services.GetRequiredService(); +var book = factory.CreateSpot("ETH-USDT"); +var startResult = await book.StartAsync(); + ``` \ No newline at end of file diff --git a/docs/Old/RateLimiter.md b/docs/Old/RateLimiter.md new file mode 100644 index 0000000..7f7f591 --- /dev/null +++ b/docs/Old/RateLimiter.md @@ -0,0 +1,74 @@ +--- +title: Rate limiting +nav_order: 9 +--- + +## 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 + { + 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. \ No newline at end of file diff --git a/docs/Old/index.md b/docs/Old/index.md new file mode 100644 index 0000000..4765f37 --- /dev/null +++ b/docs/Old/index.md @@ -0,0 +1,65 @@ +--- +title: Home +nav_order: 1 +--- + +[![.NET](https://github.com/JKorf/CryptoExchange.Net/actions/workflows/dotnet.yml/badge.svg?branch=master)](https://github.com/JKorf/CryptoExchange.Net/actions/workflows/dotnet.yml) [![Nuget version](https://img.shields.io/nuget/v/CryptoExchange.Net.svg)](https://www.nuget.org/packages/CryptoExchange.Net) [![Nuget downloads](https://img.shields.io/nuget/dt/CryptoExchange.Net.svg)](https://www.nuget.org/packages/CryptoExchange.Net) + +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| +|-|-|-| +||Binance|https://jkorf.github.io/Binance.Net/| +||Bitfinex|https://jkorf.github.io/Bitfinex.Net/| +||Bitget|https://jkorf.github.io/Bitget.Net/| +||Bittrex|https://jkorf.github.io/Bittrex.Net/| +||Bybit|https://jkorf.github.io/Bybit.Net/| +||CoinEx|https://jkorf.github.io/CoinEx.Net/| +||Huobi|https://jkorf.github.io/Huobi.Net/| +||Kraken|https://jkorf.github.io/Kraken.Net/| +||Kucoin|https://jkorf.github.io/Kucoin.Net/| +||OKX|https://jkorf.github.io/OKX.Net/| + +**Implementations by third parties** +These might not be compatible with other libraries, make sure to check the CryptoExchange.Net version. + +||Exchange| +|-|-| +||Switcheo| +||Liquid| +||Bitmex| +||HitBTC| +||LiveCoin| +||Chiliz| +||BtcTurk| +||Thodex| +||Exante| +||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. + +## Support the project +I develop and maintain this package on my own for free in my spare time, any support is greatly appreciated. + +### Referral link +Use one of the following following referral links to signup to a new exchange to pay a small percentage of the trading fees you pay to support the project instead of paying them straight to the exchange. This doesn't cost you a thing! +[Binance](https://accounts.binance.com/en/register?ref=10153680) +[Bitfinex](https://www.bitfinex.com/sign-up?refcode=kCCe-CNBO) +[Bittrex](https://bittrex.com/discover/join?referralCode=TST-DJM-CSX) +[Bybit](https://partner.bybit.com/b/jkorf) +[CoinEx](https://www.coinex.com/register?refer_code=hd6gn) +[Huobi](https://www.huobi.com/en-us/v/register/double-invite/?inviter_id=11343840&invite_code=fxp93) +[Kucoin](https://www.kucoin.com/ucenter/signup?rcode=RguMux) + +### Donate +Make a one time donation in a crypto currency of your choice. If you prefer to donate a currency not listed here please contact me. + +**Btc**: bc1qz0jv0my7fc60rxeupr23e75x95qmlq6489n8gh +**Eth**: 0x8E21C4d955975cB645589745ac0c46ECA8FAE504 + +### Sponsor +Alternatively, sponsor me on Github using [Github Sponsors](https://github.com/sponsors/JKorf). \ No newline at end of file diff --git a/docs/assets/images/BinanceInstall.png b/docs/assets/images/BinanceInstall.png new file mode 100644 index 0000000000000000000000000000000000000000..15e99d0d397269252045e8190e75e7cf95017d80 GIT binary patch literal 7861 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 N<)oFRO5T6`{$Ks|I0FCx literal 0 HcmV?d00001 diff --git a/docs/assets/images/BitfinexInstall.png b/docs/assets/images/BitfinexInstall.png new file mode 100644 index 0000000000000000000000000000000000000000..6dffa0fb4c1c6e674ab1e885b0fcebe8dd01be85 GIT binary patch literal 7945 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 literal 0 HcmV?d00001 diff --git a/docs/assets/images/BitgetInstall.png b/docs/assets/images/BitgetInstall.png new file mode 100644 index 0000000000000000000000000000000000000000..b8515a5e05dec294ed7e9f7dfbfe5b2f7864c9ea GIT binary patch literal 7949 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 literal 0 HcmV?d00001 diff --git a/docs/assets/images/BybitInstall.png b/docs/assets/images/BybitInstall.png new file mode 100644 index 0000000000000000000000000000000000000000..eca82e993874391b4522eb6724d9ddcfe6347181 GIT binary patch literal 8265 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⪚uNvjvfn(BRPJQrxC@u>lP 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

J43A3HQ&i>5AY(akbiul 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 s^xp@)|Hjn+O8%E#3jg0QxcT>ZZLNjC6!5dZ)H literal 0 HcmV?d00001 diff --git a/docs/assets/images/KrakenInstall.png b/docs/assets/images/KrakenInstall.png new file mode 100644 index 0000000000000000000000000000000000000000..a5ea718140f67265c22e0a696d3105a9218037ff GIT binary patch literal 7833 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 K$yB_1ANXI+?eJy* literal 0 HcmV?d00001 diff --git a/docs/assets/images/OKXInstall.png b/docs/assets/images/OKXInstall.png new file mode 100644 index 0000000000000000000000000000000000000000..e1e967109996b52f3be81ea69a496ecad4ebb441 GIT binary patch literal 7970 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 IN^ipd3)53{qW}N^ literal 0 HcmV?d00001 diff --git a/docs/index.html b/docs/index.html index c85b755..a8f7a5c 100644 --- a/docs/index.html +++ b/docs/index.html @@ -81,12 +81,18 @@