public void ProcessSynchronousEventsShouldPerformCashSyncOnlyAtExpectedTime()
        {
            // Initializes the transaction handler
            var transactionHandler = new TestBrokerageTransactionHandler();
            var broker             = new Mock <IBrokerage>();

            broker.Setup(m => m.GetCashBalance()).Returns(new List <Cash> {
                new Cash("USD", 10, 10)
            });

            // This is 2 am New York
            transactionHandler.TestCurrentTimeUtc = new DateTime(1, 1, 1, 7, 0, 0);

            transactionHandler.Initialize(_algorithm, broker.Object, new BacktestingResultHandler());
            _algorithm.SetLiveMode(true);

            var lastSyncDateBefore = transactionHandler.GetLastSyncDate();

            // Advance current time UTC
            transactionHandler.TestCurrentTimeUtc = transactionHandler.TestCurrentTimeUtc.AddDays(2);

            transactionHandler.ProcessSynchronousEvents();
            var lastSyncDateAfter = transactionHandler.GetLastSyncDate();

            Assert.AreEqual(lastSyncDateAfter, lastSyncDateBefore);

            broker.Verify(m => m.GetCashBalance(), Times.Exactly(0));
        }
        public void OrderFillShouldTriggerRePerformingCashSync()
        {
            // Initializes the transaction handler
            var transactionHandler = new TestBrokerageTransactionHandler();
            var broker             = new Mock <IBrokerage>();

            broker.Setup(m => m.GetCashBalance()).Returns(new List <Cash> {
                new Cash("USD", 10, 10)
            });
            transactionHandler.Initialize(_algorithm, broker.Object, new BacktestingResultHandler());
            _algorithm.SetLiveMode(true);

            var lastSyncDateBefore = transactionHandler.GetLastSyncDate();

            // Advance current time UTC so cash sync is performed
            transactionHandler.TestCurrentTimeUtc = transactionHandler.TestCurrentTimeUtc.AddDays(2);

            transactionHandler.ProcessSynchronousEvents();
            var lastSyncDateAfter = transactionHandler.GetLastSyncDate();

            // cash sync happened
            Assert.AreNotEqual(lastSyncDateAfter, lastSyncDateBefore);

            // update last fill time
            transactionHandler.TestTimeSinceLastFill = TimeSpan.FromSeconds(15);
            // delayed task should take ~10 seconds to set the perform cash sync flag up, due to TimeSinceLastFill
            Thread.Sleep(15000);

            transactionHandler.ProcessSynchronousEvents();

            broker.Verify(m => m.GetCashBalance(), Times.Exactly(2));
        }
        public void ProcessSynchronousEventsShouldPerformCashSyncOnce()
        {
            // Initializes the transaction handler
            var transactionHandler = new TestBrokerageTransactionHandler();
            var broker             = new Mock <IBrokerage>();

            broker.Setup(m => m.GetCashBalance()).Returns(new List <Cash> {
                new Cash("USD", 10, 10)
            });
            transactionHandler.Initialize(_algorithm, broker.Object, new BacktestingResultHandler());
            _algorithm.SetLiveMode(true);

            var lastSyncDateBefore = transactionHandler.GetLastSyncDate();

            // Advance current time UTC so cash sync is performed
            transactionHandler.TestCurrentTimeUtc = transactionHandler.TestCurrentTimeUtc.AddDays(2);

            transactionHandler.ProcessSynchronousEvents();
            var lastSyncDateAfter = transactionHandler.GetLastSyncDate();

            Assert.AreNotEqual(lastSyncDateAfter, lastSyncDateBefore);

            transactionHandler.ProcessSynchronousEvents();
            var lastSyncDateAfterAgain = transactionHandler.GetLastSyncDate();

            Assert.AreEqual(lastSyncDateAfter, lastSyncDateAfterAgain);

            broker.Verify(m => m.GetCashBalance(), Times.Once);
        }
        public void OrderCancellationTransitionsThroughCancelPendingStatus()
        {
            // Initializes the transaction handler
            var transactionHandler = new TestBrokerageTransactionHandler();

            transactionHandler.Initialize(_algorithm, new BacktestingBrokerage(_algorithm), new BacktestingResultHandler());

            // Creates a limit order
            var security = _algorithm.Securities[Ticker];
            var price    = 1.12m;

            security.SetMarketPrice(new Tick(DateTime.Now, security.Symbol, price, price, price));
            var orderRequest = new SubmitOrderRequest(OrderType.Limit, security.Type, security.Symbol, 1000, 0, 1.11m, DateTime.Now, "");

            // Mock the the order processor
            var orderProcessorMock = new Mock <IOrderProcessor>();

            orderProcessorMock.Setup(m => m.GetOrderTicket(It.IsAny <int>())).Returns(new OrderTicket(_algorithm.Transactions, orderRequest));
            _algorithm.Transactions.SetOrderProcessor(orderProcessorMock.Object);

            // Submit and process a limit order
            var orderTicket = transactionHandler.Process(orderRequest);

            transactionHandler.HandleOrderRequest(orderRequest);
            Assert.IsTrue(orderRequest.Response.IsProcessed);
            Assert.IsTrue(orderRequest.Response.IsSuccess);
            Assert.IsTrue(orderTicket.Status == OrderStatus.Submitted);

            // Cancel the order
            var cancelRequest = new CancelOrderRequest(DateTime.Now, orderTicket.OrderId, "");

            transactionHandler.Process(cancelRequest);
            Assert.IsTrue(cancelRequest.Response.IsProcessed);
            Assert.IsTrue(cancelRequest.Response.IsSuccess);
            Assert.IsTrue(cancelRequest.Status == OrderRequestStatus.Processing);
            Assert.IsTrue(orderTicket.Status == OrderStatus.CancelPending);
            Assert.AreEqual(transactionHandler.CancelPendingOrdersSize, 1);

            transactionHandler.HandleOrderRequest(cancelRequest);
            Assert.IsTrue(cancelRequest.Response.IsProcessed);
            Assert.IsTrue(cancelRequest.Response.IsSuccess);
            Assert.IsTrue(cancelRequest.Status == OrderRequestStatus.Processed);
            Assert.IsTrue(orderTicket.Status == OrderStatus.Canceled);
            Assert.AreEqual(transactionHandler.CancelPendingOrdersSize, 0);

            // Check CancelPending was sent
            Assert.AreEqual(_algorithm.OrderEvents.Count, 3);
            Assert.AreEqual(_algorithm.OrderEvents.Count(orderEvent => orderEvent.Status == OrderStatus.Submitted), 1);
            Assert.AreEqual(_algorithm.OrderEvents.Count(orderEvent => orderEvent.Status == OrderStatus.CancelPending), 1);
            Assert.AreEqual(_algorithm.OrderEvents.Count(orderEvent => orderEvent.Status == OrderStatus.Canceled), 1);
        }
        public void SyncFailedCancelOrderRequestShouldUpdateOrderStatusCorrectlyWithIntermediateUpdate()
        {
            // Initializes the transaction handler
            var transactionHandler = new TestBrokerageTransactionHandler();
            var broker             = new TestBroker(_algorithm, false);

            transactionHandler.Initialize(_algorithm, broker, new BacktestingResultHandler());

            var security = _algorithm.Securities[Ticker];
            var price    = 1.12m;

            security.SetMarketPrice(new Tick(DateTime.Now, security.Symbol, price, price, price));
            var orderRequest = new SubmitOrderRequest(OrderType.Market, security.Type, security.Symbol, 1000, 0, 1.11m, DateTime.Now, "");

            // Mock the the order processor
            var orderProcessorMock = new Mock <IOrderProcessor>();

            orderProcessorMock.Setup(m => m.GetOrderTicket(It.IsAny <int>())).Returns(new OrderTicket(_algorithm.Transactions, orderRequest));
            _algorithm.Transactions.SetOrderProcessor(orderProcessorMock.Object);

            var orderTicket = transactionHandler.Process(orderRequest);

            transactionHandler.HandleOrderRequest(orderRequest);
            Assert.AreEqual(orderTicket.Status, OrderStatus.Submitted);

            var cancelRequest = new CancelOrderRequest(DateTime.Now, orderTicket.OrderId, "");

            Assert.AreEqual(transactionHandler.CancelPendingOrdersSize, 0);
            transactionHandler.Process(cancelRequest);
            Assert.AreEqual(transactionHandler.CancelPendingOrdersSize, 1);
            Assert.AreEqual(cancelRequest.Status, OrderRequestStatus.Processing);
            Assert.IsTrue(cancelRequest.Response.IsSuccess);
            Assert.AreEqual(orderTicket.Status, OrderStatus.CancelPending);

            broker.Scan();
            Assert.AreEqual(orderTicket.Status, OrderStatus.Filled);

            transactionHandler.HandleOrderRequest(cancelRequest);
            Assert.AreEqual(transactionHandler.CancelPendingOrdersSize, 0);
            Assert.AreEqual(orderTicket.Status, OrderStatus.Filled);
            Assert.AreEqual(cancelRequest.Status, OrderRequestStatus.Error);
            Assert.IsTrue(cancelRequest.Response.IsProcessed);
            Assert.IsTrue(cancelRequest.Response.IsError);
            Assert.AreEqual(cancelRequest.Response.ErrorCode, OrderResponseErrorCode.InvalidOrderStatus);

            Assert.AreEqual(_algorithm.OrderEvents.Count, 3);
            Assert.AreEqual(_algorithm.OrderEvents.Count(orderEvent => orderEvent.Status == OrderStatus.CancelPending), 1);
            Assert.AreEqual(_algorithm.OrderEvents.Count(orderEvent => orderEvent.Status == OrderStatus.Submitted), 1);
            Assert.AreEqual(_algorithm.OrderEvents.Count(orderEvent => orderEvent.Status == OrderStatus.Filled), 1);
        }
Beispiel #6
0
        public void DoesNotLoopEndlesslyIfGetCashBalanceAlwaysThrows()
        {
            // simulate connect failure
            var ib = new Mock <IBrokerage>();

            ib.Setup(m => m.GetCashBalance()).Callback(() => { throw new Exception("Connection error in CashBalance"); });
            ib.Setup(m => m.IsConnected).Returns(false);

            var brokerage = ib.Object;

            Assert.IsFalse(brokerage.IsConnected);

            var algorithm                = new QCAlgorithm();
            var marketHoursDatabase      = MarketHoursDatabase.FromDataFolder();
            var symbolPropertiesDataBase = SymbolPropertiesDatabase.FromDataFolder();
            var securityService          = new SecurityService(algorithm.Portfolio.CashBook, marketHoursDatabase, symbolPropertiesDataBase, algorithm);

            algorithm.Securities.SetSecurityService(securityService);
            algorithm.SetLiveMode(true);

            var transactionHandler = new TestBrokerageTransactionHandler();

            transactionHandler.Initialize(algorithm, brokerage, new TestResultHandler());

            // Advance current time UTC so cash sync is performed
            transactionHandler.TestCurrentTimeUtc = transactionHandler.TestCurrentTimeUtc.AddDays(2);

            try
            {
                while (true)
                {
                    transactionHandler.ProcessSynchronousEvents();

                    Assert.IsFalse(brokerage.IsConnected);

                    Thread.Sleep(1000);
                }
            }
            catch (Exception exception)
            {
                // expect exception from ProcessSynchronousEvents when max attempts reached
                Assert.That(exception.Message.Contains("maximum number of attempts"));
            }
        }