Lean  $LEAN_TAG$
SecurityDatabaseKey.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 
19 {
20  /// <summary>
21  /// Represents the key to a single entry in the <see cref="MarketHoursDatabase"/> or the <see cref="SymbolPropertiesDatabase"/>
22  /// </summary>
23  public class SecurityDatabaseKey : IEquatable<SecurityDatabaseKey>
24  {
25  /// <summary>
26  /// Represents that the specified symbol or market field will match all
27  /// </summary>
28  public const string Wildcard = "[*]";
29 
30  /// <summary>
31  /// The market. If null, ignore market filtering
32  /// </summary>
33  public readonly string Market;
34 
35  /// <summary>
36  /// The symbol. If null, ignore symbol filtering
37  /// </summary>
38  public readonly string Symbol;
39 
40  /// <summary>
41  /// The security type
42  /// </summary>
43  public readonly SecurityType SecurityType;
44 
45  /// <summary>
46  /// Initializes a new instance of the <see cref="SecurityDatabaseKey"/> class
47  /// </summary>
48  /// <param name="market">The market</param>
49  /// <param name="symbol">The symbol. specify null to apply to all symbols in market/security type</param>
50  /// <param name="securityType">The security type</param>
51  public SecurityDatabaseKey(string market, string symbol, SecurityType securityType)
52  {
53  Market = string.IsNullOrEmpty(market) ? Wildcard : market;
54  SecurityType = securityType;
55  Symbol = string.IsNullOrEmpty(symbol) ? Wildcard : symbol;
56  }
57 
58  /// <summary>
59  /// Based on this entry will initializes the generic market and security type instance of the <see cref="SecurityDatabaseKey"/> class
60  /// </summary>
62  {
63  return new SecurityDatabaseKey(Market, null, SecurityType);
64  }
65 
66  /// <summary>
67  /// Parses the specified string as a <see cref="SecurityDatabaseKey"/>
68  /// </summary>
69  /// <param name="key">The string representation of the key</param>
70  /// <returns>A new <see cref="SecurityDatabaseKey"/> instance</returns>
71  public static SecurityDatabaseKey Parse(string key)
72  {
73  var parts = key.Split('-');
74  if (parts.Length != 3 || parts[0] == Wildcard)
75  {
76  throw new FormatException(Messages.SecurityDatabaseKey.KeyNotInExpectedFormat(key));
77  }
78  SecurityType type;
79  if (!parts[0].TryParseSecurityType(out type))
80  {
81  return null;
82  }
83 
84  return new SecurityDatabaseKey(parts[1], parts[2], type);
85  }
86 
87  #region Equality members
88 
89  /// <summary>
90  /// Indicates whether the current object is equal to another object of the same type.
91  /// </summary>
92  /// <returns>
93  /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
94  /// </returns>
95  /// <param name="other">An object to compare with this object.</param>
96  public bool Equals(SecurityDatabaseKey other)
97  {
98  if (ReferenceEquals(null, other)) return false;
99  if (ReferenceEquals(this, other)) return true;
100  return Market.Equals(other.Market, StringComparison.OrdinalIgnoreCase)
101  && Symbol.Equals(other.Symbol, StringComparison.OrdinalIgnoreCase)
102  && SecurityType == other.SecurityType;
103  }
104 
105  /// <summary>
106  /// Determines whether the specified object is equal to the current object.
107  /// </summary>
108  /// <returns>
109  /// true if the specified object is equal to the current object; otherwise, false.
110  /// </returns>
111  /// <param name="obj">The object to compare with the current object. </param>
112  public override bool Equals(object obj)
113  {
114  if (ReferenceEquals(null, obj)) return false;
115  if (ReferenceEquals(this, obj)) return true;
116  if (obj.GetType() != this.GetType()) return false;
117  return Equals((SecurityDatabaseKey) obj);
118  }
119 
120  /// <summary>
121  /// Serves as the default hash function.
122  /// </summary>
123  /// <returns>
124  /// A hash code for the current object.
125  /// </returns>
126  public override int GetHashCode()
127  {
128  unchecked
129  {
130  var hashCode = StringComparer.OrdinalIgnoreCase.GetHashCode(Market);
131  hashCode = (hashCode*397) ^ StringComparer.OrdinalIgnoreCase.GetHashCode(Symbol);
132  hashCode = (hashCode*397) ^ (int) SecurityType;
133  return hashCode;
134  }
135  }
136 
137  /// <summary>
138  /// Security Database Key == operator
139  /// </summary>
140  /// <returns>True if they are the same</returns>
141  public static bool operator ==(SecurityDatabaseKey left, SecurityDatabaseKey right)
142  {
143  return Equals(left, right);
144  }
145 
146  /// <summary>
147  /// Security Database Key != operator
148  /// </summary>
149  /// <returns>True if they are not the same</returns>
150  public static bool operator !=(SecurityDatabaseKey left, SecurityDatabaseKey right)
151  {
152  return !Equals(left, right);
153  }
154 
155  #endregion
156 
157  /// <summary>
158  /// Returns a string that represents the current object.
159  /// </summary>
160  /// <returns>
161  /// A string that represents the current object.
162  /// </returns>
163  public override string ToString()
164  {
165  return Messages.SecurityDatabaseKey.ToString(this);
166  }
167  }
168 }