/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2026 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using NodaTime; using System.Linq; using QuantConnect.Data; using QuantConnect.Util; using QuantConnect.Interfaces; using System.Collections.Generic; using QuantConnect.Lean.Engine.DataFeeds; namespace QuantConnect.Lean.Engine.HistoricalData { /// /// Base class for history providers that resolve symbol mappings /// and synchronize multiple data streams into time-aligned slices. /// public abstract class MappedSynchronizingHistoryProvider : SynchronizingHistoryProvider { /// /// Resolves map files to correctly handle current and historical ticker symbols. /// private static readonly Lazy _mapFileProvider = new(Composer.Instance.GetPart); /// /// Gets historical data for a single resolved history request. /// Implementations should assume the symbol is already correctly mapped. /// /// The resolved history request. /// The historical data. public abstract IEnumerable? GetHistory(HistoryRequest request); /// /// Gets the history for the requested securities /// /// The historical data requests /// The time zone used when time stamping the slice instances /// An enumerable of the slices of data covering the span specified in each request public override IEnumerable? GetHistory(IEnumerable requests, DateTimeZone sliceTimeZone) { var subscriptions = new List(); foreach (var request in requests) { var history = request .SplitHistoryRequestWithUpdatedMappedSymbol(_mapFileProvider.Value) .SelectMany(x => GetHistory(x) ?? []); var subscription = CreateSubscription(request, history); if (!subscription.MoveNext()) { continue; } subscriptions.Add(subscription); } if (subscriptions.Count == 0) { return null; } // Ownership of subscription is transferred to CreateSliceEnumerableFromSubscriptions return CreateSliceEnumerableFromSubscriptions(subscriptions, sliceTimeZone); } } }