Lean  $LEAN_TAG$
MapFileRow.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 
17 using System;
18 using System.Linq;
20 using System.Collections.Generic;
21 
23 {
24  /// <summary>
25  /// Represents a single row in a map_file. This is a csv file ordered as {date, mapped symbol}
26  /// </summary>
27  public class MapFileRow : IEquatable<MapFileRow>
28  {
29  /// <summary>
30  /// Gets the date associated with this data
31  /// </summary>
32  public DateTime Date { get; }
33 
34  /// <summary>
35  /// Gets the mapped symbol
36  /// </summary>
37  public string MappedSymbol { get; }
38 
39  /// <summary>
40  /// Gets the mapped symbol
41  /// </summary>
42  public Exchange PrimaryExchange { get; }
43 
44  /// <summary>
45  /// Gets the securities mapping mode associated to this mapping row
46  /// </summary>
48 
49  /// <summary>
50  /// Initializes a new instance of the <see cref="MapFileRow"/> class.
51  /// </summary>
52  public MapFileRow(DateTime date, string mappedSymbol, string primaryExchange,
53  string market = QuantConnect.Market.USA, SecurityType securityType = SecurityType.Equity, DataMappingMode? dataMappingMode = null)
54  : this(date, mappedSymbol, primaryExchange.GetPrimaryExchange(securityType, market), dataMappingMode)
55  { }
56 
57  /// <summary>
58  /// Initializes a new instance of the <see cref="MapFileRow"/> class.
59  /// </summary>
60  public MapFileRow(DateTime date, string mappedSymbol, Exchange primaryExchange = null, DataMappingMode? dataMappingMode = null)
61  {
62  Date = date;
63  MappedSymbol = mappedSymbol.LazyToUpper();
64  PrimaryExchange = primaryExchange ?? Exchange.UNKNOWN;
65  DataMappingMode = dataMappingMode;
66  }
67 
68  /// <summary>
69  /// Reads in the map_file for the specified equity symbol
70  /// </summary>
71  public static IEnumerable<MapFileRow> Read(string file, string market, SecurityType securityType, IDataProvider dataProvider)
72  {
73  return dataProvider.ReadLines(file)
74  .Where(l => !string.IsNullOrWhiteSpace(l))
75  .Select(s => {
76  try
77  {
78  return Parse(s, market, securityType);
79  }
80  catch (ArgumentException)
81  {
82  // skip unrecognized mapping modes for backwards compatibility
83  return null;
84  }
85  })
86  .Where(row => row != null);
87  }
88 
89  /// <summary>
90  /// Parses the specified line into a MapFileRow
91  /// </summary>
92  public static MapFileRow Parse(string line, string market, SecurityType securityType)
93  {
94  var csv = line.Split(',');
95  var primaryExchange = Exchange.UNKNOWN;
96  DataMappingMode? mappingMode = null;
97 
98  if (csv.Length >= 3)
99  {
100  primaryExchange = csv[2].GetPrimaryExchange(securityType, market);
101  }
102  if (csv.Length >= 4)
103  {
104  mappingMode = csv[3].ParseDataMappingMode();
105  }
106 
107  return new MapFileRow(DateTime.ParseExact(csv[0], DateFormat.EightCharacter, null), csv[1], primaryExchange, mappingMode);
108  }
109 
110  #region Equality members
111 
112  /// <summary>
113  /// Indicates whether the current object is equal to another object of the same type.
114  /// </summary>
115  /// <returns>
116  /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
117  /// </returns>
118  /// <param name="other">An object to compare with this object.</param>
119  public bool Equals(MapFileRow other)
120  {
121  if (ReferenceEquals(null, other)) return false;
122  if (ReferenceEquals(this, other)) return true;
123  return Date.Equals(other.Date) &&
124  string.Equals(MappedSymbol, other.MappedSymbol) &&
125  string.Equals(PrimaryExchange, other.PrimaryExchange) &&
127  }
128 
129  /// <summary>
130  /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
131  /// </summary>
132  /// <returns>
133  /// true if the specified object is equal to the current object; otherwise, false.
134  /// </returns>
135  /// <param name="obj">The object to compare with the current object. </param><filterpriority>2</filterpriority>
136  public override bool Equals(object obj)
137  {
138  if (ReferenceEquals(null, obj)) return false;
139  if (ReferenceEquals(this, obj)) return true;
140  if (obj.GetType() != this.GetType()) return false;
141  return Equals((MapFileRow)obj);
142  }
143 
144  /// <summary>
145  /// Serves as a hash function for a particular type.
146  /// </summary>
147  /// <returns>
148  /// A hash code for the current <see cref="T:System.Object"/>.
149  /// </returns>
150  /// <filterpriority>2</filterpriority>
151  public override int GetHashCode()
152  {
153  unchecked
154  {
155  return (Date.GetHashCode() * 397) ^
156  (MappedSymbol != null ? MappedSymbol.GetHashCode() : 0) ^
157  (DataMappingMode != null ? DataMappingMode.GetHashCode() : 0) ^
159  }
160  }
161 
162  /// <summary>
163  /// Determines whether or not the two instances are equal
164  /// </summary>
165  public static bool operator ==(MapFileRow left, MapFileRow right)
166  {
167  return Equals(left, right);
168  }
169 
170  /// <summary>
171  /// Determines whether or not the two instances are not equal
172  /// </summary>
173  public static bool operator !=(MapFileRow left, MapFileRow right)
174  {
175  return !Equals(left, right);
176  }
177 
178  #endregion
179 
180  /// <summary>
181  /// Writes this row to csv format
182  /// </summary>
183  public string ToCsv()
184  {
185  var encodedExchange = string.Empty;
187  {
188  if (DataMappingMode != null)
189  {
190  // be lazy, only add a comma if we have a mapping mode after
191  encodedExchange = ",";
192  }
193  }
194  else
195  {
196  encodedExchange = $",{PrimaryExchange.Code}";
197  }
198  var mappingMode = DataMappingMode != null ? $",{(int)DataMappingMode}" : string.Empty;
199  return $"{Date.ToStringInvariant(DateFormat.EightCharacter)},{MappedSymbol.ToLowerInvariant()}{encodedExchange}{mappingMode}";
200  }
201 
202  /// <summary>
203  /// Convert this row into string form
204  /// </summary>
205  /// <returns>resulting string</returns>
206  public override string ToString()
207  {
208  var mainExchange = PrimaryExchange == Exchange.UNKNOWN ? string.Empty : $" - {PrimaryExchange}";
209  var mappingMode = DataMappingMode != null ? $" - {DataMappingMode}" : string.Empty;
210  return Date.ToShortDateString() + ": " + MappedSymbol + mainExchange + mappingMode;
211  }
212  }
213 }