/// <summary> /// Creates a point-in-time snapshot of the current order book data. /// </summary> /// <returns>Returns a new <see cref="OrderbookSnapshot"/> instance.</returns> public OrderbookSnapshot GetSnapshot() { var snapshot = new OrderbookSnapshot(StockId, _timestamper.Now, AskTrades.Values.Sum(x => x.RemainingQuantity), BidTrades.Values.Sum(x => x.RemainingQuantity), AsksByPrice.ToList(), BidsByPrice.ToList()); return(snapshot); }
/// <summary> /// Recreate a matching engine from a saved <see cref="OrderbookSnapshot"/>. /// </summary> /// <param name="snapshot">The order book snapshot.</param> /// <param name="log">Optional. An Akka.NET logger.</param> /// <param name="timestamper">Optional. The time stamping service implementation. Defaults to <see cref="CurrentUtcTimestamper"/> when <c>null</c>.</param> /// <returns>A new matching engine.</returns> public static MatchingEngine FromSnapshot(OrderbookSnapshot snapshot, ILoggingAdapter log = null, ITimestamper timestamper = null) { return(new MatchingEngine(snapshot.StockId, new Dictionary <string, Order>(), new Dictionary <string, Order>(), log, timestamper)); // MongoDb serialization CANNOT handle this object for reasons unknown //return new MatchingEngine(snapshot.StockId, snapshot.Bids?.ToDictionary(x => x.OrderId, y=> y) ?? new Dictionary<string, Order>(), // snapshot.Asks?.ToDictionary(x => x.OrderId, y => y) ?? new Dictionary<string, Order>(), log, timestamper); }
public void ShouldRecreateFromNullOrderbookSnapshot() { var snapshot = new OrderbookSnapshot(TickerSymbol, DateTimeOffset.Now, 0.0d, 0.0d, null, null); var engine = MatchingEngine.FromSnapshot(snapshot); var ask = new Ask(TickerSymbol, "foo", 12.0m, 5.0, DateTimeOffset.Now); // bid is lower than ask - no trades var bid = new Bid(TickerSymbol, "bar", 11.0m, 4.0, DateTimeOffset.Now); // verify that engine still works normally var bidEvents = engine.WithBid(bid); var askEvents = engine.WithAsk(ask); askEvents.Should().BeEmpty(); bidEvents.Should().BeEmpty(); engine.AskTrades.Count.Should().Be(1); engine.BidTrades.Count.Should().Be(1); }
internal static Msgs.OrderbookSnapshot ToProto(OrderbookSnapshot o) { var obs = new Msgs.OrderbookSnapshot() { AskQuantity = o.AskQuantity, BidQuantity = o.BidQuantity, StockId = o.StockId, TimeIssued = o.Timestamp.ToUnixTimeMilliseconds() }; if (o.Asks.Count > 0) { obs.Asks.AddRange(o.Asks.Select(x => ToProto(x))); } if (o.Bids.Count > 0) { obs.Bids.AddRange(o.Bids.Select(x => ToProto(x))); } return(obs); }
/// <summary> /// Recreate a matching engine from a saved <see cref="OrderbookSnapshot"/>. /// </summary> /// <param name="snapshot">The order book snapshot.</param> /// <param name="log">Optional. An Akka.NET logger.</param> /// <param name="timestamper">Optional. The time stamping service implementation. Defaults to <see cref="CurrentUtcTimestamper"/> when <c>null</c>.</param> /// <returns>A new matching engine.</returns> public static MatchingEngine FromSnapshot(OrderbookSnapshot snapshot, ILoggingAdapter log = null, ITimestamper timestamper = null) { return(new MatchingEngine(snapshot.StockId, snapshot.Bids.ToDictionary(x => x.OrderId, y => y), snapshot.Asks.ToDictionary(x => x.OrderId, y => y), log, timestamper)); }