1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2025-07-04 05:06:16 +00:00
This commit is contained in:
Jkorf 2022-01-17 13:47:58 +01:00
parent b65669659d
commit e33e7c6775
5 changed files with 60 additions and 56 deletions

View File

@ -23,7 +23,7 @@ With for example an ASP.Net Core or Blazor project the logging can be added to t
Adding `UseSerilog()` in the `CreateHostBuilder` will add the Serilog logging implementation as an ILogger which you can inject into implementations. Adding `UseSerilog()` in the `CreateHostBuilder` will add the Serilog logging implementation as an ILogger which you can inject into implementations.
*Configuring Serilog as ILogger:* *Configuring Serilog as ILogger:*
````C# ```csharp
public static void Main(string[] args) public static void Main(string[] args)
{ {
@ -43,11 +43,11 @@ public static IHostBuilder CreateHostBuilder(string[] args) =>
webBuilder.UseStartup<Startup>(); webBuilder.UseStartup<Startup>();
}); });
```` ```
*Injecting ILogger:* *Injecting ILogger:*
````C# ```csharp
public class BinanceDataProvider public class BinanceDataProvider
{ {
@ -64,7 +64,7 @@ public class BinanceDataProvider
} }
} }
```` ```
</BlockQuote> </BlockQuote>
</Details> </Details>
@ -78,7 +78,7 @@ public class BinanceDataProvider
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: 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:* *Configuring Serilog as ILogger:*
````C# ```csharp
public static void Main(string[] args) public static void Main(string[] args)
{ {
@ -98,11 +98,11 @@ public static IHostBuilder CreateHostBuilder(string[] args) =>
context => new Startup(context.Configuration, LoggerFactory.Create(config => config.AddSerilog()) )); // <- this allows us to use ILoggerFactory in the Startup.cs context => new Startup(context.Configuration, LoggerFactory.Create(config => config.AddSerilog()) )); // <- this allows us to use ILoggerFactory in the Startup.cs
}); });
```` ```
*Injecting ILogger:* *Injecting ILogger:*
````C# ```csharp
public class Startup public class Startup
{ {
@ -127,7 +127,7 @@ public class Startup
} }
} }
```` ```
</BlockQuote> </BlockQuote>
</Details> </Details>
@ -136,7 +136,7 @@ public class Startup
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. 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:* *Configuring Serilog as ILogger:*
````C# ```csharp
var serilogLogger = new LoggerConfiguration() var serilogLogger = new LoggerConfiguration()
.MinimumLevel.Debug() .MinimumLevel.Debug()
.WriteTo.Console() .WriteTo.Console()
@ -145,17 +145,17 @@ var serilogLogger = new LoggerConfiguration()
var loggerFactory = (ILoggerFactory)new LoggerFactory(); var loggerFactory = (ILoggerFactory)new LoggerFactory();
loggerFactory.AddSerilog(serilogLogger); loggerFactory.AddSerilog(serilogLogger);
```` ```
*Injecting ILogger:* *Injecting ILogger:*
````C# ```csharp
var client = new BinanceClient(new BinanceClientOptions var client = new BinanceClient(new BinanceClientOptions
{ {
LogLevel = LogLevel.Trace, LogLevel = LogLevel.Trace,
LogWriters = new List<ILogger> { loggerFactory.CreateLogger("") } LogWriters = new List<ILogger> { loggerFactory.CreateLogger("") }
}); });
```` ```
The `BinanceClient` will now write the logging it produces to the Serilog logger. The `BinanceClient` will now write the logging it produces to the Serilog logger.
@ -165,7 +165,7 @@ To make the CryptoExchange.Net logging write to the Log4Net logge with for examp
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. 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:* *Configuring Log4Net as ILogger:*
````C# ```csharp
public static IHostBuilder CreateHostBuilder(string[] args) => public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args) Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => .ConfigureWebHostDefaults(webBuilder =>
@ -177,10 +177,10 @@ public static IHostBuilder CreateHostBuilder(string[] args) =>
}); });
webBuilder.UseStartup<Startup>(); webBuilder.UseStartup<Startup>();
}); });
```` ```
*Injecting ILogger:* *Injecting ILogger:*
````C# ```csharp
public class BinanceDataProvider public class BinanceDataProvider
{ {
@ -197,7 +197,7 @@ public class BinanceDataProvider
} }
} }
```` ```
If you don't have the Dotnet dependency container available you'll need to provide your own ILogger implementation. See [Custom logger](#custom-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).
@ -210,7 +210,7 @@ With for example an ASP.Net Core or Blazor project the logging can be added to t
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. 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:* *Configuring NLog as ILogger:*
````C# ```csharp
public static IHostBuilder CreateHostBuilder(string[] args) => public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args) Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => .ConfigureWebHostDefaults(webBuilder =>
@ -223,10 +223,10 @@ Adding `UseNLog()` to the `CreateHostBuilder()` method will add the NLog impleme
logging.SetMinimumLevel(LogLevel.Trace); logging.SetMinimumLevel(LogLevel.Trace);
}) })
.UseNLog(); .UseNLog();
```` ```
*Injecting ILogger:* *Injecting ILogger:*
````C# ```csharp
public class BinanceDataProvider public class BinanceDataProvider
{ {
@ -243,7 +243,7 @@ public class BinanceDataProvider
} }
} }
```` ```
If you don't have the Dotnet dependency container available you'll need to provide your own ILogger implementation. See [Custom logger](#custom-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).
@ -251,7 +251,7 @@ If you don't have the Dotnet dependency container available you'll need to provi
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. 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)*: *A simple console logging implementation (note that the ConsoleLogger is already available in the CryptoExchange.Net library)*:
````C# ```csharp
public class ConsoleLogger : ILogger public class ConsoleLogger : ILogger
{ {
@ -266,10 +266,10 @@ public class ConsoleLogger : ILogger
} }
} }
```` ```
*Injecting the console logging implementation:* *Injecting the console logging implementation:*
````C# ```csharp
var client = new BinanceClient(new BinanceClientOptions var client = new BinanceClient(new BinanceClientOptions
{ {
@ -277,7 +277,7 @@ var client = new BinanceClient(new BinanceClientOptions
LogWriters = new List<ILogger> { new ConsoleLogger() } LogWriters = new List<ILogger> { new ConsoleLogger() }
}); });
```` ```
## Provide logging for issues ## 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. 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.
@ -285,15 +285,15 @@ A big debugging tool when opening an issue on Github is providing logging of wha
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. 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. 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* *Enabled output data*
````C# ```csharp
var client = new BinanceClient(new BinanceClientOptions var client = new BinanceClient(new BinanceClientOptions
{ {
OutputOriginalData = true OutputOriginalData = true
}); });
```` ```
*Accessing original data* *Accessing original data*
````C# ```csharp
// Rest request // Rest request
var tickerResult = client.SpotApi.ExchangeData.GetTickersAsync(); var tickerResult = client.SpotApi.ExchangeData.GetTickersAsync();
var originallyRecievedData = tickerResult.OriginalData; var originallyRecievedData = tickerResult.OriginalData;
@ -302,23 +302,23 @@ var originallyRecievedData = tickerResult.OriginalData;
client.SpotStreams.SubscribeToAllTickerUpdatesAsync(update => { client.SpotStreams.SubscribeToAllTickerUpdatesAsync(update => {
var originallyRecievedData = update.OriginalData; var originallyRecievedData = update.OriginalData;
}); });
```` ```
### Trace logging ### Trace logging
Trace logging, which is the most verbose log level, can be enabled in the client options. Trace logging, which is the most verbose log level, can be enabled in the client options.
*Enabled output data* *Enabled output data*
````C# ```csharp
var client = new BinanceClient(new BinanceClientOptions var client = new BinanceClient(new BinanceClientOptions
{ {
LogLevel = LogLevel.Trace 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. 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: 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: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: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: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} 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. When opening an issue, please provide this logging when available.

View File

@ -23,7 +23,7 @@ Socket clients are restructured as `client.[Api]Streams.Method()`:
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 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: 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* *V4*
````C# ```csharp
var binanceClient = new BinanceClient(new BinanceApiClientOptions{ var binanceClient = new BinanceClient(new BinanceApiClientOptions{
LogLevel = LogLevel.Trace, LogLevel = LogLevel.Trace,
RequestTimeout = TimeSpan.FromSeconds(60), RequestTimeout = TimeSpan.FromSeconds(60),
@ -31,10 +31,10 @@ var binanceClient = new BinanceClient(new BinanceApiClientOptions{
BaseAddressUsdtFutures = new ApiCredentials("OTHER API KEY ONLY FOR USD FUTURES", "OTHER API SECRET ONLY FOR USD FUTURES") 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 // No way to set separate credentials for the futures API
}); });
```` ```
*V5* *V5*
````C# ```csharp
var binanceClient = new BinanceClient(new BinanceClientOptions() var binanceClient = new BinanceClient(new BinanceClientOptions()
{ {
// Client options // Client options
@ -49,14 +49,14 @@ var binanceClient = new BinanceClient(new BinanceClientOptions()
ApiCredentials = new ApiCredentials("OTHER API KEY ONLY FOR USD FUTURES", "OTHER API SECRET ONLY FOR USD FUTURES") 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. See [Client options](https://github.com/JKorf/CryptoExchange.Net/wiki/Options) for more details on the specific options.
## IExchangeClient ## 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. 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: This, in combination with the client restructuring, allows for more logically implemented interfaces, see this example:
*V4* *V4*
````C# ```csharp
var spotClients = new [] { var spotClients = new [] {
(IExhangeClient)binanceClient, (IExhangeClient)binanceClient,
(IExchangeClient)bittrexClient, (IExchangeClient)bittrexClient,
@ -64,10 +64,10 @@ var spotClients = new [] {
}; };
// There was no common implementation for futures client // There was no common implementation for futures client
```` ```
*V5* *V5*
````C# ```csharp
var spotClients = new [] { var spotClients = new [] {
binanceClient.SpotApi.ComonSpotClient, binanceClient.SpotApi.ComonSpotClient,
bittrexClient.SpotApi.ComonSpotClient, bittrexClient.SpotApi.ComonSpotClient,
@ -78,18 +78,18 @@ var futuresClients = new [] {
binanceClient.UsdFuturesApi.ComonFuturesClient, binanceClient.UsdFuturesApi.ComonFuturesClient,
kucoinClient.FuturesApi.ComonFuturesClient kucoinClient.FuturesApi.ComonFuturesClient
}; };
```` ```
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 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: 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* *V4*
````C# ```csharp
var kline = await ((IExhangeClient)binanceClient).GetKlinesAysnc(/*params*/); var kline = await ((IExhangeClient)binanceClient).GetKlinesAysnc(/*params*/);
var closePrice = kline.CommonClose; var closePrice = kline.CommonClose;
```` ```
*V5* *V5*
````C# ```csharp
var kline = await binanceClient.SpotApi.ComonSpotClient.GetKlinesAysnc(/*params*/); var kline = await binanceClient.SpotApi.ComonSpotClient.GetKlinesAysnc(/*params*/);
var closePrice = kline.ClosePrice; var closePrice = kline.ClosePrice;
```` ```

View File

@ -8,7 +8,7 @@ nav_order: 3
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. 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* *Set the default options to use for new clients*
````C# ```csharp
BinanceClient.SetDefaultOptions(new BinanceClientOptions BinanceClient.SetDefaultOptions(new BinanceClientOptions
{ {
@ -16,10 +16,10 @@ BinanceClient.SetDefaultOptions(new BinanceClientOptions
ApiCredentials = new ApiCredentials("KEY", "SECRET") ApiCredentials = new ApiCredentials("KEY", "SECRET")
}); });
```` ```
*Set the options to use for a single new client* *Set the options to use for a single new client*
````C# ```csharp
var client = new BinanceClient(new BinanceClientOptions var client = new BinanceClient(new BinanceClientOptions
{ {
@ -27,10 +27,10 @@ var client = new BinanceClient(new BinanceClientOptions
ApiCredentials = new ApiCredentials("KEY", "SECRET") 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: 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:
````C# ```csharp
BinanceClient.SetDefaultOptions(new BinanceClientOptions BinanceClient.SetDefaultOptions(new BinanceClientOptions
{ {
@ -44,7 +44,7 @@ var client = new BinanceClient(new BinanceClientOptions
ApiCredentials = new ApiCredentials("KEY", "SECRET") ApiCredentials = new ApiCredentials("KEY", "SECRET")
}); });
```` ```
The client instance will have the following options: The client instance will have the following options:
`LogLevel = Debug` `LogLevel = Debug`
@ -54,7 +54,7 @@ The client instance will have the following options:
## Api options ## 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)). 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)).
````C# ```csharp
var client = new BinanceClient(new BinanceClientOptions var client = new BinanceClient(new BinanceClientOptions
{ {
@ -67,7 +67,7 @@ var client = new BinanceClient(new BinanceClientOptions
} }
}); });
```` ```
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. 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.

View File

@ -10,7 +10,7 @@ Order book implementations are named as `[ExchangeName][Type]SymbolOrderBook`, f
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 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* *Start an order book and print the top 3 rows*
````C# ```csharp
var book = new BinanceSpotSymbolOrderBook("BTCUSDT"); var book = new BinanceSpotSymbolOrderBook("BTCUSDT");
book.OnStatusChange += (oldState, newState) => Console.WriteLine($"State changed from {oldState} to {newState}"); book.OnStatusChange += (oldState, newState) => Console.WriteLine($"State changed from {oldState} to {newState}");
@ -27,7 +27,7 @@ while(true)
await Task.Delay(500); await Task.Delay(500);
} }
```` ```
### Accessing bids/asks ### Accessing bids/asks
You can access the current Bid/Ask lists using the responding properties: You can access the current Bid/Ask lists using the responding properties:
@ -47,10 +47,10 @@ The following events are available on the symbol order book:
`book.OnOrderBookUpdate`: The book has changed, the arguments contain the changed entries. `book.OnOrderBookUpdate`: The book has changed, the arguments contain the changed entries.
`book.OnBestOffersChanged`: The best offer (best bid, best ask) has changed. `book.OnBestOffersChanged`: The best offer (best bid, best ask) has changed.
````C# ```csharp
book.OnStatusChange += (oldStatus, newStatus) => { Console.WriteLine($"State changed from {oldStatus} to {newStatus}"); }; 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.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}"); }; book.OnBestOffersChanged += (bestOffer) => { Console.WriteLine($"Best offer changed, best bid: {bestOffer.BestBid.Price}, best ask: {bestOffer.BestAsk.Price}"); };
```` ```

4
docs/RateLimiter.md Normal file
View File

@ -0,0 +1,4 @@
---
title: Rate limiting
nav_order: 6
---