public void GetInitialMarginRequiredForOrder(decimal quantity)
        {
            var algorithm = new QCAlgorithm();

            algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm));
            var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar;

            const decimal price            = 1.2345m;
            var           time             = new DateTime(2013, 1, 1);
            var           futureSecurity   = algorithm.AddFuture(ticker);
            var           buyingPowerModel = new TestFutureMarginModel(futureSecurity);

            futureSecurity.SetMarketPrice(new Tick {
                Value = price, Time = time
            });
            futureSecurity.Holdings.SetHoldings(1.5m, 1);

            var initialMargin = buyingPowerModel.GetInitialMarginRequiredForOrder(
                new InitialMarginRequiredForOrderParameters(algorithm.Portfolio.CashBook,
                                                            futureSecurity,
                                                            new MarketOrder(futureSecurity.Symbol, quantity, algorithm.UtcTime)));

            var initialMarginExpected = buyingPowerModel.GetInitialMarginRequirement(futureSecurity, quantity);

            Assert.AreEqual(initialMarginExpected
                            + 18.50m * Math.Sign(quantity), // fees -> 10 quantity * 1.85
                            initialMargin);
        }
        public void GetInitialMarginRequirement(decimal quantity)
        {
            var algorithm = new QCAlgorithm();

            algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm));
            var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar;

            const decimal price            = 1.2345m;
            var           time             = new DateTime(2013, 1, 1);
            var           futureSecurity   = algorithm.AddFuture(ticker);
            var           buyingPowerModel = new TestFutureMarginModel();

            futureSecurity.SetMarketPrice(new Tick {
                Value = price, Time = time
            });
            futureSecurity.Holdings.SetHoldings(1.5m, quantity);

            var initialMargin = buyingPowerModel.GetInitialMarginRequirement(futureSecurity, futureSecurity.Holdings.AbsoluteQuantity);

            Assert.IsTrue(initialMargin > 0);
            var overnightMargin = Math.Abs(buyingPowerModel.GetMaintenanceMargin(futureSecurity));

            // initial margin is greater than the maintenance margin
            Assert.Greater(initialMargin, overnightMargin);
        }
        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 = new TestFutureMarginModel(futureSecurity);

            futureSecurity.BuyingPowerModel = model;

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

            var expected = (algorithm.Portfolio.TotalPortfolioValue * Math.Abs(target) + model.GetInitialMarginRequirement(futureSecurity, futureSecurity.Holdings.AbsoluteQuantity))
                           / model.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);
        }