Lean  $LEAN_TAG$
MultiPeriodField.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.Linq;
17 using Python.Runtime;
18 using System.Collections.Generic;
20 
22 {
23  /// <summary>
24  /// Abstract base class for multi-period fields
25  /// </summary>
26  public abstract class MultiPeriodField<T> : ReusuableCLRObject
27  {
28  /// <summary>
29  /// No Value
30  /// </summary>
31  public static T NoValue { get; } = BaseFundamentalDataProvider.GetDefault<T>();
32 
33  /// <summary>
34  /// The time provider instance to use
35  /// </summary>
36  protected ITimeProvider TimeProvider { get; }
37 
38  /// <summary>
39  /// The default period
40  /// </summary>
41  protected abstract string DefaultPeriod { get; }
42 
43  /// <summary>
44  /// The target security identifier
45  /// </summary>
46  protected SecurityIdentifier SecurityIdentifier { get; set; }
47 
48  /// <summary>
49  /// Returns true if the field contains a value for the default period
50  /// </summary>
51  public abstract bool HasValue { get; }
52 
53  /// <summary>
54  /// Returns the default value for the field
55  /// </summary>
56  public virtual T Value => GetPeriodValues().Select(x => x.Value).DefaultIfEmpty(NoValue).FirstOrDefault();
57 
58  /// <summary>
59  /// Creates an empty instance
60  /// </summary>
61  protected MultiPeriodField()
62  {
63  }
64 
65  /// <summary>
66  /// Creates a new instance
67  /// </summary>
68  /// <param name="timeProvider"></param>
69  /// <param name="securityIdentifier"></param>
70  protected MultiPeriodField(ITimeProvider timeProvider, SecurityIdentifier securityIdentifier)
71  {
72  TimeProvider = timeProvider;
73  SecurityIdentifier = securityIdentifier;
74  }
75 
76  /// <summary>
77  /// Gets a dictionary of period names and values for the field
78  /// </summary>
79  public abstract IReadOnlyDictionary<string, T> GetPeriodValues();
80 
81  /// <summary>
82  /// Returns true if the field contains a value for the requested period
83  /// </summary>
84  /// <returns>True if the field contains a value for the requested period</returns>
85  public virtual bool HasPeriodValue(string period) => !BaseFundamentalDataProvider.IsNone(typeof(T), GetPeriodValue(period));
86 
87  /// <summary>
88  /// Gets the value of the field for the requested period
89  /// </summary>
90  /// <param name="period">The requested period</param>
91  /// <returns>The value for the period</returns>
92  public abstract T GetPeriodValue(string period);
93 
94  /// <summary>
95  /// Gets the list of available period names for the field
96  /// </summary>
97  public IEnumerable<string> GetPeriodNames()
98  {
99  return GetPeriodValues().Select(x => x.Key);
100  }
101 
102  /// <summary>
103  /// Returns true if the field has at least one value for one period
104  /// </summary>
105  public bool HasValues()
106  {
107  return GetPeriodValues().Any();
108  }
109 
110  /// <summary>
111  /// Returns a string that represents the current object.
112  /// </summary>
113  public override string ToString()
114  {
115  return string.Join(";", GetPeriodValues().Select(kvp => $"{kvp.Key}:{kvp.Value}"));
116  }
117 
118  /// <summary>
119  /// Returns a string that represents the current object.
120  /// </summary>
121  protected string ConvertPeriod(string period)
122  {
123  if (string.IsNullOrEmpty(period))
124  {
125  return DefaultPeriod;
126  }
127 
128  switch (period)
129  {
130  case Period.OneMonth:
131  return "OneMonth";
132  case Period.TwoMonths:
133  return "TwoMonths";
134  case Period.ThreeMonths:
135  return "ThreeMonths";
136  case Period.SixMonths:
137  return "SixMonths";
138  case Period.NineMonths:
139  return "NineMonths";
140  case Period.TwelveMonths:
141  return "TwelveMonths";
142  case Period.OneYear:
143  return "OneYear";
144  case Period.TwoYears:
145  return "TwoYears";
146  case Period.ThreeYears:
147  return "ThreeYears";
148  case Period.FiveYears:
149  return "FiveYears";
150  case Period.TenYears:
151  return "TenYears";
152  default:
153  return period;
154  }
155  }
156 
157  /// <summary>
158  /// Returns the default value for the field
159  /// </summary>
160  public static implicit operator T(MultiPeriodField<T> instance)
161  {
162  return instance.Value;
163  }
164  }
165 
166  /// <summary>
167  /// Abstract class for multi-period fields
168  /// </summary>
169  public abstract class MultiPeriodField : MultiPeriodField<double>
170  {
171  /// <summary>
172  /// Creates an empty instance
173  /// </summary>
174  protected MultiPeriodField()
175  {
176  }
177 
178  /// <summary>
179  /// Creates a new instance
180  /// </summary>
181  /// <param name="timeProvider"></param>
182  /// <param name="securityIdentifier"></param>
183  protected MultiPeriodField(ITimeProvider timeProvider, SecurityIdentifier securityIdentifier) : base(timeProvider, securityIdentifier)
184  {
185  }
186 
187  /// <summary>
188  /// Returns the default value for the field
189  /// </summary>
190  public static implicit operator decimal(MultiPeriodField instance)
191  {
192  return (decimal)instance.Value;
193  }
194  }
195 
196  /// <summary>
197  /// Abstract class for multi-period fields long
198  /// </summary>
199  public abstract class MultiPeriodFieldLong : MultiPeriodField<long>
200  {
201  /// <summary>
202  /// Creates an empty instance
203  /// </summary>
205  {
206  }
207 
208  /// <summary>
209  /// Creates a new instance
210  /// </summary>
211  /// <param name="timeProvider"></param>
212  /// <param name="securityIdentifier"></param>
213  protected MultiPeriodFieldLong(ITimeProvider timeProvider, SecurityIdentifier securityIdentifier) : base(timeProvider, securityIdentifier)
214  {
215  }
216 
217  /// <summary>
218  /// Returns the default value for the field
219  /// </summary>
220  public static implicit operator decimal(MultiPeriodFieldLong instance)
221  {
222  return (decimal)instance.Value;
223  }
224  }
225 }