diff --git a/Algorithm/QCAlgorithm.History.cs b/Algorithm/QCAlgorithm.History.cs index 4186176509b5..94960655662e 100644 --- a/Algorithm/QCAlgorithm.History.cs +++ b/Algorithm/QCAlgorithm.History.cs @@ -1084,11 +1084,18 @@ private IEnumerable GetMatchingSubscriptions(Symbol symb // since this might be called when creating a security and warming it up if (configs != null && configs.Count != 0) { - // Check if resolution is set and not Daily or Hourly for an Equity symbol - if (resolution.HasValue && resolution != Resolution.Daily && resolution != Resolution.Hour && symbol.SecurityType == SecurityType.Equity) + if (resolution.HasValue && symbol.SecurityType == SecurityType.Equity) { - // Lookup the subscription configuration data type for the Equity symbol, filtering for Quote tick type - type = SubscriptionManager.LookupSubscriptionConfigDataTypes(SecurityType.Equity, resolution.Value, false).Where(e => e.Item2 == TickType.Quote).FirstOrDefault().Item1; + // Check if resolution is set and not Daily or Hourly for an Equity symbol + if (resolution == Resolution.Daily || resolution == Resolution.Hour) + { + // for Daily and Hour resolution, for equities, we have to + // filter out any existing subscriptions that could be of Quote type + // This could happen if they were Resolution.Minute/Second/Tick + return configs.Where(s => s.TickType != TickType.Quote); + } + + type = typeof(QuoteBar); var entry = MarketHoursDatabase.GetEntry(symbol, new[] { type }); // Create a new SubscriptionDataConfig @@ -1110,15 +1117,7 @@ private IEnumerable GetMatchingSubscriptions(Symbol symb // Sort the configs in descending order based on tick type configs = configs.OrderByDescending(config => GetTickTypeOrder(config.SecurityType, config.TickType)).ToList(); - } - if (resolution.HasValue - && (resolution == Resolution.Daily || resolution == Resolution.Hour) - && symbol.SecurityType == SecurityType.Equity) - { - // for Daily and Hour resolution, for equities, we have to - // filter out any existing subscriptions that could be of Quote type - // This could happen if they were Resolution.Minute/Second/Tick - return configs.Where(s => s.TickType != TickType.Quote); + } if (symbol.IsCanonical() && configs.Count > 1) diff --git a/Tests/Algorithm/AlgorithmHistoryTests.cs b/Tests/Algorithm/AlgorithmHistoryTests.cs index f8d211bcf5a9..ce111d4e7b90 100644 --- a/Tests/Algorithm/AlgorithmHistoryTests.cs +++ b/Tests/Algorithm/AlgorithmHistoryTests.cs @@ -303,28 +303,66 @@ public void ExplicitTickResolutionHistoryRequestTradeBarApiThrowsException() Assert.Throws(() => _algorithm.History(spy, 1, Resolution.Tick).ToList()); } - [Test] - public void VerifyHistoryWithMinuteResolutionDespiteEquityHourResolution() + [TestCase(Resolution.Tick, Resolution.Tick, true)] + [TestCase(Resolution.Tick, Resolution.Second, true)] + [TestCase(Resolution.Tick, Resolution.Minute, true)] + [TestCase(Resolution.Tick, Resolution.Hour, true)] + [TestCase(Resolution.Tick, Resolution.Daily, true)] + [TestCase(Resolution.Second, Resolution.Tick, true)] + [TestCase(Resolution.Second, Resolution.Second, true)] + [TestCase(Resolution.Second, Resolution.Minute, true)] + [TestCase(Resolution.Second, Resolution.Hour, true)] + [TestCase(Resolution.Second, Resolution.Daily, true)] + [TestCase(Resolution.Minute, Resolution.Tick, true)] + [TestCase(Resolution.Minute, Resolution.Second, true)] + [TestCase(Resolution.Minute, Resolution.Minute, true)] + [TestCase(Resolution.Minute, Resolution.Hour, true)] + [TestCase(Resolution.Minute, Resolution.Daily, true)] + [TestCase(Resolution.Hour, Resolution.Tick, false)] + [TestCase(Resolution.Hour, Resolution.Second, false)] + [TestCase(Resolution.Hour, Resolution.Minute, false)] + [TestCase(Resolution.Hour, Resolution.Hour, false)] + [TestCase(Resolution.Hour, Resolution.Daily, false)] + [TestCase(Resolution.Daily, Resolution.Tick, false)] + [TestCase(Resolution.Daily, Resolution.Second, false)] + [TestCase(Resolution.Daily, Resolution.Minute, false)] + [TestCase(Resolution.Daily, Resolution.Hour, false)] + [TestCase(Resolution.Daily, Resolution.Daily, false)] + public void VerifyReceivedDataBasedOnHistoryResolutionOnly(Resolution historyResolution, Resolution equityResolution, bool expected) { var algorithm = GetAlgorithm(new DateTime(2013, 10, 1)); - algorithm.SetStartDate(2013, 10, 8); + algorithm.SetStartDate(2013, 10, 10); var spy = algorithm.AddEquity("SPY", Resolution.Minute).Symbol; - var ibm = algorithm.AddEquity("IBM", Resolution.Hour).Symbol; + var ibm = algorithm.AddEquity("IBM", equityResolution).Symbol; - // Retrieve history for both symbols with Minute resolution - var history = algorithm.History(new[] { spy, ibm }, TimeSpan.FromDays(1), Resolution.Minute).ToList(); + // Retrieving history for both symbols based on the given resolution + var history = algorithm.History(new[] { spy, ibm }, TimeSpan.FromDays(1), historyResolution); + var allHistory = history.SelectMany(slice => slice.AllData).ToList(); - bool bothSymbolsHaveQuoteBars = history.Any(slice => slice.QuoteBars.ContainsKey(spy) && slice.QuoteBars.ContainsKey(ibm)); - bool bothSymbolsHaveBars = history.Any(slice => slice.Bars.ContainsKey(spy) && slice.Bars.ContainsKey(ibm)); + // Flags to check if there's Quote data for SPY and IBM + var spyFlag = false; + var ibmFlag = false; - // Ensure history contains data - Assert.IsTrue(history.Count > 0); + // If the history resolution is Tick, check for Quote-type ticks + if (historyResolution == Resolution.Tick) + { + var ticks = allHistory.OfType().Where(e => e.TickType == TickType.Quote).ToList(); + spyFlag = ticks.Any(e => e.Symbol == spy); + ibmFlag = ticks.Any(e => e.Symbol == ibm); + } + + // Checking for QuoteBar data for SPY and IBM + var quoteBars = allHistory.Where(e => e.DataType == MarketDataType.QuoteBar).ToList(); + spyFlag |= quoteBars.Any(e => e.Symbol == spy); + ibmFlag |= quoteBars.Any(e => e.Symbol == ibm); + // Verifying that both symbols have Quote data based on the history resolution + bool bothSymbolsHaveQuotes = spyFlag & ibmFlag; - // Assert both symbols have QuoteBars data - Assert.IsTrue(bothSymbolsHaveQuoteBars); + // Ensure history contains data + Assert.IsTrue(allHistory.Count > 0); - // Assert both symbols have Bars data - Assert.IsTrue(bothSymbolsHaveBars); + // Asserting that the result matches the expected outcome + Assert.AreEqual(expected, bothSymbolsHaveQuotes); } [TestCase(Language.CSharp)]