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); }
private static Security InitAndGetSecurity(QCAlgorithm algo, decimal fee, SecurityType securityType = SecurityType.Equity, string symbol = "SPY", DateTime?time = null) { algo.SubscriptionManager.SetDataManager(new DataManagerStub(algo)); Security security; if (securityType == SecurityType.Equity) { security = algo.AddEquity(symbol); _symbol = security.Symbol; } else if (securityType == SecurityType.Option) { security = algo.AddOption(symbol); _symbol = security.Symbol; } else if (securityType == SecurityType.Future) { security = algo.AddFuture(symbol == "SPY" ? "ES" : symbol); _symbol = security.Symbol; } else { throw new Exception("SecurityType not implemented"); } security.FeeModel = new ConstantFeeModel(fee); Update(security, 25, time); return(security); }
private static Security InitAndGetSecurity(QCAlgorithm algo, decimal fee, SecurityType securityType = SecurityType.Equity, string symbol = "SPY") { algo.SubscriptionManager.SetDataManager(new DataManagerStub(algo)); Security security; if (securityType == SecurityType.Equity) { security = algo.AddEquity(symbol); _symbol = security.Symbol; } else if (securityType == SecurityType.Option) { security = algo.AddOption(symbol); _symbol = security.Symbol; } else if (securityType == SecurityType.Future) { security = algo.AddFuture(symbol); _symbol = security.Symbol; } else { throw new Exception("SecurityType not implemented"); } security.TransactionModel = new ConstantFeeTransactionModel(fee); Update(algo.Portfolio.CashBook, security, 25); return(security); }
public void PortfolioStatusPositionWhenPriceIncreases() { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar; var futureSecurity = algorithm.AddFuture(ticker); futureSecurity.BuyingPowerModel = GetModel(futureSecurity, out _futureMarginModel); futureSecurity.Holdings.SetHoldings(20, 100); Update(futureSecurity, 20, algorithm); var marginUsed = algorithm.Portfolio.TotalMarginUsed; Assert.IsTrue(marginUsed > 0); Assert.IsTrue(algorithm.Portfolio.TotalPortfolioValue > 0); Assert.IsTrue(algorithm.Portfolio.MarginRemaining > 0); // Increase from $20 to $40 Update(futureSecurity, 40, algorithm); var expected = (40 - 20) * 100 * futureSecurity.SymbolProperties.ContractMultiplier - 1.85m * 100; Assert.AreEqual(futureSecurity.Holdings.UnrealizedProfit, expected); // we have a massive win because of futures leverage Assert.IsTrue(algorithm.Portfolio.TotalPortfolioValue > 0); Assert.IsTrue(algorithm.Portfolio.MarginRemaining > 0); // margin used didn't change because for futures it relies on the maintenance margin Assert.AreEqual(marginUsed, algorithm.Portfolio.TotalMarginUsed); }
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 = GetModel(futureSecurity, out _futureMarginModel); futureSecurity.SetMarketPrice(new Tick { Value = price, Time = time }); futureSecurity.Holdings.SetHoldings(1.5m, quantity); var res = buyingPowerModel.GetMaintenanceMargin(futureSecurity); Assert.AreEqual(_futureMarginModel.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(_futureMarginModel.MaintenanceOvernightMarginRequirement * futureSecurity.Holdings.AbsoluteQuantity, res); }
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 = GetModel(futureSecurity, out _futureMarginModel); futureSecurity.SetMarketPrice(new Tick { Value = price, Time = time }); futureSecurity.Holdings.SetHoldings(1.5m, quantity); var initialMargin = buyingPowerModel.GetInitialMarginRequiredForOrder( new InitialMarginRequiredForOrderParameters(algorithm.Portfolio.CashBook, futureSecurity, new MarketOrder(futureSecurity.Symbol, quantity, algorithm.UtcTime))).Value; var initialMarginExpected = buyingPowerModel.GetInitialMarginRequirement(futureSecurity, quantity); Assert.AreEqual(initialMarginExpected + 18.50m * Math.Sign(quantity), // fees -> 10 quantity * 1.85 initialMargin); }
public void NonAccountCurrency_GetMaintenanceMarginRequirement() { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); algorithm.Portfolio.SetAccountCurrency("EUR"); algorithm.Portfolio.SetCash(10000); algorithm.Portfolio.SetCash(Currencies.USD, 0, 0.88m); // For this symbol we dont have history var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar; const decimal price = 1.2345m; var time = new DateTime(2013, 1, 1); var futureSecurity = algorithm.AddFuture(ticker); futureSecurity.SetMarketPrice(new Tick { Value = price, Time = time }); futureSecurity.Holdings.SetHoldings(1.5m, 1); var buyingPowerModel = new FutureMarginModel(); // 625 overnight / (1.5 price * 1 quantity * 0.88 rate * 2500 multiplier) ~= 0.18939 var res = buyingPowerModel.GetMaintenanceMarginRequirement(futureSecurity); Assert.AreEqual(0.18939, (double)res, 0.00001); }
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 = GetModel(futureSecurity, out _futureMarginModel, algorithm.Portfolio); 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 MarginRequirementsChangeWithDate() { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar; var futureSecurity = algorithm.AddFuture(ticker); var model = futureSecurity.BuyingPowerModel as FutureMarginModel; Update(futureSecurity, 100, algorithm, new DateTime(2001, 01, 07)); var initial = model.InitialOvernightMarginRequirement; var maintenance = model.MaintenanceOvernightMarginRequirement; Assert.AreEqual(810, initial); Assert.AreEqual(600, maintenance); // date previous to margin change Update(futureSecurity, 100, algorithm, new DateTime(2001, 12, 10)); Assert.AreEqual(810, initial); Assert.AreEqual(600, maintenance); // new margins! Update(futureSecurity, 100, algorithm, new DateTime(2001, 12, 11)); Assert.AreEqual(945, model.InitialOvernightMarginRequirement); Assert.AreEqual(700, model.MaintenanceOvernightMarginRequirement); }
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); }
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 Setup() { var algo = new QCAlgorithm(); var settings = new UniverseSettings(Resolution.Second, 1, true, false, TimeSpan.Zero); var timeKeeper = new TimeKeeper(new DateTime(2015, 12, 07)); var subscriptionManager = new SubscriptionManager(timeKeeper); var securityInitializer = SecurityInitializer.Null; _canonicalSecurity = algo.AddFuture(RootGold); _futuresChainUniverse = new FuturesChainUniverse(_canonicalSecurity, settings, subscriptionManager, securityInitializer); }
public void SetLeverageThrowsException(int leverage) { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar; var futureSecurity = algorithm.AddFuture(ticker); Assert.Throws <InvalidOperationException>(() => futureSecurity.BuyingPowerModel.SetLeverage(futureSecurity, leverage)); }
public void AddFutureOptionAddsUniverseSelectionModel() { var algo = new QCAlgorithm(); algo.SubscriptionManager.SetDataManager(new DataManagerStub(algo)); var underlying = algo.AddFuture("ES", Resolution.Minute, Market.CME); underlying.SetFilter(0, 365); algo.AddFutureOption(underlying.Symbol, _ => _); Assert.IsTrue(algo.UniverseSelection is OptionChainedUniverseSelectionModel); }
public void GetMaximumOrderQuantityForTargetBuyingPower_ThrowsForInvalidTarget(decimal target) { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar; var futureSecurity = algorithm.AddFuture(ticker); Assert.Throws <InvalidOperationException>(() => futureSecurity.BuyingPowerModel.GetMaximumOrderQuantityForTargetBuyingPower( new GetMaximumOrderQuantityForTargetBuyingPowerParameters(algorithm.Portfolio, futureSecurity, target))); }
public void GetLeverage() { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar; var futureSecurity = algorithm.AddFuture(ticker); Update(futureSecurity, 100, algorithm); var leverage = futureSecurity.BuyingPowerModel.GetLeverage(futureSecurity); Assert.AreEqual(1, leverage); }
public void SubscriptionHistoryRequestWithDifferentDataMappingMode() { var dataMappingModes = GetAllDataMappingModes(); var historyStart = new DateTime(2013, 10, 6); var historyEnd = new DateTime(2014, 1, 1); var resolution = Resolution.Daily; _algorithm = GetAlgorithm(historyEnd); var symbol = _algorithm.AddFuture(Futures.Indices.SP500EMini, resolution, dataMappingMode: dataMappingModes.First()).Symbol; var historyResults = dataMappingModes .Select(x => _algorithm.History(new [] { symbol }, historyStart, historyEnd, resolution, dataMappingMode: x).ToList()) .ToList(); CheckThatHistoryResultsHaveEqualBarCount(historyResults); // Check that all history results have a mapping date at some point in the history HashSet <DateTime> mappingDates = new HashSet <DateTime>(); for (int i = 0; i < historyResults.Count; i++) { var underlying = historyResults[i].First().Bars.Keys.First().Underlying; int mappingsCount = 0; foreach (var slice in historyResults[i]) { var dataUnderlying = slice.Bars.Keys.First().Underlying; if (dataUnderlying != underlying) { underlying = dataUnderlying; mappingsCount++; mappingDates.Add(slice.Time.Date); } } if (mappingsCount == 0) { throw new Exception($"History results for {dataMappingModes[i]} data mapping mode did not contain any mappings"); } } if (mappingDates.Count < dataMappingModes.Length) { throw new Exception($"History results should have had different mapping dates for each data mapping mode"); } CheckThatHistoryResultsHaveDifferentClosePrices(historyResults, dataMappingModes.Length, $"History results close prices should have been different for each data mapping mode at each time"); }
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 AddOptionWithUnderlyingFuture() { // Adds an option containing a Future as its underlying Symbol. // This is an essential step in enabling custom derivatives // based on any asset class provided to Option. This test // checks the ability to create Future Options. var algo = new QCAlgorithm(); algo.SubscriptionManager.SetDataManager(new DataManagerStub(algo)); var underlying = algo.AddFuture("ES", Resolution.Minute, Market.CME); underlying.SetFilter(0, 365); var futureOption = algo.AddOption(underlying.Symbol, Resolution.Minute); Assert.IsTrue(futureOption.Symbol.HasUnderlying); Assert.AreEqual(underlying.Symbol, futureOption.Symbol.Underlying); }
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 NonAccountCurrency_GetBuyingPower(decimal nonAccountCurrencyCash) { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); algorithm.Portfolio.SetAccountCurrency("EUR"); algorithm.Portfolio.SetCash(10000); algorithm.Portfolio.SetCash(Currencies.USD, nonAccountCurrencyCash, 0.88m); // For this symbol we dont have history var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar; var futureSecurity = algorithm.AddFuture(ticker); var buyingPowerModel = new FutureMarginModel(); var quantity = buyingPowerModel.GetBuyingPower(new BuyingPowerParameters( algorithm.Portfolio, futureSecurity, OrderDirection.Buy)); Assert.AreEqual(10000m + algorithm.Portfolio.CashBook[Currencies.USD].ValueInAccountCurrency, quantity.Value); }
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); }
public void MarginUsedForPositionWhenPriceIncreases(decimal quantity) { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar; var futureSecurity = algorithm.AddFuture(ticker); futureSecurity.Holdings.SetHoldings(20, quantity); Update(futureSecurity, 20, algorithm); var marginForPosition = futureSecurity.BuyingPowerModel.GetReservedBuyingPowerForPosition( new ReservedBuyingPowerForPositionParameters(futureSecurity)).AbsoluteUsedBuyingPower; // Increase from $20 to $40 Update(futureSecurity, 40, algorithm); var marginForPositionAfter = futureSecurity.BuyingPowerModel.GetReservedBuyingPowerForPosition( new ReservedBuyingPowerForPositionParameters(futureSecurity)).AbsoluteUsedBuyingPower; Assert.AreEqual(marginForPosition, marginForPositionAfter); }
public void AddDataSecurityTickerNoUnderlying(string ticker, Type customDataType, SecurityType securityType, bool securityShouldBeMapped, bool customDataShouldBeMapped) { SymbolCache.Clear(); var qcAlgorithm = new QCAlgorithm(); qcAlgorithm.SubscriptionManager.SetDataManager(new DataManagerStub(qcAlgorithm)); Security asset; switch (securityType) { case SecurityType.Cfd: asset = qcAlgorithm.AddCfd(ticker, Resolution.Daily); break; case SecurityType.Crypto: asset = qcAlgorithm.AddCrypto(ticker, Resolution.Daily); break; case SecurityType.Equity: asset = qcAlgorithm.AddEquity(ticker, Resolution.Daily); break; case SecurityType.Forex: asset = qcAlgorithm.AddForex(ticker, Resolution.Daily); break; case SecurityType.Future: asset = qcAlgorithm.AddFuture(ticker, Resolution.Daily); break; default: throw new Exception($"SecurityType {securityType} is not valid for this test"); } // Dummy here is meant to try to corrupt the SymbolCache. Ideally, SymbolCache should return non-custom data types with higher priority // in case we want to add two custom data types, but still have them associated with the equity from the cache if we're using it. // This covers the case where two idential data subscriptions are created. var dummy = qcAlgorithm.AddData(customDataType, ticker, Resolution.Daily, qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First().DataTimeZone); var customData = qcAlgorithm.AddData(customDataType, ticker, Resolution.Daily, qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First().DataTimeZone); // Check to see if we have an underlying symbol when we shouldn't Assert.IsFalse(customData.Symbol.HasUnderlying, $"{customDataType.Name} has underlying symbol for SecurityType {securityType} with ticker {ticker}"); Assert.AreEqual(customData.Symbol.Underlying, null, $"{customDataType.Name} - Custom data underlying Symbol for SecurityType {securityType} is not null"); var assetSubscription = qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First(); var customDataSubscription = qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == SecurityType.Base).Single(); var assetShouldBeMapped = assetSubscription.TickerShouldBeMapped(); var customShouldBeMapped = customDataSubscription.TickerShouldBeMapped(); Assert.AreEqual(securityShouldBeMapped, assetShouldBeMapped); Assert.AreEqual(customDataShouldBeMapped, customShouldBeMapped); Assert.AreNotEqual(assetSubscription, customDataSubscription); if (assetShouldBeMapped == customShouldBeMapped) { // Would fail with CL future without this check because MappedSymbol returns "/CL" for the Future symbol if (assetSubscription.SecurityType == SecurityType.Future) { Assert.AreNotEqual(assetSubscription.MappedSymbol, customDataSubscription.MappedSymbol); Assert.AreNotEqual(asset.Symbol.Value, customData.Symbol.Value.Split('.').First()); } else { Assert.AreEqual(assetSubscription.MappedSymbol, customDataSubscription.MappedSymbol); Assert.AreEqual(asset.Symbol.Value, customData.Symbol.Value.Split('.').First()); } } }
public void AddDataSecurityTickerWithUnderlying(string ticker, Type customDataType, SecurityType securityType, bool securityShouldBeMapped, bool customDataShouldBeMapped) { SymbolCache.Clear(); var qcAlgorithm = new QCAlgorithm(); qcAlgorithm.SubscriptionManager.SetDataManager(new DataManagerStub(qcAlgorithm)); Security asset; switch (securityType) { case SecurityType.Cfd: asset = qcAlgorithm.AddCfd(ticker, Resolution.Daily); break; case SecurityType.Crypto: asset = qcAlgorithm.AddCrypto(ticker, Resolution.Daily); break; case SecurityType.Equity: asset = qcAlgorithm.AddEquity(ticker, Resolution.Daily); break; case SecurityType.Forex: asset = qcAlgorithm.AddForex(ticker, Resolution.Daily); break; case SecurityType.Future: asset = qcAlgorithm.AddFuture(ticker, Resolution.Daily); break; default: throw new Exception($"SecurityType {securityType} is not valid for this test"); } // Aliased value for Futures contains a forward-slash, which causes the // lookup in the SymbolCache to fail if (securityType == SecurityType.Future) { ticker = asset.Symbol.Value; } // Dummy here is meant to try to corrupt the SymbolCache. Ideally, SymbolCache should return non-custom data types with higher priority // in case we want to add two custom data types, but still have them associated with the equity from the cache if we're using it. // This covers the case where two idential data subscriptions are created. var dummy = qcAlgorithm.AddData(customDataType, ticker, Resolution.Daily, qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First().DataTimeZone); var customData = qcAlgorithm.AddData(customDataType, ticker, Resolution.Daily, qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First().DataTimeZone); Assert.IsTrue(customData.Symbol.HasUnderlying, $"Custom data added as {ticker} Symbol with SecurityType {securityType} does not have underlying"); Assert.AreEqual(customData.Symbol.Underlying, asset.Symbol, $"Custom data underlying does not match {securityType} Symbol for {ticker}"); var assetSubscription = qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == securityType).First(); var customDataSubscription = qcAlgorithm.SubscriptionManager.Subscriptions.Where(x => x.SecurityType == SecurityType.Base).Single(); var assetShouldBeMapped = assetSubscription.TickerShouldBeMapped(); var customShouldBeMapped = customDataSubscription.TickerShouldBeMapped(); if (securityType == SecurityType.Equity) { Assert.AreEqual(securityShouldBeMapped, assetShouldBeMapped); Assert.AreEqual(customDataShouldBeMapped, customShouldBeMapped); Assert.AreNotEqual(assetSubscription, customDataSubscription); if (assetShouldBeMapped == customShouldBeMapped) { Assert.AreEqual(assetSubscription.MappedSymbol, customDataSubscription.MappedSymbol); Assert.AreEqual(asset.Symbol.Value, customData.Symbol.Value.Split('.').First()); } } }
/// <summary> /// Creates and adds a new <see cref="Future"/> security to the algorithm /// </summary> /// <param name="symbol">The futures contract symbol</param> /// <param name="resolution">The <see cref="Resolution"/> of market data, Tick, Second, Minute, Hour, or Daily. Default is <see cref="Resolution.Minute"/></param> /// <param name="market">The futures market, <seealso cref="Market"/>. Default is value null and looked up using BrokerageModel.DefaultMarkets in <see cref="AddSecurity{T}"/></param> /// <param name="fillDataForward">If true, returns the last available data even if none in that timeslice. Default is <value>true</value></param> /// <param name="leverage">The requested leverage for this equity. Default is set by <see cref="SecurityInitializer"/></param> /// <returns>The new <see cref="Future"/> security</returns> public Future AddFuture(string symbol, Resolution resolution = Resolution.Minute, string market = null, bool fillDataForward = true, decimal leverage = 0m) { return(_algorithm.AddFuture(symbol, resolution, market, fillDataForward, leverage)); }