/* * 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.Generic; using System.Linq; using QuantConnect.Util; namespace QuantConnect.Data { /// /// Helper methods used to determine different configurations properties /// for a given set of /// public static class SubscriptionDataConfigExtensions { /// /// Extension method used to obtain the highest /// for a given set of /// /// /// The highest resolution, if there /// are no subscriptions public static Resolution GetHighestResolution( this IEnumerable subscriptionDataConfigs) { return subscriptionDataConfigs .Select(x => x.Resolution) .DefaultIfEmpty(Resolution.Daily) .Min(); } /// /// Extension method used to determine if FillForward is enabled /// for a given set of /// /// /// True, at least one subscription has it enabled public static bool IsFillForward( this IEnumerable subscriptionDataConfigs) { return subscriptionDataConfigs.Any(x => x.FillDataForward); } /// /// Extension method used to determine if ExtendedMarketHours is enabled /// for a given set of /// /// /// True, at least one subscription has it enabled public static bool IsExtendedMarketHours( this IEnumerable subscriptionDataConfigs) { return subscriptionDataConfigs.Any(x => x.ExtendedMarketHours); } /// /// Extension method used to determine if it is custom data /// for a given set of /// /// /// True, at least one subscription is custom data public static bool IsCustomData( this IEnumerable subscriptionDataConfigs) { return subscriptionDataConfigs.Any(x => x.IsCustomData); } /// /// Extension method used to determine what /// to use for a given set of /// /// /// The first DataNormalizationMode, /// if there are no subscriptions public static DataNormalizationMode DataNormalizationMode( this IEnumerable subscriptionDataConfigs) { return subscriptionDataConfigs. Select(x => x.DataNormalizationMode) .DefaultIfEmpty(QuantConnect.DataNormalizationMode.Adjusted) .First(); } /// /// Sets the data normalization mode to be used by /// this set of /// public static void SetDataNormalizationMode( this IEnumerable subscriptionDataConfigs, DataNormalizationMode mode) { foreach (var subscription in subscriptionDataConfigs) { subscription.DataNormalizationMode = mode; } } /// /// Will determine if mapping should be used for this subscription configuration /// /// The subscription data configuration we are processing /// One of the objectives of this method is to normalize the 'use mapping' /// check and void code duplication and related issues /// True if ticker should be mapped public static bool TickerShouldBeMapped(this SubscriptionDataConfig config) { // we create an instance of the data type, if it is a custom type // it can override RequiresMapping else it will use security type\ return config.GetBaseDataInstance().RequiresMapping(); } /// /// Will determine if price scaling should be used for this subscription configuration /// /// The subscription data configuration we are processing /// One of the objectives of this method is to normalize the 'use price scale' /// check and void code duplication and related issues /// True, is this is a live mode data stream /// True if ticker prices should be scaled public static bool PricesShouldBeScaled(this SubscriptionDataConfig config, bool liveMode = false) { if (config.IsCustomData || config.Symbol.Value.Contains("UNIVERSE")) { return false; } if(config.SecurityType == SecurityType.Equity && !liveMode) { return true; } if (config.SecurityType == SecurityType.Future && config.Symbol.IsCanonical()) { return LeanData.IsCommonLeanDataType(config.Type); } return false; } /// /// Will determine if splits and dividends should be used for this subscription configuration /// /// The subscription data configuration we are processing /// Different than because prices could be scale and no split and dividends /// really exist, like in the continuous futures case /// True if this configuration requires split and divided handling public static bool EmitSplitsAndDividends(this SubscriptionDataConfig config) { return !config.IsCustomData && !config.Symbol.Value.Contains("UNIVERSE") && config.SecurityType == SecurityType.Equity; } /// /// Initializes a new instance of the type defined in with the symbol properly set /// public static BaseData GetBaseDataInstance(this SubscriptionDataConfig config) { var instance = config.Type.GetBaseDataInstance(); instance.Symbol = config.Symbol; return instance; } } }