Lean  $LEAN_TAG$
CoarseFundamentalDataProvider.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 System.IO;
18 using System.Collections.Generic;
20 
22 {
23  /// <summary>
24  /// Coarse base fundamental data provider
25  /// </summary>
27  {
28  private DateTime _date;
29  private readonly Dictionary<SecurityIdentifier, CoarseFundamental> _coarseFundamental = new();
30 
31  /// <summary>
32  /// Will fetch the requested fundamental information for the requested time and symbol
33  /// </summary>
34  /// <typeparam name="T">The expected data type</typeparam>
35  /// <param name="time">The time to request this data for</param>
36  /// <param name="securityIdentifier">The security identifier</param>
37  /// <param name="enumName">The name of the fundamental property</param>
38  /// <returns>The fundamental information</returns>
39  public override T Get<T>(DateTime time, SecurityIdentifier securityIdentifier, FundamentalProperty enumName)
40  {
41  var name = Enum.GetName(enumName);
42  lock (_coarseFundamental)
43  {
44  if (time == _date)
45  {
46  return GetProperty<T>(securityIdentifier, name);
47  }
48  _date = time;
49 
50  var path = Path.Combine(Globals.DataFolder, "equity", "usa", "fundamental", "coarse", $"{time:yyyyMMdd}.csv");
51  var fileStream = DataProvider.Fetch(path);
52  if (fileStream == null)
53  {
54  return GetDefault<T>();
55  }
56 
57  _coarseFundamental.Clear();
58  using (var reader = new StreamReader(fileStream))
59  {
60  while (!reader.EndOfStream)
61  {
62  var line = reader.ReadLine();
63  var coarse = Read(line, time);
64  if (coarse != null)
65  {
66  _coarseFundamental[coarse.Symbol.ID] = coarse;
67  }
68  }
69  }
70 
71  return GetProperty<T>(securityIdentifier, name);
72  }
73  }
74 
75  public static CoarseFundamentalSource Read(string line, DateTime date)
76  {
77  try
78  {
79  var csv = line.Split(',');
80  var coarse = new CoarseFundamentalSource
81  {
82  Symbol = new Symbol(SecurityIdentifier.Parse(csv[0]), csv[1]),
83  Time = date,
84  Value = csv[2].ToDecimal(),
85  VolumeSetter = csv[3].ToInt64(),
86  DollarVolumeSetter = (double)csv[4].ToDecimal()
87  };
88 
89  if (csv.Length > 5)
90  {
91  coarse.HasFundamentalDataSetter = csv[5].ConvertInvariant<bool>();
92  }
93 
94  if (csv.Length > 7)
95  {
96  coarse.PriceFactorSetter = csv[6].ToDecimal();
97  coarse.SplitFactorSetter = csv[7].ToDecimal();
98  }
99 
100  return coarse;
101  }
102  catch (Exception)
103  {
104  return null;
105  }
106 
107  }
108 
109  private dynamic GetProperty<T>(SecurityIdentifier securityIdentifier, string property)
110  {
111  if (!_coarseFundamental.TryGetValue(securityIdentifier, out var coarse))
112  {
113  return GetDefault<T>();
114  }
115 
116  switch (property)
117  {
118  case nameof(CoarseFundamental.Price):
119  return coarse.Price;
120  case nameof(CoarseFundamental.Value):
121  return coarse.Value;
122  case nameof(CoarseFundamental.Market):
123  return coarse.Market;
124  case nameof(CoarseFundamental.Volume):
125  return coarse.Volume;
126  case nameof(CoarseFundamental.PriceFactor):
127  return coarse.PriceFactor;
128  case nameof(CoarseFundamental.SplitFactor):
129  return coarse.SplitFactor;
130  case nameof(CoarseFundamental.DollarVolume):
131  return coarse.DollarVolume;
132  case nameof(CoarseFundamental.HasFundamentalData):
133  return false;
134  }
135 
136  return GetDefault<T>();
137  }
138 
139  /// <summary>
140  /// Coarse fundamental with setters
141  /// </summary>
143  {
144  public long VolumeSetter;
145  public double DollarVolumeSetter;
146  public decimal PriceFactorSetter = 1;
147  public decimal SplitFactorSetter = 1;
148  public bool HasFundamentalDataSetter;
149 
150  /// <summary>
151  /// Gets the day's dollar volume for this symbol
152  /// </summary>
153  public override double DollarVolume => DollarVolumeSetter;
154 
155  /// <summary>
156  /// Gets the day's total volume
157  /// </summary>
158  public override long Volume => VolumeSetter;
159 
160  /// <summary>
161  /// Returns whether the symbol has fundamental data for the given date
162  /// </summary>
163  public override bool HasFundamentalData => HasFundamentalDataSetter;
164 
165  /// <summary>
166  /// Gets the price factor for the given date
167  /// </summary>
168  public override decimal PriceFactor => PriceFactorSetter;
169 
170  /// <summary>
171  /// Gets the split factor for the given date
172  /// </summary>
173  public override decimal SplitFactor => SplitFactorSetter;
174  }
175  }
176 }