/* * 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.Globalization; using QuantConnect.Logging; using QuantConnect.Brokerages; using QuantConnect.Configuration; using QuantConnect.DownloaderDataProvider.Launcher.Models.Constants; namespace QuantConnect.DownloaderDataProvider.Launcher.Models; /// /// Abstract base class for configuring data download parameters, including common properties and initialization logic. /// public abstract class BaseDataDownloadConfig { /// /// Gets the start date for the data download. /// public DateTime StartDate { get; set; } /// /// Gets the end date for the data download. /// public DateTime EndDate { get; set; } /// /// Gets or sets the resolution of the downloaded data. /// public Resolution Resolution { get; protected set; } /// /// Gets or sets the market name for which the data will be downloaded. /// public string MarketName { get; protected set; } /// /// Gets the type of security for which the data is being downloaded. /// public SecurityType SecurityType { get; set; } /// /// Gets or sets the type of tick data to be downloaded. /// public TickType TickType { get; protected set; } /// /// The type of data based on /// public abstract Type DataType { get; } /// /// Gets the list of symbols for which the data will be downloaded. /// public IReadOnlyCollection Symbols { get; protected set; } = []; /// /// Initializes a new instance of the class. /// protected BaseDataDownloadConfig() { StartDate = ParseDate(Config.Get(DownloaderCommandArguments.CommandStartDate).ToString()); EndDate = ParseDate(Config.Get(DownloaderCommandArguments.CommandEndDate).ToString()); SecurityType = ParseEnum(Config.Get(DownloaderCommandArguments.CommandSecurityType).ToString()); MarketName = Config.Get(DownloaderCommandArguments.CommandMarketName).ToString().ToLower(CultureInfo.InvariantCulture); if (string.IsNullOrEmpty(MarketName)) { MarketName = DefaultBrokerageModel.DefaultMarketMap[SecurityType]; Log.Trace($"{nameof(BaseDataDownloadConfig)}: Default market '{MarketName}' applied for SecurityType '{SecurityType}'"); } if (!Market.SupportedMarkets().Contains(MarketName)) { throw new ArgumentException($"The specified market '{MarketName}' is not supported. Supported markets are: {string.Join(", ", Market.SupportedMarkets())}."); } Symbols = LoadSymbols(Config.GetValue>(DownloaderCommandArguments.CommandTickers), SecurityType, MarketName); } /// /// Initializes a new instance of the class with the specified parameters. /// /// The type of tick data to be downloaded. /// The type of security for which data is being downloaded. /// The resolution of the data being downloaded. /// The start date for the data download range. /// The end date for the data download range. /// The name of the market from which the data is being downloaded. /// A list of symbols for which data is being downloaded. protected BaseDataDownloadConfig(TickType tickType, SecurityType securityType, Resolution resolution, DateTime startDate, DateTime endDate, string marketName, List symbols) { StartDate = startDate; EndDate = endDate; Resolution = resolution; MarketName = marketName; SecurityType = securityType; TickType = tickType; Symbols = symbols; } /// /// Loads the symbols for which data will be downloaded. /// /// A dictionary of tickers to load symbols for. /// The type of security to download data for. /// The market for which the symbols are valid. /// A collection of symbols for the specified market and security type. /// private static IReadOnlyCollection LoadSymbols(Dictionary tickers, SecurityType securityType, string market) { if (tickers == null || tickers.Count == 0) { throw new ArgumentException($"{nameof(BaseDataDownloadConfig)}.{nameof(LoadSymbols)}: The tickers dictionary cannot be null or empty."); } return tickers.Keys.Select(ticker => Symbol.Create(ticker, securityType, market)).ToList(); } /// /// Parses a string to a using a specific date format. /// /// The date string to parse. /// The parsed value. protected static DateTime ParseDate(string date) => DateTime.ParseExact(date, DateFormat.EightCharacter, CultureInfo.InvariantCulture); /// /// Parses a string value into an enum of the specified type. /// /// The enum type to parse the value into. /// The string value to parse. /// The parsed enum value. /// Thrown if the value cannot be parsed or is not a valid enum value. protected static TEnum ParseEnum(string value) where TEnum : struct, Enum { if (!Enum.TryParse(value, true, out TEnum result) || !Enum.IsDefined(result)) { throw new ArgumentException($"Invalid {typeof(TEnum).Name} specified: '{value}'. Please provide a valid {typeof(TEnum).Name}. " + $"Valid values are: {string.Join(", ", Enum.GetNames())}."); } return result; } }