Lean  $LEAN_TAG$
DataQueueFuturesChainUniverseDataCollectionEnumerator.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 System.Collections.Generic;
19 using QuantConnect.Data;
21 using System.Collections;
22 using System.Linq;
25 using QuantConnect.Logging;
26 
28 {
29  /// <summary>
30  /// Enumerates live futures symbol universe data into <see cref="BaseDataCollection"/> instances
31  /// </summary>
32  public class DataQueueFuturesChainUniverseDataCollectionEnumerator : IEnumerator<BaseDataCollection>
33  {
34  private readonly SubscriptionRequest _subscriptionRequest;
35  private readonly IDataQueueUniverseProvider _universeProvider;
36  private readonly ITimeProvider _timeProvider;
37 
38  private bool _needNewCurrent;
39  private DateTime _lastEmitTime;
40 
41  /// <summary>
42  /// Initializes a new instance of the <see cref="DataQueueFuturesChainUniverseDataCollectionEnumerator"/> class.
43  /// </summary>
44  /// <param name="subscriptionRequest">The subscription request to be used</param>
45  /// <param name="universeProvider">Symbol universe provider of the data queue</param>
46  /// <param name="timeProvider">The time provider to be used</param>
48  SubscriptionRequest subscriptionRequest,
49  IDataQueueUniverseProvider universeProvider,
50  ITimeProvider timeProvider)
51  {
52  _subscriptionRequest = subscriptionRequest;
53  _universeProvider = universeProvider;
54  _timeProvider = timeProvider;
55 
56  _needNewCurrent = true;
57  }
58 
59  /// <summary>
60  /// Returns current futures chain enumerator position
61  /// </summary>
62  public BaseDataCollection Current { get; private set; }
63 
64  /// <summary>
65  /// Returns current futures chain enumerator position
66  /// </summary>
67  object IEnumerator.Current => Current;
68 
69  /// <summary>
70  /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
71  /// </summary>
72  public void Dispose()
73  {
74  }
75 
76  /// <summary>
77  /// Advances the enumerator to the next element of the collection.
78  /// </summary>
79  /// <returns>
80  /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.
81  /// </returns>
82  public bool MoveNext()
83  {
84  if (!_needNewCurrent)
85  {
86  // refresh on date change (in exchange time zone)
87  _needNewCurrent = _timeProvider.GetUtcNow().ConvertFromUtc(_subscriptionRequest.Configuration.ExchangeTimeZone).Date != _lastEmitTime.Date;
88  }
89 
90  if (_needNewCurrent)
91  {
92  if (!_universeProvider.CanPerformSelection())
93  {
94  Current = null;
95  return true;
96  }
97 
98  var localTime = _timeProvider.GetUtcNow()
99  .ConvertFromUtc(_subscriptionRequest.Configuration.ExchangeTimeZone)
100  .RoundDown(_subscriptionRequest.Configuration.Increment);
101 
102  // loading the list of futures contracts and converting them into zip entries
103  var symbols = _universeProvider.LookupSymbols(_subscriptionRequest.Security.Symbol, false);
104  var zipEntries = symbols.Select(x => new ZipEntryName { Time = localTime, Symbol = x } as BaseData).ToList();
105  var current = new BaseDataCollection
106  {
107  Symbol = _subscriptionRequest.Security.Symbol,
108  Data = zipEntries,
109  Time = localTime,
110  EndTime = localTime
111  };
112 
113  _lastEmitTime = localTime;
114 
115  Log.Trace($"DataQueueFuturesChainUniverseDataCollectionEnumerator({current.Symbol}): Emitting data point: {current.EndTime}. Count: {current.Data.Count}");
116 
117  Current = current;
118  _needNewCurrent = false;
119  }
120  else
121  {
122  Current = null;
123  }
124 
125  return true;
126  }
127 
128  /// <summary>
129  /// Sets the enumerator to its initial position, which is before the first element in the collection.
130  /// </summary>
131  public void Reset()
132  {
133  _needNewCurrent = true;
134  }
135  }
136 }