diff --git a/CryptoExchange.Net/CryptoExchange.Net.xml b/CryptoExchange.Net/CryptoExchange.Net.xml index 4a27286..0a2f54e 100644 --- a/CryptoExchange.Net/CryptoExchange.Net.xml +++ b/CryptoExchange.Net/CryptoExchange.Net.xml @@ -1574,6 +1574,16 @@ Event when the state changes + + + Event when orderbook was updated. Be careful! It can generate a lot of events at high-liquidity markets + + + + + Should be useful for low-liquidity order-books to monitor market activity + + The number of asks in the book diff --git a/CryptoExchange.Net/Objects/Options.cs b/CryptoExchange.Net/Objects/Options.cs index 525f1c8..22c3729 100644 --- a/CryptoExchange.Net/Objects/Options.cs +++ b/CryptoExchange.Net/Objects/Options.cs @@ -26,8 +26,8 @@ namespace CryptoExchange.Net.Objects /// /// Base for order book options /// - public class OrderBookOptions: BaseOptions - { + public class OrderBookOptions : BaseOptions + { /// /// The name of the order book implementation /// @@ -43,7 +43,7 @@ namespace CryptoExchange.Net.Objects /// The name of the order book implementation /// Whether each update should have a consecutive id number. Used to identify and reconnect when numbers are skipped. public OrderBookOptions(string name, bool sequencesAreConsecutive) - { + { OrderBookName = name; SequenceNumbersAreConsecutive = sequencesAreConsecutive; } @@ -52,7 +52,7 @@ namespace CryptoExchange.Net.Objects /// /// Base client options /// - public class ClientOptions: BaseOptions + public class ClientOptions : BaseOptions { /// @@ -74,7 +74,7 @@ namespace CryptoExchange.Net.Objects /// /// Base for rest client options /// - public class RestClientOptions: ClientOptions + public class RestClientOptions : ClientOptions { /// /// List of rate limiters to use @@ -96,7 +96,7 @@ namespace CryptoExchange.Net.Objects /// /// /// - public T Copy() where T:RestClientOptions, new() + public T Copy() where T : RestClientOptions, new() { var copy = new T { @@ -119,7 +119,7 @@ namespace CryptoExchange.Net.Objects /// /// Base for socket client options /// - public class SocketClientOptions: ClientOptions + public class SocketClientOptions : ClientOptions { /// /// Whether or not the socket should automatically reconnect when losing connection diff --git a/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs b/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs index e6c2e29..d942ed9 100644 --- a/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs +++ b/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs @@ -13,7 +13,7 @@ namespace CryptoExchange.Net.OrderBook /// /// Base for order book implementations /// - public abstract class SymbolOrderBook: IDisposable + public abstract class SymbolOrderBook : IDisposable { /// /// The process buffer, used while syncing @@ -27,6 +27,7 @@ namespace CryptoExchange.Net.OrderBook /// /// The bid list /// + protected SortedList bids; private OrderBookStatus status; private UpdateSubscription subscription; @@ -70,6 +71,14 @@ namespace CryptoExchange.Net.OrderBook /// Event when the state changes /// public event Action OnStatusChange; + /// + /// Event when orderbook was updated. Be careful! It can generate a lot of events at high-liquidity markets + /// + public event Action OnOrderBookUpdate; + /// + /// Should be useful for low-liquidity order-books to monitor market activity + /// + public DateTime LastOrderBookUpdate; /// /// The number of asks in the book @@ -163,7 +172,7 @@ namespace CryptoExchange.Net.OrderBook { Status = OrderBookStatus.Connecting; var startResult = await DoStart().ConfigureAwait(false); - if(!startResult.Success) + if (!startResult.Success) return new CallResult(false, startResult.Error); subscription = startResult.Data; @@ -231,7 +240,7 @@ namespace CryptoExchange.Net.OrderBook /// /// protected abstract Task> DoResync(); - + /// /// Set the initial data for the order book /// @@ -246,7 +255,7 @@ namespace CryptoExchange.Net.OrderBook return; asks.Clear(); - foreach(var ask in askList) + foreach (var ask in askList) asks.Add(ask.Price, new OrderBookEntry(ask.Price, ask.Quantity)); bids.Clear(); foreach (var bid in bidList) @@ -259,6 +268,8 @@ namespace CryptoExchange.Net.OrderBook CheckProcessBuffer(); bookSet = true; + LastOrderBookUpdate = DateTime.UtcNow; + OnOrderBookUpdate?.Invoke(); log.Write(LogVerbosity.Debug, $"{id} order book {Symbol} data set: {BidCount} bids, {AskCount} asks"); } } @@ -295,10 +306,12 @@ namespace CryptoExchange.Net.OrderBook } else { - foreach(var entry in entries) + foreach (var entry in entries) ProcessUpdate(entry.Type, entry.Entry); LastSequenceNumber = lastSequenceNumber; CheckProcessBuffer(); + LastOrderBookUpdate = DateTime.UtcNow; + OnOrderBookUpdate?.Invoke(); log.Write(LogVerbosity.Debug, $"{id} order book {Symbol} update: {entries.Count} entries processed"); } } @@ -311,7 +324,7 @@ namespace CryptoExchange.Net.OrderBook { foreach (var bufferEntry in processBuffer.OrderBy(b => b.FirstSequence).ToList()) { - if(bufferEntry.LastSequence < LastSequenceNumber) + if (bufferEntry.LastSequence < LastSequenceNumber) { processBuffer.Remove(bufferEntry); continue; @@ -320,7 +333,7 @@ namespace CryptoExchange.Net.OrderBook if (bufferEntry.FirstSequence > LastSequenceNumber + 1) break; - foreach(var entry in bufferEntry.Entries) + foreach (var entry in bufferEntry.Entries) ProcessUpdate(entry.Type, entry.Entry); processBuffer.Remove(bufferEntry); LastSequenceNumber = bufferEntry.LastSequence;