/* * 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.Collections.Concurrent; using QuantConnect.Configuration; using QuantConnect.Interfaces; using QuantConnect.Util; namespace QuantConnect.Data.Auxiliary { /// /// Provides an implementation of that searches the local disk /// public class LocalDiskFactorFileProvider : IFactorFileProvider { private readonly IMapFileProvider _mapFileProvider; private readonly ConcurrentDictionary _cache; /// /// Initializes a new instance of that uses configuration /// to resolve an instance of from the /// public LocalDiskFactorFileProvider() : this(Composer.Instance.GetExportedValueByTypeName(Config.Get("map-file-provider", "LocalDiskMapFileProvider"))) { } /// /// Initializes a new instance of the using the specified /// map file provider /// /// The map file provider used to resolve permticks of securities public LocalDiskFactorFileProvider(IMapFileProvider mapFileProvider) { _mapFileProvider = mapFileProvider; _cache = new ConcurrentDictionary(); } /// /// Gets a instance for the specified symbol, or null if not found /// /// The security's symbol whose factor file we seek /// The resolved factor file, or null if not found public FactorFile Get(Symbol symbol) { FactorFile factorFile; if (_cache.TryGetValue(symbol, out factorFile)) { return factorFile; } var market = symbol.ID.Market; // we first need to resolve the map file to get a permtick, that's how the factor files are stored var mapFileResolver = _mapFileProvider.Get(market); if (mapFileResolver == null) { return GetFactorFile(symbol, symbol.Value, market); } var mapFile = mapFileResolver.ResolveMapFile(symbol.ID.Symbol, symbol.ID.Date); if (mapFile.IsNullOrEmpty()) { return GetFactorFile(symbol, symbol.Value, market); } return GetFactorFile(symbol, mapFile.Permtick, market); } /// /// Checks that the factor file exists on disk, and if it does, loads it into memory /// private FactorFile GetFactorFile(Symbol symbol, string permtick, string market) { FactorFile factorFile = null; if (FactorFile.HasScalingFactors(permtick, market)) { factorFile = FactorFile.Read(permtick, market); _cache.AddOrUpdate(symbol, factorFile, (s, c) => factorFile); } else { // add null value to the cache, we don't want to check the disk multiple times // but keep existing value if it exists, just in case _cache.AddOrUpdate(symbol, factorFile, (s, oldValue) => oldValue); } return factorFile; } } }