示例#1
0
        public void PartiallyFilledOrdersAreTakenIntoAccount(Language language)
        {
            var actualOrdersSubmitted = new List <SubmitOrderRequest>();

            var algorithm = new QCAlgorithm();

            algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm));
            algorithm.SetPandasConverter();

            var security = algorithm.AddEquity(Symbols.AAPL.Value);

            security.SetMarketPrice(new TradeBar {
                Value = 250
            });

            algorithm.SetFinishedWarmingUp();

            var openOrderRequest = new SubmitOrderRequest(OrderType.Market, SecurityType.Equity, Symbols.AAPL, 100, 0, 0, DateTime.MinValue, "");

            openOrderRequest.SetOrderId(1);
            var openOrderTicket = new OrderTicket(algorithm.Transactions, openOrderRequest);

            openOrderTicket.AddOrderEvent(new OrderEvent(1, Symbols.AAPL, DateTime.MinValue, OrderStatus.PartiallyFilled, OrderDirection.Buy, 250, 70, OrderFee.Zero));

            var orderProcessor = new Mock <IOrderProcessor>();

            orderProcessor.Setup(m => m.Process(It.IsAny <SubmitOrderRequest>()))
            .Returns((SubmitOrderRequest request) => new OrderTicket(algorithm.Transactions, request))
            .Callback((SubmitOrderRequest request) => actualOrdersSubmitted.Add(request));
            orderProcessor.Setup(m => m.GetOpenOrders(It.IsAny <Func <Order, bool> >()))
            .Returns(new List <Order> {
                new MarketOrder(Symbols.AAPL, 100, DateTime.MinValue)
            });
            orderProcessor.Setup(m => m.GetOpenOrderTickets(It.IsAny <Func <OrderTicket, bool> >()))
            .Returns(new List <OrderTicket> {
                openOrderTicket
            });
            algorithm.Transactions.SetOrderProcessor(orderProcessor.Object);

            var model = GetExecutionModel(language);

            algorithm.SetExecution(model);

            var changes = new SecurityChanges(Enumerable.Empty <Security>(), Enumerable.Empty <Security>());

            model.OnSecuritiesChanged(algorithm, changes);

            var targets = new IPortfolioTarget[] { new PortfolioTarget(Symbols.AAPL, 80) };

            model.Execute(algorithm, targets);

            Assert.AreEqual(1, actualOrdersSubmitted.Count);

            // Remaining quantity for partially filled order = 100 - 70 = 30
            // Quantity submitted = 80 - 30 = 50
            Assert.AreEqual(50, actualOrdersSubmitted.Sum(x => x.Quantity));
        }
示例#2
0
        /// <summary>
        /// Gets the remaining quantity to be ordered to reach the specified target quantity.
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="target">The portfolio target</param>
        /// <param name="security">The target security</param>
        /// <returns>The signed remaining quantity to be ordered</returns>
        public static decimal GetUnorderedQuantity(IAlgorithm algorithm, IPortfolioTarget target, Security security)
        {
            var holdings          = security.Holdings.Quantity;
            var openOrderQuantity = algorithm.Transactions.GetOpenOrderTickets(target.Symbol)
                                    .Aggregate(0m, (d, t) => d + t.Quantity - t.QuantityFilled);
            var quantity = target.Quantity - holdings - openOrderQuantity;

            return(AdjustByLotSize(security, quantity));
        }
        public void FillsOnTradesOnlyRespectingExchangeOpen(Language language, int expectedOrdersSubmitted, decimal expectedTotalQuantity, bool exchangeOpen)
        {
            var actualOrdersSubmitted = new List <SubmitOrderRequest>();

            var time = new DateTime(2018, 8, 2, 0, 0, 0);

            if (exchangeOpen)
            {
                time = time.AddHours(14);
            }

            var algorithm = new QCAlgorithm();

            algorithm.SetPandasConverter();
            algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm));
            algorithm.SetDateTime(time.AddMinutes(5));

            var security = algorithm.AddEquity(Symbols.AAPL.Value);

            security.SetMarketPrice(new TradeBar {
                Value = 250
            });

            algorithm.SetFinishedWarmingUp();

            var orderProcessor = new Mock <IOrderProcessor>();

            orderProcessor.Setup(m => m.Process(It.IsAny <SubmitOrderRequest>()))
            .Returns((SubmitOrderRequest request) => new OrderTicket(algorithm.Transactions, request))
            .Callback((OrderRequest request) => actualOrdersSubmitted.Add((SubmitOrderRequest)request));
            orderProcessor.Setup(m => m.GetOpenOrders(It.IsAny <Func <Order, bool> >()))
            .Returns(new List <Order>());
            algorithm.Transactions.SetOrderProcessor(orderProcessor.Object);

            var model = GetExecutionModel(language);

            algorithm.SetExecution(model);

            var changes = new SecurityChanges(new[] { security }, Enumerable.Empty <Security>());

            model.OnSecuritiesChanged(algorithm, changes);

            var targets = new IPortfolioTarget[] { new PortfolioTarget(Symbols.AAPL, 10) };

            model.Execute(algorithm, targets);

            Assert.AreEqual(expectedOrdersSubmitted, actualOrdersSubmitted.Count);
            Assert.AreEqual(expectedTotalQuantity, actualOrdersSubmitted.Sum(x => x.Quantity));

            if (actualOrdersSubmitted.Count == 1)
            {
                var request = actualOrdersSubmitted[0];
                Assert.AreEqual(expectedTotalQuantity, request.Quantity);
                Assert.AreEqual(algorithm.UtcTime, request.Time);
            }
        }
示例#4
0
        /// <summary>
        /// Gets the remaining quantity to be ordered to reach the specified target quantity.
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="target">The portfolio target</param>
        /// <returns>The remaining quantity to be ordered</returns>
        public static decimal GetUnorderedQuantity(IAlgorithm algorithm, IPortfolioTarget target)
        {
            var security          = algorithm.Securities[target.Symbol];
            var holdings          = security.Holdings.Quantity;
            var openOrderQuantity = algorithm.Transactions.GetOpenOrders(target.Symbol).Aggregate(0m, (d, o) => d + o.Quantity);
            var quantity          = target.Quantity - holdings - openOrderQuantity;

            // check if we're below the lot size threshold
            if (Math.Abs(quantity) < security.SymbolProperties.LotSize)
            {
                return(0m);
            }

            return(quantity);
        }
        public void OrdersAreSubmittedImmediatelyForTargetsToExecute(
            Language language,
            double[] historicalPrices,
            decimal openOrdersQuantity,
            int expectedOrdersSubmitted,
            decimal expectedTotalQuantity)
        {
            var actualOrdersSubmitted = new List <SubmitOrderRequest>();

            var time            = new DateTime(2018, 8, 2, 16, 0, 0);
            var historyProvider = new Mock <IHistoryProvider>();

            historyProvider.Setup(m => m.GetHistory(It.IsAny <IEnumerable <HistoryRequest> >(), It.IsAny <DateTimeZone>()))
            .Returns(historicalPrices.Select((x, i) =>
                                             new Slice(time.AddMinutes(i),
                                                       new List <BaseData>
            {
                new TradeBar
                {
                    Time   = time.AddMinutes(i),
                    Symbol = Symbols.AAPL,
                    Open   = Convert.ToDecimal(x),
                    High   = Convert.ToDecimal(x),
                    Low    = Convert.ToDecimal(x),
                    Close  = Convert.ToDecimal(x),
                    Volume = 100m
                }
            })));

            var algorithm = new QCAlgorithm();

            algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm));
            algorithm.SetPandasConverter();
            algorithm.SetHistoryProvider(historyProvider.Object);
            algorithm.SetDateTime(time.AddMinutes(5));

            var security = algorithm.AddEquity(Symbols.AAPL.Value);

            security.SetMarketPrice(new TradeBar {
                Value = 250
            });

            algorithm.SetFinishedWarmingUp();

            var openOrderRequest = new SubmitOrderRequest(OrderType.Market, SecurityType.Equity, Symbols.AAPL, openOrdersQuantity, 0, 0, DateTime.MinValue, "");

            openOrderRequest.SetOrderId(1);
            var openOrderTicket = new OrderTicket(algorithm.Transactions, openOrderRequest);

            var orderProcessor = new Mock <IOrderProcessor>();

            orderProcessor.Setup(m => m.Process(It.IsAny <SubmitOrderRequest>()))
            .Returns((SubmitOrderRequest request) => new OrderTicket(algorithm.Transactions, request))
            .Callback((OrderRequest request) => actualOrdersSubmitted.Add((SubmitOrderRequest)request));
            orderProcessor.Setup(m => m.GetOpenOrders(It.IsAny <Func <Order, bool> >()))
            .Returns(new List <Order> {
                new MarketOrder(Symbols.AAPL, openOrdersQuantity, DateTime.MinValue)
            });
            orderProcessor.Setup(m => m.GetOpenOrderTickets(It.IsAny <Func <OrderTicket, bool> >()))
            .Returns(new List <OrderTicket> {
                openOrderTicket
            });
            algorithm.Transactions.SetOrderProcessor(orderProcessor.Object);

            var model = GetExecutionModel(language);

            algorithm.SetExecution(model);

            var changes = SecurityChangesTests.CreateNonInternal(new[] { security }, Enumerable.Empty <Security>());

            model.OnSecuritiesChanged(algorithm, changes);

            var targets = new IPortfolioTarget[] { new PortfolioTarget(Symbols.AAPL, 10) };

            model.Execute(algorithm, targets);

            Assert.AreEqual(expectedOrdersSubmitted, actualOrdersSubmitted.Count);
            Assert.AreEqual(expectedTotalQuantity, actualOrdersSubmitted.Sum(x => x.Quantity));

            if (actualOrdersSubmitted.Count == 1)
            {
                var request = actualOrdersSubmitted[0];
                Assert.AreEqual(expectedTotalQuantity, request.Quantity);
                Assert.AreEqual(algorithm.UtcTime, request.Time);
            }
        }
示例#6
0
        /// <summary>
        /// They different framework models will process the new provided insight.
        /// The <see cref="IPortfolioConstructionModel"/> will create targets,
        /// the <see cref="IRiskManagementModel"/> will adjust the targets
        /// and the <see cref="IExecutionModel"/> will execute the <see cref="IPortfolioTarget"/>
        /// </summary>
        /// <param name="insights">The insight to process</param>
        private void ProcessInsights(Insight[] insights)
        {
            // construct portfolio targets from insights
            var targetsEnumerable = PortfolioConstruction.CreateTargets(this, insights);
            // for performance only call 'ToArray' if not empty enumerable (which is static)
            var targets = targetsEnumerable == Enumerable.Empty <IPortfolioTarget>()
                ? new IPortfolioTarget[] {} : targetsEnumerable.ToArray();

            // set security targets w/ those generated via portfolio construction module
            foreach (var target in targets)
            {
                var security = Securities[target.Symbol];
                security.Holdings.Target = target;
            }

            if (DebugMode)
            {
                // debug printing of generated targets
                if (targets.Length > 0)
                {
                    Log($"{Time}: PORTFOLIO: {string.Join(" | ", targets.Select(t => t.ToString()).OrderBy(t => t))}");
                }
            }

            var riskTargetOverridesEnumerable = RiskManagement.ManageRisk(this, targets);
            // for performance only call 'ToArray' if not empty enumerable (which is static)
            var riskTargetOverrides = riskTargetOverridesEnumerable == Enumerable.Empty <IPortfolioTarget>()
                ? new IPortfolioTarget[] { } : riskTargetOverridesEnumerable.ToArray();

            // override security targets w/ those generated via risk management module
            foreach (var target in riskTargetOverrides)
            {
                var security = Securities[target.Symbol];
                security.Holdings.Target = target;
            }

            if (DebugMode)
            {
                // debug printing of generated risk target overrides
                if (riskTargetOverrides.Length > 0)
                {
                    Log($"{Time}: RISK: {string.Join(" | ", riskTargetOverrides.Select(t => t.ToString()).OrderBy(t => t))}");
                }
            }

            IPortfolioTarget[] riskAdjustedTargets;
            // for performance we check the length before
            if (riskTargetOverrides.Length != 0 ||
                targets.Length != 0)
            {
                // execute on the targets, overriding targets for symbols w/ risk targets
                riskAdjustedTargets = riskTargetOverrides.Concat(targets).DistinctBy(pt => pt.Symbol).ToArray();
            }
            else
            {
                riskAdjustedTargets = new IPortfolioTarget[] { };
            }

            if (DebugMode)
            {
                // only log adjusted targets if we've performed an adjustment
                if (riskTargetOverrides.Length > 0)
                {
                    Log($"{Time}: RISK ADJUSTED TARGETS: {string.Join(" | ", riskAdjustedTargets.Select(t => t.ToString()).OrderBy(t => t))}");
                }
            }

            Execution.Execute(this, riskAdjustedTargets);
        }
示例#7
0
        public void OrdersAreSubmittedWhenRequiredForTargetsToExecute(
            Language language,
            double[] historicalPrices,
            decimal lastVolume,
            int expectedOrdersSubmitted,
            decimal expectedTotalQuantity)
        {
            var actualOrdersSubmitted = new List <SubmitOrderRequest>();

            var time            = new DateTime(2018, 8, 2, 16, 0, 0);
            var historyProvider = new Mock <IHistoryProvider>();

            historyProvider.Setup(m => m.GetHistory(It.IsAny <IEnumerable <HistoryRequest> >(), It.IsAny <DateTimeZone>()))
            .Returns(historicalPrices.Select((x, i) =>
                                             new Slice(time.AddMinutes(i),
                                                       new List <BaseData>
            {
                new TradeBar
                {
                    Time   = time.AddMinutes(i),
                    Symbol = Symbols.AAPL,
                    Open   = Convert.ToDecimal(x),
                    High   = Convert.ToDecimal(x),
                    Low    = Convert.ToDecimal(x),
                    Close  = Convert.ToDecimal(x),
                    Volume = 100m
                }
            })));

            var algorithm = new QCAlgorithm();

            algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm));
            algorithm.SetPandasConverter();
            algorithm.SetHistoryProvider(historyProvider.Object);
            algorithm.SetDateTime(time.AddMinutes(5));

            var security = algorithm.AddEquity(Symbols.AAPL.Value);

            security.SetMarketPrice(new TradeBar {
                Value = 250, Volume = lastVolume
            });

            algorithm.SetFinishedWarmingUp();

            var orderProcessor = new Mock <IOrderProcessor>();

            orderProcessor.Setup(m => m.Process(It.IsAny <SubmitOrderRequest>()))
            .Returns((SubmitOrderRequest request) => new OrderTicket(algorithm.Transactions, request))
            .Callback((OrderRequest request) => actualOrdersSubmitted.Add((SubmitOrderRequest)request));
            orderProcessor.Setup(m => m.GetOpenOrders(It.IsAny <Func <Order, bool> >()))
            .Returns(new List <Order>());
            algorithm.Transactions.SetOrderProcessor(orderProcessor.Object);

            var model = GetExecutionModel(language);

            algorithm.SetExecution(model);

            var changes = new SecurityChanges(new[] { security }, Enumerable.Empty <Security>());

            model.OnSecuritiesChanged(algorithm, changes);

            algorithm.History(new List <Symbol> {
                security.Symbol
            }, historicalPrices.Length, Resolution.Minute)
            .PushThroughConsolidators(symbol => algorithm.Securities[symbol].Subscriptions.Single(s => s.TickType == LeanData.GetCommonTickType(SecurityType.Equity)).Consolidators.First());

            var targets = new IPortfolioTarget[] { new PortfolioTarget(security.Symbol, 10) };

            model.Execute(algorithm, targets);

            Assert.AreEqual(expectedOrdersSubmitted, actualOrdersSubmitted.Count);
            Assert.AreEqual(expectedTotalQuantity, actualOrdersSubmitted.Sum(x => x.Quantity));

            if (actualOrdersSubmitted.Count == 1)
            {
                var request = actualOrdersSubmitted[0];
                Assert.AreEqual(expectedTotalQuantity, request.Quantity);
                Assert.AreEqual(algorithm.UtcTime, request.Time);
            }
        }
        public void OrdersAreSubmittedWhenRequiredForTargetsToExecute(
            Language language,
            decimal currentPrice,
            int expectedOrdersSubmitted,
            decimal expectedTotalQuantity)
        {
            var actualOrdersSubmitted = new List <SubmitOrderRequest>();

            var time = new DateTime(2018, 8, 2, 14, 0, 0);

            var algorithm = new QCAlgorithm();

            algorithm.SetPandasConverter();
            algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm));
            algorithm.SetDateTime(time.AddMinutes(5));

            var security = algorithm.AddEquity(Symbols.AAPL.Value);

            security.SetMarketPrice(new TradeBar {
                Value = 250
            });
            // pushing the ask higher will cause the spread the widen and no trade to happen
            var ask = expectedOrdersSubmitted == 0 ? currentPrice * 1.1m : currentPrice;

            security.SetMarketPrice(new QuoteBar
            {
                Time   = time,
                Symbol = Symbols.AAPL,
                Ask    = new Bar(ask, ask, ask, ask),
                Bid    = new Bar(currentPrice, currentPrice, currentPrice, currentPrice)
            });

            algorithm.SetFinishedWarmingUp();

            var orderProcessor = new Mock <IOrderProcessor>();

            orderProcessor.Setup(m => m.Process(It.IsAny <SubmitOrderRequest>()))
            .Returns((SubmitOrderRequest request) => new OrderTicket(algorithm.Transactions, request))
            .Callback((OrderRequest request) => actualOrdersSubmitted.Add((SubmitOrderRequest)request));
            orderProcessor.Setup(m => m.GetOpenOrders(It.IsAny <Func <Order, bool> >()))
            .Returns(new List <Order>());
            algorithm.Transactions.SetOrderProcessor(orderProcessor.Object);

            var model = GetExecutionModel(language);

            algorithm.SetExecution(model);

            var changes = new SecurityChanges(new[] { security }, Enumerable.Empty <Security>());

            model.OnSecuritiesChanged(algorithm, changes);

            var targets = new IPortfolioTarget[] { new PortfolioTarget(Symbols.AAPL, 10) };

            model.Execute(algorithm, targets);

            Assert.AreEqual(expectedOrdersSubmitted, actualOrdersSubmitted.Count);
            Assert.AreEqual(expectedTotalQuantity, actualOrdersSubmitted.Sum(x => x.Quantity));

            if (actualOrdersSubmitted.Count == 1)
            {
                var request = actualOrdersSubmitted[0];
                Assert.AreEqual(expectedTotalQuantity, request.Quantity);
                Assert.AreEqual(algorithm.UtcTime, request.Time);
            }
        }
示例#9
0
        /// <summary>
        /// Gets the remaining quantity to be ordered to reach the specified target quantity.
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="target">The portfolio target</param>
        /// <returns>The signed remaining quantity to be ordered</returns>
        public static decimal GetUnorderedQuantity(IAlgorithm algorithm, IPortfolioTarget target)
        {
            var security = algorithm.Securities[target.Symbol];

            return(GetUnorderedQuantity(algorithm, target, security));
        }
示例#10
0
        /// <summary>
        /// They different framework models will process the new provided insight.
        /// The <see cref="IPortfolioConstructionModel"/> will create targets,
        /// the <see cref="IRiskManagementModel"/> will adjust the targets
        /// and the <see cref="IExecutionModel"/> will execute the <see cref="IPortfolioTarget"/>
        /// </summary>
        /// <param name="insights">The insight to process</param>
        protected void ProcessInsights(Insight[] insights)
        {
            // construct portfolio targets from insights
            var targetsEnumerable = PortfolioConstruction.CreateTargets(this, insights);
            // for performance only call 'ToArray' if not empty enumerable (which is static)
            var targets = targetsEnumerable == Enumerable.Empty <IPortfolioTarget>()
                ? new IPortfolioTarget[] {} : targetsEnumerable.ToArray();

            // set security targets w/ those generated via portfolio construction module
            foreach (var target in targets)
            {
                var security = Securities[target.Symbol];
                security.Holdings.Target = target;
            }

            if (DebugMode)
            {
                // debug printing of generated targets
                if (targets.Length > 0)
                {
                    Log($"{Time}: PORTFOLIO: {string.Join(" | ", targets.Select(t => t.ToString()).OrderBy(t => t))}");
                }
            }

            var riskTargetOverridesEnumerable = RiskManagement.ManageRisk(this, targets);
            // for performance only call 'ToArray' if not empty enumerable (which is static)
            var riskTargetOverrides = riskTargetOverridesEnumerable == Enumerable.Empty <IPortfolioTarget>()
                ? new IPortfolioTarget[] { } : riskTargetOverridesEnumerable.ToArray();

            // override security targets w/ those generated via risk management module
            foreach (var target in riskTargetOverrides)
            {
                var security = Securities[target.Symbol];
                security.Holdings.Target = target;
            }

            if (DebugMode)
            {
                // debug printing of generated risk target overrides
                if (riskTargetOverrides.Length > 0)
                {
                    Log($"{Time}: RISK: {string.Join(" | ", riskTargetOverrides.Select(t => t.ToString()).OrderBy(t => t))}");
                }
            }

            IPortfolioTarget[] riskAdjustedTargets;
            // for performance we check the length before
            if (riskTargetOverrides.Length != 0 ||
                targets.Length != 0)
            {
                // execute on the targets, overriding targets for symbols w/ risk targets
                riskAdjustedTargets = riskTargetOverrides.Concat(targets).DistinctBy(pt => pt.Symbol).ToArray();
            }
            else
            {
                riskAdjustedTargets = new IPortfolioTarget[] { };
            }

            if (DebugMode)
            {
                // only log adjusted targets if we've performed an adjustment
                if (riskTargetOverrides.Length > 0)
                {
                    Log($"{Time}: RISK ADJUSTED TARGETS: {string.Join(" | ", riskAdjustedTargets.Select(t => t.ToString()).OrderBy(t => t))}");
                }
            }

            if (riskAdjustedTargets.Length > 0 &&
                Execution.GetType() != typeof(NullExecutionModel) &&
                BrokerageModel.AccountType == AccountType.Cash)
            {
                throw new InvalidOperationException($"Non null {nameof(IExecutionModel)} and {nameof(IPortfolioConstructionModel)} are currently unsuitable for Cash Modeled brokerages (e.g. GDAX) and may result in unexpected trades."
                                                    + " To prevent possible user error we've restricted them to Margin trading. You can select margin account types with"
                                                    + $" SetBrokerage( ... AccountType.Margin). Or please set them to {nameof(NullExecutionModel)}, {nameof(NullPortfolioConstructionModel)}");
            }

            Execution.Execute(this, riskAdjustedTargets);
        }