Lean  $LEAN_TAG$
FastForwardEnumerator.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;
19 using System.Collections.Generic;
20 using NodaTime;
21 using QuantConnect.Data;
22 
24 {
25  /// <summary>
26  /// Provides the ability to fast forward an enumerator based on the age of the data
27  /// </summary>
28  public class FastForwardEnumerator : IEnumerator<BaseData>
29  {
30  private BaseData _current;
31 
32  private readonly DateTimeZone _timeZone;
33  private readonly TimeSpan _maximumDataAge;
34  private readonly ITimeProvider _timeProvider;
35  private readonly IEnumerator<BaseData> _enumerator;
36 
37  /// <summary>
38  /// Initializes a new instance of the <see cref="FastForwardEnumerator"/> class
39  /// </summary>
40  /// <param name="enumerator">The source enumerator</param>
41  /// <param name="timeProvider">A time provider used to determine age of data</param>
42  /// <param name="timeZone">The data's time zone</param>
43  /// <param name="maximumDataAge">The maximum age of data allowed</param>
44  public FastForwardEnumerator(IEnumerator<BaseData> enumerator, ITimeProvider timeProvider, DateTimeZone timeZone, TimeSpan maximumDataAge)
45  {
46  _enumerator = enumerator;
47  _timeProvider = timeProvider;
48  _timeZone = timeZone;
49  _maximumDataAge = maximumDataAge;
50  }
51 
52  /// <summary>
53  /// Advances the enumerator to the next element of the collection.
54  /// </summary>
55  /// <returns>
56  /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.
57  /// </returns>
58  public bool MoveNext()
59  {
60  // keep churning until recent data or null
61  while (_enumerator.MoveNext())
62  {
63  // we can't fast forward nulls or bad times
64  if (_enumerator.Current == null || _enumerator.Current.Time == DateTime.MinValue)
65  {
66  _current = null;
67  return true;
68  }
69 
70  // make sure we never emit past data
71  if (_current != null && _current.EndTime > _enumerator.Current.EndTime)
72  {
73  continue;
74  }
75 
76  // comute the age of the data, if within limits we're done
77  var age = _timeProvider.GetUtcNow().ConvertFromUtc(_timeZone) - _enumerator.Current.EndTime;
78  if (age <= _maximumDataAge)
79  {
80  _current = _enumerator.Current;
81  return true;
82  }
83  }
84 
85  // we've exhausted the underlying enumerator, iterator completed
86  _current = null;
87  return false;
88  }
89 
90  /// <summary>
91  /// Sets the enumerator to its initial position, which is before the first element in the collection.
92  /// </summary>
93  /// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception><filterpriority>2</filterpriority>
94  public void Reset()
95  {
96  _enumerator.Reset();
97  }
98 
99  /// <summary>
100  /// Gets the element in the collection at the current position of the enumerator.
101  /// </summary>
102  /// <returns>
103  /// The element in the collection at the current position of the enumerator.
104  /// </returns>
105  public BaseData Current
106  {
107  get { return _current; }
108  }
109 
110  /// <summary>
111  /// Gets the current element in the collection.
112  /// </summary>
113  /// <returns>
114  /// The current element in the collection.
115  /// </returns>
116  /// <filterpriority>2</filterpriority>
117  object IEnumerator.Current
118  {
119  get { return _current; }
120  }
121 
122  /// <summary>
123  /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
124  /// </summary>
125  /// <filterpriority>2</filterpriority>
126  public void Dispose()
127  {
128  _enumerator.Dispose();
129  }
130 
131  }
132 }