Example #1
0
        public void VerifyMarginCallOrderLongOpenMarket()
        {
            var securityPrice = 100m;
            var quantity      = 300;

            var orderProcessor = new FakeOrderProcessor();
            var portfolio      = GetPortfolio(orderProcessor, quantity, Noon);
            var model          = GetModel();

            // Open Market
            var security = CreateSecurity(model.SecurityModel, Noon);

            security.BuyingPowerModel = model;
            security.Holdings.SetHoldings(securityPrice, quantity);
            portfolio.Securities.Add(security);
            portfolio.CashBook["USD"].AddAmount(-25000);
            portfolio.InvalidateTotalPortfolioValue();
            var netLiquidationValue = portfolio.TotalPortfolioValue;
            var totalMargin         = portfolio.TotalMarginUsed;

            portfolio.MarginCallModel = new TestDefaultMarginCallModel(portfolio, new OrderProperties());

            var expected = -(int)(Math.Round((totalMargin - netLiquidationValue) / securityPrice, MidpointRounding.AwayFromZero) * 4m);
            var actual   = (portfolio.MarginCallModel as TestDefaultMarginCallModel).GenerateMarginCallOrder(security, netLiquidationValue, totalMargin).Quantity;

            Assert.AreEqual(expected, actual);
        }
Example #2
0
        public void VerifyMarginCallOrderShort()
        {
            var netLiquidationValue = 5000m;
            var totalMargin         = 10000m;
            var securityPrice       = 100m;
            var quantity            = -300;

            var orderProcessor = new FakeOrderProcessor();
            var portfolio      = GetPortfolio(orderProcessor, quantity);
            var model          = new PatternDayTradingMarginModel();

            // Open Market
            var security = CreateSecurity(Noon);

            security.Holdings.SetHoldings(securityPrice, quantity);

            var expected = (int)(Math.Round((totalMargin - netLiquidationValue) / securityPrice, MidpointRounding.AwayFromZero) * 4m);
            var actual   = portfolio.MarginCallModel.GenerateMarginCallOrder(security, netLiquidationValue, totalMargin, model.GetMaintenanceMarginRequirement(security)).Quantity;

            Assert.AreEqual(expected, actual);

            // Closed Market
            security = CreateSecurity(Midnight);
            security.Holdings.SetHoldings(securityPrice, quantity);

            expected = (int)(Math.Round((totalMargin - netLiquidationValue) / securityPrice, MidpointRounding.AwayFromZero) * 2m);
            actual   = portfolio.MarginCallModel.GenerateMarginCallOrder(security, netLiquidationValue, totalMargin, model.GetMaintenanceMarginRequirement(security)).Quantity;

            Assert.AreEqual(expected, actual);
        }
Example #3
0
        public void HasSufficientBuyingPowerForOrderInvalidTargets(decimal target)
        {
            var algorithm = new QCAlgorithm();

            algorithm.SetFinishedWarmingUp();
            algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm));
            var orderProcessor = new FakeOrderProcessor();

            algorithm.Transactions.SetOrderProcessor(orderProcessor);

            var ticker         = QuantConnect.Securities.Futures.Financials.EuroDollar;
            var futureSecurity = algorithm.AddFuture(ticker);

            // set closed market for simpler math
            futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 1));
            Update(futureSecurity, 100, algorithm);
            var model = futureSecurity.BuyingPowerModel as FutureMarginModel;

            var quantity = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target);
            var request  = GetOrderRequest(futureSecurity.Symbol, quantity);

            request.SetOrderId(0);
            orderProcessor.AddTicket(new OrderTicket(algorithm.Transactions, request));

            var result = model.HasSufficientBuyingPowerForOrder(new HasSufficientBuyingPowerForOrderParameters(
                                                                    algorithm.Portfolio,
                                                                    futureSecurity,
                                                                    // we get the maximum target value 1/-1 and add a lot size it shouldn't be a valid order
                                                                    new MarketOrder(futureSecurity.Symbol, quantity + futureSecurity.SymbolProperties.LotSize * Math.Sign(quantity), DateTime.UtcNow)));

            Assert.IsFalse(result.IsSufficient);
        }
        public void GetMarginRemainingTests()
        {
            const int     quantity       = 1000;
            const decimal leverage       = 2;
            var           orderProcessor = new FakeOrderProcessor();
            var           portfolio      = GetPortfolio(orderProcessor, quantity);

            var security         = GetSecurity(Symbols.AAPL);
            var buyingPowerModel = new TestSecurityMarginModel(leverage);

            security.BuyingPowerModel = buyingPowerModel;
            portfolio.Securities.Add(security);

            security.Holdings.SetHoldings(1m, quantity);
            var actual1 = buyingPowerModel.GetMarginRemaining(portfolio, security, OrderDirection.Buy);

            Assert.AreEqual(quantity / leverage, actual1);

            var actual2 = buyingPowerModel.GetMarginRemaining(portfolio, security, OrderDirection.Sell);

            Assert.AreEqual(quantity, actual2);

            security.Holdings.SetHoldings(1m, -quantity);
            var actual3 = buyingPowerModel.GetMarginRemaining(portfolio, security, OrderDirection.Sell);

            Assert.AreEqual(quantity / leverage, actual3);

            var actual4 = buyingPowerModel.GetMarginRemaining(portfolio, security, OrderDirection.Buy);

            Assert.AreEqual(quantity, actual4);
        }
        public void ClosingSoonIntradayClosedMarketMargins(decimal target)
        {
            var algorithm = new QCAlgorithm();

            algorithm.SetFinishedWarmingUp();
            algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm));
            var orderProcessor = new FakeOrderProcessor();

            algorithm.Transactions.SetOrderProcessor(orderProcessor);

            var ticker         = QuantConnect.Securities.Futures.Financials.EuroDollar;
            var futureSecurity = algorithm.AddFuture(ticker);

            Update(futureSecurity, 100, algorithm);
            var localTime  = new DateTime(2020, 2, 3);
            var utcTime    = localTime.ConvertToUtc(futureSecurity.Exchange.TimeZone);
            var timeKeeper = new TimeKeeper(utcTime, futureSecurity.Exchange.TimeZone);
            var model      = GetModel(futureSecurity, out _futureMarginModel, algorithm.Portfolio);

            // this is important
            _futureMarginModel.EnableIntradayMargins = true;

            // Open market
            futureSecurity.Exchange.SetLocalDateTimeFrontier(localTime);

            var quantity = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target);
            var request  = GetOrderRequest(futureSecurity.Symbol, quantity);

            request.SetOrderId(0);
            orderProcessor.AddTicket(new OrderTicket(algorithm.Transactions, request));

            Assert.IsTrue(model.HasSufficientBuyingPowerForOrder(
                              new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio,
                                                                             futureSecurity,
                                                                             new MarketOrder(futureSecurity.Symbol, quantity, DateTime.UtcNow))).IsSufficient);

            // Closing soon market
            futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 3, 15, 50, 0));

            Assert.IsFalse(model.HasSufficientBuyingPowerForOrder(
                               new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio,
                                                                              futureSecurity,
                                                                              new MarketOrder(futureSecurity.Symbol, quantity, DateTime.UtcNow))).IsSufficient);
            Assert.IsTrue(futureSecurity.Exchange.ExchangeOpen);
            Assert.IsTrue(futureSecurity.Exchange.ClosingSoon);

            // Close market
            futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 1));
            Assert.IsFalse(futureSecurity.Exchange.ExchangeOpen);

            Assert.IsFalse(model.HasSufficientBuyingPowerForOrder(
                               new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio,
                                                                              futureSecurity,
                                                                              new MarketOrder(futureSecurity.Symbol, quantity, DateTime.UtcNow))).IsSufficient);
        }
        public void IntradayVersusOvernightMargins(decimal target)
        {
            var algorithm = new QCAlgorithm();

            algorithm.SetFinishedWarmingUp();
            algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm));
            var orderProcessor = new FakeOrderProcessor();

            algorithm.Transactions.SetOrderProcessor(orderProcessor);

            var ticker         = QuantConnect.Securities.Futures.Financials.EuroDollar;
            var futureSecurity = algorithm.AddFuture(ticker);
            var lotSize        = futureSecurity.SymbolProperties.LotSize;

            Update(futureSecurity, 100, algorithm);
            var model = GetModel(futureSecurity, out _futureMarginModel, algorithm.Portfolio);

            // Close market
            futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 1));

            var quantityClosedMarket = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target);

            Assert.AreEqual(quantityClosedMarket.DiscretelyRoundBy(lotSize), quantityClosedMarket,
                            "Calculated order quantity was not whole number multiple of the lot size"
                            );
            var request = GetOrderRequest(futureSecurity.Symbol, quantityClosedMarket);

            request.SetOrderId(0);
            orderProcessor.AddTicket(new OrderTicket(algorithm.Transactions, request));

            Assert.IsTrue(model.HasSufficientBuyingPowerForOrder(
                              new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio,
                                                                             futureSecurity,
                                                                             new MarketOrder(futureSecurity.Symbol, quantityClosedMarket, DateTime.UtcNow))).IsSufficient);

            var initialOvernight     = _futureMarginModel.InitialOvernightMarginRequirement;
            var maintenanceOvernight = _futureMarginModel.MaintenanceOvernightMarginRequirement;

            // Open market
            futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 3));

            var fourtyPercentQuantity = (quantityClosedMarket * 0.4m).DiscretelyRoundBy(lotSize);

            futureSecurity.Holdings.SetHoldings(100, fourtyPercentQuantity);

            var halfQuantity = (quantityClosedMarket / 2).DiscretelyRoundBy(lotSize);

            Assert.IsTrue(model.HasSufficientBuyingPowerForOrder(
                              new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio,
                                                                             futureSecurity,
                                                                             new MarketOrder(futureSecurity.Symbol, halfQuantity, DateTime.UtcNow))).IsSufficient);

            Assert.Greater(initialOvernight, _futureMarginModel.InitialIntradayMarginRequirement);
            Assert.Greater(maintenanceOvernight, _futureMarginModel.MaintenanceIntradayMarginRequirement);
        }
        private static QCAlgorithm GetAlgorithm()
        {
            SymbolCache.Clear();
            // Initialize algorithm
            var algo = new QCAlgorithm();

            algo.SetFinishedWarmingUp();
            _fakeOrderProcessor = new FakeOrderProcessor();
            algo.Transactions.SetOrderProcessor(_fakeOrderProcessor);
            return(algo);
        }
Example #8
0
        private static QCAlgorithm GetAlgorithm(out Security security, decimal fee)
        {
            SymbolCache.Clear();
            // Initialize algorithm
            var algo = new QCAlgorithm();

            algo.SetCash(100000);
            algo.SetFinishedWarmingUp();
            _fakeOrderProcessor = new FakeOrderProcessor();
            algo.Transactions.SetOrderProcessor(_fakeOrderProcessor);
            security = algo.AddEquity("SPY");
            security.TransactionModel = new ConstantFeeTransactionModel(fee);
            Update(algo.Portfolio.CashBook, security, 25);
            return(algo);
        }
        public void IntradayVersusOvernightMargins(decimal target)
        {
            var algorithm = new QCAlgorithm();

            algorithm.SetFinishedWarmingUp();
            algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm));
            var orderProcessor = new FakeOrderProcessor();

            algorithm.Transactions.SetOrderProcessor(orderProcessor);

            var ticker         = QuantConnect.Securities.Futures.Financials.EuroDollar;
            var futureSecurity = algorithm.AddFuture(ticker);

            Update(futureSecurity, 100, algorithm);
            var model = futureSecurity.BuyingPowerModel as FutureMarginModel;

            // Close market
            futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 1));

            var quantityClosedMarket = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target);
            var request = GetOrderRequest(futureSecurity.Symbol, quantityClosedMarket);

            request.SetOrderId(0);
            orderProcessor.AddTicket(new OrderTicket(algorithm.Transactions, request));

            Assert.IsTrue(model.HasSufficientBuyingPowerForOrder(
                              new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio,
                                                                             futureSecurity,
                                                                             new MarketOrder(futureSecurity.Symbol, quantityClosedMarket, DateTime.UtcNow))).IsSufficient);

            var initialOvernight     = model.InitialOvernightMarginRequirement;
            var maintenanceOvernight = model.MaintenanceOvernightMarginRequirement;

            // Open market
            futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 3));

            futureSecurity.Holdings.SetHoldings(100, quantityClosedMarket * 0.4m);

            Assert.IsTrue(model.HasSufficientBuyingPowerForOrder(
                              new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio,
                                                                             futureSecurity,
                                                                             new MarketOrder(futureSecurity.Symbol, quantityClosedMarket / 2, DateTime.UtcNow))).IsSufficient);

            Assert.Greater(initialOvernight, model.InitialIntradayMarginRequirement);
            Assert.Greater(maintenanceOvernight, model.MaintenanceIntradayMarginRequirement);
        }
        public void GetMarginRemainingTests()
        {
            const int     quantity       = 1000;
            const decimal leverage       = 2;
            var           orderProcessor = new FakeOrderProcessor();
            var           portfolio      = GetPortfolio(orderProcessor, cash: 1000);

            var security         = GetSecurity(Symbols.AAPL);
            var buyingPowerModel = new TestSecurityMarginModel(leverage);

            security.BuyingPowerModel = buyingPowerModel;
            portfolio.Securities.Add(security);

            // we buy $1000 worth of shares
            security.Holdings.SetHoldings(1m, quantity);
            portfolio.SetCash(0);

            // current value is used to determine reserved buying power
            security.SetMarketPrice(new TradeBar
            {
                Time   = DateTime.Now,
                Symbol = security.Symbol,
                Open   = 1,
                High   = 1,
                Low    = 1,
                Close  = 1
            });
            var actual1 = buyingPowerModel.GetMarginRemaining(portfolio, security, OrderDirection.Buy);

            Assert.AreEqual(quantity / leverage, actual1);

            var actual2 = buyingPowerModel.GetMarginRemaining(portfolio, security, OrderDirection.Sell);

            Assert.AreEqual(quantity + quantity / leverage, actual2);

            security.Holdings.SetHoldings(1m, -quantity);
            var actual3 = buyingPowerModel.GetMarginRemaining(portfolio, security, OrderDirection.Sell);

            Assert.AreEqual(quantity / leverage, actual3);

            var actual4 = buyingPowerModel.GetMarginRemaining(portfolio, security, OrderDirection.Buy);

            Assert.AreEqual(quantity + quantity / leverage, actual4);
        }
        public void GetMaximumOrderQuantityForTargetBuyingPower_WithHoldingsInverseDirection(decimal target)
        {
            var algorithm = new QCAlgorithm();

            algorithm.SetFinishedWarmingUp();
            algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm));
            var orderProcessor = new FakeOrderProcessor();

            algorithm.Transactions.SetOrderProcessor(orderProcessor);

            var ticker         = QuantConnect.Securities.Futures.Financials.EuroDollar;
            var futureSecurity = algorithm.AddFuture(ticker);

            // set closed market for simpler math
            futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 1));
            futureSecurity.Holdings.SetHoldings(100, 10 * -1 * Math.Sign(target));
            Update(futureSecurity, 100, algorithm);

            var model = GetModel(futureSecurity, out _futureMarginModel, algorithm.Portfolio);

            futureSecurity.BuyingPowerModel = _futureMarginModel;

            var quantity = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target);

            var expected = (algorithm.Portfolio.TotalPortfolioValue * Math.Abs(target) + Math.Abs(model.GetInitialMarginRequirement(futureSecurity, futureSecurity.Holdings.Quantity)))
                           / _futureMarginModel.InitialOvernightMarginRequirement - 1 * Math.Abs(target); // -1 fees

            expected -= expected % futureSecurity.SymbolProperties.LotSize;
            Log.Trace($"Expected {expected}");

            Assert.AreEqual(expected * Math.Sign(target), quantity);

            var request = GetOrderRequest(futureSecurity.Symbol, quantity);

            request.SetOrderId(0);
            orderProcessor.AddTicket(new OrderTicket(algorithm.Transactions, request));

            Assert.IsTrue(model.HasSufficientBuyingPowerForOrder(
                              new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio,
                                                                             futureSecurity,
                                                                             new MarketOrder(futureSecurity.Symbol, expected * Math.Sign(target), DateTime.UtcNow))).IsSufficient);
        }
        public void NegativeMarginRemaining(bool isError, int target, int side)
        {
            var algo     = GetAlgorithm();
            var security = InitAndGetSecurity(algo, 5);

            security.Holdings.SetHoldings(security.Price, 1000 * side);
            algo.Portfolio.CashBook.Add(algo.AccountCurrency, -100000, 1);
            var fakeOrderProcessor = new FakeOrderProcessor();

            algo.Transactions.SetOrderProcessor(fakeOrderProcessor);

            Assert.IsTrue(algo.Portfolio.MarginRemaining < 0);

            var quantity = security.BuyingPowerModel.GetMaximumOrderQuantityForTargetBuyingPower(
                new GetMaximumOrderQuantityForTargetBuyingPowerParameters(algo.Portfolio,
                                                                          security,
                                                                          target * side,
                                                                          0)).Quantity;

            if (!isError)
            {
                Assert.AreEqual(1000 * side * -1, quantity);
            }
            else
            {
                // even if we don't have margin 'GetMaximumOrderQuantityForTargetBuyingPower' doesn't care
                Assert.AreNotEqual(0, quantity);
            }

            var order = new MarketOrder(security.Symbol, quantity, new DateTime(2020, 1, 1));

            fakeOrderProcessor.AddTicket(order.ToOrderTicket(algo.Transactions));
            var actual = security.BuyingPowerModel.HasSufficientBuyingPowerForOrder(
                new HasSufficientBuyingPowerForOrderParameters(algo.Portfolio,
                                                               security,
                                                               order));

            Assert.AreEqual(!isError, actual.IsSufficient);
        }
        public void GetMaximumOrderQuantityForTargetBuyingPower_TwoStep(decimal target)
        {
            var algorithm = new QCAlgorithm();

            algorithm.SetFinishedWarmingUp();
            algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm));
            var orderProcessor = new FakeOrderProcessor();

            algorithm.Transactions.SetOrderProcessor(orderProcessor);

            var ticker         = QuantConnect.Securities.Futures.Financials.EuroDollar;
            var futureSecurity = algorithm.AddFuture(ticker);

            futureSecurity.BuyingPowerModel = GetModel(futureSecurity, out _futureMarginModel, algorithm.Portfolio);
            // set closed market for simpler math
            futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 1));
            Update(futureSecurity, 100, algorithm);
            var expectedFinalQuantity = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target);

            var quantity = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target / 2);

            futureSecurity.Holdings.SetHoldings(100, quantity);
            algorithm.Portfolio.InvalidateTotalPortfolioValue();

            var quantity2 = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target);

            var request = GetOrderRequest(futureSecurity.Symbol, quantity2);

            request.SetOrderId(0);
            orderProcessor.AddTicket(new OrderTicket(algorithm.Transactions, request));

            Assert.IsTrue(futureSecurity.BuyingPowerModel.HasSufficientBuyingPowerForOrder(
                              new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio,
                                                                             futureSecurity,
                                                                             new MarketOrder(futureSecurity.Symbol, quantity2, DateTime.UtcNow))).IsSufficient);

            // two step operation is the same as 1 step
            Assert.AreEqual(expectedFinalQuantity, quantity + quantity2);
        }
Example #14
0
        public void GenerateMarginCallOrderTests()
        {
            const int     quantity       = 1000;
            const decimal leverage       = 1m;
            var           orderProcessor = new FakeOrderProcessor();
            var           portfolio      = GetPortfolio(orderProcessor, quantity);

            portfolio.MarginCallModel = new DefaultMarginCallModel(portfolio, null);

            var security = GetSecurity(Symbols.AAPL);

            portfolio.Securities.Add(security);

            var           time     = DateTime.Now;
            const decimal buyPrice = 1m;

            security.SetMarketPrice(new Tick(time, Symbols.AAPL, buyPrice, buyPrice));

            var order = new MarketOrder(Symbols.AAPL, quantity, time)
            {
                Price = buyPrice
            };
            var fill = new OrderEvent(order, DateTime.UtcNow, 0)
            {
                FillPrice = buyPrice, FillQuantity = quantity
            };

            orderProcessor.AddOrder(order);
            var request = new SubmitOrderRequest(OrderType.Market, security.Type, security.Symbol, order.Quantity, 0, 0, order.Time, null);

            request.SetOrderId(0);
            orderProcessor.AddTicket(new OrderTicket(null, request));
            Assert.AreEqual(portfolio.Cash, fill.FillPrice * fill.FillQuantity);

            portfolio.ProcessFill(fill);

            Assert.AreEqual(0, portfolio.MarginRemaining);
            Assert.AreEqual(quantity, portfolio.TotalMarginUsed);
            Assert.AreEqual(quantity, portfolio.TotalPortfolioValue);

            // we shouldn't be able to place a trader
            var newOrder = new MarketOrder(Symbols.AAPL, 1, time.AddSeconds(1))
            {
                Price = buyPrice
            };
            var hasSufficientBuyingPower = security.BuyingPowerModel.HasSufficientBuyingPowerForOrder(portfolio, security, newOrder).IsSufficient;

            Assert.IsFalse(hasSufficientBuyingPower);

            // now the stock doubles, so we should have margin remaining
            time = time.AddDays(1);
            const decimal highPrice = buyPrice * 2;

            security.SetMarketPrice(new Tick(time, Symbols.AAPL, highPrice, highPrice));

            Assert.AreEqual(quantity, portfolio.MarginRemaining);
            Assert.AreEqual(quantity, portfolio.TotalMarginUsed);
            Assert.AreEqual(quantity * 2, portfolio.TotalPortfolioValue);

            // we shouldn't be able to place a trader
            var anotherOrder = new MarketOrder(Symbols.AAPL, 1, time.AddSeconds(1))
            {
                Price = highPrice
            };

            hasSufficientBuyingPower = security.BuyingPowerModel.HasSufficientBuyingPowerForOrder(portfolio, security, anotherOrder).IsSufficient;
            Assert.IsTrue(hasSufficientBuyingPower);

            // now the stock plummets, so we should have negative margin remaining
            time = time.AddDays(1);
            const decimal lowPrice = buyPrice / 2;

            security.SetMarketPrice(new Tick(time, Symbols.AAPL, lowPrice, lowPrice));

            Assert.AreEqual(-quantity / 2m, portfolio.MarginRemaining);
            Assert.AreEqual(quantity, portfolio.TotalMarginUsed);
            Assert.AreEqual(quantity / 2m, portfolio.TotalPortfolioValue);

            // this would not cause a margin call due to leverage = 1
            bool issueMarginCallWarning;
            var  marginCallOrders = portfolio.MarginCallModel.GetMarginCallOrders(out issueMarginCallWarning);

            Assert.IsFalse(issueMarginCallWarning);
            Assert.AreEqual(0, marginCallOrders.Count);

            // now change the leverage to test margin call warning and margin call logic
            security.SetLeverage(leverage * 2);

            // Stock price increase by minimum variation
            const decimal newPrice = lowPrice + 0.01m;

            security.SetMarketPrice(new Tick(time, Symbols.AAPL, newPrice, newPrice));

            // this would not cause a margin call, only a margin call warning
            marginCallOrders = portfolio.MarginCallModel.GetMarginCallOrders(out issueMarginCallWarning);
            Assert.IsTrue(issueMarginCallWarning);
            Assert.AreEqual(0, marginCallOrders.Count);

            // Price drops again to previous low, margin call orders will be issued
            security.SetMarketPrice(new Tick(time, Symbols.AAPL, lowPrice, lowPrice));

            order = new MarketOrder(Symbols.AAPL, quantity, time)
            {
                Price = buyPrice
            };
            fill = new OrderEvent(order, DateTime.UtcNow, 0)
            {
                FillPrice = buyPrice, FillQuantity = quantity
            };
            portfolio.ProcessFill(fill);

            Assert.AreEqual(0, portfolio.TotalPortfolioValue);

            marginCallOrders = portfolio.MarginCallModel.GetMarginCallOrders(out issueMarginCallWarning);
            Assert.IsTrue(issueMarginCallWarning);
            Assert.AreEqual(1, marginCallOrders.Count);
        }