Lean  $LEAN_TAG$
BaseDataSubscriptionEnumeratorFactory.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 
17 using System;
18 using QuantConnect.Data;
20 using System.Collections.Generic;
23 
25 {
26  /// <summary>
27  /// Provides a default implementation of <see cref="ISubscriptionEnumeratorFactory"/> that uses
28  /// <see cref="BaseData"/> factory methods for reading sources
29  /// </summary>
31  {
32  private readonly IOptionChainProvider _optionChainProvider;
33  private readonly IFutureChainProvider _futureChainProvider;
34  private readonly Func<SubscriptionRequest, IEnumerable<DateTime>> _tradableDaysProvider;
35 
36  /// <summary>
37  /// Initializes a new instance of the <see cref="BaseDataSubscriptionEnumeratorFactory"/> class
38  /// </summary>
39  /// <param name="optionChainProvider">The option chain provider</param>
40  /// <param name="futureChainProvider">The future chain provider</param>
41  public BaseDataSubscriptionEnumeratorFactory(IOptionChainProvider optionChainProvider, IFutureChainProvider futureChainProvider)
42  {
43  _futureChainProvider = futureChainProvider;
44  _optionChainProvider = optionChainProvider;
45  _tradableDaysProvider = (request => request.TradableDaysInDataTimeZone);
46  }
47 
48  /// <summary>
49  /// Creates an enumerator to read the specified request
50  /// </summary>
51  /// <param name="request">The subscription request to be read</param>
52  /// <param name="dataProvider">Provider used to get data when it is not present on disk</param>
53  /// <returns>An enumerator reading the subscription request</returns>
54  public IEnumerator<BaseData> CreateEnumerator(SubscriptionRequest request, IDataProvider dataProvider)
55  {
56  // We decide to use the ZipDataCacheProvider instead of the SingleEntryDataCacheProvider here
57  // for resiliency and as a fix for an issue preventing us from reading non-equity options data.
58  // It has the added benefit of caching any zip files that we request from the filesystem, and reading
59  // files contained within the zip file, which the SingleEntryDataCacheProvider does not support.
60  var sourceFactory = request.Configuration.GetBaseDataInstance();
61  foreach (var date in _tradableDaysProvider(request))
62  {
63  IEnumerable<Symbol> symbols;
64  if (request.Configuration.SecurityType.IsOption())
65  {
66  symbols = _optionChainProvider.GetOptionContractList(request.Configuration.Symbol, date);
67  }
68  else if (request.Configuration.SecurityType == SecurityType.Future)
69  {
70  symbols = _futureChainProvider.GetFutureContractList(request.Configuration.Symbol, date);
71  }
72  else
73  {
74  throw new NotImplementedException($"{request.Configuration.SecurityType} is not supported");
75  }
76 
77  // we are going to use these symbols to create a collection that for options will also have the underlying that will be emitted in exchange time zone
78  // note the merging of the data will happen based on their end time so time zones are important to respect
79  var exchangeTimeZoneDate = date.ConvertTo(request.Configuration.DataTimeZone, request.ExchangeHours.TimeZone);
80  foreach (var symbol in symbols)
81  {
82  yield return new ZipEntryName { Symbol = symbol, Time = exchangeTimeZoneDate };
83  }
84  }
85  }
86  }
87 }