Lean  $LEAN_TAG$
HistoryExtensions.cs
1 /*
2  * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3  * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14 */
15 
16 using System;
17 using System.Linq;
19 using System.Collections.Generic;
21 using System.Text.RegularExpressions;
22 
23 namespace QuantConnect.Data
24 {
25  public static class HistoryExtensions
26  {
27  private static readonly Regex _brokerageHistoryProvider = new("QuantConnect.Lean.Engine.HistoricalData.([a-zA-z]+)HistoryProvider", RegexOptions.Compiled);
28 
29  /// <summary>
30  /// Helper method to get the brokerage name
31  /// </summary>
32  public static bool TryGetBrokerageName(string historyProviderName, out string brokerageName)
33  {
34  brokerageName = null;
35  if (historyProviderName != "QuantConnect.Lean.Engine.HistoricalData.BrokerageHistoryProvider"
36  && historyProviderName != "QuantConnect.Lean.Engine.HistoricalData.SubscriptionDataReaderHistoryProvider")
37  {
38  var matches = _brokerageHistoryProvider.Match(historyProviderName);
39  if (matches.Success)
40  {
41  brokerageName = matches.Groups[1].Value;
42  return true;
43  }
44  }
45 
46  return false;
47  }
48 
49  /// <summary>
50  /// Split <see cref="HistoryRequest"/> on several request with update mapped symbol.
51  /// </summary>
52  /// <param name="request">Represents historical data requests</param>
53  /// <param name="mapFileProvider">Provides instances of <see cref="MapFileResolver"/> at run time</param>
54  /// <returns>
55  /// Return HistoryRequests with different <see cref="BaseDataRequest.StartTimeUtc"/> - <seealso cref="BaseDataRequest.EndTimeUtc"/> range
56  /// and <seealso cref="Symbol.Value"/>
57  /// </returns>
58  /// <exception cref="ArgumentNullException">Thrown when <paramref name="mapFileProvider"/> is null.</exception>
59  /// <example>
60  /// For instances:
61  /// request = { StartTimeUtc = 2013/01/01, EndTimeUtc = 2017/02/02, Symbol = "GOOGL" } split request on:
62  /// 1: request = { StartTimeUtc = 2013/01/01, EndTimeUtc = 2014/04/02, Symbol.Value = "GOOG" }
63  /// 2: request = { StartTimeUtc = 2014/04/**03**, EndTimeUtc = 2017/02/02, Symbol.Value = "GOOGL" }
64  /// > GOOGLE: IPO: August 19, 2004 Name = GOOG then it was restructured: from "GOOG" to "GOOGL" on April 2, 2014
65  /// </example>
66  public static IEnumerable<HistoryRequest> SplitHistoryRequestWithUpdatedMappedSymbol(this HistoryRequest request, IMapFileProvider mapFileProvider)
67  {
68  if (request == null)
69  {
70  throw new ArgumentNullException(nameof(request));
71  }
72 
73  if (request.Symbol.SecurityType != SecurityType.Future && request.Symbol.RequiresMapping())
74  {
75  var isReturnHistoryRequest = default(bool);
76  foreach (var tickerDateRange in mapFileProvider.RetrieveSymbolHistoricalDefinitionsInDateRange(request.Symbol, request.StartTimeLocal, request.EndTimeLocal))
77  {
78  isReturnHistoryRequest = true;
79  var symbol = request.Symbol.UpdateMappedSymbol(tickerDateRange.Ticker);
80  yield return new HistoryRequest(
81  request,
82  symbol,
83  tickerDateRange.StartDateTimeLocal.ConvertToUtc(request.ExchangeHours.TimeZone),
84  tickerDateRange.EndDateTimeLocal.ConvertToUtc(request.ExchangeHours.TimeZone)
85  );
86  }
87 
88  if (!isReturnHistoryRequest)
89  {
90  yield return request;
91  }
92  }
93  else
94  {
95  yield return request;
96  }
97  }
98  }
99 }