Lean  $LEAN_TAG$
BaseDataCollection.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.Linq;
19 using System.Collections;
20 using System.Collections.Generic;
21 
23 {
24  /// <summary>
25  /// This type exists for transport of data as a single packet
26  /// </summary>
27  public class BaseDataCollection : BaseData, IEnumerable<BaseData>
28  {
29  private DateTime _endTime;
30 
31  /// <summary>
32  /// The associated underlying price data if any
33  /// </summary>
34  public BaseData Underlying { get; set; }
35 
36  /// <summary>
37  /// Gets or sets the contracts selected by the universe
38  /// </summary>
39  public HashSet<Symbol> FilteredContracts { get; set; }
40 
41  /// <summary>
42  /// Gets the data list
43  /// </summary>
44  public List<BaseData> Data { get; set; }
45 
46  /// <summary>
47  /// Gets or sets the end time of this data
48  /// </summary>
49  public override DateTime EndTime
50  {
51  get
52  {
53  if (_endTime == default)
54  {
55  // to be user friendly let's return Time if not set, like BaseData does
56  return Time;
57  }
58  return _endTime;
59  }
60  set
61  {
62  _endTime = value;
63  }
64  }
65 
66  /// <summary>
67  /// Initializes a new default instance of the <see cref="BaseDataCollection"/> c;ass
68  /// </summary>
70  : this(DateTime.MinValue, Symbol.Empty)
71  {
72  }
73 
74  /// <summary>
75  /// Initializes a new instance of the <see cref="BaseDataCollection"/> class
76  /// </summary>
77  /// <param name="time">The time of this data</param>
78  /// <param name="symbol">A common identifier for all data in this packet</param>
79  /// <param name="data">The data to add to this collection</param>
80  public BaseDataCollection(DateTime time, Symbol symbol, IEnumerable<BaseData> data = null)
81  : this(time, time, symbol, data)
82  {
83  }
84 
85  /// <summary>
86  /// Initializes a new instance of the <see cref="BaseDataCollection"/> class
87  /// </summary>
88  /// <param name="time">The start time of this data</param>
89  /// <param name="endTime">The end time of this data</param>
90  /// <param name="symbol">A common identifier for all data in this packet</param>
91  /// <param name="data">The data to add to this collection</param>
92  /// <param name="underlying">The associated underlying price data if any</param>
93  /// <param name="filteredContracts">The contracts selected by the universe</param>
94  public BaseDataCollection(DateTime time, DateTime endTime, Symbol symbol, IEnumerable<BaseData> data = null, BaseData underlying = null, HashSet<Symbol> filteredContracts = null)
95  : this(time, endTime, symbol, data != null ? data.ToList() : new List<BaseData>(), underlying, filteredContracts)
96  {
97  }
98 
99  /// <summary>
100  /// Initializes a new instance of the <see cref="BaseDataCollection"/> class
101  /// </summary>
102  /// <param name="time">The start time of this data</param>
103  /// <param name="endTime">The end time of this data</param>
104  /// <param name="symbol">A common identifier for all data in this packet</param>
105  /// <param name="data">The data to add to this collection</param>
106  /// <param name="underlying">The associated underlying price data if any</param>
107  /// <param name="filteredContracts">The contracts selected by the universe</param>
108  public BaseDataCollection(DateTime time, DateTime endTime, Symbol symbol, List<BaseData> data, BaseData underlying, HashSet<Symbol> filteredContracts)
109  {
110  Symbol = symbol;
111  Time = time;
112  _endTime = endTime;
113  Underlying = underlying;
114  FilteredContracts = filteredContracts;
115  if (data != null && data.Count == 1 && data[0] is BaseDataCollection collection && collection.Data.Count > 0)
116  {
117  // we were given a base data collection, let's be nice and fetch it's data if it has any
118  Data = collection.Data;
119  }
120  else
121  {
122  Data = data ?? new List<BaseData>();
123  }
124  }
125 
126  /// <summary>
127  /// Creates the universe symbol for the target market
128  /// </summary>
129  /// <returns>The universe symbol to use</returns>
130  public virtual Symbol UniverseSymbol(string market = null)
131  {
132  market ??= QuantConnect.Market.USA;
133  var ticker = $"{GetType().Name}-{market}-{Guid.NewGuid()}";
134  return Symbol.Create(ticker, SecurityType.Base, market, baseDataType: GetType());
135  }
136 
137  /// <summary>
138  /// Indicates whether this contains data that should be stored in the security cache
139  /// </summary>
140  /// <returns>Whether this contains data that should be stored in the security cache</returns>
141  public override bool ShouldCacheToSecurity()
142  {
143  if (Data.Count == 0)
144  {
145  return true;
146  }
147  // if we hold the same data type we are, else we ask underlying type
148  return Data[0].GetType() == GetType() || Data[0].ShouldCacheToSecurity();
149  }
150 
151  /// <summary>
152  /// Adds a new data point to this collection
153  /// </summary>
154  /// <param name="newDataPoint">The new data point to add</param>
155  public virtual void Add(BaseData newDataPoint)
156  {
157  Data.Add(newDataPoint);
158  }
159 
160  /// <summary>
161  /// Adds a new data points to this collection
162  /// </summary>
163  /// <param name="newDataPoints">The new data points to add</param>
164  public virtual void AddRange(IEnumerable<BaseData> newDataPoints)
165  {
166  Data.AddRange(newDataPoints);
167  }
168 
169  /// <summary>
170  /// Return a new instance clone of this object, used in fill forward
171  /// </summary>
172  /// <remarks>
173  /// This base implementation uses reflection to copy all public fields and properties
174  /// </remarks>
175  /// <returns>A clone of the current object</returns>
176  public override BaseData Clone()
177  {
179  }
180 
181  /// <summary>
182  /// Returns an IEnumerator for this enumerable Object. The enumerator provides
183  /// a simple way to access all the contents of a collection.
184  /// </summary>
185  public IEnumerator<BaseData> GetEnumerator()
186  {
187  return (Data ?? Enumerable.Empty<BaseData>()).GetEnumerator();
188  }
189 
190  /// <summary>
191  /// Returns an IEnumerator for this enumerable Object. The enumerator provides
192  /// a simple way to access all the contents of a collection.
193  /// </summary>
194  IEnumerator IEnumerable.GetEnumerator()
195  {
196  return GetEnumerator();
197  }
198  }
199 }