diff --git a/CryptoExchange.Net/CryptoExchange.Net.xml b/CryptoExchange.Net/CryptoExchange.Net.xml
index 800ba58..eb9478e 100644
--- a/CryptoExchange.Net/CryptoExchange.Net.xml
+++ b/CryptoExchange.Net/CryptoExchange.Net.xml
@@ -797,6 +797,11 @@
Event when order book was updated. Be careful! It can generate a lot of events at high-liquidity markets
+
+
+ Event when the BestBid or BestAsk changes ie a Pricing Tick
+
+
Timestamp of the last update
@@ -1769,6 +1774,11 @@
Event when the state changes
+
+
+ Event when the BestBid or BestAsk changes ie a Pricing Tick
+
+
Event when order book was updated, containing the changed bids and asks. Be careful! It can generate a lot of events at high-liquidity markets
@@ -2888,5 +2898,148 @@
+
+
+ Specifies that is allowed as an input even if the
+ corresponding type disallows it.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+ Specifies that is disallowed as an input even if the
+ corresponding type allows it.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+ Specifies that a method that will never return under any circumstance.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+ Specifies that the method will not return if the associated
+ parameter is passed the specified value.
+
+
+
+
+ Gets the condition parameter value.
+ Code after the method is considered unreachable by diagnostics if the argument
+ to the associated parameter matches this value.
+
+
+
+
+ Initializes a new instance of the
+ class with the specified parameter value.
+
+
+ The condition parameter value.
+ Code after the method is considered unreachable by diagnostics if the argument
+ to the associated parameter matches this value.
+
+
+
+
+ Specifies that an output may be even if the
+ corresponding type disallows it.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+ Specifies that when a method returns ,
+ the parameter may be even if the corresponding type disallows it.
+
+
+
+
+ Gets the return value condition.
+ If the method returns this value, the associated parameter may be .
+
+
+
+
+ Initializes the attribute with the specified return value condition.
+
+
+ The return value condition.
+ If the method returns this value, the associated parameter may be .
+
+
+
+
+ Specifies that an output is not even if the
+ corresponding type allows it.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+ Specifies that the output will be non- if the
+ named parameter is non-.
+
+
+
+
+ Gets the associated parameter name.
+ The output will be non- if the argument to the
+ parameter specified is non-.
+
+
+
+
+ Initializes the attribute with the associated parameter name.
+
+
+ The associated parameter name.
+ The output will be non- if the argument to the
+ parameter specified is non-.
+
+
+
+
+ Specifies that when a method returns ,
+ the parameter will not be even if the corresponding type allows it.
+
+
+
+
+ Gets the return value condition.
+ If the method returns this value, the associated parameter will not be .
+
+
+
+
+ Initializes the attribute with the specified return value condition.
+
+
+ The return value condition.
+ If the method returns this value, the associated parameter will not be .
+
+
diff --git a/CryptoExchange.Net/Interfaces/ISymbolOrderBook.cs b/CryptoExchange.Net/Interfaces/ISymbolOrderBook.cs
index 1571feb..1800689 100644
--- a/CryptoExchange.Net/Interfaces/ISymbolOrderBook.cs
+++ b/CryptoExchange.Net/Interfaces/ISymbolOrderBook.cs
@@ -33,6 +33,10 @@ namespace CryptoExchange.Net.Interfaces
///
event Action, IEnumerable> OnOrderBookUpdate;
///
+ /// Event when the BestBid or BestAsk changes ie a Pricing Tick
+ ///
+ event Action OnPriceChanged;
+ ///
/// Timestamp of the last update
///
DateTime LastOrderBookUpdate { get; }
diff --git a/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs b/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs
index cc890c8..b33512d 100644
--- a/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs
+++ b/CryptoExchange.Net/OrderBook/SymbolOrderBook.cs
@@ -51,7 +51,7 @@ namespace CryptoExchange.Net.OrderBook
///
/// The status of the order book. Order book is up to date when the status is `Synced`
///
- public OrderBookStatus Status
+ public OrderBookStatus Status
{
get => status;
set
@@ -79,6 +79,12 @@ namespace CryptoExchange.Net.OrderBook
/// Event when the state changes
///
public event Action? OnStatusChange;
+
+ ///
+ /// Event when the BestBid or BestAsk changes ie a Pricing Tick
+ ///
+ public event Action? OnPriceChanged;
+
///
/// Event when order book was updated, containing the changed bids and asks. Be careful! It can generate a lot of events at high-liquidity markets
///
@@ -112,7 +118,7 @@ namespace CryptoExchange.Net.OrderBook
///
/// The list of bids
///
- public IEnumerable Bids
+ public IEnumerable Bids
{
get
{
@@ -136,7 +142,7 @@ namespace CryptoExchange.Net.OrderBook
///
/// The best ask currently in the order book
///
- public ISymbolOrderBookEntry BestAsk
+ public ISymbolOrderBookEntry BestAsk
{
get
{
@@ -286,9 +292,16 @@ namespace CryptoExchange.Net.OrderBook
log.Write(LogVerbosity.Debug, $"{Id} order book {Symbol} data set: {BidCount} bids, {AskCount} asks. #{orderBookSequenceNumber}");
CheckProcessBuffer();
OnOrderBookUpdate?.Invoke(bidList, askList);
+ OnPriceChanged?.Invoke(BestBid, BestAsk);
}
}
+ private bool BestPricingUpdated(ISymbolOrderBookEntry prevBestBid, ISymbolOrderBookEntry prevBestAsk)
+ {
+ return BestBid.Price != prevBestBid.Price || BestBid.Quantity != prevBestBid.Quantity ||
+ BestAsk.Price != prevBestAsk.Price || BestAsk.Quantity != prevBestAsk.Quantity;
+ }
+
///
/// Update the order book using a single id for an update
///
@@ -315,8 +328,12 @@ namespace CryptoExchange.Net.OrderBook
else
{
CheckProcessBuffer();
+ var prevBestBid = BestBid;
+ var prevBestAsk = BestAsk;
ProcessSingleSequenceUpdates(rangeUpdateId, bids, asks);
OnOrderBookUpdate?.Invoke(bids, asks);
+ if (BestPricingUpdated(prevBestBid, prevBestAsk))
+ OnPriceChanged?.Invoke(BestBid, BestAsk);
}
}
}
@@ -349,8 +366,12 @@ namespace CryptoExchange.Net.OrderBook
else
{
CheckProcessBuffer();
+ var prevBestBid = BestBid;
+ var prevBestAsk = BestAsk;
ProcessRangeUpdates(firstUpdateId, lastUpdateId, bids, asks);
OnOrderBookUpdate?.Invoke(bids, asks);
+ if (BestPricingUpdated(prevBestBid, prevBestAsk))
+ OnPriceChanged?.Invoke(BestBid, BestAsk);
}
}
}
@@ -376,8 +397,13 @@ namespace CryptoExchange.Net.OrderBook
else
{
CheckProcessBuffer();
+ var prevBestBid = BestBid;
+ var prevBestAsk = BestAsk;
ProcessUpdates(bids, asks);
OnOrderBookUpdate?.Invoke(bids, asks);
+ if (BestPricingUpdated(prevBestBid, prevBestAsk))
+ OnPriceChanged?.Invoke(BestBid, BestAsk);
+
}
}
}
diff --git a/CryptoExchange.Net/RestClient.cs b/CryptoExchange.Net/RestClient.cs
index 521f9b9..048cf6c 100644
--- a/CryptoExchange.Net/RestClient.cs
+++ b/CryptoExchange.Net/RestClient.cs
@@ -181,7 +181,7 @@ namespace CryptoExchange.Net
}
string? paramString = null;
- if (parameters != null && method == HttpMethod.Post)
+ if (method == HttpMethod.Post)
paramString = " with request body " + request.Content;
log.Write(LogVerbosity.Debug, $"Sending {method}{(signed ? " signed" : "")} request to {request.Uri}{paramString ?? " "}{(apiProxy == null? "": $" via proxy {apiProxy.Host}")}");