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()]);
        }
예제 #4
0
        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()]);
        }
예제 #5
0
        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);
        }
예제 #8
0
        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()]);
        }
예제 #13
0
        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);
        }