1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2025-06-09 00:46:19 +00:00

Cleaned up order book

This commit is contained in:
Jan Korf 2019-10-21 21:44:51 +02:00
parent 964403d750
commit 3ba0507a79
7 changed files with 55 additions and 137 deletions

View File

@ -538,6 +538,13 @@
<param name="value">The value of the object</param> <param name="value">The value of the object</param>
<param name="argumentName">Name of the parameter</param> <param name="argumentName">Name of the parameter</param>
</member> </member>
<member name="M:CryptoExchange.Net.ExtensionMethods.ValidateNotNull``1(System.Collections.Generic.IEnumerable{``0},System.String)">
<summary>
Validates a list is not null or empty
</summary>
<param name="value">The value of the object</param>
<param name="argumentName">Name of the parameter</param>
</member>
<member name="T:CryptoExchange.Net.Interfaces.IRateLimiter"> <member name="T:CryptoExchange.Net.Interfaces.IRateLimiter">
<summary> <summary>
Rate limiter interface Rate limiter interface
@ -1637,28 +1644,6 @@
<member name="M:CryptoExchange.Net.Objects.SocketClientOptions.ToString"> <member name="M:CryptoExchange.Net.Objects.SocketClientOptions.ToString">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="T:CryptoExchange.Net.OrderBook.OrderBookEntry">
<summary>
Order book entry
</summary>
</member>
<member name="P:CryptoExchange.Net.OrderBook.OrderBookEntry.Quantity">
<summary>
Quantity of the entry
</summary>
</member>
<member name="P:CryptoExchange.Net.OrderBook.OrderBookEntry.Price">
<summary>
Price of the entry
</summary>
</member>
<member name="M:CryptoExchange.Net.OrderBook.OrderBookEntry.#ctor(System.Decimal,System.Decimal)">
<summary>
ctor
</summary>
<param name="price"></param>
<param name="quantity"></param>
</member>
<member name="T:CryptoExchange.Net.OrderBook.ProcessBufferEntry"> <member name="T:CryptoExchange.Net.OrderBook.ProcessBufferEntry">
<summary> <summary>
Buffer entry for order book Buffer entry for order book
@ -1674,38 +1659,16 @@
The last sequence number of the entries The last sequence number of the entries
</summary> </summary>
</member> </member>
<member name="P:CryptoExchange.Net.OrderBook.ProcessBufferEntry.Entries"> <member name="P:CryptoExchange.Net.OrderBook.ProcessBufferEntry.Asks">
<summary> <summary>
List of entries List of asks
</summary> </summary>
</member> </member>
<member name="M:CryptoExchange.Net.OrderBook.ProcessBufferEntry.#ctor"> <member name="P:CryptoExchange.Net.OrderBook.ProcessBufferEntry.Bids">
<summary> <summary>
ctor List of bids
</summary> </summary>
</member> </member>
<member name="T:CryptoExchange.Net.OrderBook.ProcessEntry">
<summary>
Process entry for order book
</summary>
</member>
<member name="P:CryptoExchange.Net.OrderBook.ProcessEntry.Entry">
<summary>
The entry
</summary>
</member>
<member name="P:CryptoExchange.Net.OrderBook.ProcessEntry.Type">
<summary>
The type
</summary>
</member>
<member name="M:CryptoExchange.Net.OrderBook.ProcessEntry.#ctor(CryptoExchange.Net.Objects.OrderBookEntryType,CryptoExchange.Net.Interfaces.ISymbolOrderBookEntry)">
<summary>
ctor
</summary>
<param name="type"></param>
<param name="entry"></param>
</member>
<member name="T:CryptoExchange.Net.OrderBook.SymbolOrderBook"> <member name="T:CryptoExchange.Net.OrderBook.SymbolOrderBook">
<summary> <summary>
Base for order book implementations Base for order book implementations
@ -1758,7 +1721,7 @@
</member> </member>
<member name="E:CryptoExchange.Net.OrderBook.SymbolOrderBook.OnOrderBookUpdate"> <member name="E:CryptoExchange.Net.OrderBook.SymbolOrderBook.OnOrderBookUpdate">
<summary> <summary>
Event when order book was updated. Be careful! It can generate a lot of events at high-liquidity markets 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
</summary> </summary>
</member> </member>
<member name="P:CryptoExchange.Net.OrderBook.SymbolOrderBook.LastOrderBookUpdate"> <member name="P:CryptoExchange.Net.OrderBook.SymbolOrderBook.LastOrderBookUpdate">
@ -1852,13 +1815,14 @@
<param name="askList">List of asks</param> <param name="askList">List of asks</param>
<param name="bidList">List of bids</param> <param name="bidList">List of bids</param>
</member> </member>
<member name="M:CryptoExchange.Net.OrderBook.SymbolOrderBook.UpdateOrderBook(System.Int64,System.Int64,System.Collections.Generic.List{CryptoExchange.Net.OrderBook.ProcessEntry})"> <member name="M:CryptoExchange.Net.OrderBook.SymbolOrderBook.UpdateOrderBook(System.Int64,System.Int64,System.Collections.Generic.IEnumerable{CryptoExchange.Net.Interfaces.ISymbolOrderBookEntry},System.Collections.Generic.IEnumerable{CryptoExchange.Net.Interfaces.ISymbolOrderBookEntry})">
<summary> <summary>
Update the order book with entries Update the order book with entries
</summary> </summary>
<param name="firstSequenceNumber">First sequence number</param> <param name="firstSequenceNumber">First sequence number</param>
<param name="lastSequenceNumber">Last sequence number</param> <param name="lastSequenceNumber">Last sequence number</param>
<param name="entries">List of entries</param> <param name="bids">List of bids</param>
<param name="asks">List of asks</param>
</member> </member>
<member name="M:CryptoExchange.Net.OrderBook.SymbolOrderBook.CheckProcessBuffer"> <member name="M:CryptoExchange.Net.OrderBook.SymbolOrderBook.CheckProcessBuffer">
<summary> <summary>

View File

@ -262,6 +262,17 @@ namespace CryptoExchange.Net
if (value == null) if (value == null)
throw new ArgumentException($"No value provided for parameter {argumentName}"); throw new ArgumentException($"No value provided for parameter {argumentName}");
} }
/// <summary>
/// Validates a list is not null or empty
/// </summary>
/// <param name="value">The value of the object</param>
/// <param name="argumentName">Name of the parameter</param>
public static void ValidateNotNull<T>(this IEnumerable<T> value, string argumentName)
{
if (value == null || !value.Any())
throw new ArgumentException($"No values provided for parameter {argumentName}");
}
} }
} }

View File

@ -31,7 +31,7 @@ namespace CryptoExchange.Net.Interfaces
/// <summary> /// <summary>
/// Event when order book was updated. Be careful! It can generate a lot of events at high-liquidity markets /// Event when order book was updated. Be careful! It can generate a lot of events at high-liquidity markets
/// </summary> /// </summary>
event Action OnOrderBookUpdate; event Action<IEnumerable<ISymbolOrderBookEntry>, IEnumerable<ISymbolOrderBookEntry>> OnOrderBookUpdate;
/// <summary> /// <summary>
/// Timestamp of the last update /// Timestamp of the last update
/// </summary> /// </summary>

View File

@ -1,30 +0,0 @@
using CryptoExchange.Net.Interfaces;
namespace CryptoExchange.Net.OrderBook
{
/// <summary>
/// Order book entry
/// </summary>
public class OrderBookEntry : ISymbolOrderBookEntry
{
/// <summary>
/// Quantity of the entry
/// </summary>
public decimal Quantity { get; set; }
/// <summary>
/// Price of the entry
/// </summary>
public decimal Price { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="price"></param>
/// <param name="quantity"></param>
public OrderBookEntry(decimal price, decimal quantity)
{
Quantity = quantity;
Price = price;
}
}
}

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using CryptoExchange.Net.Interfaces;
using System.Collections.Generic;
namespace CryptoExchange.Net.OrderBook namespace CryptoExchange.Net.OrderBook
{ {
@ -16,16 +17,12 @@ namespace CryptoExchange.Net.OrderBook
/// </summary> /// </summary>
public long LastSequence { get; set; } public long LastSequence { get; set; }
/// <summary> /// <summary>
/// List of entries /// List of asks
/// </summary> /// </summary>
public List<ProcessEntry> Entries { get; set; } public IEnumerable<ISymbolOrderBookEntry> Asks { get; set; } = new List<ISymbolOrderBookEntry>();
/// <summary> /// <summary>
/// ctor /// List of bids
/// </summary> /// </summary>
public ProcessBufferEntry() public IEnumerable<ISymbolOrderBookEntry> Bids { get; set; } = new List<ISymbolOrderBookEntry>();
{
Entries = new List<ProcessEntry>();
}
} }
} }

View File

@ -1,31 +0,0 @@
using CryptoExchange.Net.Interfaces;
using CryptoExchange.Net.Objects;
namespace CryptoExchange.Net.OrderBook
{
/// <summary>
/// Process entry for order book
/// </summary>
public class ProcessEntry
{
/// <summary>
/// The entry
/// </summary>
public ISymbolOrderBookEntry Entry { get; set; }
/// <summary>
/// The type
/// </summary>
public OrderBookEntryType Type { get; set; }
/// <summary>
/// ctor
/// </summary>
/// <param name="type"></param>
/// <param name="entry"></param>
public ProcessEntry(OrderBookEntryType type, ISymbolOrderBookEntry entry)
{
Type = type;
Entry = entry;
}
}
}

View File

@ -77,9 +77,9 @@ namespace CryptoExchange.Net.OrderBook
/// </summary> /// </summary>
public event Action<OrderBookStatus, OrderBookStatus>? OnStatusChange; public event Action<OrderBookStatus, OrderBookStatus>? OnStatusChange;
/// <summary> /// <summary>
/// Event when order book was updated. Be careful! It can generate a lot of events at high-liquidity markets /// 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
/// </summary> /// </summary>
public event Action? OnOrderBookUpdate; public event Action<IEnumerable<ISymbolOrderBookEntry>, IEnumerable<ISymbolOrderBookEntry>>? OnOrderBookUpdate;
/// <summary> /// <summary>
/// Timestamp of the last update /// Timestamp of the last update
/// </summary> /// </summary>
@ -268,10 +268,10 @@ namespace CryptoExchange.Net.OrderBook
asks.Clear(); asks.Clear();
foreach (var ask in askList) foreach (var ask in askList)
asks.Add(ask.Price, new OrderBookEntry(ask.Price, ask.Quantity)); asks.Add(ask.Price, ask);
bids.Clear(); bids.Clear();
foreach (var bid in bidList) foreach (var bid in bidList)
bids.Add(bid.Price, new OrderBookEntry(bid.Price, bid.Quantity)); bids.Add(bid.Price, bid);
LastSequenceNumber = orderBookSequenceNumber; LastSequenceNumber = orderBookSequenceNumber;
@ -281,7 +281,7 @@ namespace CryptoExchange.Net.OrderBook
CheckProcessBuffer(); CheckProcessBuffer();
bookSet = true; bookSet = true;
LastOrderBookUpdate = DateTime.UtcNow; LastOrderBookUpdate = DateTime.UtcNow;
OnOrderBookUpdate?.Invoke(); OnOrderBookUpdate?.Invoke(bidList, askList);
log.Write(LogVerbosity.Debug, $"{Id} order book {Symbol} data set: {BidCount} bids, {AskCount} asks"); log.Write(LogVerbosity.Debug, $"{Id} order book {Symbol} data set: {BidCount} bids, {AskCount} asks");
} }
} }
@ -291,8 +291,9 @@ namespace CryptoExchange.Net.OrderBook
/// </summary> /// </summary>
/// <param name="firstSequenceNumber">First sequence number</param> /// <param name="firstSequenceNumber">First sequence number</param>
/// <param name="lastSequenceNumber">Last sequence number</param> /// <param name="lastSequenceNumber">Last sequence number</param>
/// <param name="entries">List of entries</param> /// <param name="bids">List of bids</param>
protected void UpdateOrderBook(long firstSequenceNumber, long lastSequenceNumber, List<ProcessEntry> entries) /// <param name="asks">List of asks</param>
protected void UpdateOrderBook(long firstSequenceNumber, long lastSequenceNumber, IEnumerable<ISymbolOrderBookEntry> bids, IEnumerable<ISymbolOrderBookEntry> asks)
{ {
lock (bookLock) lock (bookLock)
{ {
@ -305,7 +306,8 @@ namespace CryptoExchange.Net.OrderBook
{ {
FirstSequence = firstSequenceNumber, FirstSequence = firstSequenceNumber,
LastSequence = lastSequenceNumber, LastSequence = lastSequenceNumber,
Entries = entries Asks = asks,
Bids = bids
}; };
processBuffer.Add(entry); processBuffer.Add(entry);
log.Write(LogVerbosity.Debug, $"{Id} order book {Symbol} update before synced; buffering"); log.Write(LogVerbosity.Debug, $"{Id} order book {Symbol} update before synced; buffering");
@ -318,13 +320,15 @@ namespace CryptoExchange.Net.OrderBook
} }
else else
{ {
foreach (var entry in entries) foreach (var entry in asks)
ProcessUpdate(entry.Type, entry.Entry); ProcessUpdate(OrderBookEntryType.Ask, entry);
foreach (var entry in bids)
ProcessUpdate(OrderBookEntryType.Bid, entry);
LastSequenceNumber = lastSequenceNumber; LastSequenceNumber = lastSequenceNumber;
CheckProcessBuffer(); CheckProcessBuffer();
LastOrderBookUpdate = DateTime.UtcNow; LastOrderBookUpdate = DateTime.UtcNow;
OnOrderBookUpdate?.Invoke(); OnOrderBookUpdate?.Invoke(bids, asks);
log.Write(LogVerbosity.Debug, $"{Id} order book {Symbol} update: {entries.Count} entries processed"); log.Write(LogVerbosity.Debug, $"{Id} order book {Symbol} update: {asks.Count()} asks, {bids.Count()} bids processed");
} }
} }
} }
@ -345,8 +349,11 @@ namespace CryptoExchange.Net.OrderBook
if (bufferEntry.FirstSequence > LastSequenceNumber + 1) if (bufferEntry.FirstSequence > LastSequenceNumber + 1)
break; break;
foreach (var entry in bufferEntry.Entries) foreach (var entry in bufferEntry.Asks)
ProcessUpdate(entry.Type, entry.Entry); ProcessUpdate(OrderBookEntryType.Ask, entry);
foreach (var entry in bufferEntry.Bids)
ProcessUpdate(OrderBookEntryType.Bid, entry);
processBuffer.Remove(bufferEntry); processBuffer.Remove(bufferEntry);
LastSequenceNumber = bufferEntry.LastSequence; LastSequenceNumber = bufferEntry.LastSequence;
} }
@ -373,7 +380,7 @@ namespace CryptoExchange.Net.OrderBook
{ {
if (!listToChange.ContainsKey(entry.Price)) if (!listToChange.ContainsKey(entry.Price))
{ {
listToChange.Add(entry.Price, new OrderBookEntry(entry.Price, entry.Quantity)); listToChange.Add(entry.Price, entry);
if (type == OrderBookEntryType.Ask) AskCount++; if (type == OrderBookEntryType.Ask) AskCount++;
else BidCount++; else BidCount++;
} }