public void OnNext(byte[] data, long sequence, bool endOfBatch) { object getObject = StreamConversion.ByteArrayToObject(data); if (getObject is Order) { _receviedOrder = getObject as Order; } if (getObject is Trade) { _receivedTrade = getObject as Trade; } if (getObject is LimitOrderBook) { _receivedLimitOrderBook = getObject as LimitOrderBook; } if (getObject is Depth) { _receivedDepth = getObject as Depth; } if (getObject is BBO) { _receivedBbo = getObject as BBO; } }
/// <summary> /// Executed every time the synchronisation timer fires /// </summary> void _synchronisationTimer_Tick(object sender, EventArgs e) { //Check if synchronisation is complete if ((_lastQuoteUpdateCount == _quoteUpdateCount) && (_lastUpdateTime != string.Empty)) { Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff") + "\t" + _lastQuoteUpdateCount + "\t" + _quoteUpdateCount + "\t" + _lastUpdateTime); LimitOrderBook depthClone = _depthReference.Clone(); lblDepthView.Text = (DisplayAggregateDepth) ? CreateAggregateOrderDepthText(depthClone) : CreateOrderDepthText(depthClone); lblMarketTime.Text = _lastUpdateTime; lblMarketState.Text = _security.State.ToString(); bool hasTrades = (_tradeEntries.Count > 0); if (hasTrades) { lbTrades.BeginUpdate(); while (_tradeEntries.Count > 0) { lbTrades.Items.Insert(0, _tradeEntries.Dequeue()); } lbTrades.EndUpdate(); } //Disable the synchronisation timer so that it stops firing IsSynchronising = false; _synchronisationTimer.Stop(); } else { //Update the last trade queue count //Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff") + "\t" + _lastQuoteUpdateCount + "\t" + _quoteUpdateCount + "\t" + _lastUpdateTime); _lastQuoteUpdateCount = _quoteUpdateCount; } }
public void AddBuyOrderBookToMemoryImage_ChecksWhetherOrderBooksGetAddedToImageListsPrperly_VerifiesImageListsToConfirm() { LimitOrderBook orderBook = new LimitOrderBook(CurrencyConstants.BtcUsd); Order buyOrder1 = new Order(new OrderId("1"), CurrencyConstants.BtcUsd, new Price(1251), OrderSide.Buy, OrderType.Limit, new Volume(250), new TraderId("1")); Order buyOrder2 = new Order(new OrderId("2"), CurrencyConstants.BtcUsd, new Price(1250), OrderSide.Buy, OrderType.Limit, new Volume(250), new TraderId("2")); Order buyOrder3 = new Order(new OrderId("3"), CurrencyConstants.BtcUsd, new Price(1252), OrderSide.Buy, OrderType.Limit, new Volume(250), new TraderId("3")); Order buyOrder4 = new Order(new OrderId("4"), CurrencyConstants.BtcUsd, new Price(1251), OrderSide.Buy, OrderType.Limit, new Volume(250), new TraderId("4")); orderBook.AddOrder(buyOrder1); orderBook.AddOrder(buyOrder2); orderBook.AddOrder(buyOrder3); orderBook.AddOrder(buyOrder4); OrderBookMemoryImage orderBookMemory = new OrderBookMemoryImage(); orderBookMemory.OnOrderBookChanged(orderBook); Assert.AreEqual(CurrencyConstants.BtcUsd, orderBookMemory.BidBooks.First().CurrencyPair, "Currency pair of the first book in the" + " memory image's list of BidOrderBook representations"); Assert.AreEqual(4, orderBookMemory.BidBooks.First().Count(), "Count of the Bids in the first Bid Book present in the memory image"); Assert.AreEqual(0, orderBookMemory.AskBooks.First().Count(), "Count of the Asks in te first Ask Book present in the memory image"); }
/// <summary> /// Addes provided orders to the Limit Order Book /// </summary> /// <param name="orderBook"></param> /// <param name="orders"></param> /// <returns></returns> private int AddOrders(LimitOrderBook orderBook, Order[] orders) { int count = 0; var start = DateTime.Now; for (int i = 0; i < orders.Length; i++) { if (orders[i].Price != null && orders[i].Volume != null) { orderBook.AddOrder(orders[i]); count++; } else { throw new Exception(); } } var end = DateTime.Now; Console.WriteLine("Orders Places: {0} Time elapsed: {1} seconds", count, (end - start).TotalSeconds); Console.WriteLine("Bids: " + orderBook.Bids.Count() + ", Ask: " + orderBook.Asks.Count() + ", Trades: " + (_exchange.ExchangeEssentials.First().TradeListener.Trades != null ? _exchange.ExchangeEssentials.First().TradeListener.Trades.Count() : 0)); return(count); }
public void SellOrdersPartiallyFilledTest_ChecksIfFilledOrdersAreRepresentedCorrectlyInAskBooksVolumes_VerifiesThroughAskBookOutput() { LimitOrderBook orderBook = new LimitOrderBook(CurrencyConstants.BtcUsd); Order buyOrder1 = new Order(new OrderId("1"), CurrencyConstants.BtcUsd, new Price(941), OrderSide.Buy, OrderType.Limit, new Volume(100), new TraderId("1")); Order buyOrder2 = new Order(new OrderId("2"), CurrencyConstants.BtcUsd, new Price(942), OrderSide.Buy, OrderType.Limit, new Volume(200), new TraderId("2")); Order buyOrder3 = new Order(new OrderId("3"), CurrencyConstants.BtcUsd, new Price(943), OrderSide.Buy, OrderType.Limit, new Volume(300), new TraderId("3")); Order buyOrder4 = new Order(new OrderId("4"), CurrencyConstants.BtcUsd, new Price(944), OrderSide.Buy, OrderType.Limit, new Volume(400), new TraderId("4")); Order sellOrder1 = new Order(new OrderId("5"), CurrencyConstants.BtcUsd, new Price(941), OrderSide.Sell, OrderType.Limit, new Volume(200), new TraderId("5")); Order sellOrder2 = new Order(new OrderId("6"), CurrencyConstants.BtcUsd, new Price(942), OrderSide.Sell, OrderType.Limit, new Volume(400), new TraderId("6")); Order sellOrder3 = new Order(new OrderId("7"), CurrencyConstants.BtcUsd, new Price(943), OrderSide.Sell, OrderType.Limit, new Volume(600), new TraderId("7")); Order sellOrder4 = new Order(new OrderId("8"), CurrencyConstants.BtcUsd, new Price(944), OrderSide.Sell, OrderType.Limit, new Volume(800), new TraderId("8")); orderBook.AddOrder(buyOrder1); orderBook.AddOrder(buyOrder2); orderBook.AddOrder(buyOrder3); orderBook.AddOrder(buyOrder4); orderBook.AddOrder(sellOrder4); orderBook.AddOrder(sellOrder3); orderBook.AddOrder(sellOrder2); orderBook.AddOrder(sellOrder1); OrderBookMemoryImage orderBookMemory = new OrderBookMemoryImage(); orderBookMemory.OnOrderBookChanged(orderBook); Assert.AreEqual(CurrencyConstants.BtcUsd, orderBookMemory.BidBooks.First().CurrencyPair, "Currency pair of " + "the first book in the memory image's list of BidOrderBook representations"); // Both books contain one currency pair Assert.AreEqual(1, orderBookMemory.BidBooks.Count()); Assert.AreEqual(1, orderBookMemory.AskBooks.Count()); // Each currency pair contains several entries for the orders Assert.AreEqual(0, orderBookMemory.BidBooks.First().Count(), "Count of the Bids in the first Bid Book present in the memory image"); Assert.AreEqual(4, orderBookMemory.AskBooks.First().Count(), "Count of the Asks in te first Ask Book present in the memory image"); // Check the Volume elements of the first order book in the Memory Image's list of Order representations Assert.AreEqual(100, orderBookMemory.AskBooks.First().ToList()[0].Volume); Assert.AreEqual(200, orderBookMemory.AskBooks.First().ToList()[1].Volume); Assert.AreEqual(300, orderBookMemory.AskBooks.First().ToList()[2].Volume); Assert.AreEqual(400, orderBookMemory.AskBooks.First().ToList()[3].Volume); // Check Prices Assert.AreEqual(941, orderBookMemory.AskBooks.First().ToList()[0].Price); Assert.AreEqual(942, orderBookMemory.AskBooks.First().ToList()[1].Price); Assert.AreEqual(943, orderBookMemory.AskBooks.First().ToList()[2].Price); Assert.AreEqual(944, orderBookMemory.AskBooks.First().ToList()[3].Price); }
public void GetOrderBookTest_ChecksIfOrderBookIsRetreivedProperly_ValidatesReturnedOrderBook() { // Get the context // IApplicationContext applicationContext = ContextRegistry.GetContext(); // Get the instance through Spring configuration MarketController marketController = (MarketController)_applicationContext["MarketController"]; LimitOrderBook limitOrderBook = new LimitOrderBook("XBTUSD"); Order buyOrder1 = OrderFactory.CreateOrder("1233", "XBTUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_BUY, 150, 481.34M, new StubbedOrderIdGenerator()); Order buyOrder2 = OrderFactory.CreateOrder("1234", "XBTUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_BUY, 50, 482.34M, new StubbedOrderIdGenerator()); Order buyOrder3 = OrderFactory.CreateOrder("1222", "XBTUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_BUY, 50, 483.34M, new StubbedOrderIdGenerator()); Order sellOrder1 = OrderFactory.CreateOrder("1233", "XBTUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_SELL, 150, 491.34M, new StubbedOrderIdGenerator()); Order sellOrder2 = OrderFactory.CreateOrder("1234", "XBTUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_SELL, 50, 492.34M, new StubbedOrderIdGenerator()); Order sellrder3 = OrderFactory.CreateOrder("1222", "XBTUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_SELL, 50, 493.34M, new StubbedOrderIdGenerator()); limitOrderBook.PlaceOrder(buyOrder1); limitOrderBook.PlaceOrder(buyOrder2); limitOrderBook.PlaceOrder(buyOrder3); limitOrderBook.PlaceOrder(sellOrder1); limitOrderBook.PlaceOrder(sellOrder2); limitOrderBook.PlaceOrder(sellrder3); OrderBookMemoryImage orderBookMemoryImage = (OrderBookMemoryImage)_applicationContext["OrderBookMemoryImage"]; orderBookMemoryImage.OnOrderBookChanged(limitOrderBook); IHttpActionResult httpActionResult = marketController.GetOrderBook("XBTUSD"); OkNegotiatedContentResult <object> okResponseMessage = (OkNegotiatedContentResult <object>)httpActionResult; OrderBookRepresentation representation = okResponseMessage.Content as OrderBookRepresentation; Assert.IsNotNull(okResponseMessage); Assert.IsNotNull(representation); // Check the Currency Pair for Bid Book Assert.AreEqual("XBTUSD", representation.Bids.CurrencyPair); // Check the Currency Pair for Ask Book Assert.AreEqual("XBTUSD", representation.Asks.CurrencyPair); // Count of the number of Bids in the Bid Order Book Assert.AreEqual(3, representation.Bids.Count()); // Count of the number of Asks in the Ask Order Book Assert.AreEqual(3, representation.Asks.Count()); Assert.AreEqual(50, representation.Bids.ToList()[0].Volume); // Highest Bid Volumein Bid Order Book Assert.AreEqual(483.34M, representation.Bids.ToList()[0].Price); // Highest Bid Price in Bid Order Book Assert.AreEqual(150, representation.Asks.ToList()[0].Volume); // Highest Ask Volumein Ask Order Book Assert.AreEqual(491.34M, representation.Asks.ToList()[0].Price); // Highest Ask Price in Ask Order Book }
/// <summary> /// Adds and cancels orders /// </summary> /// <param name="orderBook"></param> /// <param name="orders"></param> /// <param name="orderIds"></param> /// <returns></returns> private void AddOrdersAndCancel(LimitOrderBook orderBook, Order[] orders, List <OrderId> orderIds) { Console.WriteLine(orders.Length + " orders received for sending over to exchange."); var overallStart = DateTime.Now; Console.WriteLine("Start time: " + DateTime.Now); int count = 0; var startAdd = DateTime.Now; for (int i = 0; i < orders.Length; i++) { if (orders[i].Price != null && orders[i].Volume != null) { orderBook.AddOrder(orders[i]); count++; } else { throw new Exception(); } } var endAdd = DateTime.Now; Console.WriteLine("Orders added. : {0} | Time elapsed: {1} seconds", count, (endAdd - startAdd).TotalSeconds); Console.WriteLine("Bids: " + orderBook.Bids.Count() + ", Ask: " + orderBook.Asks.Count() + ", Trades: " + _exchange.ExchangeEssentials.First().TradeListener.Trades.Count()); var startCancel = DateTime.Now; count = 0; foreach (OrderId orderId in orderIds) { if (orderId != null) { if (orderBook.CancelOrder(orderId)) { count++; } } else { throw new Exception(); } } var endCancel = DateTime.Now; Console.WriteLine("Orders cancelled. : {0} | Time elapsed: {1} seconds", count, (endCancel - startCancel).TotalSeconds); Console.WriteLine("Bids: " + orderBook.Bids.Count() + ", Ask: " + orderBook.Asks.Count()); var overAllEnd = DateTime.Now; Console.WriteLine("Overall Operation Time elapsed: {0} seconds", (overAllEnd - overallStart).TotalSeconds); Console.Write("End time: " + DateTime.Now); }
/// <summary> /// Checks if Order was partially or fully filled /// </summary> /// <param name="orderBook"></param> /// <param name="order"></param> /// <param name="isPartiallyFilled"> </param> /// <returns></returns> public bool FilledPartiallyOrComplete(LimitOrderBook orderBook, Order order, bool isPartiallyFilled) { bool matched = orderBook.AddOrder(order); if (isPartiallyFilled) { return(order.OrderState == OrderState.PartiallyFilled); } else { return(matched && order.OrderState == OrderState.Complete); } }
public void GetBidOrderBookTest_ChecksIfOrderBookIsretreivedSuccessfully_VerifiesOrderBookToSeeItContainsValuesAsExpected() { OrderBookMemoryImage orderBookMemoryImage = new OrderBookMemoryImage(); MarketDataQueryService memoryImageQueryService = new MarketDataQueryService(orderBookMemoryImage, null, null, null, null); LimitOrderBook limitOrderBook = new LimitOrderBook("BTCUSD"); Order buyOrder1 = OrderFactory.CreateOrder("1233", "BTCUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_BUY, 100, 941, new StubbedOrderIdGenerator()); Order buyOrder2 = OrderFactory.CreateOrder("1234", "BTCUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_BUY, 100, 945, new StubbedOrderIdGenerator()); Order buyOrder3 = OrderFactory.CreateOrder("1234", "BTCUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_BUY, 100, 946, new StubbedOrderIdGenerator()); Order buyOrder4 = OrderFactory.CreateOrder("12347", "BTCUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_BUY, 100, 940, new StubbedOrderIdGenerator()); Order sellOrder1 = OrderFactory.CreateOrder("1244", "BTCUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_SELL, 100, 949, new StubbedOrderIdGenerator()); Order sellOrder2 = OrderFactory.CreateOrder("1222", "BTCUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_SELL, 100, 948, new StubbedOrderIdGenerator()); Order sellOrder3 = OrderFactory.CreateOrder("1222", "BTCUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_SELL, 100, 947, new StubbedOrderIdGenerator()); Order sellOrder4 = OrderFactory.CreateOrder("127633", "BTCUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_SELL, 100, 950, new StubbedOrderIdGenerator()); limitOrderBook.AddOrder(buyOrder1); limitOrderBook.AddOrder(buyOrder2); limitOrderBook.AddOrder(buyOrder3); limitOrderBook.AddOrder(buyOrder4); limitOrderBook.AddOrder(sellOrder1); limitOrderBook.AddOrder(sellOrder2); limitOrderBook.AddOrder(sellOrder3); limitOrderBook.AddOrder(sellOrder4); Assert.AreEqual(4, limitOrderBook.Bids.Count()); Assert.AreEqual(4, limitOrderBook.Asks.Count()); orderBookMemoryImage.OnOrderBookChanged(limitOrderBook); OrderBookRepresentation orderBooksTuple = (OrderBookRepresentation)memoryImageQueryService.GetOrderBook("BTCUSD", 3); Assert.AreEqual(3, orderBooksTuple.Bids.Count()); Assert.AreEqual("BTCUSD", orderBooksTuple.Bids.CurrencyPair); Assert.AreEqual(100, orderBooksTuple.Bids.ToList()[0].Volume); // Volume Assert.AreEqual(946, orderBooksTuple.Bids.ToList()[0].Price); // Price Assert.AreEqual(100, orderBooksTuple.Bids.ToList()[1].Volume); // Volume Assert.AreEqual(945, orderBooksTuple.Bids.ToList()[1].Price); // Price Assert.AreEqual(100, orderBooksTuple.Bids.ToList()[2].Volume); // Volume Assert.AreEqual(941, orderBooksTuple.Bids.ToList()[2].Price); // Price }
/// <summary> /// Executed in response to a depth update for the security /// </summary> private void _security_OnDepthUpdate(object sender, GenericEventArgs <LimitOrderBook> e) { _quoteUpdateCount++; _depthReference = e.Value; if (IsSynchronising) { _lastUpdateTime = e.TimeStamp.ToMarketTime(); } else { string depthText = (DisplayAggregateDepth) ? CreateAggregateOrderDepthText(e.Value) : CreateOrderDepthText(e.Value); UpdateLabelText(lblDepthView, depthText); UpdateLabelText(lblMarketTime, e.TimeStamp.ToMarketTime()); } }
/// <summary> /// Generate multi-line string that displays the limit order book /// </summary> /// <param name="orderBook"></param> private string CreateAggregateOrderDepthText(LimitOrderBook orderBook) { //Generate aggregate limit order book view AggregatedLimitOrderBook aggregateOrderBook = new AggregatedLimitOrderBook(orderBook, DepthLevels); //Build header StringBuilder output = new StringBuilder(); output.Append("#".PadLeft(8)); output.Append("VOLUME".PadLeft(11)); output.Append("BID ".PadLeft(9)); output.Append("".PadRight(4)); output.Append(" ASK".PadRight(9)); output.Append("VOLUME".PadRight(11)); output.Append("#".ToString()); output.AppendLine(); output.AppendLine(); //Build depth view for (int i = 0; i < DepthLevels; i++) { //Write bid text for level if (aggregateOrderBook.Bid.Count > i) { LimitOrderBookPriceLevel bidOrder = aggregateOrderBook.Bid[i]; output.Append(bidOrder.Count.ToString().PadLeft(8)); output.Append(bidOrder.Volume.ToString().PadLeft(11)); output.Append(bidOrder.Price.ToDecimalPrice().ToShortPriceString().PadLeft(9)); output.Append("".PadRight(4)); } else { output.Append("".PadRight(32)); } //Write ask text for level if (aggregateOrderBook.Ask.Count > i) { LimitOrderBookPriceLevel askOrder = aggregateOrderBook.Ask[i]; output.Append(askOrder.Price.ToDecimalPrice().ToShortPriceString().PadRight(9)); output.Append(askOrder.Volume.ToString().PadRight(11)); output.Append(askOrder.Count.ToString()); } output.AppendLine(); } return(output.ToString()); }
public void PublishOrderBookToDisruptor_IfOrderBookIsConvertedToByteArray_ItShouldBeReceivedAndCastedToOrderBook() { LimitOrderBook limitOrderBook = new LimitOrderBook("XBTUSD"); Order buyOrder = OrderFactory.CreateOrder("1234", "XBTUSD", "limit", "buy", 5, 10, new StubbedOrderIdGenerator()); Order sellOrder = OrderFactory.CreateOrder("1234", "XBTUSD", "limit", "sell", 5, 11, new StubbedOrderIdGenerator()); limitOrderBook.PlaceOrder(buyOrder); limitOrderBook.PlaceOrder(sellOrder); //byte[] array = ObjectToByteArray(limitOrderBook); OutputDisruptor.Publish(limitOrderBook); _manualResetEvent.WaitOne(3000); Assert.NotNull(_receivedLimitOrderBook); Assert.AreEqual(_receivedLimitOrderBook.AskCount, 1); Assert.AreEqual(_receivedLimitOrderBook.BidCount, 1); }
public void PlaceBuyOrderPriceGreaterThanEqualTest() { LimitOrderBook limitOrderBook = new LimitOrderBook("XBTUSD"); Order order1 = OrderFactory.CreateOrder("1233", "XBTUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_SELL, 150, 480.34M, new StubbedOrderIdGenerator()); limitOrderBook.PlaceOrder(order1); Assert.AreEqual(1, limitOrderBook.AskCount, "Count of Buy Orders after trade execution"); bool placeOrder = limitOrderBook.PlaceOrder(new Order(new OrderId("1"), "XBTUSD", new Price(490.34M), OrderSide.Buy, OrderType.Limit, new Volume(150), new TraderId("1"))); Assert.AreEqual(0, limitOrderBook.AskCount, "Count of Buy Orders after trade execution"); Assert.AreEqual(0, limitOrderBook.BidCount, "Count of Sell Orders after trade execution"); Assert.IsTrue(placeOrder); }
/// <summary> /// OnNext /// </summary> /// <param name="data"></param> /// <param name="sequence"></param> /// <param name="endOfBatch"></param> public void OnNext(byte[] data, long sequence, bool endOfBatch) { object getObject = ByteArrayToObject(data); if (getObject is Order) { //NOTE: Commented out due event store issues //_eventStore.StoreEvent(getObject as Order); // Raising Event to be handled by OrderEventListener. Moved here from ReceiveCommit.cs OrderEvent.Raise(getObject as Order); } if (getObject is Trade) { //NOTE: Commented out due event store issues //_eventStore.StoreEvent(getObject as Trade); // Raising Event to be handled by TradeEventListener. Moved here from ReceiveCommit.cs TradeEvent.Raise(getObject as Trade); } if (getObject is LimitOrderBook) { LimitOrderBook limitOrderBook = getObject as LimitOrderBook; // Raise the event for the memory event to catch LimitOrderBookEvent.Raise(limitOrderBook); // Store the LimitOrderBook in the event store if no last snapshot datetime has been assigned or if the snapshot // was taken yesterday and new day has begun /*if ((limitOrderBook.LastSnapshotTaken == DateTime.MinValue || * limitOrderBook.LastSnapshotTaken.Day < DateTime.Today.Day)) * { * _eventStore.StoreEvent(limitOrderBook); * limitOrderBook.LastSnapshotTaken = DateTime.Now; * }*/ } if (getObject is Depth) { DepthEvent.Raise(getObject as Depth); } if (getObject is BBO) { BBOEvent.Raise(getObject as BBO); } }
/// <summary> /// Generate multi-line string that displays the limit order book /// </summary> /// <param name="orderBook"></param> private string CreateOrderDepthText(LimitOrderBook orderBook) { //Build header StringBuilder output = new StringBuilder(); output.Append("TIME ".PadLeft(10)); output.Append("VOLUME".PadLeft(9)); output.Append("BID ".PadLeft(9)); output.Append("".PadRight(4)); output.Append(" ASK".PadRight(9)); output.Append("VOLUME".PadRight(9)); output.Append("TIME".ToString()); output.AppendLine(); output.AppendLine(); //Build depth view for (int i = 0; i < DepthLevels; i++) { //Write bid text for level if (orderBook.Bid.Count > i) { LimitOrder bidOrder = orderBook.Bid[i]; output.Append(bidOrder.TimeStamp.ToMarketTime().PadRight(10)); output.Append(bidOrder.Volume.ToString().PadLeft(9)); output.Append(bidOrder.Price.ToDecimalPrice().ToShortPriceString().PadLeft(9)); output.Append("".PadRight(4)); } else { output.Append("".PadRight(32)); } //Write ask text for level if (orderBook.Ask.Count > i) { LimitOrder askOrder = orderBook.Ask[i]; output.Append(askOrder.Price.ToDecimalPrice().ToShortPriceString().PadRight(9)); output.Append(askOrder.Volume.ToString().PadRight(9)); output.Append(askOrder.TimeStamp.ToMarketTime()); } output.AppendLine(); } return(output.ToString()); }
public void PlaceBuyOrderGreaterQuantityTest() { LimitOrderBook limitOrderBook = new LimitOrderBook("XBTUSD"); Order order1 = OrderFactory.CreateOrder("1233", "XBTUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_SELL, 150, 491.34M, new StubbedOrderIdGenerator()); limitOrderBook.PlaceOrder(order1); Assert.AreEqual(1, limitOrderBook.AskCount, "Count of Buy Orders after trade execution"); bool placeOrder = limitOrderBook.PlaceOrder(new Order(new OrderId("1"), "XBTUSD", new Price(491.34M), OrderSide.Buy, OrderType.Limit, new Volume(200), new TraderId("1"))); Assert.AreEqual(0, limitOrderBook.AskCount, "Count of Buy Orders after trade execution"); Assert.AreEqual(1, limitOrderBook.BidCount, "Count of Sell Orders after trade execution"); Assert.AreEqual(50, limitOrderBook.Bids.First().OpenQuantity.Value, "Volume of the Buy Order after updating"); Assert.IsTrue(placeOrder); }
public void AddBuyOrdersAndSortTest() { LimitOrderBook limitOrderBook = new LimitOrderBook("XBTUSD"); Order order1 = OrderFactory.CreateOrder("1233", "XBTUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_BUY, 250, 493.34M, new StubbedOrderIdGenerator()); Order order2 = OrderFactory.CreateOrder("1234", "XBTUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_BUY, 250, 491.34M, new StubbedOrderIdGenerator()); Order order3 = OrderFactory.CreateOrder("1222", "XBTUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_BUY, 250, 492.34M, new StubbedOrderIdGenerator()); limitOrderBook.PlaceOrder(order1); limitOrderBook.PlaceOrder(order2); limitOrderBook.PlaceOrder(order3); Assert.AreEqual(3, limitOrderBook.BidCount, "Count of Buy Orders"); Assert.AreEqual(493.34M, limitOrderBook.Bids.First().Price.Value, "First element of Buy Orders list"); Assert.AreEqual(491.34M, limitOrderBook.Bids.Last().Price.Value, "Last element of Buy Orders list"); }
/// <summary> /// /// </summary> private void Initialise() { //Clear controls lblDepthView.Text = string.Empty; lbTrades.Items.Clear(); //Initialise synchronisation objects if (EnableSynchronisation) { _lastQuoteUpdateCount = 0; _tradeEntries.Clear(); _depthReference = null; _lastUpdateTime = string.Empty; IsSynchronising = true; _synchronisationTimer.Start(); lblMarketState.Text = "Synchronising..."; } else { IsSynchronising = false; } }
public void CheckAskBookVolumes_ChecksWhetherOrderOfAsksPricesIsSameAsTheLimitOrderBook_VerifiesImageListsToConfirm() { LimitOrderBook orderBook = new LimitOrderBook(CurrencyConstants.BtcUsd); Order sellOrder1 = new Order(new OrderId("1"), CurrencyConstants.BtcUsd, new Price(1251), OrderSide.Sell, OrderType.Limit, new Volume(100), new TraderId("1")); Order sellOrder2 = new Order(new OrderId("2"), CurrencyConstants.BtcUsd, new Price(1250), OrderSide.Sell, OrderType.Limit, new Volume(200), new TraderId("2")); Order sellOrder3 = new Order(new OrderId("3"), CurrencyConstants.BtcUsd, new Price(1252), OrderSide.Sell, OrderType.Limit, new Volume(300), new TraderId("3")); Order sellOrder4 = new Order(new OrderId("4"), CurrencyConstants.BtcUsd, new Price(1253), OrderSide.Sell, OrderType.Limit, new Volume(400), new TraderId("4")); orderBook.AddOrder(sellOrder1); orderBook.AddOrder(sellOrder2); orderBook.AddOrder(sellOrder3); orderBook.AddOrder(sellOrder4); OrderBookMemoryImage orderBookMemory = new OrderBookMemoryImage(); orderBookMemory.OnOrderBookChanged(orderBook); Assert.AreEqual(CurrencyConstants.BtcUsd, orderBookMemory.AskBooks.First().CurrencyPair, "Currency pair of " + "the first book in the memory image's list of BidOrderBook representations"); Assert.AreEqual(1, orderBookMemory.BidBooks.Count()); Assert.AreEqual(1, orderBookMemory.AskBooks.Count()); Assert.AreEqual(0, orderBookMemory.BidBooks.First().Count(), "Count of the Bids in the first Bid Book present in the memory image"); Assert.AreEqual(4, orderBookMemory.AskBooks.First().Count(), "Count of the Asks in te first Ask Book present in the memory image"); // Check the Prices elements of the first order book in the Memory Image's list of Order representations Assert.AreEqual(200, orderBookMemory.AskBooks.First().ToList()[0].Volume); Assert.AreEqual(100, orderBookMemory.AskBooks.First().ToList()[1].Volume); Assert.AreEqual(300, orderBookMemory.AskBooks.First().ToList()[2].Volume); Assert.AreEqual(400, orderBookMemory.AskBooks.First().ToList()[3].Volume); Assert.AreEqual(1, orderBookMemory.BidBooks.Count()); Assert.AreEqual(1, orderBookMemory.AskBooks.Count()); }
/// <summary> /// Gets the orders for rebuilding the LimitOrderBook state by replaying an event stream for orders /// </summary> /// <returns></returns> public List <Order> GetOrdersForReplay(LimitOrderBook limitOrderBook) { List <Order> replayOrderList = new List <Order>(); var orders = _eventStore.GetOrdersByCurrencyPair(limitOrderBook.CurrencyPair); if (orders != null) { foreach (Order order in orders) { // Only going to choose those orders that were submitted after the last snapshot and are of state accepted // or Cancelled if ( /*order.DateTime > limitOrderBook.LastSnapshotTaken && */ (order.OrderState == OrderState.Accepted || order.OrderState == OrderState.Cancelled)) { replayOrderList.Add(order); } } } if (replayOrderList.Count <= 0) { replayOrderList = null; } return(replayOrderList); }
public void PlaceSellOrderAbundantTest() { LimitOrderBook limitOrderBook = new LimitOrderBook("XBTUSD"); Order order1 = OrderFactory.CreateOrder("1233", "XBTUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_BUY, 150, 491.34M, new StubbedOrderIdGenerator()); Order order2 = OrderFactory.CreateOrder("1234", "XBTUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_BUY, 50, 491.34M, new StubbedOrderIdGenerator()); Order order3 = OrderFactory.CreateOrder("1222", "XBTUSD", Constants.ORDER_TYPE_LIMIT, Constants.ORDER_SIDE_BUY, 50, 491.34M, new StubbedOrderIdGenerator()); limitOrderBook.PlaceOrder(order1); limitOrderBook.PlaceOrder(order2); limitOrderBook.PlaceOrder(order3); Assert.AreEqual(3, limitOrderBook.BidCount, "Count of Buy Orders after trade execution"); bool placeOrder = limitOrderBook.PlaceOrder(new Order(new OrderId("1"), "XBTUSD", new Price(491.34M), OrderSide.Sell, OrderType.Limit, new Volume(250), new TraderId("1"))); Assert.AreEqual(0, limitOrderBook.BidCount, "Count of Buy Orders after trade execution"); Assert.AreEqual(0, limitOrderBook.AskCount, "Count of Sell Orders after trade execution"); Assert.IsTrue(placeOrder); }
/// <summary> /// Receives the Order Book from the output Disruptor /// </summary> /// <param name="orderBook"></param> public void OnOrderBookChanged(LimitOrderBook orderBook) { UpdateBids(orderBook.Bids); UpdateAsks(orderBook.Asks); }
public void PublishAllTypesToOutputDisruptor_IfAllTypesAreConvertedToByteArray_ItShouldReceivedAndProperlyCasted() { Order order = OrderFactory.CreateOrder("1234", "XBTUSD", "market", "buy", 5, 0, new StubbedOrderIdGenerator()); //byte[] array = ObjectToByteArray(order); OutputDisruptor.Publish(order); Order buyOrder = OrderFactory.CreateOrder("1234", "XBTUSD", "limit", "buy", 5, 10, new StubbedOrderIdGenerator()); Order sellOrder = OrderFactory.CreateOrder("1234", "XBTUSD", "limit", "sell", 5, 11, new StubbedOrderIdGenerator()); Trade trade = new Trade(new TradeId("123"), "XBTUSD", new Price(100), new Volume(10), DateTime.Now, buyOrder, sellOrder); //byte[] array1 = ObjectToByteArray(trade); OutputDisruptor.Publish(trade); LimitOrderBook limitOrderBook = new LimitOrderBook("XBTUSD"); limitOrderBook.PlaceOrder(buyOrder); limitOrderBook.PlaceOrder(sellOrder); //byte[] array2 = ObjectToByteArray(limitOrderBook); OutputDisruptor.Publish(limitOrderBook); Depth depth = new Depth("XBTUSD", 3); depth.AddOrder(new Price(490), new Volume(100), OrderSide.Buy); depth.AddOrder(new Price(491), new Volume(100), OrderSide.Buy); depth.AddOrder(new Price(492), new Volume(200), OrderSide.Buy); //byte[] array3 = ObjectToByteArray(depth); OutputDisruptor.Publish(depth); DepthLevel askDepthLevel = new DepthLevel(new Price(491.32M)); bool addOrder1 = askDepthLevel.AddOrder(new Volume(2000)); bool addOrder2 = askDepthLevel.AddOrder(new Volume(1000)); DepthLevel bidDepthLevel = new DepthLevel(new Price(491.32M)); addOrder1 = bidDepthLevel.AddOrder(new Volume(2000)); addOrder2 = bidDepthLevel.AddOrder(new Volume(1000)); bool addOrder3 = bidDepthLevel.AddOrder(new Volume(3000)); BBO bbo = new BBO("XBTUSD", bidDepthLevel, askDepthLevel); //byte[] array4 = ObjectToByteArray(bbo); OutputDisruptor.Publish(bbo); _manualResetEvent.WaitOne(3000); Assert.NotNull(_receviedOrder); Assert.AreEqual(_receviedOrder, order); Assert.NotNull(_receivedTrade); Assert.AreEqual(_receivedTrade.BuyOrder, buyOrder); Assert.AreEqual(_receivedTrade.SellOrder, sellOrder); Assert.NotNull(_receivedLimitOrderBook); Assert.AreEqual(_receivedLimitOrderBook.AskCount, 1); Assert.AreEqual(_receivedLimitOrderBook.BidCount, 1); Assert.NotNull(_receivedDepth); Assert.AreEqual(_receivedDepth.BidLevels[0].Price.Value, 492); Assert.AreEqual(_receivedDepth.BidLevels[1].Price.Value, 491); Assert.AreEqual(_receivedDepth.BidLevels[2].Price.Value, 490); Assert.NotNull(_receivedBbo); Assert.AreEqual(_receivedBbo.BestAsk.OrderCount, 2); Assert.AreEqual(_receivedBbo.BestBid.OrderCount, 3); }