private QCAlgorithm GetAlgorithm(decimal?holdings = null) { var algorithm = new AlgorithmStub(); algorithm.Transactions.SetOrderProcessor(new FakeOrderProcessor()); var aapl = algorithm.AddEquity(Symbols.AAPL.Value); Update(aapl, 1); if (holdings != null) { aapl.Holdings.SetHoldings(10, holdings.Value); } return(algorithm); }
public void WarmUpInternalSubscriptions() { var algo = new AlgorithmStub(new MockDataFeed()) { HistoryProvider = new SubscriptionDataReaderHistoryProvider() }; algo.SetStartDate(2013, 10, 08); algo.AddCfd("DE30EUR", Resolution.Second, Market.Oanda); algo.SetWarmup(10); algo.PostInitialize(); algo.DataManager.UniverseSelection.EnsureCurrencyDataFeeds(SecurityChanges.None); Assert.AreEqual(algo.StartDate - TimeSpan.FromSeconds(10), algo.Time); }
public void Works() { var algorithm = new AlgorithmStub(); algorithm.HistoryProvider = new TestHistoryProvider(); var security = algorithm.AddEquity(Symbols.SPY); var model = new TestVolatilityModel(); security.VolatilityModel = model; AlgorithmManager.ProcessVolatilityHistoryRequirements(algorithm); Assert.AreEqual(1, model.dataUpdate.Count); Assert.AreEqual(Symbols.SPY, model.dataUpdate.First().Symbol); Assert.AreEqual(4, model.dataUpdate.First().Price); }
public void DailySampleValueBasedOnMarketHour(bool extendedMarketHoursEnabled) { var referenceDate = new DateTime(2020, 11, 25); var resultHandler = new LiveTradingResultHandler(); resultHandler.Initialize(new LiveNodePacket(), new QuantConnect.Messaging.Messaging(), new Api.Api(), new BacktestingTransactionHandler()); var algo = new AlgorithmStub(createDataManager: false); algo.SetFinishedWarmingUp(); var dataManager = new DataManagerStub(new TestDataFeed(), algo); algo.SubscriptionManager.SetDataManager(dataManager); var aapl = algo.AddEquity("AAPL", extendedMarketHours: extendedMarketHoursEnabled); algo.PostInitialize(); resultHandler.SetAlgorithm(algo, 100000); resultHandler.OnSecuritiesChanged(SecurityChangesTests.AddedNonInternal(aapl)); // Add values during market hours, should always update algo.Portfolio.CashBook["USD"].AddAmount(1000); algo.Portfolio.InvalidateTotalPortfolioValue(); resultHandler.Sample(referenceDate.AddHours(15)); Assert.IsTrue(resultHandler.Charts.ContainsKey("Strategy Equity")); Assert.AreEqual(1, resultHandler.Charts["Strategy Equity"].Series["Equity"].Values.Count); var currentEquityValue = resultHandler.Charts["Strategy Equity"].Series["Equity"].Values.Last().y; Assert.AreEqual(101000, currentEquityValue); // Add value to portfolio, see if portfolio updates with new sample // will be changed to 'extendedMarketHoursEnabled' = true algo.Portfolio.CashBook["USD"].AddAmount(10000); algo.Portfolio.InvalidateTotalPortfolioValue(); resultHandler.Sample(referenceDate.AddHours(22)); Assert.AreEqual(2, resultHandler.Charts["Strategy Equity"].Series["Equity"].Values.Count); currentEquityValue = resultHandler.Charts["Strategy Equity"].Series["Equity"].Values.Last().y; Assert.AreEqual(extendedMarketHoursEnabled ? 111000 : 101000, currentEquityValue); resultHandler.Exit(); }
public void DailySampleValueBasedOnMarketHour(bool extendedMarketHoursEnabled) { var referenceDate = new DateTime(2020, 11, 25); var resultHandler = new TestLiveTradingResultHandler { // market is open InitialSampleTime = referenceDate.AddHours(10) }; resultHandler.Initialize(new LiveNodePacket(), new QuantConnect.Messaging.Messaging(), new Api.Api(), new BacktestingTransactionHandler()); var algo = new AlgorithmStub(createDataManager: false); algo.SetFinishedWarmingUp(); var dataManager = new DataManagerStub(new TestDataFeed(), algo); algo.SubscriptionManager.SetDataManager(dataManager); var aapl = algo.AddEquity("AAPL", extendedMarketHours: extendedMarketHoursEnabled); algo.PostInitialize(); resultHandler.SetAlgorithm(algo, 100000); resultHandler.OnSecuritiesChanged(SecurityChanges.Added(aapl)); algo.Portfolio.CashBook["USD"].AddAmount(1000); algo.Portfolio.InvalidateTotalPortfolioValue(); resultHandler.Sample(referenceDate.AddHours(15)); Assert.IsFalse(resultHandler.Charts.ContainsKey("Strategy Equity"), "Should not sample on the same start date"); // will be ignored based on 'extendedMarketHoursEnabled' algo.Portfolio.CashBook["USD"].AddAmount(10000); algo.Portfolio.InvalidateTotalPortfolioValue(); resultHandler.Sample(referenceDate.AddHours(22)); Assert.IsFalse(resultHandler.Charts.ContainsKey("Strategy Equity"), "Should not sample on the same start date"); resultHandler.Sample(referenceDate.AddHours(24)); Assert.IsTrue(resultHandler.Charts.ContainsKey("Strategy Equity"), "Expect sample of date change"); Assert.AreEqual(extendedMarketHoursEnabled ? 111000 : 101000, resultHandler.Charts["Strategy Equity"].Series["Equity"].Values.Single().y); resultHandler.Exit(); }
public void WarmUpPythonIndicatorProperly() { var algo = new AlgorithmStub { HistoryProvider = new SubscriptionDataReaderHistoryProvider() }; var zipCacheProvider = new ZipDataCacheProvider(TestGlobals.DataProvider); algo.HistoryProvider.Initialize(new HistoryProviderInitializeParameters( null, null, TestGlobals.DataProvider, zipCacheProvider, TestGlobals.MapFileProvider, TestGlobals.FactorFileProvider, null, false, new DataPermissionManager())); algo.SetStartDate(2013, 10, 08); algo.AddEquity("SPY", Resolution.Minute); // Different types of indicators var indicatorDataPoint = new SimpleMovingAverage("SPY", 10); var indicatorDataBar = new AverageTrueRange("SPY", 10); var indicatorTradeBar = new VolumeWeightedAveragePriceIndicator("SPY", 10); using (Py.GIL()) { var sma = indicatorDataPoint.ToPython(); var atr = indicatorTradeBar.ToPython(); var vwapi = indicatorDataBar.ToPython(); Assert.DoesNotThrow(() => algo.WarmUpIndicator("SPY", sma, Resolution.Minute)); Assert.DoesNotThrow(() => algo.WarmUpIndicator("SPY", atr, Resolution.Minute)); Assert.DoesNotThrow(() => algo.WarmUpIndicator("SPY", vwapi, Resolution.Minute)); var smaIsReady = ((dynamic)sma).IsReady; var atrIsReady = ((dynamic)atr).IsReady; var vwapiIsReady = ((dynamic)vwapi).IsReady; Assert.IsTrue(smaIsReady.IsTrue()); Assert.IsTrue(atrIsReady.IsTrue()); Assert.IsTrue(vwapiIsReady.IsTrue()); } zipCacheProvider.DisposeSafely(); }
public void GetUnorderedQuantityHoldingsNoOrders(decimal holdings, decimal target, decimal expected) { var algo = new AlgorithmStub(); algo.Transactions.SetOrderProcessor(new FakeOrderProcessor()); var security = algo.AddFutureContract(Symbols.Future_CLF19_Jan2019); security.SetMarketPrice(new TradeBar { Value = 250 }); security.Holdings.SetHoldings(250, holdings); var result = OrderSizing.GetUnorderedQuantity(algo, new PortfolioTarget(Symbols.Future_CLF19_Jan2019, target)); Assert.AreEqual(expected, result); }
public void WarmUpUniverseSelection() { var algo = new AlgorithmStub(new MockDataFeed()) { HistoryProvider = new SubscriptionDataReaderHistoryProvider() }; algo.SetStartDate(2013, 10, 08); var universe = algo.AddUniverse((_) => Enumerable.Empty <Symbol>()); var barCount = 3; algo.SetWarmup(barCount); algo.PostInitialize(); // +2 is due to the weekend Assert.AreEqual(algo.StartDate - universe.Configuration.Resolution.ToTimeSpan() * (barCount + 2), algo.Time); }
public void GetOrderSizeForMaximumValue(decimal maximumOrderValue, decimal target, decimal expected) { var algo = new AlgorithmStub(); var security = algo.AddFutureContract(Symbols.Future_CLF19_Jan2019); security.SetMarketPrice(new TradeBar { Value = 250 }); var result = OrderSizing.GetOrderSizeForMaximumValue(security, maximumOrderValue, target); var expectedCalculated = maximumOrderValue / (security.Price * security.SymbolProperties.ContractMultiplier); expectedCalculated -= expectedCalculated % security.SymbolProperties.LotSize; Assert.AreEqual(Math.Min(expectedCalculated, Math.Abs(target)) * Math.Sign(target), result); Assert.AreEqual(expected, result); }
public void DoesNotAddOnEndOfDayEventsIfNotImplemented(Language language) { Security security; IAlgorithm algorithm; if (language == Language.CSharp) { algorithm = new AlgorithmStub(); security = (algorithm as QCAlgorithm).AddEquity("SPY"); } else { algorithm = new AlgorithmPythonWrapper("Test_CustomDataAlgorithm"); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); security = algorithm.AddSecurity(SecurityType.Equity, "SPY", Resolution.Daily, Market.USA, false, 1, false); } var realTimeHandler = new TestBacktestingRealTimeHandler(); realTimeHandler.Setup(algorithm, new AlgorithmNodePacket(PacketType.AlgorithmNode) { Language = language }, _resultHandler, null, new TestTimeLimitManager()); Assert.AreEqual(0, realTimeHandler.GetScheduledEventsCount); realTimeHandler.OnSecuritiesChanged( new SecurityChanges(new[] { security }, Enumerable.Empty <Security>())); Assert.AreEqual(0, realTimeHandler.GetScheduledEventsCount); realTimeHandler.Exit(); }
public void GetUnorderedQuantityHoldingsOpenOrders(decimal holdings, decimal target, decimal filledQuantity, decimal expected) { var algo = new AlgorithmStub(); var orderProcessor = new FakeOrderProcessor(); var orderRequest = new SubmitOrderRequest( OrderType.Market, SecurityType.Future, Symbols.Future_CLF19_Jan2019, filledQuantity * 2, 250, 250, new DateTime(2020, 1, 1), "Pepe" ); var order = Order.CreateOrder(orderRequest); var ticket = new OrderTicket(algo.Transactions, orderRequest); ticket.SetOrder(order); ticket.AddOrderEvent(new OrderEvent(1, Symbols.Future_CLF19_Jan2019, new DateTime(2020, 1, 1), OrderStatus.Filled, filledQuantity > 0 ? OrderDirection.Buy : OrderDirection.Sell, 250, filledQuantity, OrderFee.Zero)); orderProcessor.AddTicket(ticket); algo.Transactions.SetOrderProcessor(orderProcessor); var security = algo.AddFutureContract(Symbols.Future_CLF19_Jan2019); security.SetMarketPrice(new TradeBar { Value = 250 }); security.Holdings.SetHoldings(250, holdings); var result = OrderSizing.GetUnorderedQuantity(algo, new PortfolioTarget(Symbols.Future_CLF19_Jan2019, target)); Assert.AreEqual(expected, result); }
public void AppliesDividendDistributionDirectlyToPortfolioCashBook() { // init algorithm var algorithm = new AlgorithmStub(new MockDataFeed()); algorithm.AddSecurities(equities: new List <string> { "SPY" }); algorithm.PostInitialize(); // init holdings var SPY = algorithm.Securities[Symbols.SPY]; SPY.SetMarketPrice(new Tick { Value = 100m }); SPY.Holdings.SetHoldings(100m, 1000); // resolve expected outcome var USD = algorithm.Portfolio.CashBook[Currencies.USD]; var preDistributionCash = USD.Amount; var distributionPerShare = 10m; var expectedTotalDistribution = distributionPerShare * SPY.Holdings.Quantity; // create slice w/ dividend var slice = new Slice(algorithm.Time, new List <BaseData>(), algorithm.Time); slice.Dividends.Add(new Dividend(Symbols.SPY, algorithm.Time, distributionPerShare, 100m)); algorithm.SetCurrentSlice(slice); // invoke brokerage var brokerage = new PaperBrokerage(algorithm, null); brokerage.Scan(); // verify results var postDistributionCash = USD.Amount; Assert.AreEqual(preDistributionCash + expectedTotalDistribution, postDistributionCash); }
public void WarmupStartDate_NoAsset(bool withResolution) { var algo = new AlgorithmStub(); algo.SetStartDate(2013, 10, 01); DateTime expected; if (withResolution) { algo.SetWarmUp(100, Resolution.Daily); expected = new DateTime(2013, 06, 23); } else { algo.SetWarmUp(100); // defaults to universe settings expected = new DateTime(2013, 09, 30, 22, 20, 0); } algo.PostInitialize(); Assert.AreEqual(expected, algo.Time); }
public void SetsAlgorithmRunTimeErrorOnDisconnectIfNonCustomSecurityIsOpen() { var algorithm = new AlgorithmStub(equities: new List <string> { "SPY" }); algorithm.Securities["SPY"].Exchange = new SecurityExchange(SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork)); var job = new LiveNodePacket(); var results = new TestResultHandler();//packet => Console.WriteLine(FieldsToString(packet))); var api = new Api.Api(); var handler = new DefaultBrokerageMessageHandler(algorithm, job, results, api, TimeSpan.Zero); Assert.IsNull(algorithm.RunTimeError); handler.Handle(BrokerageMessageEvent.Disconnected("Disconnection!")); Thread.Sleep(10); Assert.IsNotNull(algorithm.RunTimeError); results.Exit(); }
public void WarmUpInternalSubscriptionsHistoryRequest() { var algo = new AlgorithmStub(new MockDataFeed()) { HistoryProvider = new SubscriptionDataReaderHistoryProvider() }; algo.SetStartDate(2013, 10, 08); algo.AddCfd("DE30EUR", Resolution.Second, Market.Oanda); algo.SetWarmup(10); algo.PostInitialize(); algo.OnEndOfTimeStep(); algo.DataManager.UniverseSelection.EnsureCurrencyDataFeeds(SecurityChanges.None); var result = algo.GetWarmupHistoryRequests(); foreach (var historyRequest in result) { Assert.AreEqual(Resolution.Second, historyRequest.Resolution); Assert.AreEqual(TimeSpan.FromSeconds(10), historyRequest.EndTimeUtc - historyRequest.StartTimeUtc); } }
public void DoesNotSetAlgorithmRunTimeErrorOnDisconnectIfAllSecuritiesClosed() { var referenceTime = DateTime.UtcNow; var algorithm = new AlgorithmStub(equities: new List <string> { "SPY" }); algorithm.SetDateTime(referenceTime); algorithm.Securities[Symbols.SPY].Exchange.SetMarketHours(Enumerable.Empty <MarketHoursSegment>(), referenceTime.ConvertFromUtc(TimeZones.NewYork).DayOfWeek); var job = new LiveNodePacket(); var results = new TestResultHandler();//packet => Console.WriteLine(FieldsToString(packet))); var api = new Api.Api(); var handler = new DefaultBrokerageMessageHandler(algorithm, job, results, api, TimeSpan.FromMinutes(15)); Assert.IsNull(algorithm.RunTimeError); handler.Handle(BrokerageMessageEvent.Disconnected("Disconnection!")); Assert.IsNull(algorithm.RunTimeError); results.Exit(); }
public void OptionExersiceWhenFullyInvested() { var algorithm = new AlgorithmStub(); algorithm.SetFinishedWarmingUp(); var backtestingTransactionHandler = new BacktestingTransactionHandler(); algorithm.Transactions.SetOrderProcessor(backtestingTransactionHandler); backtestingTransactionHandler.Initialize(algorithm, new BacktestingBrokerage(algorithm), new TestResultHandler(packet => { })); const decimal price = 2600m; var time = new DateTime(2020, 10, 14); var expDate = new DateTime(2021, 3, 19); // 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 = algorithm.AddOptionContract(symbol); optionSecurity.Underlying = algorithm.AddFutureContract(future); optionSecurity.Underlying.SetMarketPrice(new Tick { Value = price, Time = time }); optionSecurity.SetMarketPrice(new Tick { Value = 150, Time = time }); optionSecurity.Holdings.SetHoldings(1.5m, 10); var request = optionSecurity.CreateDelistedSecurityOrderRequest(algorithm.UtcTime); var ticket = algorithm.Transactions.AddOrder(request); Assert.AreEqual(OrderStatus.Filled, ticket.Status); }
public void DoesNotSetRunTimeErrorWhenReconnectMessageComesThrough() { var algorithm = new AlgorithmStub(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); algorithm.AddSecurities(equities: new List <string> { "SPY" }); var referenceTime = DateTime.UtcNow; algorithm.SetDateTime(referenceTime); var localReferencTime = referenceTime.ConvertFromUtc(TimeZones.NewYork); var open = localReferencTime.AddSeconds(1).TimeOfDay; var closed = TimeSpan.FromDays(1); var marketHours = new MarketHoursSegment(MarketHoursState.Market, open, closed); algorithm.Securities[Symbols.SPY].Exchange.SetMarketHours(new [] { marketHours }, localReferencTime.DayOfWeek); var job = new LiveNodePacket(); var results = new TestResultHandler();//packet => Console.WriteLine(FieldsToString(packet))); var api = new Api.Api(); var handler = new DefaultBrokerageMessageHandler(algorithm, job, api, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(.25)); Assert.IsNull(algorithm.RunTimeError); handler.Handle(BrokerageMessageEvent.Disconnected("Disconnection!")); Thread.Sleep(100); handler.Handle(BrokerageMessageEvent.Reconnected("Reconnected!")); Thread.Sleep(500); Assert.IsNull(algorithm.RunTimeError); results.Exit(); }
public void AppliesDividendsOnce() { // init algorithm var algorithm = new AlgorithmStub(new MockDataFeed()); algorithm.SetLiveMode(true); var dividend = new Dividend(Symbols.SPY, DateTime.UtcNow, 10m, 100m); var feed = new MockDataFeed(); var marketHoursDatabase = MarketHoursDatabase.FromDataFolder(); var symbolPropertiesDataBase = SymbolPropertiesDatabase.FromDataFolder(); var dataPermissionManager = new DataPermissionManager(); var dataManager = new DataManager(feed, new UniverseSelection( algorithm, new SecurityService(algorithm.Portfolio.CashBook, marketHoursDatabase, symbolPropertiesDataBase, algorithm, RegisteredSecurityDataTypesProvider.Null, new SecurityCacheProvider(algorithm.Portfolio)), dataPermissionManager, new DefaultDataProvider()), algorithm, algorithm.TimeKeeper, marketHoursDatabase, true, RegisteredSecurityDataTypesProvider.Null, dataPermissionManager); var synchronizer = new NullSynchronizer(algorithm, dividend); algorithm.SubscriptionManager.SetDataManager(dataManager); algorithm.AddSecurities(equities: new List <string> { "SPY" }); algorithm.Securities[Symbols.SPY].Holdings.SetHoldings(100m, 1); algorithm.PostInitialize(); var initializedCash = algorithm.Portfolio.CashBook[Currencies.USD].Amount; // init algorithm manager var manager = new AlgorithmManager(true); var job = new LiveNodePacket { UserId = 1, ProjectId = 2, DeployId = $"{nameof(PaperBrokerageTests)}.{nameof(AppliesDividendsOnce)}" }; var results = new LiveTradingResultHandler(); var transactions = new BacktestingTransactionHandler(); var brokerage = new PaperBrokerage(algorithm, job); // initialize results and transactions results.Initialize(job, new EventMessagingHandler(), new Api.Api(), transactions); results.SetAlgorithm(algorithm, algorithm.Portfolio.TotalPortfolioValue); transactions.Initialize(algorithm, brokerage, results); var realTime = new BacktestingRealTimeHandler(); // run algorithm manager manager.Run(job, algorithm, synchronizer, transactions, results, realTime, new AlgorithmManagerTests.NullLeanManager(), new AlgorithmManagerTests.NullAlphaHandler(), new CancellationToken() ); var postDividendCash = algorithm.Portfolio.CashBook[Currencies.USD].Amount; realTime.Exit(); results.Exit(); Assert.AreEqual(initializedCash + dividend.Distribution, postDividendCash); }
public void PythonDoesNotImplementDetermineTargetPercent() { var algorithm = new AlgorithmStub(); using (Py.GIL()) { dynamic model = PythonEngine.ModuleFromString( "TestPCM", @" from clr import AddReference AddReference(""QuantConnect.Algorithm.Framework"") from QuantConnect.Algorithm.Framework.Portfolio import * class PyPCM(EqualWeightingPortfolioConstructionModel): def __init__(self): self.CreateTargets_WasCalled = False self.OnSecuritiesChanged_WasCalled = False self.ShouldCreateTargetForInsight_WasCalled = False self.IsRebalanceDue_WasCalled = False self.GetTargetInsights_WasCalled = False def CreateTargets(self, algorithm, insights): self.CreateTargets_WasCalled = True return super().CreateTargets(algorithm, insights) def OnSecuritiesChanged(self, algorithm, changes): self.OnSecuritiesChanged_WasCalled = True super().OnSecuritiesChanged(algorithm, changes) def ShouldCreateTargetForInsight(self, insight): self.ShouldCreateTargetForInsight_WasCalled = True return super().ShouldCreateTargetForInsight(insight) def IsRebalanceDue(self, insights, algorithmUtc): self.IsRebalanceDue_WasCalled = True return True def GetTargetInsights(self): self.GetTargetInsights_WasCalled = True return super().GetTargetInsights() " ).GetAttr("PyPCM").Invoke(); var now = new DateTime(2020, 1, 10); var wrappedModel = new PortfolioConstructionModelPythonWrapper(model); var aapl = algorithm.AddEquity("AAPL"); aapl.SetMarketPrice(new Tick(now, aapl.Symbol, 10, 10)); algorithm.SetDateTime(now); wrappedModel.OnSecuritiesChanged(algorithm, new SecurityChanges(SecurityChanges.Added(aapl))); Assert.IsTrue((bool)model.OnSecuritiesChanged_WasCalled); var insight = new Insight(now, aapl.Symbol, TimeSpan.FromDays(1), InsightType.Price, InsightDirection.Down, null, null); var result = wrappedModel.CreateTargets(algorithm, new[] { insight }).ToList(); Assert.AreEqual(1, result.Count); Assert.IsTrue((bool)model.CreateTargets_WasCalled); Assert.IsTrue((bool)model.GetTargetInsights_WasCalled); Assert.IsTrue((bool)model.IsRebalanceDue_WasCalled); Assert.IsTrue((bool)model.ShouldCreateTargetForInsight_WasCalled); } }