public void TestMockOrderBook() { var orderBook = new MockOrderBook(1); var b1 = new ExchangeOrder(1, 1, OrderSide.Buy, OrderType.Limit, 10, 10); orderBook = orderBook.PlaceOrder(b1); Assert.AreEqual(1, orderBook.Orders.Count); Assert.AreEqual(1, orderBook.Bids.Count); Assert.AreEqual(0, orderBook.Asks.Count); var b2 = new ExchangeOrder(2, 1, OrderSide.Buy, OrderType.Limit, 11, 10); orderBook = orderBook.PlaceOrder(b2); Assert.AreEqual(2, orderBook.Orders.Count); Assert.AreEqual(2, orderBook.Bids.Count); Assert.AreEqual(0, orderBook.Asks.Count); var a1 = new ExchangeOrder(3, 1, OrderSide.Sell, OrderType.Limit, 10.5m, 5); orderBook = orderBook.PlaceOrder(a1); //all orders, even completed, should be contained in the dictionary Assert.AreEqual(3, orderBook.Orders.Count); //best bid was only half filled Assert.AreEqual(2, orderBook.Bids.Count); //the sell order was fully filled. asks should be empty Assert.AreEqual(0, orderBook.Asks.Count); Assert.AreEqual(5, orderBook.Bids[0].RemainingVolume); //check the order dictionary is update Assert.AreEqual(5, orderBook.Orders[2].RemainingVolume); Assert.AreEqual(0, orderBook.Orders[3].RemainingVolume); var a2 = new ExchangeOrder(4, 1, OrderSide.Sell, OrderType.Limit, 10, 7); orderBook = orderBook.PlaceOrder(a2); Assert.AreEqual(4, orderBook.Orders.Count); //best bid was fully filled Assert.AreEqual(1, orderBook.Bids.Count); //the ask was fully filled Assert.AreEqual(0, orderBook.Asks.Count); //the next best bid was partially filled Assert.AreEqual(8, orderBook.Bids[0].RemainingVolume); Assert.AreEqual(0, orderBook.Orders[2].RemainingVolume); Assert.AreEqual(0, orderBook.Orders[4].RemainingVolume); Assert.AreEqual(8, orderBook.Orders[1].RemainingVolume); var b3 = new ExchangeOrder(5, 1, OrderSide.Buy, OrderType.Limit, 9, 10); orderBook = orderBook.PlaceOrder(b3); var a3 = new ExchangeOrder(6, 1, OrderSide.Sell, OrderType.Limit, 10, 10); orderBook = orderBook.PlaceOrder(a3); Assert.AreEqual(6, orderBook.Orders.Count); //the best bid was totally filled Assert.AreEqual(1, orderBook.Bids.Count); Assert.AreEqual(0, orderBook.Orders[1].RemainingVolume); Assert.AreEqual(1, orderBook.Asks.Count); Assert.AreEqual(2, orderBook.Orders[6].RemainingVolume); //the second bid was not touched because too low Assert.AreEqual(10, orderBook.Bids[0].RemainingVolume); }
public void TestAggregatedOrderBook() { #region Check Union of sorted sets is still sorted var o11 = new ExchangeOrder(1, 1, OrderSide.Buy, OrderType.Limit, 10, 5); var o12 = new ExchangeOrder(2, 1, OrderSide.Buy, OrderType.Limit, 9, 4); var o13 = new ExchangeOrder(3, 1, OrderSide.Sell, OrderType.Limit, 12, 6); var o14 = new ExchangeOrder(4, 1, OrderSide.Sell, OrderType.Limit, 11, 7); var orderBook1 = new MockOrderBook(1).PlaceOrder(o11) .PlaceOrder(o12) .PlaceOrder(o13) .PlaceOrder(o14); var o21 = new ExchangeOrder(5, 2, OrderSide.Buy, OrderType.Limit, 10.5m, 5.5m); var o22 = new ExchangeOrder(6, 2, OrderSide.Buy, OrderType.Limit, 9.5m, 4.5m); var o23 = new ExchangeOrder(7, 2, OrderSide.Sell, OrderType.Limit, 12.5m, 5.5m); var o24 = new ExchangeOrder(8, 2, OrderSide.Sell, OrderType.Limit, 11.5m, 6.5m); var orderBook2 = new MockOrderBook(2).PlaceOrder(o21) .PlaceOrder(o22) .PlaceOrder(o23) .PlaceOrder(o24); var aggregatedOrderBook = new AggregatedOrderBook().InsertBook(orderBook1) .InsertBook(orderBook2); Assert.AreEqual(5, aggregatedOrderBook.Bids[0].ID); Assert.AreEqual(1, aggregatedOrderBook.Bids[1].ID); Assert.AreEqual(6, aggregatedOrderBook.Bids[2].ID); Assert.AreEqual(2, aggregatedOrderBook.Bids[3].ID); Assert.AreEqual(4, aggregatedOrderBook.Asks[0].ID); Assert.AreEqual(8, aggregatedOrderBook.Asks[1].ID); Assert.AreEqual(3, aggregatedOrderBook.Asks[2].ID); Assert.AreEqual(7, aggregatedOrderBook.Asks[3].ID); #endregion #region Check replacing an order book var o222 = o22.WithUpdatedRemainingVolume(1); var o232 = o23.WithUpdatedRemainingVolume(0.5m); var o242 = o24.WithUpdatedRemainingVolume(0.2m); var o25 = new ExchangeOrder(9, 2, OrderSide.Sell, OrderType.Limit, 13, 10); var orderBook22 = new MockOrderBook(2).PlaceOrder(o222) .PlaceOrder(o232) .PlaceOrder(o242) .PlaceOrder(o25); var aggregatedOrderBook2 = aggregatedOrderBook.InsertBook(orderBook22); Assert.AreEqual(1, aggregatedOrderBook2.Bids[0].ID); Assert.AreEqual(6, aggregatedOrderBook2.Bids[1].ID); Assert.AreEqual(3.5m, aggregatedOrderBook2.Bids[1].RemainingVolume); Assert.AreEqual(2, aggregatedOrderBook2.Bids[2].ID); Assert.AreEqual(4, aggregatedOrderBook2.Asks[0].ID); Assert.AreEqual(8, aggregatedOrderBook2.Asks[1].ID); Assert.AreEqual(6.3m, aggregatedOrderBook2.Asks[1].RemainingVolume); Assert.AreEqual(3, aggregatedOrderBook2.Asks[2].ID); Assert.AreEqual(7, aggregatedOrderBook2.Asks[3].ID); Assert.AreEqual(5, aggregatedOrderBook2.Asks[3].RemainingVolume); Assert.AreEqual(9, aggregatedOrderBook2.Asks[4].ID); #endregion #region Check arbitrage scanning var o31 = new ExchangeOrder(1, 3, OrderSide.Buy, OrderType.Limit, 12, 5); var o32 = new ExchangeOrder(2, 3, OrderSide.Buy, OrderType.Limit, 9, 7); var o33 = new ExchangeOrder(3, 3, OrderSide.Sell, OrderType.Limit, 13, 4); var o34 = new ExchangeOrder(4, 3, OrderSide.Sell, OrderType.Limit, 14, 6); var orderBook3 = new MockOrderBook(3).PlaceOrder(o31) .PlaceOrder(o32) .PlaceOrder(o33) .PlaceOrder(o34); var o41 = new ExchangeOrder(5, 4, OrderSide.Buy, OrderType.Limit, 10.5m, 2); var o42 = new ExchangeOrder(6, 4, OrderSide.Buy, OrderType.Limit, 8, 6); var o43 = new ExchangeOrder(7, 4, OrderSide.Sell, OrderType.Limit, 11, 8); var o44 = new ExchangeOrder(8, 4, OrderSide.Sell, OrderType.Limit, 13.5m, 2); var orderBook4 = new MockOrderBook(4).PlaceOrder(o41) .PlaceOrder(o42) .PlaceOrder(o43) .PlaceOrder(o44); var aggregatedOrderBook3 = new AggregatedOrderBook().InsertBook(orderBook3) .InsertBook(orderBook4); var arbitrage = aggregatedOrderBook3.LookForArbitrage(); Assert.AreEqual(5, arbitrage.BuyDico[4]); Assert.AreEqual(5, arbitrage.SellDico[3]); #endregion #region Check arbitrage scanning 2 var o51 = new ExchangeOrder(1, 5, OrderSide.Buy, OrderType.Limit, 13, 5); var o52 = new ExchangeOrder(2, 5, OrderSide.Buy, OrderType.Limit, 12.8m, 2); var o53 = new ExchangeOrder(3, 5, OrderSide.Buy, OrderType.Limit, 12.7m, 6); var o54 = new ExchangeOrder(4, 5, OrderSide.Buy, OrderType.Limit, 12, 4); var orderBook5 = new MockOrderBook(5).PlaceOrder(o51) .PlaceOrder(o52) .PlaceOrder(o53) .PlaceOrder(o54); var o61 = new ExchangeOrder(1, 6, OrderSide.Sell, OrderType.Limit, 12.5m, 10); var o62 = new ExchangeOrder(2, 6, OrderSide.Sell, OrderType.Limit, 13, 4); var orderBook6 = new MockOrderBook(6).PlaceOrder(o61) .PlaceOrder(o62); var o71 = new ExchangeOrder(1, 7, OrderSide.Sell, OrderType.Limit, 12, 7); var o72 = new ExchangeOrder(2, 7, OrderSide.Sell, OrderType.Limit, 12.7m, 5); var orderBook7 = new MockOrderBook(7).PlaceOrder(o71) .PlaceOrder(o72); var aggregatedOrderBook4 = new AggregatedOrderBook().InsertBook(orderBook5) .InsertBook(orderBook6) .InsertBook(orderBook7); var arbitrage2 = aggregatedOrderBook4.LookForArbitrage(); Assert.AreEqual(7, arbitrage2.BuyDico[7]); Assert.AreEqual(6, arbitrage2.BuyDico[6]); Assert.AreEqual(13, arbitrage2.SellDico[5]); #endregion }