public void ShouldIgnoreOrderWithDifferentPriceOnAdd() { IPriceSlot priceSlot = new PriceSlot(90, new LimitOrderMatchingAlgorithm(new DateService()), new MarketOrderMatchingAlgorithm(new DateService())); var buyOrder = new LimitOrder("ABC", 10, 91, WayEnum.Buy, 9); priceSlot.AddOrder(buyOrder); Assert.AreEqual(0, priceSlot.BuyOrders.Count); }
public void ShouldRegisterDeleteHandlerAndRaiseDeleteEvent() { var receivedDeletedOrders = new List<ILimitOrder>(); var newOrder = new LimitOrder("ABC", 10, 99.22d, WayEnum.Buy, 3); newOrder.RegisterDeleteNotificationHandler(receivedDeletedOrders.Add); newOrder.Delete(); Assert.AreEqual(1, receivedDeletedOrders.Count); }
public void ShouldAddSellOrder() { IPriceSlot priceSlot = new PriceSlot(90, new LimitOrderMatchingAlgorithm(new DateService()), new MarketOrderMatchingAlgorithm(new DateService())); var sellOrder = new LimitOrder("ABC", 10, 90, WayEnum.Sell, 9); priceSlot.AddOrder(sellOrder); Assert.AreEqual(1, priceSlot.SellOrders.Count); Assert.AreEqual(sellOrder, priceSlot.SellOrders[0]); }
public void ShouldInstantiateWithValues() { var newOrder = new LimitOrder("ABC", 10, 99.22d, WayEnum.Buy, 3); Assert.AreEqual("ABC", newOrder.Symbol); Assert.AreEqual(10, newOrder.Quantity); Assert.AreEqual(99.22d, newOrder.Price); Assert.AreEqual(WayEnum.Buy, newOrder.Way); Assert.AreEqual(3, newOrder.ClientId); }
public void BookShouldSetBestAskAndNullBidOnOneSellOrder() { var orderBookBestBidAsk = new OrderBookBestBidAsk("ABC"); var book = new OrderBook("ABC", limitOrderMatchingAlgorithmMock, marketOrderMatchingAlgorithmMock, orderBookBestBidAsk); var sellOrder = new LimitOrder("ABC", 10, 90, WayEnum.Sell, 9); book.AddLimitOrder(sellOrder); Assert.AreEqual(90, orderBookBestBidAsk.BestAskPrice); Assert.IsNull(orderBookBestBidAsk.BestBidPrice); }
public void ShouldRegisterFilledHandlerAndReceiveFilledEvent() { var filledOrders = new List<ILimitOrder>(); var newOrder = new LimitOrder("ABC", 10, 99.22d, WayEnum.Buy, 3); newOrder.RegisterFilledNotification(filledOrders.Add); newOrder.Modify(0, 88.44d); Assert.AreEqual(1, filledOrders.Count); Assert.AreEqual(newOrder, filledOrders[0]); }
public void BookShouldRemoveSlotWhenOrderIsFilled() { var orderBookBestBidAsk = new OrderBookBestBidAsk("ABC"); var book = new OrderBook("ABC", limitOrderMatchingAlgorithmMock, marketOrderMatchingAlgorithmMock, orderBookBestBidAsk); var buyOrder = new LimitOrder("ABC", 10, 90, WayEnum.Buy, 9); book.AddLimitOrder(buyOrder); Assert.IsTrue(book.PriceSlots.ContainsKey(90)); Assert.AreEqual(buyOrder, book.PriceSlots[90].BuyOrders[0]); buyOrder.Modify(0); Assert.IsFalse(book.PriceSlots.ContainsKey(90)); }
public void ShouldRegisterModifyEventHandlerAndReceiveModifyEvent() { var newOrder = new LimitOrder("ABC", 10, 99.22d, WayEnum.Buy, 3); newOrder.RegisterModifyNotificationHandler((order, oldQuantity, oldPrice) => { Assert.AreEqual(newOrder, order); Assert.AreEqual(11, order.Quantity); Assert.AreEqual(88.44d, order.Price); Assert.AreEqual(10, oldQuantity); Assert.AreEqual(99.22d, oldPrice); }); newOrder.Modify(11, 88.44d); }
public void ShouldExecuteOnLowestQuantity() { var staticDatetimeOffset = DateTimeOffset.UtcNow; dateServiceMock.Stub(a => a.UtcNow()).Return(staticDatetimeOffset); var generatedExecutions = new List<INewExecution>(); var algo = new LimitOrderMatchingAlgorithm(dateServiceMock); algo.AddExecutionsHandler(generatedExecutions.Add); ILimitOrder sellOrder = new LimitOrder("ABC", 40, 90, WayEnum.Sell, 13); ILimitOrder buyOrder = new LimitOrder("ABC", 100, 90, WayEnum.Buy, 12); algo.TryMatch(buyOrder, sellOrder); Assert.AreEqual(1, generatedExecutions.Count); Assert.AreEqual(40, generatedExecutions[0].MatchedQuantity); }
public void OrdersShouldNotHaveModifiedQuantitiesAfterNoMatch() { var staticDatetimeOffset = DateTimeOffset.UtcNow; dateServiceMock.Stub(a => a.UtcNow()).Return(staticDatetimeOffset); var generatedExecutions = new List<INewExecution>(); var algo = new LimitOrderMatchingAlgorithm(dateServiceMock); algo.AddExecutionsHandler(generatedExecutions.Add); ILimitOrder sellOrder = new LimitOrder("ABC", 40, 91, WayEnum.Sell, 13); ILimitOrder buyOrder = new LimitOrder("ABC", 100, 90, WayEnum.Buy, 12); algo.TryMatch(buyOrder, sellOrder); Assert.AreEqual(40, sellOrder.Quantity); Assert.AreEqual(100, buyOrder.Quantity); }
public void PublisherShouldReceiveOrderModifiedData() { var limitOrder = new LimitOrder("ABC", 21, 20d, WayEnum.Buy, 90); outgoingQueue.EnqueueUpdatedLimitOrder(limitOrder, 21, 20d); Thread.Sleep(100); messagePublisherMock.AssertWasCalled(a => a.OnNext(Arg<ServerToClientMessage>.Matches(b => b.MessageType == ServerToClientMessageTypeEnum.LimitOrderChanged && b.LimitOrder.ClientId == 90 && b.LimitOrder.Price == 20d && b.LimitOrder.Quantity == 21 && b.LimitOrder.Symbol == "ABC" && b.LimitOrder.Way == WayEnum.Buy), Arg<long>.Is.Anything, Arg<bool>.Is.Anything), options => options.Repeat.Once()); }
public void ShouldRegisterModifyEventHandlerAndUnregister() { var receivedModifedOrders = new List<ILimitOrder>(); var newOrder = new LimitOrder("ABC", 10, 99.22d, WayEnum.Buy, 3); Action<ILimitOrder, int, double> eventHandler; eventHandler = (order, oldQuantity, oldPrice) => { receivedModifedOrders.Add(order); }; newOrder.RegisterModifyNotificationHandler(eventHandler); newOrder.Modify(11, 88.44d); newOrder.UnRegisterModifyNotificationHandler(eventHandler); newOrder.Modify(13, 12.44d); Assert.AreEqual(1, receivedModifedOrders.Count); }
public void ShouldMatchBuyOrderCompletely() { var executions = new List<INewExecution>(); var executionalgo = new LimitOrderMatchingAlgorithm(new DateService()); executionalgo.AddExecutionsHandler(executions.Add); var priceSlot = new PriceSlot(90, executionalgo, new MarketOrderMatchingAlgorithm(new DateService())); var sellOrder = new LimitOrder("ABC", 100, 90, WayEnum.Sell, 90); var buyOrder = new LimitOrder("ABC", 10, 90, WayEnum.Buy, 80); priceSlot.AddOrder(sellOrder); priceSlot.TryMatchLimitOrder(buyOrder); Assert.AreEqual(1, executions.Count); Assert.AreEqual(0, priceSlot.BuyOrders.Count); Assert.AreEqual(1, priceSlot.SellOrders.Count); Assert.AreEqual(90, priceSlot.SellOrders[0].Quantity); }
public void ShouldMatchMultipleSellOrdersToSameBuyOrder() { var executions = new List<INewExecution>(); var executionalgo = new LimitOrderMatchingAlgorithm(new DateService()); executionalgo.AddExecutionsHandler(executions.Add); var priceSlot = new PriceSlot(90, executionalgo, new MarketOrderMatchingAlgorithm(new DateService())); var sellOrder1 = new LimitOrder("ABC", 10, 90, WayEnum.Sell, 90); var sellOrder2 = new LimitOrder("ABC", 40, 90, WayEnum.Sell, 90); var buyOrder = new LimitOrder("ABC", 50, 90, WayEnum.Buy, 80); priceSlot.AddOrder(sellOrder1); priceSlot.AddOrder(sellOrder2); priceSlot.TryMatchLimitOrder(buyOrder); Assert.AreEqual(2, executions.Count); Assert.AreEqual(0, priceSlot.BuyOrders.Count); Assert.AreEqual(0, priceSlot.SellOrders.Count); }
public void BookShouldSetBestBidOnHigherBuyOrders() { var orderBookBestBidAsk = new OrderBookBestBidAsk("ABC"); var book = new OrderBook("ABC", limitOrderMatchingAlgorithmMock, marketOrderMatchingAlgorithmMock, orderBookBestBidAsk); Assert.IsNull(orderBookBestBidAsk.BestBidPrice); var buyOrder1 = new LimitOrder("ABC", 10, 90.1d, WayEnum.Buy, 1); book.AddLimitOrder(buyOrder1); Assert.AreEqual(90.1d, orderBookBestBidAsk.BestBidPrice); var buyOrder2 = new LimitOrder("ABC", 10, 90.2d, WayEnum.Buy, 1); book.AddLimitOrder(buyOrder2); Assert.AreEqual(90.2d, orderBookBestBidAsk.BestBidPrice); var buyOrder3 = new LimitOrder("ABC", 10, 80.0d, WayEnum.Buy, 1); book.AddLimitOrder(buyOrder3); Assert.AreEqual(90.2d, orderBookBestBidAsk.BestBidPrice); }
public void ShouldNotMatchOrdersWithZeroQuantity() { var generatedExecutions = new List<INewExecution>(); var algo = new LimitOrderMatchingAlgorithm(dateServiceMock); algo.AddExecutionsHandler(generatedExecutions.Add); ILimitOrder sellOrder = new LimitOrder("ABC", 0, 90, WayEnum.Sell, 13); ILimitOrder buyOrder = new LimitOrder("ABC", 10, 90, WayEnum.Buy, 12); algo.TryMatch(buyOrder, sellOrder); Assert.AreEqual(0, generatedExecutions.Count); sellOrder.Modify(90); buyOrder.Modify(0); algo.TryMatch(buyOrder, sellOrder); Assert.AreEqual(0, generatedExecutions.Count); }
public void ShouldNotMatchHigherSellOrderWithLowerBuyOrder() { var generatedExecutions = new List<INewExecution>(); var algo = new LimitOrderMatchingAlgorithm(dateServiceMock); algo.AddExecutionsHandler(generatedExecutions.Add); ILimitOrder sellOrder = new LimitOrder("ABC", 10, 100, WayEnum.Sell, 13); ILimitOrder buyOrder = new LimitOrder("ABC", 10, 90, WayEnum.Buy, 12); algo.TryMatch(buyOrder, sellOrder); Assert.AreEqual(0, generatedExecutions.Count); }
public void ShouldGenerateExecutionWithSamePriceAsBuyAndSell() { var staticDatetimeOffset = DateTimeOffset.UtcNow; dateServiceMock.Stub(a => a.UtcNow()).Return(staticDatetimeOffset); var generatedExecutions = new List<INewExecution>(); var algo = new LimitOrderMatchingAlgorithm(dateServiceMock); algo.AddExecutionsHandler(generatedExecutions.Add); ILimitOrder sellOrder = new LimitOrder("ABC", 10, 90, WayEnum.Sell, 13); ILimitOrder buyOrder = new LimitOrder("ABC", 10, 90, WayEnum.Buy, 12); algo.TryMatch(buyOrder, sellOrder); Assert.AreEqual(1, generatedExecutions.Count); Assert.AreEqual(10, generatedExecutions[0].MatchedQuantity); Assert.AreEqual(90, generatedExecutions[0].MatchedPrice); Assert.AreEqual(buyOrder, generatedExecutions[0].BuySideOrder); Assert.AreEqual(sellOrder, generatedExecutions[0].SellSideOrder); Assert.AreEqual(staticDatetimeOffset, generatedExecutions[0].ExecutionTime); }
public void BookShouldSetBestAskOnLowerSellOrders() { var orderBookBestBidAsk = new OrderBookBestBidAsk("ABC"); var book = new OrderBook("ABC", limitOrderMatchingAlgorithmMock, marketOrderMatchingAlgorithmMock, orderBookBestBidAsk); Assert.IsNull(orderBookBestBidAsk.BestAskPrice); var order1 = new LimitOrder("ABC", 10, 90.1d, WayEnum.Sell, 1); book.AddLimitOrder(order1); Assert.AreEqual(90.1d, orderBookBestBidAsk.BestAskPrice); var order2 = new LimitOrder("ABC", 10, 90.0d, WayEnum.Sell, 1); book.AddLimitOrder(order2); Assert.AreEqual(90.0d, orderBookBestBidAsk.BestAskPrice); var order3 = new LimitOrder("ABC", 10, 99.0d, WayEnum.Sell, 1); book.AddLimitOrder(order3); Assert.AreEqual(90.0d, orderBookBestBidAsk.BestAskPrice); }
public void ShouldUnregisterAllHandlersOnDelete() { var receivedDeletedOrders = new List<ILimitOrder>(); var receivedModifyOrders = new List<ILimitOrder>(); var newOrder = new LimitOrder("ABC", 10, 99.22d, WayEnum.Buy, 3); Action<ILimitOrder, int, double> modifyEventHandler; modifyEventHandler = (order, oldQuantity, oldPrice) => { receivedModifyOrders.Add(order); }; newOrder.RegisterDeleteNotificationHandler(receivedDeletedOrders.Add); newOrder.RegisterModifyNotificationHandler(modifyEventHandler); newOrder.Delete(); newOrder.Modify(90,20); newOrder.Delete(); Assert.AreEqual(1, receivedDeletedOrders.Count); Assert.AreEqual(0, receivedModifyOrders.Count); }
public void ShouldNotMatchSellStopLimitOrderLowerThanMarket() { var executions = new List<INewExecution>(); var orderBookBestBidAsk = new OrderBookBestBidAsk("ABC"); var matchAlgo = new LimitOrderMatchingAlgorithm(new DateService()); matchAlgo.AddExecutionsHandler(executions.Add); var book = new OrderBook("ABC", matchAlgo, marketOrderMatchingAlgorithmMock, orderBookBestBidAsk); var sellOrder1 = new LimitOrder("ABC", 10, 1161.8d, WayEnum.Sell, 9); book.AddLimitOrder(sellOrder1); var buyOrder1 = new LimitOrder("ABC", 10, 1161.7d, WayEnum.Buy, 9); book.AddLimitOrder(buyOrder1); var trigger = new BestPriceTrigger("ABC", 1160, WayEnum.Sell); trigger.SetTriggerAction(() => { Console.WriteLine("Boom!"); int i = 0; }); var sellStopLimit = new StopLimitOrder("ABC", 1, 1160,1160, WayEnum.Sell, 5, trigger); book.AddStopLimitOrder(sellStopLimit); Assert.AreEqual(0, executions.Count); }
public void ShouldNotMatchOrderWhenMatchingIsSuspendedButMatchWhenSuspensionsIsCancelled() { var executions = new List<INewExecution>(); var orderBookBestBidAsk = new OrderBookBestBidAsk("ABC"); var matchAlgo = new LimitOrderMatchingAlgorithm(new DateService()); matchAlgo.AddExecutionsHandler(executions.Add); var book = new OrderBook("ABC", matchAlgo, marketOrderMatchingAlgorithmMock, orderBookBestBidAsk); var sellOrder1 = new LimitOrder("ABC", 10, 90, WayEnum.Sell, 9); var buyOrder1 = new LimitOrder("ABC", 10, 80, WayEnum.Buy, 9); sellOrder1.RegisterModifyNotificationHandler(book.HandleLimitOrderModify); buyOrder1.RegisterModifyNotificationHandler(book.HandleLimitOrderModify); book.AddLimitOrder(sellOrder1); book.AddLimitOrder(buyOrder1); Assert.AreEqual(0, executions.Count); book.SetSuspendLimitOrderMatchingStatus(true); sellOrder1.Modify(10,70); Assert.AreEqual(0, executions.Count); book.SetSuspendLimitOrderMatchingStatus(true); book.TryMatchLimitOrder(sellOrder1); book.TryMatchLimitOrder(buyOrder1); Assert.AreEqual(1, executions.Count); }
public void IncomingBuyOrderShouldBeMatchedCompletelyAndNotBooked() { var orderBookBestBidAsk = new OrderBookBestBidAsk("ABC"); var book = new OrderBook("ABC", new LimitOrderMatchingAlgorithm(new DateService()), new MarketOrderMatchingAlgorithm(new DateService()), orderBookBestBidAsk); var sellOrder1 = new LimitOrder("ABC", 100, 90, WayEnum.Sell, 9); book.AddLimitOrder(sellOrder1); var buyOrder1 = new LimitOrder("ABC", 10, 90, WayEnum.Buy, 9); book.AddLimitOrder(buyOrder1); Assert.AreEqual(0, buyOrder1.Quantity); Assert.AreEqual(90, sellOrder1.Quantity); Assert.AreEqual(0, book.PriceSlots[90].BuyOrders.Count); Assert.AreEqual(1, book.PriceSlots[90].SellOrders.Count); }
public void HigherBuyOrderShouldMatchLowerSellOrdersAndPlaceBuyOrderInBookOnRestQuantity() { var executions = new List<INewExecution>(); var orderBookBestBidAsk = new OrderBookBestBidAsk("ABC"); var matchAlgo = new LimitOrderMatchingAlgorithm(new DateService()); matchAlgo.AddExecutionsHandler(executions.Add); var book = new OrderBook("ABC", matchAlgo, marketOrderMatchingAlgorithmMock, orderBookBestBidAsk); var sellOrder1 = new LimitOrder("ABC", 10, 90, WayEnum.Sell, 9); var sellOrder2 = new LimitOrder("ABC", 10, 91, WayEnum.Sell, 9); var sellOrder3 = new LimitOrder("ABC", 10, 92, WayEnum.Sell, 9); var sellOrder4 = new LimitOrder("ABC", 10, 93, WayEnum.Sell, 9); var sellOrder5 = new LimitOrder("ABC", 10, 94, WayEnum.Sell, 9); book.AddLimitOrder(sellOrder1); book.AddLimitOrder(sellOrder2); book.AddLimitOrder(sellOrder3); book.AddLimitOrder(sellOrder4); book.AddLimitOrder(sellOrder5); Assert.AreEqual(90, orderBookBestBidAsk.BestAskPrice); Assert.AreEqual(10, orderBookBestBidAsk.BestAskQuantity); var buyOrder1 = new LimitOrder("ABC", 100, 93, WayEnum.Buy, 9); book.AddLimitOrder(buyOrder1); Assert.AreEqual(4, executions.Count); Assert.AreEqual(60, buyOrder1.Quantity); Assert.AreEqual(94, orderBookBestBidAsk.BestAskPrice); Assert.AreEqual(10, orderBookBestBidAsk.BestAskQuantity); Assert.AreEqual(93, orderBookBestBidAsk.BestBidPrice); Assert.AreEqual(60, orderBookBestBidAsk.BestBidQuantity); }
public void BookShouldUpdateBestBidWhenBetterBuyPriceComesIn() { var orderBookBestBidAsk = new OrderBookBestBidAsk("ABC"); var book = new OrderBook("ABC", limitOrderMatchingAlgorithmMock, marketOrderMatchingAlgorithmMock, orderBookBestBidAsk); var buyOrder1 = new LimitOrder("ABC", 10, 90, WayEnum.Buy, 9); book.AddLimitOrder(buyOrder1); Assert.AreEqual(90, orderBookBestBidAsk.BestBidPrice); var buyOrder2 = new LimitOrder("ABC", 10, 91, WayEnum.Buy, 9); book.AddLimitOrder(buyOrder2); Assert.AreEqual(91, orderBookBestBidAsk.BestBidPrice); }
public void ShouldReturnTrueWhenSellOrdersArePresent() { var slot = new PriceSlot(90, new LimitOrderMatchingAlgorithm(new DateService()), new MarketOrderMatchingAlgorithm(new DateService())); var sellOrder = new LimitOrder("ABC", 50, 90, WayEnum.Sell, 80); slot.AddOrder(sellOrder); Assert.IsTrue(slot.HasOrders); Assert.IsTrue(slot.HasAsks); Assert.IsFalse(slot.HasBids); }
public void ShouldRemoveBuyOrder() { IPriceSlot priceSlot = new PriceSlot(90, new LimitOrderMatchingAlgorithm(new DateService()), new MarketOrderMatchingAlgorithm(new DateService())); var buyOrder = new LimitOrder("ABC", 10, 90, WayEnum.Buy, 9); priceSlot.AddOrder(buyOrder); Assert.AreEqual(1, priceSlot.BuyOrders.Count); Assert.AreEqual(buyOrder, priceSlot.BuyOrders[0]); priceSlot.RemoveOrder(buyOrder); Assert.AreEqual(0, priceSlot.BuyOrders.Count); }
public ILimitOrder NewLimitOrder(string symbol, int clientId, double price, int quantity, WayEnum way) { if (!ClientOrders.ContainsKey(clientId)) ClientOrders.Add(clientId, new EditableList<ILimitOrder>()); ILimitOrder toReturn = new LimitOrder(symbol, quantity, price, way, clientId); toReturn.SetExchangeOrderId(globalItemCounter); LimitOrders.Add(toReturn.ExchangeOrderId, toReturn); ClientOrders[clientId].Add(toReturn); toReturn.RegisterDeleteNotificationHandler(HandleDeletedLimitOrder); toReturn.RegisterFilledNotification(HandleDeletedLimitOrder); globalItemCounter++; return toReturn; }
public void BookShouldUpdateBestAskWhenBetterSellPriceComesIn() { var orderBookBestBidAsk = new OrderBookBestBidAsk("ABC"); var book = new OrderBook("ABC", limitOrderMatchingAlgorithmMock, marketOrderMatchingAlgorithmMock, orderBookBestBidAsk); var sellOrder1 = new LimitOrder("ABC", 10, 90, WayEnum.Sell, 9); book.AddLimitOrder(sellOrder1); Assert.AreEqual(90, orderBookBestBidAsk.BestAskPrice); var sellOrder2 = new LimitOrder("ABC", 10, 89, WayEnum.Sell, 9); book.AddLimitOrder(sellOrder2); Assert.AreEqual(89, orderBookBestBidAsk.BestAskPrice); }