Lean  $LEAN_TAG$
BaseSubscriptionDataSourceReader.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 QuantConnect.Data;
18 using System.ComponentModel;
20 using System.Collections.Generic;
23 
25 {
26  /// <summary>
27  /// A base class for implementations of the <see cref="ISubscriptionDataSourceReader"/>
28  /// </summary>
30  {
31  /// <summary>
32  /// True if we're in live mode, false for backtesting
33  /// </summary>
34  protected bool IsLiveMode { get; }
35 
36  /// <summary>
37  /// The data cache provider to use
38  /// </summary>
40 
41  /// <summary>
42  /// The object store to use
43  /// </summary>
44  protected IObjectStore ObjectStore { get; }
45 
46  /// <summary>
47  /// Event fired when the specified source is considered invalid, this may
48  /// be from a missing file or failure to download a remote source
49  /// </summary>
50  public event EventHandler<InvalidSourceEventArgs> InvalidSource;
51 
52  /// <summary>
53  /// Creates a new instance
54  /// </summary>
55  protected BaseSubscriptionDataSourceReader(IDataCacheProvider dataCacheProvider, bool isLiveMode, IObjectStore objectStore)
56  {
57  DataCacheProvider = dataCacheProvider;
58  IsLiveMode = isLiveMode;
59  ObjectStore = objectStore;
60  }
61 
62  /// <summary>
63  /// Reads the specified <paramref name="source"/>
64  /// </summary>
65  /// <param name="source">The source to be read</param>
66  /// <returns>An <see cref="IEnumerable{BaseData}"/> that contains the data in the source</returns>
67  public abstract IEnumerable<BaseData> Read(SubscriptionDataSource source);
68 
69  /// <summary>
70  /// Creates a new <see cref="IStreamReader"/> for the specified <paramref name="subscriptionDataSource"/>
71  /// </summary>
72  /// <param name="subscriptionDataSource">The source to produce an <see cref="IStreamReader"/> for</param>
73  /// <returns>A new instance of <see cref="IStreamReader"/> to read the source, or null if there was an error</returns>
74  protected IStreamReader CreateStreamReader(SubscriptionDataSource subscriptionDataSource)
75  {
76  IStreamReader reader = null;
77  try
78  {
79  switch (subscriptionDataSource.TransportMedium)
80  {
81  case SubscriptionTransportMedium.LocalFile:
82  reader = new LocalFileSubscriptionStreamReader(DataCacheProvider, subscriptionDataSource.Source);
83  break;
84 
85  case SubscriptionTransportMedium.RemoteFile:
86  reader = HandleRemoteSourceFile(subscriptionDataSource);
87  break;
88 
90  reader = new RestSubscriptionStreamReader(subscriptionDataSource.Source, subscriptionDataSource.Headers, IsLiveMode);
91  break;
92 
93  case SubscriptionTransportMedium.ObjectStore:
94  reader = new ObjectStoreSubscriptionStreamReader(ObjectStore, subscriptionDataSource.Source);
95  break;
96 
97  default:
98  throw new InvalidEnumArgumentException("Unexpected SubscriptionTransportMedium specified: " + subscriptionDataSource.TransportMedium);
99  }
100  }
101  catch (Exception e)
102  {
103  OnInvalidSource(subscriptionDataSource, e);
104  return reader;
105  }
106 
107  if (reader == null || reader.EndOfStream)
108  {
109  OnInvalidSource(subscriptionDataSource, new Exception($"The reader was empty for source: ${subscriptionDataSource.Source}"));
110  return null;
111  }
112  return reader;
113  }
114 
115  /// <summary>
116  /// Event invocator for the <see cref="InvalidSource"/> event
117  /// </summary>
118  /// <param name="source">The <see cref="SubscriptionDataSource"/> that was invalid</param>
119  /// <param name="exception">The exception if one was raised, otherwise null</param>
120  protected void OnInvalidSource(SubscriptionDataSource source, Exception exception)
121  {
122  InvalidSource?.Invoke(this, new InvalidSourceEventArgs(source, exception));
123  }
124 
125  /// <summary>
126  /// Opens up an IStreamReader for a remote file source
127  /// </summary>
128  private IStreamReader HandleRemoteSourceFile(SubscriptionDataSource source)
129  {
131 
132  try
133  {
134  // this will fire up a web client in order to download the 'source' file to the cache
136  }
137  catch (Exception)
138  {
139  return null;
140  }
141  }
142  }
143 }