/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 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 System.Linq; using QuantConnect.Interfaces; using System.Collections.Generic; using QuantConnect.Data.Auxiliary; using System.Text.RegularExpressions; namespace QuantConnect.Data { /// /// Helper extension methods for objects related with Histotical data /// public static class HistoryExtensions { private static readonly Regex _brokerageHistoryProvider = new("QuantConnect.Lean.Engine.HistoricalData.([a-zA-z]+)HistoryProvider", RegexOptions.Compiled); /// /// Helper method to get the brokerage name /// public static bool TryGetBrokerageName(string historyProviderName, out string brokerageName) { brokerageName = null; if (historyProviderName != "QuantConnect.Lean.Engine.HistoricalData.BrokerageHistoryProvider" && historyProviderName != "QuantConnect.Lean.Engine.HistoricalData.SubscriptionDataReaderHistoryProvider") { var matches = _brokerageHistoryProvider.Match(historyProviderName); if (matches.Success) { brokerageName = matches.Groups[1].Value; return true; } } return false; } /// /// Split on several request with update mapped symbol. /// /// Represents historical data requests /// Provides instances of at run time /// /// Return HistoryRequests with different - range /// and /// /// Thrown when is null. /// /// For instances: /// request = { StartTimeUtc = 2013/01/01, EndTimeUtc = 2017/02/02, Symbol = "GOOGL" } split request on: /// 1: request = { StartTimeUtc = 2013/01/01, EndTimeUtc = 2014/04/02, Symbol.Value = "GOOG" } /// 2: request = { StartTimeUtc = 2014/04/**03**, EndTimeUtc = 2017/02/02, Symbol.Value = "GOOGL" } /// > GOOGLE: IPO: August 19, 2004 Name = GOOG then it was restructured: from "GOOG" to "GOOGL" on April 2, 2014 /// public static IEnumerable SplitHistoryRequestWithUpdatedMappedSymbol(this HistoryRequest request, IMapFileProvider mapFileProvider) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (request.Symbol.SecurityType != SecurityType.Future && request.Symbol.RequiresMapping()) { var isReturnHistoryRequest = default(bool); foreach (var tickerDateRange in mapFileProvider.RetrieveSymbolHistoricalDefinitionsInDateRange(request.Symbol, request.StartTimeLocal, request.EndTimeLocal)) { isReturnHistoryRequest = true; var symbol = request.Symbol.UpdateMappedSymbol(tickerDateRange.Ticker); yield return new HistoryRequest( request, symbol, tickerDateRange.StartDateTimeLocal.ConvertToUtc(request.ExchangeHours.TimeZone), tickerDateRange.EndDateTimeLocal.ConvertToUtc(request.ExchangeHours.TimeZone) ); } if (!isReturnHistoryRequest) { yield return request; } } else { yield return request; } } } }