/* * 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.Linq; using Python.Runtime; using System.Collections.Generic; using QuantConnect.Data.UniverseSelection; namespace QuantConnect.Data.Fundamental { /// /// Abstract base class for multi-period fields /// public abstract class MultiPeriodField : ReusuableCLRObject { /// /// No Value /// public static T NoValue { get; } = BaseFundamentalDataProvider.GetDefault(); /// /// The time provider instance to use /// protected ITimeProvider TimeProvider { get; } /// /// The default period /// protected abstract string DefaultPeriod { get; } /// /// The target security identifier /// protected SecurityIdentifier SecurityIdentifier { get; set; } /// /// Returns true if the field contains a value for the default period /// public abstract bool HasValue { get; } /// /// Returns the default value for the field /// public virtual T Value => GetPeriodValues().Select(x => x.Value).DefaultIfEmpty(NoValue).FirstOrDefault(); /// /// Creates an empty instance /// protected MultiPeriodField() { } /// /// Creates a new instance /// /// /// protected MultiPeriodField(ITimeProvider timeProvider, SecurityIdentifier securityIdentifier) { TimeProvider = timeProvider; SecurityIdentifier = securityIdentifier; } /// /// Gets a dictionary of period names and values for the field /// public abstract IReadOnlyDictionary GetPeriodValues(); /// /// Returns true if the field contains a value for the requested period /// /// True if the field contains a value for the requested period public virtual bool HasPeriodValue(string period) => !BaseFundamentalDataProvider.IsNone(typeof(T), GetPeriodValue(period)); /// /// Gets the value of the field for the requested period /// /// The requested period /// The value for the period public abstract T GetPeriodValue(string period); /// /// Gets the list of available period names for the field /// public IEnumerable GetPeriodNames() { return GetPeriodValues().Select(x => x.Key); } /// /// Returns true if the field has at least one value for one period /// public bool HasValues() { return GetPeriodValues().Any(); } /// /// Returns a string that represents the current object. /// public override string ToString() { return string.Join(";", GetPeriodValues().Select(kvp => $"{kvp.Key}:{kvp.Value}")); } /// /// Returns a string that represents the current object. /// protected string ConvertPeriod(string period) { if (string.IsNullOrEmpty(period)) { return DefaultPeriod; } switch (period) { case Period.OneMonth: return "OneMonth"; case Period.TwoMonths: return "TwoMonths"; case Period.ThreeMonths: return "ThreeMonths"; case Period.SixMonths: return "SixMonths"; case Period.NineMonths: return "NineMonths"; case Period.TwelveMonths: return "TwelveMonths"; case Period.OneYear: return "OneYear"; case Period.TwoYears: return "TwoYears"; case Period.ThreeYears: return "ThreeYears"; case Period.FiveYears: return "FiveYears"; case Period.TenYears: return "TenYears"; default: return period; } } /// /// Returns the default value for the field /// public static implicit operator T(MultiPeriodField instance) { return instance.Value; } } /// /// Abstract class for multi-period fields /// public abstract class MultiPeriodField : MultiPeriodField { /// /// Creates an empty instance /// protected MultiPeriodField() { } /// /// Creates a new instance /// /// /// protected MultiPeriodField(ITimeProvider timeProvider, SecurityIdentifier securityIdentifier) : base(timeProvider, securityIdentifier) { } /// /// Returns the default value for the field /// public static implicit operator decimal(MultiPeriodField instance) { return (decimal)instance.Value; } } /// /// Abstract class for multi-period fields long /// public abstract class MultiPeriodFieldLong : MultiPeriodField { /// /// Creates an empty instance /// protected MultiPeriodFieldLong() { } /// /// Creates a new instance /// /// /// protected MultiPeriodFieldLong(ITimeProvider timeProvider, SecurityIdentifier securityIdentifier) : base(timeProvider, securityIdentifier) { } /// /// Returns the default value for the field /// public static implicit operator decimal(MultiPeriodFieldLong instance) { return (decimal)instance.Value; } } }