Lean  $LEAN_TAG$
LeanDataPathComponents.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;
17 using System.IO;
19 
20 namespace QuantConnect.Util
21 {
22  /// <summary>
23  /// Type representing the various pieces of information emebedded into a lean data file path
24  /// </summary>
26  {
27  /// <summary>
28  /// Gets the date component from the file name
29  /// </summary>
30  public DateTime Date
31  {
32  get; private set;
33  }
34 
35  /// <summary>
36  /// Gets the security type from the path
37  /// </summary>
39  {
40  get; private set;
41  }
42 
43  /// <summary>
44  /// Gets the market from the path
45  /// </summary>
46  public string Market
47  {
48  get; private set;
49  }
50 
51  /// <summary>
52  /// Gets the resolution from the path
53  /// </summary>
54  public Resolution Resolution
55  {
56  get; private set;
57  }
58 
59  /// <summary>
60  /// Gets the file name, not inluding directory information
61  /// </summary>
62  public string Filename
63  {
64  get; private set;
65  }
66 
67  /// <summary>
68  /// Gets the symbol object implied by the path. For options, or any
69  /// multi-entry zip file, this should be the canonical symbol
70  /// </summary>
71  public Symbol Symbol
72  {
73  get; private set;
74  }
75 
76  /// <summary>
77  /// Gets the tick type from the file name
78  /// </summary>
79  public TickType TickType
80  {
81  get; private set;
82  }
83 
84  /// <summary>
85  /// Initializes a new instance of the <see cref="LeanDataPathComponents"/> class
86  /// </summary>
87  public LeanDataPathComponents(SecurityType securityType, string market, Resolution resolution, Symbol symbol, string filename, DateTime date, TickType tickType)
88  {
89  Date = date;
90  SecurityType = securityType;
91  Market = market;
92  Resolution = resolution;
93  Filename = filename;
94  Symbol = symbol;
95  TickType = tickType;
96  }
97 
98  /// <summary>
99  /// Parses the specified path into a new instance of the <see cref="LeanDataPathComponents"/> class
100  /// </summary>
101  /// <param name="path">The path to be parsed</param>
102  /// <returns>A new instance of the <see cref="LeanDataPathComponents"/> class representing the specified path</returns>
103  public static LeanDataPathComponents Parse(string path)
104  {
105  //"../Data/equity/usa/hour/spy.zip"
106  //"../Data/equity/usa/hour/spy/20160218_trade.zip"
107  var fileinfo = new FileInfo(path);
108  var filename = fileinfo.Name;
109  var parts = path.Split('/', '\\');
110 
111  // defines the offsets of the security relative to the end of the path
112  const int LowResSecurityTypeOffset = 4;
113  const int HighResSecurityTypeOffset = 5;
114 
115  // defines other offsets relative to the beginning of the substring produce by the above offsets
116  const int MarketOffset = 1;
117  const int ResolutionOffset = 2;
118  const int TickerOffset = 3;
119 
120 
121  if (parts.Length < LowResSecurityTypeOffset)
122  {
123  throw new FormatException($"Unexpected path format: {path}");
124  }
125 
126  var securityTypeOffset = LowResSecurityTypeOffset;
127  SecurityType securityType;
128  var rawValue = parts[parts.Length - securityTypeOffset];
129  if (!Enum.TryParse(rawValue, true, out securityType))
130  {
131  securityTypeOffset = HighResSecurityTypeOffset;
132  rawValue = parts[parts.Length - securityTypeOffset];
133  if (!Enum.TryParse(rawValue, true, out securityType))
134  {
135  throw new FormatException($"Unexpected path format: {path}");
136  }
137  }
138 
139  var market = parts[parts.Length - securityTypeOffset + MarketOffset];
140  var resolution = (Resolution) Enum.Parse(typeof (Resolution), parts[parts.Length - securityTypeOffset + ResolutionOffset], true);
141  string ticker;
142  if (securityTypeOffset == LowResSecurityTypeOffset)
143  {
144  ticker = Path.GetFileNameWithoutExtension(path);
145  if (securityType.IsOption())
146  {
147  // ticker_year_trade_american
148  ticker = ticker.Substring(0, ticker.IndexOf("_", StringComparison.InvariantCulture));
149  }
150  if (securityType == SecurityType.Future || securityType == SecurityType.CryptoFuture)
151  {
152  // ticker_trade
153  ticker = ticker.Substring(0, ticker.LastIndexOfInvariant("_"));
154  }
155  if (securityType == SecurityType.Crypto &&
156  (resolution == Resolution.Daily || resolution == Resolution.Hour))
157  {
158  // ticker_trade or ticker_quote
159  ticker = ticker.Substring(0, ticker.LastIndexOfInvariant("_"));
160  }
161  }
162  else
163  {
164  ticker = parts[parts.Length - securityTypeOffset + TickerOffset];
165  }
166 
167  var date = securityTypeOffset == LowResSecurityTypeOffset ? DateTime.MinValue : DateTime.ParseExact(filename.Substring(0, filename.IndexOf("_", StringComparison.Ordinal)), DateFormat.EightCharacter, null);
168 
169  Symbol symbol;
170  if (securityType == SecurityType.Option)
171  {
172  var withoutExtension = Path.GetFileNameWithoutExtension(filename);
173  rawValue = withoutExtension.Substring(withoutExtension.LastIndexOf("_", StringComparison.Ordinal) + 1);
174  var style = (OptionStyle) Enum.Parse(typeof (OptionStyle), rawValue, true);
175  symbol = Symbol.CreateOption(ticker, market, style, default, 0, SecurityIdentifier.DefaultDate);
176  }
177  else if (securityType == SecurityType.FutureOption || securityType == SecurityType.IndexOption)
178  {
179  var withoutExtension = Path.GetFileNameWithoutExtension(filename);
180  rawValue = withoutExtension.Substring(withoutExtension.LastIndexOf("_", StringComparison.Ordinal) + 1);
181  var style = (OptionStyle) Enum.Parse(typeof (OptionStyle), rawValue, true);
182  var underlyingSecurityType = Symbol.GetUnderlyingFromOptionType(securityType);
183  var underlyingSymbol = Symbol.Create(OptionSymbol.MapToUnderlying(ticker, securityType), underlyingSecurityType, market);
184  symbol = Symbol.CreateOption(underlyingSymbol, ticker, market, style, default, 0, SecurityIdentifier.DefaultDate);
185  }
186  else if (securityType == SecurityType.Future)
187  {
188  symbol = Symbol.CreateFuture(ticker, market, SecurityIdentifier.DefaultDate);
189  }
190  else
191  {
192  symbol = Symbol.Create(ticker, securityType, market);
193  }
194 
195  var tickType = filename.Contains("_quote") ? TickType.Quote : (filename.Contains("_openinterest") ? TickType.OpenInterest : TickType.Trade);
196 
197  return new LeanDataPathComponents(securityType, market, resolution, symbol, filename, date, tickType);
198  }
199  }
200 }