Lean  $LEAN_TAG$
LocalDiskFactorFileProvider.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.IO;
18 using QuantConnect.Util;
20 using System.Collections.Concurrent;
21 
23 {
24  /// <summary>
25  /// Provides an implementation of <see cref="IFactorFileProvider"/> that searches the local disk
26  /// </summary>
28  {
29  private IMapFileProvider _mapFileProvider;
30  private IDataProvider _dataProvider;
31  private readonly ConcurrentDictionary<Symbol, IFactorProvider> _cache;
32 
33  /// <summary>
34  /// Creates a new instance of the <see cref="LocalDiskFactorFileProvider"/>
35  /// </summary>
37  {
38  _cache = new ConcurrentDictionary<Symbol, IFactorProvider>();
39  }
40 
41  /// <summary>
42  /// Initializes our FactorFileProvider by supplying our mapFileProvider
43  /// and dataProvider
44  /// </summary>
45  /// <param name="mapFileProvider">MapFileProvider to use</param>
46  /// <param name="dataProvider">DataProvider to use</param>
47  public void Initialize(IMapFileProvider mapFileProvider, IDataProvider dataProvider)
48  {
49  _mapFileProvider = mapFileProvider;
50  _dataProvider = dataProvider;
51  }
52 
53  /// <summary>
54  /// Gets a <see cref="FactorFile{T}"/> instance for the specified symbol, or null if not found
55  /// </summary>
56  /// <param name="symbol">The security's symbol whose factor file we seek</param>
57  /// <returns>The resolved factor file, or null if not found</returns>
58  public IFactorProvider Get(Symbol symbol)
59  {
60  symbol = symbol.GetFactorFileSymbol();
61  IFactorProvider factorFile;
62  if (_cache.TryGetValue(symbol, out factorFile))
63  {
64  return factorFile;
65  }
66 
67  // we first need to resolve the map file to get a permtick, that's how the factor files are stored
68  var mapFileResolver = _mapFileProvider.Get(AuxiliaryDataKey.Create(symbol));
69  if (mapFileResolver == null)
70  {
71  return GetFactorFile(symbol, symbol.Value);
72  }
73 
74  var mapFile = mapFileResolver.ResolveMapFile(symbol);
75  if (mapFile.IsNullOrEmpty())
76  {
77  return GetFactorFile(symbol, symbol.Value);
78  }
79 
80  return GetFactorFile(symbol, mapFile.Permtick);
81  }
82 
83  /// <summary>
84  /// Checks that the factor file exists on disk, and if it does, loads it into memory
85  /// </summary>
86  private IFactorProvider GetFactorFile(Symbol symbol, string permtick)
87  {
89  var path = Path.Combine(basePath, permtick.ToLowerInvariant() + ".csv");
90 
91  var factorFile = PriceScalingExtensions.SafeRead(permtick, _dataProvider.ReadLines(path), symbol.SecurityType);
92  _cache.AddOrUpdate(symbol, factorFile, (s, c) => factorFile);
93  return factorFile;
94  }
95  }
96 }