public async Task ImmediateOrderShouldNotPersistOnEmptyMarket() { // Arrange IStockExchange stockExchange = new InMemoryStockExchangeRepository(_securitiesProvider, _ordersHistory , _orderTraceRepository, _marketOpeningTimes); string ticker = "A"; uint amount = 500; decimal askPrice = 13.0m; Order order = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = true, OrderTimeInForce = OrderTimeInForce.GoodOrKill }; // Act Order placedOrder = await stockExchange.PlaceOrder(order); OrdersPlaced ordersPlaced = stockExchange.GetOrdersPlaced(ticker); // Assert Assert.True(placedOrder.OrderStatus == OrderStatus.NoMatch); Assert.Equal(0m, ordersPlaced.ClosestAskPrice); Assert.Equal(0m, ordersPlaced.ClosestBidPrice); }
public async Task PlaceMarketOrder() { // Arrange IStockExchange stockExchange = new InMemoryStockExchangeRepository(_securitiesProvider, _ordersHistory , _orderTraceRepository, _marketOpeningTimes); string ticker = "A"; uint amount = 500; decimal askPrice = 13.0m; Order order = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = true, LimitOrder = false }; // Act Order placedOrder = await stockExchange.PlaceOrder(order); OrdersPlaced ordersPlaced = stockExchange.GetOrdersPlaced(ticker); // Assert Assert.False(placedOrder.LimitOrder); }
public async Task OrderShouldNotExecuteInAClosedMarket() { // Arrange MarketOpeningTimesTestingRepository marketTimes = new MarketOpeningTimesTestingRepository(); IStockExchange stockExchange = new InMemoryStockExchangeRepository(_securitiesProvider, _ordersHistory , _orderTraceRepository, marketTimes); string ticker = "A"; uint amount = 500; decimal askPrice = 13.0m; Order buyOrder = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = true, }; Order sellOrder = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = false, }; // Act Order placedBuyOrder1 = await stockExchange.PlaceOrder(buyOrder); Order placedSellOrder2 = await stockExchange.PlaceOrder(sellOrder); OrdersPlaced ordersPlaced = stockExchange.GetOrdersPlaced(ticker); // Assert Assert.Equal(amount, ordersPlaced.BuyOrders[askPrice.ToString()]); Assert.Equal(amount, ordersPlaced.SellOrders[askPrice.ToString()]); }
public async Task DeleteOrderAndExpectAskPriceToBeZero() { // Arrange IStockExchange stockExchange = new InMemoryStockExchangeRepository(_securitiesProvider, _ordersHistory, _orderTraceRepository, _marketOpeningTimes); string ticker = "A"; uint amount = 500; decimal askPrice = 13.0m; Order order = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = true, }; // Act Order placedOrder = await stockExchange.PlaceOrder(order); Order deletedOrder = stockExchange.RemoveOrder(placedOrder.Id); OrdersPlaced ordersPlaced = stockExchange.GetOrdersPlaced(ticker); // Assert Assert.Equal(OrderStatus.Deleted, deletedOrder.OrderStatus); Assert.False(string.IsNullOrEmpty(deletedOrder.OrderDeletionTime)); Assert.Equal(0u, ordersPlaced.BuyOrders[askPrice.ToString()]); Assert.Equal(0u, ordersPlaced.SellOrders[askPrice.ToString()]); }
public async Task ExecuteASuccessfulOrderAtSamePriceAndAddAnotherBuyOrderAtDifferentPriceThenRemoveIt() { // Arrange IStockExchange stockExchange = new InMemoryStockExchangeRepository(_securitiesProvider, _ordersHistory, _orderTraceRepository, _marketOpeningTimes); string ticker = "A"; uint amount = 500; decimal firstAskPrice = 13.0m; Order order1 = new Order { Ticker = ticker, Amount = amount, AskPrice = firstAskPrice, BuyOrder = true, }; Order order2 = new Order { Ticker = ticker, Amount = amount, AskPrice = firstAskPrice, BuyOrder = false, }; decimal secondAskPrice = 11.95m; Order order3 = new Order { Ticker = ticker, Amount = amount, AskPrice = secondAskPrice, BuyOrder = true, }; // Act Order placedOrder1 = await stockExchange.PlaceOrder(order1); Order placedOrder2 = await stockExchange.PlaceOrder(order2); OrdersPlaced ordersPlaced1 = stockExchange.GetOrdersPlaced(ticker); Order placedOrder3 = await stockExchange.PlaceOrder(order3); OrdersPlaced ordersPlaced2 = stockExchange.GetOrdersPlaced(ticker); // Assert Assert.Equal(firstAskPrice, ordersPlaced1.ClosestAskPrice); Assert.Equal(firstAskPrice, ordersPlaced1.ClosestBidPrice); Assert.Equal(secondAskPrice, ordersPlaced2.ClosestAskPrice); Assert.Equal(firstAskPrice, ordersPlaced2.ClosestBidPrice); }
public async Task TwoLimitOrdersSamePriceSameAmountExecutedThenPlaceADifferentOrder() { // Arrange IStockExchange stockExchange = new InMemoryStockExchangeRepository(_securitiesProvider, _ordersHistory , _orderTraceRepository, _marketOpeningTimes); string ticker = "A"; uint amount = 500; decimal askPrice = 13.0m; decimal thirdAskPrice = 14.3m; decimal expectedSpread = Math.Abs(askPrice - thirdAskPrice); Order buyOrder = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = true, }; Order sellOrder = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = false, }; Order thirdOrder = new Order { Ticker = ticker, Amount = amount, AskPrice = thirdAskPrice, BuyOrder = false, }; // Act Order placedBuyOrder = await stockExchange.PlaceOrder(buyOrder); Order placedSellOrder = await stockExchange.PlaceOrder(sellOrder); Order placedThridOrder = await stockExchange.PlaceOrder(thirdOrder); OrdersPlaced ordersPlaced = stockExchange.GetOrdersPlaced(ticker); // Assert Assert.Equal(askPrice, ordersPlaced.ClosestAskPrice); Assert.Equal(amount, ordersPlaced.SellOrders[thirdAskPrice.ToString()]); Assert.Equal(thirdAskPrice, placedThridOrder.AskPrice); Assert.Equal(thirdAskPrice, ordersPlaced.ClosestBidPrice); Assert.Equal(expectedSpread, ordersPlaced.ClosestSpread); }
public async Task TwoLimitOrdersDifferentPricesSameAmountNotExecuted() { // Arrange IStockExchange stockExchange = new InMemoryStockExchangeRepository(_securitiesProvider, _ordersHistory , _orderTraceRepository, _marketOpeningTimes); string ticker = "A"; uint amount = 500; decimal askBuyPrice = 13.0m; decimal askSellPrice = 13.4m; decimal expectedSpread = Math.Abs(askBuyPrice - askSellPrice); Order buyOrder = new Order { Ticker = ticker, Amount = amount, AskPrice = askBuyPrice, BuyOrder = true, }; Order sellOrder = new Order { Ticker = ticker, Amount = amount, AskPrice = askSellPrice, BuyOrder = false, }; // Act Order placedBuyOrder = await stockExchange.PlaceOrder(buyOrder); Order placedSellOrder = await stockExchange.PlaceOrder(sellOrder); OrdersPlaced ordersPlaced = stockExchange.GetOrdersPlaced(ticker); // Assert Assert.Equal(OrderStatus.InMarket, placedBuyOrder.OrderStatus); Assert.Equal(OrderStatus.InMarket, placedSellOrder.OrderStatus); Assert.Equal(amount, ordersPlaced.BuyOrders[askBuyPrice.ToString()]); Assert.Equal(0u, ordersPlaced.BuyOrders[askSellPrice.ToString()]); Assert.Equal(0u, ordersPlaced.SellOrders[askBuyPrice.ToString()]); Assert.Equal(amount, ordersPlaced.SellOrders[askSellPrice.ToString()]); Assert.Equal(askBuyPrice, ordersPlaced.ClosestAskPrice); Assert.Equal(askSellPrice, ordersPlaced.ClosestBidPrice); Assert.Equal(expectedSpread, ordersPlaced.ClosestSpread); }
public async Task PerformBasicTradeWhileCheckingHistoryIsCorrect() { // Arrange IStockExchange stockExchange = new InMemoryStockExchangeRepository(_securitiesProvider, _ordersHistory, _orderTraceRepository, _marketOpeningTimes); string ticker = "A"; uint amount = 500; decimal askPrice = 13.0m; string buyOrderId = Guid.NewGuid().ToString(); string sellOrderId = Guid.NewGuid().ToString(); Order sellOrder = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = true, Id = sellOrderId }; Order buyOrder = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = false, Id = buyOrderId }; // Act I await stockExchange.PlaceOrder(sellOrder); // Assert I Assert.True(_ordersHistory._archivedOrders.ContainsKey(sellOrderId)); Assert.Equal(OrderStatus.InMarket, _ordersHistory._archivedOrders[sellOrderId].OrderStatus); // Act II await stockExchange.PlaceOrder(buyOrder); // Assert II Assert.True(_ordersHistory._archivedOrders.ContainsKey(buyOrderId)); Assert.Equal(OrderStatus.Executed, _ordersHistory._archivedOrders[sellOrderId].OrderStatus); Assert.Equal(OrderStatus.Executed, _ordersHistory._archivedOrders[buyOrderId].OrderStatus); }
public async Task PlaceLimitOrderThenMarketOrderShouldExecute() { // Arrange IStockExchange stockExchange = new InMemoryStockExchangeRepository(_securitiesProvider, _ordersHistory , _orderTraceRepository, _marketOpeningTimes); string ticker = "A"; uint amount = 500; decimal askPrice = 13.0m; Order limitOrder = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = false }; Order marketOrder = new Order { Ticker = ticker, Amount = amount, BuyOrder = true, AskPrice = 1, LimitOrder = false }; // Act Order placedLimitOrder = await stockExchange.PlaceOrder(limitOrder); Order placedMarketOrder = await stockExchange.PlaceOrder(marketOrder); OrdersPlaced ordersPlaced = stockExchange.GetOrdersPlaced(ticker); // Assert Assert.Equal(OrderStatus.Executed, placedLimitOrder.OrderStatus); Assert.Equal(OrderStatus.Executed, placedMarketOrder.OrderStatus); Assert.Equal(0u, ordersPlaced.BuyOrders[askPrice.ToString()]); Assert.Equal(0u, ordersPlaced.SellOrders[askPrice.ToString()]); Assert.Equal(placedMarketOrder.ExecutedPrice, ordersPlaced.ClosestBidPrice); Assert.Equal(askPrice, ordersPlaced.ClosestAskPrice); }
public async Task TwoLimitOrdersSamePriceSameAmountBeingExecutedTest() { // Arrange IStockExchange stockExchange = new InMemoryStockExchangeRepository(_securitiesProvider, _ordersHistory , _orderTraceRepository, _marketOpeningTimes); string ticker = "A"; uint amount = 500; decimal askPrice = 13.0m; Order buyOrder = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = true, }; Order sellOrder = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = false, }; // Act Order placedBuyOrder = await stockExchange.PlaceOrder(buyOrder); Order placedSellOrder = await stockExchange.PlaceOrder(sellOrder); OrdersPlaced ordersPlaced = stockExchange.GetOrdersPlaced(ticker); // Assert Assert.True(placedBuyOrder.OrderStatus == OrderStatus.Executed); Assert.True(placedSellOrder.OrderStatus == OrderStatus.Executed); Assert.Equal(0u, ordersPlaced.BuyOrders[askPrice.ToString()]); Assert.Equal(0u, ordersPlaced.SellOrders[askPrice.ToString()]); Assert.Equal(askPrice, ordersPlaced.ClosestAskPrice); Assert.Equal(askPrice, ordersPlaced.ClosestBidPrice); Assert.Equal(0m, ordersPlaced.ClosestSpread); }
public async Task BasicPlaceASingleOrderTest() { // Arrange IStockExchange stockExchange = new InMemoryStockExchangeRepository(_securitiesProvider, _ordersHistory , _orderTraceRepository, _marketOpeningTimes); string ticker = "A"; uint amount = 500; decimal askPrice = 13.0m; Order order = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = true, }; // Act Order placedOrder = await stockExchange.PlaceOrder(order); OrdersPlaced ordersPlaced = stockExchange.GetOrdersPlaced(ticker); // Assert Assert.Equal(ticker, placedOrder.Ticker); Assert.Equal(amount, placedOrder.Amount); Assert.Equal(askPrice, order.AskPrice); Assert.Equal(OrderStatus.InMarket, placedOrder.OrderStatus); Assert.True(placedOrder.BuyOrder); Assert.True(placedOrder.LimitOrder); Assert.True(ordersPlaced.BuyOrders.Count == 1); Assert.True(ordersPlaced.SellOrders.Count == 1); Assert.Equal(amount, ordersPlaced.BuyOrders[askPrice.ToString()]); Assert.Equal(0u, ordersPlaced.SellOrders[askPrice.ToString()]); Assert.Equal(askPrice, ordersPlaced.ClosestAskPrice); Assert.Equal(askPrice, ordersPlaced.ClosestSpread); }
public async Task ImmediateOrderShouldExecuteOnMarketWithLiquidity() { // Arrange IStockExchange stockExchange = new InMemoryStockExchangeRepository(_securitiesProvider, _ordersHistory , _orderTraceRepository, _marketOpeningTimes); string ticker = "A"; uint amount = 1500; decimal askPrice = 13.0m; Order order1 = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = true, }; Order order2 = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = false, OrderTimeInForce = OrderTimeInForce.GoodOrKill }; // Act Order placedOrder1 = await stockExchange.PlaceOrder(order1); Order placedOrder2 = await stockExchange.PlaceOrder(order2); OrdersPlaced ordersPlaced = stockExchange.GetOrdersPlaced(ticker); // Assert Assert.Equal(OrderStatus.Executed, placedOrder2.OrderStatus); Assert.Equal(0u, ordersPlaced.BuyOrders[askPrice.ToString()]); // TODO there is a bug below, most likely due to the language, remedy it //Assert.Equal(0u, ordersPlaced.SellOrders[askPrice.ToString()]); }
public async Task ShouldShowCorrectTraceOnExecutedOrders() { IStockExchange stockExchange = new InMemoryStockExchangeRepository(_securitiesProvider, _ordersHistory , _orderTraceRepository, _marketOpeningTimes); string ticker = "A"; uint amount = 500; decimal askPrice = 13.0m; Order order1 = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = true, }; Order order2 = new Order { Ticker = ticker, Amount = amount, AskPrice = askPrice, BuyOrder = false, }; // Act I Order placedOrder1 = await stockExchange.PlaceOrder(order1); // Assert I Assert.True(_orderTraceRepository._orderTraces.Count == 1); Assert.Equal(placedOrder1.Id, _orderTraceRepository._orderTraces.First.Value.OrderId); // Act II Order placedOrder2 = await stockExchange.PlaceOrder(order2); // Assert II Assert.True(_orderTraceRepository._orderTraces.Count == 4); Assert.Equal(OrderStatus.Executed, _orderTraceRepository._orderTraces.Last.Previous.Value.OrderStatus); Assert.Equal(OrderStatus.Executed, _orderTraceRepository._orderTraces.Last.Value.OrderStatus); }