Lean  $LEAN_TAG$
LeanEngineAlgorithmHandlers.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.ComponentModel.Composition;
20 using QuantConnect.Data;
29 using QuantConnect.Logging;
30 using QuantConnect.Util;
31 
33 {
34  /// <summary>
35  /// Provides a container for the algorithm specific handlers
36  /// </summary>
37  public class LeanEngineAlgorithmHandlers : IDisposable
38  {
39  /// <summary>
40  /// Gets the result handler used to communicate results from the algorithm
41  /// </summary>
42  public IResultHandler Results { get; }
43 
44  /// <summary>
45  /// Gets the setup handler used to initialize the algorithm state
46  /// </summary>
47  public ISetupHandler Setup { get; }
48 
49  /// <summary>
50  /// Gets the data feed handler used to provide data to the algorithm
51  /// </summary>
52  public IDataFeed DataFeed { get; }
53 
54  /// <summary>
55  /// Gets the transaction handler used to process orders from the algorithm
56  /// </summary>
58 
59  /// <summary>
60  /// Gets the real time handler used to process real time events
61  /// </summary>
62  public IRealTimeHandler RealTime { get; }
63 
64  /// <summary>
65  /// Gets the map file provider used as a map file source for the data feed
66  /// </summary>
68 
69  /// <summary>
70  /// Gets the map file provider used as a map file source for the data feed
71  /// </summary>
73 
74  /// <summary>
75  /// Gets the data file provider used to retrieve security data if it is not on the file system
76  /// </summary>
77  public IDataProvider DataProvider { get; }
78 
79  /// <summary>
80  /// Gets the data file provider used to retrieve security data if it is not on the file system
81  /// </summary>
83 
84  /// <summary>
85  /// Gets the object store used for persistence
86  /// </summary>
87  public IObjectStore ObjectStore { get; }
88 
89  /// <summary>
90  /// Entity in charge of handling data permissions
91  /// </summary>
93 
94  /// <summary>
95  /// Monitors data requests and reports on missing data
96  /// </summary>
97  public IDataMonitor DataMonitor { get; }
98 
99  /// <summary>
100  /// Initializes a new instance of the <see cref="LeanEngineAlgorithmHandlers"/> class from the specified handlers
101  /// </summary>
102  /// <param name="results">The result handler for communicating results from the algorithm</param>
103  /// <param name="setup">The setup handler used to initialize algorithm state</param>
104  /// <param name="dataFeed">The data feed handler used to pump data to the algorithm</param>
105  /// <param name="transactions">The transaction handler used to process orders from the algorithm</param>
106  /// <param name="realTime">The real time handler used to process real time events</param>
107  /// <param name="mapFileProvider">The map file provider used to retrieve map files for the data feed</param>
108  /// <param name="factorFileProvider">Map file provider used as a map file source for the data feed</param>
109  /// <param name="dataProvider">file provider used to retrieve security data if it is not on the file system</param>
110  /// <param name="objectStore">The object store used for persistence</param>
111  /// <param name="dataPermissionsManager">The data permission manager to use</param>
112  /// <param name="liveMode">True for live mode, false otherwise</param>
113  /// <param name="researchMode">True for research mode, false otherwise. This has less priority than liveMode</param>
115  ISetupHandler setup,
116  IDataFeed dataFeed,
117  ITransactionHandler transactions,
118  IRealTimeHandler realTime,
119  IMapFileProvider mapFileProvider,
120  IFactorFileProvider factorFileProvider,
121  IDataProvider dataProvider,
122  IObjectStore objectStore,
123  IDataPermissionManager dataPermissionsManager,
124  bool liveMode,
125  bool researchMode = false
126  )
127  {
128  if (results == null)
129  {
130  throw new ArgumentNullException(nameof(results));
131  }
132  if (setup == null)
133  {
134  throw new ArgumentNullException(nameof(setup));
135  }
136  if (dataFeed == null)
137  {
138  throw new ArgumentNullException(nameof(dataFeed));
139  }
140  if (transactions == null)
141  {
142  throw new ArgumentNullException(nameof(transactions));
143  }
144  if (realTime == null)
145  {
146  throw new ArgumentNullException(nameof(realTime));
147  }
148  if (mapFileProvider == null)
149  {
150  throw new ArgumentNullException(nameof(mapFileProvider));
151  }
152  if (factorFileProvider == null)
153  {
154  throw new ArgumentNullException(nameof(factorFileProvider));
155  }
156  if (dataProvider == null)
157  {
158  throw new ArgumentNullException(nameof(dataProvider));
159  }
160  if (objectStore == null)
161  {
162  throw new ArgumentNullException(nameof(objectStore));
163  }
164  if (dataPermissionsManager == null)
165  {
166  throw new ArgumentNullException(nameof(dataPermissionsManager));
167  }
168 
169  Results = results;
170  Setup = setup;
171  DataFeed = dataFeed;
172  Transactions = transactions;
173  RealTime = realTime;
174  MapFileProvider = mapFileProvider;
175  FactorFileProvider = factorFileProvider;
176  DataProvider = dataProvider;
177  ObjectStore = objectStore;
178  DataPermissionsManager = dataPermissionsManager;
179  DataCacheProvider = new ZipDataCacheProvider(DataProvider, isDataEphemeral: liveMode);
180  DataMonitor = new DataMonitor();
181 
182  if (!liveMode && !researchMode)
183  {
185  }
186  }
187 
188  /// <summary>
189  /// Creates a new instance of the <see cref="LeanEngineAlgorithmHandlers"/> class from the specified composer using type names from configuration
190  /// </summary>
191  /// <param name="composer">The composer instance to obtain implementations from</param>
192  /// <param name="researchMode">True for research mode, false otherwise</param>
193  /// <returns>A fully hydrates <see cref="LeanEngineSystemHandlers"/> instance.</returns>
194  /// <exception cref="CompositionException">Throws a CompositionException during failure to load</exception>
195  public static LeanEngineAlgorithmHandlers FromConfiguration(Composer composer, bool researchMode = false)
196  {
197  var setupHandlerTypeName = Config.Get("setup-handler", "ConsoleSetupHandler");
198  var transactionHandlerTypeName = Config.Get("transaction-handler", "BacktestingTransactionHandler");
199  var realTimeHandlerTypeName = Config.Get("real-time-handler", "BacktestingRealTimeHandler");
200  var dataFeedHandlerTypeName = Config.Get("data-feed-handler", "FileSystemDataFeed");
201  var resultHandlerTypeName = Config.Get("result-handler", "BacktestingResultHandler");
202  var mapFileProviderTypeName = Config.Get("map-file-provider", "LocalDiskMapFileProvider");
203  var factorFileProviderTypeName = Config.Get("factor-file-provider", "LocalDiskFactorFileProvider");
204  var dataProviderTypeName = Config.Get("data-provider", "DefaultDataProvider");
205  var objectStoreTypeName = Config.Get("object-store", "LocalObjectStore");
206  var dataPermissionManager = Config.Get("data-permission-manager", "DataPermissionManager");
207 
208  var result = new LeanEngineAlgorithmHandlers(
209  composer.GetExportedValueByTypeName<IResultHandler>(resultHandlerTypeName),
210  composer.GetExportedValueByTypeName<ISetupHandler>(setupHandlerTypeName),
211  composer.GetExportedValueByTypeName<IDataFeed>(dataFeedHandlerTypeName),
212  composer.GetExportedValueByTypeName<ITransactionHandler>(transactionHandlerTypeName),
213  composer.GetExportedValueByTypeName<IRealTimeHandler>(realTimeHandlerTypeName),
214  composer.GetExportedValueByTypeName<IMapFileProvider>(mapFileProviderTypeName),
215  composer.GetExportedValueByTypeName<IFactorFileProvider>(factorFileProviderTypeName),
216  composer.GetExportedValueByTypeName<IDataProvider>(dataProviderTypeName),
217  composer.GetExportedValueByTypeName<IObjectStore>(objectStoreTypeName),
218  composer.GetExportedValueByTypeName<IDataPermissionManager>(dataPermissionManager),
220  researchMode
221  );
222 
223  result.FactorFileProvider.Initialize(result.MapFileProvider, result.DataProvider);
224  result.MapFileProvider.Initialize(result.DataProvider);
225 
226  if (result.DataProvider is ApiDataProvider
227  && (result.FactorFileProvider is not LocalZipFactorFileProvider || result.MapFileProvider is not LocalZipMapFileProvider))
228  {
229  throw new ArgumentException($"The {typeof(ApiDataProvider)} can only be used with {typeof(LocalZipFactorFileProvider)}" +
230  $" and {typeof(LocalZipMapFileProvider)}, please update 'config.json'");
231  }
232 
233  FundamentalService.Initialize(result.DataProvider, Globals.LiveMode);
234 
235  return result;
236  }
237 
238  /// <summary>
239  /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
240  /// </summary>
241  /// <filterpriority>2</filterpriority>
242  public void Dispose()
243  {
244  Log.Trace("LeanEngineAlgorithmHandlers.Dispose(): start...");
245 
246  DataCacheProvider.DisposeSafely();
247  Setup.DisposeSafely();
248  ObjectStore.DisposeSafely();
249  DataMonitor.DisposeSafely();
250 
251  Log.Trace("LeanEngineAlgorithmHandlers.Dispose(): Disposed of algorithm handlers.");
252  }
253  }
254 }