public void TestMarginForSymbolWithOneLinerHistory()
        {
            const decimal price   = 1.2345m;
            var           time    = new DateTime(2016, 1, 1);
            var           expDate = new DateTime(2017, 1, 1);
            var           tz      = TimeZones.NewYork;

            // For this symbol we dont have any history, but only one date and margins line
            var ticker = QuantConnect.Securities.Futures.Softs.Coffee;
            var symbol = Symbol.CreateFuture(ticker, Market.ICE, expDate);

            var futureSecurity = new Future(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), symbol, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

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

            var buyingPowerModel = new TestFutureMarginModel(futureSecurity);

            Assert.AreEqual(buyingPowerModel.MaintenanceOvernightMarginRequirement, buyingPowerModel.GetMaintenanceMargin(futureSecurity));
        }
        public void TestMarginForSymbolWithNoHistory()
        {
            const decimal price   = 1.2345m;
            var           time    = new DateTime(2016, 1, 1);
            var           expDate = new DateTime(2017, 1, 1);
            var           tz      = TimeZones.NewYork;

            // For this symbol we dont have any history at all
            var ticker = "NOT-A-SYMBOL";
            var symbol = Symbol.CreateFuture(ticker, Market.USA, expDate);

            var futureSecurity = new Future(SecurityExchangeHours.AlwaysOpen(tz),
                                            new SubscriptionDataConfig(typeof(TradeBar), symbol, Resolution.Minute, tz, tz, true, false, false),
                                            new Cash(Currencies.USD, 0, 1m),
                                            new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                                            ErrorCurrencyConverter.Instance,
                                            RegisteredSecurityDataTypesProvider.Null);

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

            var buyingPowerModel = new TestFutureMarginModel();

            Assert.AreEqual(0m, buyingPowerModel.GetMaintenanceMargin(futureSecurity));
        }
        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 GetMaintenanceMargin(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, quantity);

            var res = buyingPowerModel.GetMaintenanceMargin(futureSecurity);

            Assert.AreEqual(buyingPowerModel.MaintenanceOvernightMarginRequirement * futureSecurity.Holdings.AbsoluteQuantity, res);

            // We increase the quantity * 2, maintenance margin should DOUBLE
            futureSecurity.Holdings.SetHoldings(1.5m, quantity * 2);
            res = buyingPowerModel.GetMaintenanceMargin(futureSecurity);
            Assert.AreEqual(buyingPowerModel.MaintenanceOvernightMarginRequirement * futureSecurity.Holdings.AbsoluteQuantity, res);
        }
        public void TestMarginForSymbolWithHistory()
        {
            const decimal price   = 1.2345m;
            var           time    = new DateTime(2013, 1, 1);
            var           expDate = new DateTime(2017, 1, 1);
            var           tz      = TimeZones.NewYork;

            // For this symbol we dont have history
            var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar;
            var symbol = Symbol.CreateFuture(ticker, Market.CME, expDate);

            var futureSecurity = new Future(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), symbol, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

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

            var buyingPowerModel = new TestFutureMarginModel(futureSecurity);

            Assert.AreEqual(buyingPowerModel.MaintenanceOvernightMarginRequirement,
                            buyingPowerModel.GetMaintenanceMargin(futureSecurity));

            // now we move forward to exact date when margin req changed
            time = new DateTime(2014, 06, 13);
            futureSecurity.SetMarketPrice(new Tick {
                Value = price, Time = time
            });
            Assert.AreEqual(buyingPowerModel.MaintenanceOvernightMarginRequirement, buyingPowerModel.GetMaintenanceMargin(futureSecurity));

            // now we fly beyond the last line of the history file (currently) to see how margin model resolves future dates
            time = new DateTime(2016, 06, 04);
            futureSecurity.SetMarketPrice(new Tick {
                Value = price, Time = time
            });
            Assert.AreEqual(buyingPowerModel.MaintenanceOvernightMarginRequirement, buyingPowerModel.GetMaintenanceMargin(futureSecurity));
        }
        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);
        }
        public void MarginForSymbolWithOneLinerHistory()
        {
            const decimal price   = 1.2345m;
            var           time    = new DateTime(2020, 10, 14);
            var           expDate = new DateTime(2021, 3, 19);
            var           tz      = TimeZones.NewYork;

            // For this symbol we dont have any history, but only one date and margins line
            var ticker = QuantConnect.Securities.Futures.Indices.SP500EMini;
            var future = Symbol.CreateFuture(ticker, Market.CME, expDate);
            var symbol = Symbol.CreateOption(future, Market.CME, OptionStyle.American, OptionRight.Call, 2550m, new DateTime(2021, 3, 19));

            var optionSecurity = new Option(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), symbol, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );

            optionSecurity.Underlying = new Future(
                SecurityExchangeHours.AlwaysOpen(tz),
                new SubscriptionDataConfig(typeof(TradeBar), future, Resolution.Minute, tz, tz, true, false, false),
                new Cash(Currencies.USD, 0, 1m),
                new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );
            optionSecurity.Underlying.SetMarketPrice(new Tick {
                Value = price, Time = time
            });
            optionSecurity.Underlying.Holdings.SetHoldings(1.5m, 1);

            var futureBuyingPowerModel       = new TestFutureMarginModel(optionSecurity.Underlying);
            var futureOptionBuyingPowerModel = new TestFuturesOptionsMarginModel(optionSecurity);

            Assert.AreNotEqual(0m, futureOptionBuyingPowerModel.GetMaintenanceMargin(optionSecurity));
            Assert.AreEqual(futureBuyingPowerModel.GetMaintenanceMargin(optionSecurity.Underlying) * 1.5m, futureOptionBuyingPowerModel.GetMaintenanceMargin(optionSecurity));
        }