public void GetOpenOrders_IfTraderIdIsProvided_RetrievedOrdersShouldBeDateTimeSortedAsDescending()
        {
            ManualResetEvent resetEvent = new ManualResetEvent(false);
            Order            order      = OrderFactory.CreateOrder("100", "XBTUSD", "limit", "buy", 5, 10,
                                                                   new StubbedOrderIdGenerator());

            resetEvent.WaitOne(2000);
            resetEvent.Reset();
            Order order1 = OrderFactory.CreateOrder("100", "XBTUSD", "limit", "buy", 5, 10,
                                                    new StubbedOrderIdGenerator());

            resetEvent.WaitOne(2000);
            resetEvent.Reset();
            Order order2 = OrderFactory.CreateOrder("100", "XBTUSD", "limit", "buy", 5, 10,
                                                    new StubbedOrderIdGenerator());

            resetEvent.WaitOne(2000);
            resetEvent.Reset();
            OrderReadModel model = ReadModelAdapter.GetOrderReadModel(order);

            _persistanceRepository.SaveOrUpdate(model);
            OrderReadModel model1 = ReadModelAdapter.GetOrderReadModel(order1);

            _persistanceRepository.SaveOrUpdate(model1);
            OrderReadModel model2 = ReadModelAdapter.GetOrderReadModel(order2);

            _persistanceRepository.SaveOrUpdate(model2);
            IList <OrderReadModel> getReadModel = _orderRepository.GetOpenOrders("100");

            Assert.NotNull(getReadModel);
            Assert.AreEqual(getReadModel.Count, 3);
            Assert.True(getReadModel[0].DateTime > getReadModel[1].DateTime);
            Assert.True(getReadModel[1].DateTime > getReadModel[2].DateTime);
        }
        public void ValidateCancelOrderCommand_IfOrderIdAndTraderIdIsValidAndOrderStatusIsNotCompleteOrCancelled_CommandWillBeValidated()
        {
            Order order = OrderFactory.CreateOrder("1234", "XBTUSD", "limit", "buy", 5, 10,
                                                   new StubbedOrderIdGenerator());
            OrderReadModel model = ReadModelAdapter.GetOrderReadModel(order);

            _persistanceRepository.SaveOrUpdate(model);
            CancelOrderCommand            command    = new CancelOrderCommand(order.OrderId, order.TraderId);
            ICancelOrderCommandValidation validation = new CancelOrderCommandValidation(_orderRepository);

            Assert.True(validation.ValidateCancelOrderCommand(command));
        }
        public void ValidateCancelOrderCommand_IfOrderIdAndTraderIdIsValidAndOrderStatusIsCancelled_InvalidOperationException()
        {
            Order order = OrderFactory.CreateOrder("1234", "XBTUSD", "limit", "buy", 5, 10,
                                                   new StubbedOrderIdGenerator());

            order.OrderState = OrderState.Cancelled;
            OrderReadModel model = ReadModelAdapter.GetOrderReadModel(order);

            _persistanceRepository.SaveOrUpdate(model);
            CancelOrderCommand            command    = new CancelOrderCommand(order.OrderId, order.TraderId);
            ICancelOrderCommandValidation validation = new CancelOrderCommandValidation(_orderRepository);

            validation.ValidateCancelOrderCommand(command);
        }
        public void SaveOrderReadModel_IfStateIsAccepted_ClosingTimeShouldBeNull()
        {
            Order order = OrderFactory.CreateOrder("1234", "XBTUSD", "limit", "buy", 5, 10,
                                                   new StubbedOrderIdGenerator());
            string id = DateTime.Now.ToString();

            order.OrderState = OrderState.Accepted;
            OrderReadModel model = ReadModelAdapter.GetOrderReadModel(order);

            _persistanceRepository.SaveOrUpdate(model);
            OrderReadModel getReadModel = _orderRepository.GetOrderById(order.OrderId.Id.ToString());

            Assert.NotNull(getReadModel);
            AssertAreEqual(getReadModel, model);
            Assert.Null(getReadModel.ClosingDateTime);
        }
        public void SaveOrderReadModel_IfSaveOrUpdateMethodIsCalled_ItShouldGetSavedInTheDatabase()
        {
            Order order = OrderFactory.CreateOrder("1234", "XBTUSD", "limit", "buy", 5, 10,
                                                   new StubbedOrderIdGenerator());
            string id = DateTime.Now.ToString();

            order.OrderState = OrderState.Complete;
            OrderReadModel model = ReadModelAdapter.GetOrderReadModel(order);

            _persistanceRepository.SaveOrUpdate(model);
            OrderReadModel getReadModel = _orderRepository.GetOrderById(order.OrderId.Id.ToString());

            Assert.NotNull(getReadModel);
            AssertAreEqual(getReadModel, model);
            Assert.NotNull(getReadModel.ClosingDateTime);
        }
        public void GetClosedOrders_IfTraderIdIsProvided_ItShouldRetireveAllClosedOrdersOfTrader()
        {
            Order order = OrderFactory.CreateOrder("999", "XBTUSD", "limit", "buy", 5, 10,
                                                   new StubbedOrderIdGenerator());

            order.OrderState = OrderState.Complete;
            string         id    = DateTime.Now.ToString();
            OrderReadModel model = ReadModelAdapter.GetOrderReadModel(order);

            _persistanceRepository.SaveOrUpdate(model);
            IList <OrderReadModel> getReadModel = _orderRepository.GetClosedOrders("999");

            Assert.NotNull(getReadModel);
            Assert.AreEqual(getReadModel.Count, 1);
            AssertAreEqual(getReadModel[0], model);
        }
        /// <summary>
        /// Handles the event of change in orders
        /// </summary>
        /// <param name="order"></param>
        void OnOrderStatusChanged(Order order)
        {
            _persistanceRepository.SaveOrUpdate(ReadModelAdapter.GetOrderReadModel(order));

            // If the order has been cancelled, send the info to Funds BC so that the funds can be updated
            if (order.OrderState == OrderState.Cancelled)
            {
                // First split the curreny pair into base and quote currency
                Tuple <string, string> splittedCurrencyPair =
                    CurrencySplitterService.SplitCurrencyPair(order.CurrencyPair);
                if (!string.IsNullOrEmpty(splittedCurrencyPair.Item1) &&
                    !string.IsNullOrEmpty(splittedCurrencyPair.Item2))
                {
                    // Send to the Infrastructure service which will communicate cross Bounded Context
                    _balanceValidationService.OrderCancelled(splittedCurrencyPair.Item1, splittedCurrencyPair.Item2,
                                                             order.TraderId.Id, order.OrderSide.ToString(),
                                                             order.OrderId.Id,
                                                             order.OpenQuantity.Value, order.Price.Value);
                }
            }
        }