/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.ComponentModel.Composition;
using QuantConnect.Configuration;
using QuantConnect.Data;
using QuantConnect.Data.Auxiliary;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Interfaces;
using QuantConnect.Lean.Engine.DataFeeds;
using QuantConnect.Lean.Engine.RealTime;
using QuantConnect.Lean.Engine.Results;
using QuantConnect.Lean.Engine.Setup;
using QuantConnect.Lean.Engine.TransactionHandlers;
using QuantConnect.Logging;
using QuantConnect.Util;
namespace QuantConnect.Lean.Engine
{
///
/// Provides a container for the algorithm specific handlers
///
public class LeanEngineAlgorithmHandlers : IDisposable
{
private bool _dataMonitorWired;
///
/// Gets the result handler used to communicate results from the algorithm
///
public IResultHandler Results { get; }
///
/// Gets the setup handler used to initialize the algorithm state
///
public ISetupHandler Setup { get; }
///
/// Gets the data feed handler used to provide data to the algorithm
///
public IDataFeed DataFeed { get; }
///
/// Gets the transaction handler used to process orders from the algorithm
///
public ITransactionHandler Transactions { get; }
///
/// Gets the real time handler used to process real time events
///
public IRealTimeHandler RealTime { get; }
///
/// Gets the map file provider used as a map file source for the data feed
///
public IMapFileProvider MapFileProvider { get; }
///
/// Gets the map file provider used as a map file source for the data feed
///
public IFactorFileProvider FactorFileProvider { get; }
///
/// Gets the data file provider used to retrieve security data if it is not on the file system
///
public IDataProvider DataProvider { get; }
///
/// Gets the data file provider used to retrieve security data if it is not on the file system
///
public IDataCacheProvider DataCacheProvider { get; }
///
/// Gets the object store used for persistence
///
public IObjectStore ObjectStore { get; }
///
/// Entity in charge of handling data permissions
///
public IDataPermissionManager DataPermissionsManager { get; }
///
/// Monitors data requests and reports on missing data
///
public IDataMonitor DataMonitor { get; }
///
/// Initializes a new instance of the class from the specified handlers
///
/// The result handler for communicating results from the algorithm
/// The setup handler used to initialize algorithm state
/// The data feed handler used to pump data to the algorithm
/// The transaction handler used to process orders from the algorithm
/// The real time handler used to process real time events
/// The map file provider used to retrieve map files for the data feed
/// Map file provider used as a map file source for the data feed
/// file provider used to retrieve security data if it is not on the file system
/// The object store used for persistence
/// The data permission manager to use
/// True for live mode, false otherwise
/// True for research mode, false otherwise. This has less priority than liveMode
/// Optionally the data monitor instance to use
public LeanEngineAlgorithmHandlers(IResultHandler results,
ISetupHandler setup,
IDataFeed dataFeed,
ITransactionHandler transactions,
IRealTimeHandler realTime,
IMapFileProvider mapFileProvider,
IFactorFileProvider factorFileProvider,
IDataProvider dataProvider,
IObjectStore objectStore,
IDataPermissionManager dataPermissionsManager,
bool liveMode,
bool researchMode = false,
IDataMonitor dataMonitor = null
)
{
if (results == null)
{
throw new ArgumentNullException(nameof(results));
}
if (setup == null)
{
throw new ArgumentNullException(nameof(setup));
}
if (dataFeed == null)
{
throw new ArgumentNullException(nameof(dataFeed));
}
if (transactions == null)
{
throw new ArgumentNullException(nameof(transactions));
}
if (realTime == null)
{
throw new ArgumentNullException(nameof(realTime));
}
if (mapFileProvider == null)
{
throw new ArgumentNullException(nameof(mapFileProvider));
}
if (factorFileProvider == null)
{
throw new ArgumentNullException(nameof(factorFileProvider));
}
if (dataProvider == null)
{
throw new ArgumentNullException(nameof(dataProvider));
}
if (objectStore == null)
{
throw new ArgumentNullException(nameof(objectStore));
}
if (dataPermissionsManager == null)
{
throw new ArgumentNullException(nameof(dataPermissionsManager));
}
Results = results;
Setup = setup;
DataFeed = dataFeed;
Transactions = transactions;
RealTime = realTime;
MapFileProvider = mapFileProvider;
FactorFileProvider = factorFileProvider;
DataProvider = dataProvider;
ObjectStore = objectStore;
DataPermissionsManager = dataPermissionsManager;
DataCacheProvider = new ZipDataCacheProvider(DataProvider, isDataEphemeral: liveMode);
DataMonitor = dataMonitor ?? new DataMonitor();
if (!liveMode && !researchMode)
{
_dataMonitorWired = true;
DataProvider.NewDataRequest += DataMonitor.OnNewDataRequest;
}
}
///
/// Creates a new instance of the class from the specified composer using type names from configuration
///
/// The composer instance to obtain implementations from
/// True for research mode, false otherwise
/// A fully hydrates instance.
/// Throws a CompositionException during failure to load
public static LeanEngineAlgorithmHandlers FromConfiguration(Composer composer, bool researchMode = false)
{
var setupHandlerTypeName = Config.Get("setup-handler", "ConsoleSetupHandler");
var transactionHandlerTypeName = Config.Get("transaction-handler", "BacktestingTransactionHandler");
var realTimeHandlerTypeName = Config.Get("real-time-handler", "BacktestingRealTimeHandler");
var dataFeedHandlerTypeName = Config.Get("data-feed-handler", "FileSystemDataFeed");
var resultHandlerTypeName = Config.Get("result-handler", "BacktestingResultHandler");
var mapFileProviderTypeName = Config.Get("map-file-provider", "LocalDiskMapFileProvider");
var factorFileProviderTypeName = Config.Get("factor-file-provider", "LocalDiskFactorFileProvider");
var dataProviderTypeName = Config.Get("data-provider", "DefaultDataProvider");
var objectStoreTypeName = Config.Get("object-store", "LocalObjectStore");
var dataPermissionManager = Config.Get("data-permission-manager", "DataPermissionManager");
var dataMonitor = Config.Get("data-monitor", "QuantConnect.Data.DataMonitor");
var result = new LeanEngineAlgorithmHandlers(
composer.GetExportedValueByTypeName(resultHandlerTypeName),
composer.GetExportedValueByTypeName(setupHandlerTypeName),
composer.GetExportedValueByTypeName(dataFeedHandlerTypeName),
composer.GetExportedValueByTypeName(transactionHandlerTypeName),
composer.GetExportedValueByTypeName(realTimeHandlerTypeName),
composer.GetExportedValueByTypeName(mapFileProviderTypeName),
composer.GetExportedValueByTypeName(factorFileProviderTypeName),
composer.GetExportedValueByTypeName(dataProviderTypeName),
composer.GetExportedValueByTypeName(objectStoreTypeName),
composer.GetExportedValueByTypeName(dataPermissionManager),
Globals.LiveMode,
researchMode,
composer.GetExportedValueByTypeName(dataMonitor)
);
result.FactorFileProvider.Initialize(result.MapFileProvider, result.DataProvider);
result.MapFileProvider.Initialize(result.DataProvider);
if (result.DataProvider is ApiDataProvider
&& (result.FactorFileProvider is not LocalZipFactorFileProvider || result.MapFileProvider is not LocalZipMapFileProvider))
{
throw new ArgumentException($"The {typeof(ApiDataProvider)} can only be used with {typeof(LocalZipFactorFileProvider)}" +
$" and {typeof(LocalZipMapFileProvider)}, please update 'config.json'");
}
FundamentalService.Initialize(result.DataProvider, Globals.LiveMode);
return result;
}
///
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
///
/// 2
public void Dispose()
{
Log.Trace("LeanEngineAlgorithmHandlers.Dispose(): start...");
DataCacheProvider.DisposeSafely();
Setup.DisposeSafely();
ObjectStore.DisposeSafely();
if (_dataMonitorWired)
{
DataProvider.NewDataRequest -= DataMonitor.OnNewDataRequest;
}
DataMonitor.DisposeSafely();
Log.Trace("LeanEngineAlgorithmHandlers.Dispose(): Disposed of algorithm handlers.");
}
}
}