/* * 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; using System.IO; using QuantConnect.Securities.Option; namespace QuantConnect.Util { /// /// Type representing the various pieces of information emebedded into a lean data file path /// public class LeanDataPathComponents { /// /// Gets the date component from the file name /// public DateTime Date { get; private set; } /// /// Gets the security type from the path /// public SecurityType SecurityType { get; private set; } /// /// Gets the market from the path /// public string Market { get; private set; } /// /// Gets the resolution from the path /// public Resolution Resolution { get; private set; } /// /// Gets the file name, not inluding directory information /// public string Filename { get; private set; } /// /// Gets the symbol object implied by the path. For options, or any /// multi-entry zip file, this should be the canonical symbol /// public Symbol Symbol { get; private set; } /// /// Gets the tick type from the file name /// public TickType TickType { get; private set; } /// /// Initializes a new instance of the class /// public LeanDataPathComponents(SecurityType securityType, string market, Resolution resolution, Symbol symbol, string filename, DateTime date, TickType tickType) { Date = date; SecurityType = securityType; Market = market; Resolution = resolution; Filename = filename; Symbol = symbol; TickType = tickType; } /// /// Parses the specified path into a new instance of the class /// /// The path to be parsed /// A new instance of the class representing the specified path public static LeanDataPathComponents Parse(string path) { //"../Data/equity/usa/hour/spy.zip" //"../Data/equity/usa/hour/spy/20160218_trade.zip" var fileinfo = new FileInfo(path); var filename = fileinfo.Name; var parts = path.Split('/', '\\'); // defines the offsets of the security relative to the end of the path const int LowResSecurityTypeOffset = 4; const int HighResSecurityTypeOffset = 5; // defines other offsets relative to the beginning of the substring produce by the above offsets const int MarketOffset = 1; const int ResolutionOffset = 2; const int TickerOffset = 3; if (parts.Length < LowResSecurityTypeOffset) { throw new FormatException($"Unexpected path format: {path}"); } var securityTypeOffset = LowResSecurityTypeOffset; SecurityType securityType; var rawValue = parts[parts.Length - securityTypeOffset]; if (!Enum.TryParse(rawValue, true, out securityType)) { securityTypeOffset = HighResSecurityTypeOffset; rawValue = parts[parts.Length - securityTypeOffset]; if (!Enum.TryParse(rawValue, true, out securityType)) { throw new FormatException($"Unexpected path format: {path}"); } } var market = parts[parts.Length - securityTypeOffset + MarketOffset]; var resolution = (Resolution) Enum.Parse(typeof (Resolution), parts[parts.Length - securityTypeOffset + ResolutionOffset], true); string ticker; if (securityTypeOffset == LowResSecurityTypeOffset) { ticker = Path.GetFileNameWithoutExtension(path); if (securityType.IsOption()) { // ticker_year_trade_american ticker = ticker.Substring(0, ticker.IndexOf("_", StringComparison.InvariantCulture)); } if (securityType == SecurityType.Future || securityType == SecurityType.CryptoFuture) { // ticker_trade ticker = ticker.Substring(0, ticker.LastIndexOfInvariant("_")); } if (securityType == SecurityType.Crypto && (resolution == Resolution.Daily || resolution == Resolution.Hour)) { // ticker_trade or ticker_quote ticker = ticker.Substring(0, ticker.LastIndexOfInvariant("_")); } } else { ticker = parts[parts.Length - securityTypeOffset + TickerOffset]; } var date = securityTypeOffset == LowResSecurityTypeOffset ? DateTime.MinValue : DateTime.ParseExact(filename.Substring(0, filename.IndexOf("_", StringComparison.Ordinal)), DateFormat.EightCharacter, null); Symbol symbol; if (securityType == SecurityType.Option) { var withoutExtension = Path.GetFileNameWithoutExtension(filename); rawValue = withoutExtension.Substring(withoutExtension.LastIndexOf("_", StringComparison.Ordinal) + 1); var style = (OptionStyle) Enum.Parse(typeof (OptionStyle), rawValue, true); symbol = Symbol.CreateOption(ticker, market, style, default, 0, SecurityIdentifier.DefaultDate); } else if (securityType == SecurityType.FutureOption || securityType == SecurityType.IndexOption) { var withoutExtension = Path.GetFileNameWithoutExtension(filename); rawValue = withoutExtension.Substring(withoutExtension.LastIndexOf("_", StringComparison.Ordinal) + 1); var style = (OptionStyle) Enum.Parse(typeof (OptionStyle), rawValue, true); var underlyingSecurityType = Symbol.GetUnderlyingFromOptionType(securityType); var underlyingSymbol = Symbol.Create(OptionSymbol.MapToUnderlying(ticker, securityType), underlyingSecurityType, market); symbol = Symbol.CreateOption(underlyingSymbol, ticker, market, style, default, 0, SecurityIdentifier.DefaultDate); } else if (securityType == SecurityType.Future) { symbol = Symbol.CreateFuture(ticker, market, SecurityIdentifier.DefaultDate); } else { symbol = Symbol.Create(ticker, securityType, market); } var tickType = filename.Contains("_quote") ? TickType.Quote : (filename.Contains("_openinterest") ? TickType.OpenInterest : TickType.Trade); return new LeanDataPathComponents(securityType, market, resolution, symbol, filename, date, tickType); } } }