Lean  $LEAN_TAG$
SubscriptionDataSource.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.Linq;
18 using System.Collections.Generic;
19 using static QuantConnect.StringExtensions;
20 
21 namespace QuantConnect.Data
22 {
23  /// <summary>
24  /// Represents the source location and transport medium for a subscription
25  /// </summary>
26  public class SubscriptionDataSource : IEquatable<SubscriptionDataSource>
27  {
28  private readonly static IReadOnlyList<KeyValuePair<string, string>> _empty = new List<KeyValuePair<string, string>>();
29 
30  /// <summary>
31  /// Identifies where to get the subscription's data from
32  /// </summary>
33  public readonly string Source;
34 
35  /// <summary>
36  /// Identifies the format of the data within the source
37  /// </summary>
38  public readonly FileFormat Format;
39 
40  /// <summary>
41  /// Identifies the transport medium used to access the data, such as a local or remote file, or a polling rest API
42  /// </summary>
44 
45  /// <summary>
46  /// Gets the header values to be used in the web request.
47  /// </summary>
48  public readonly IReadOnlyList<KeyValuePair<string, string>> Headers;
49 
50  /// <summary>
51  /// Initializes a new instance of the <see cref="SubscriptionDataSource"/> class.
52  /// </summary>
53  /// <param name="source">The subscription's data source location</param>
54  public SubscriptionDataSource(string source)
55  : this(source, GetDefaultSubscriptionTransportMedium(source), FileFormat.Csv)
56  {
57  }
58 
59  /// <summary>
60  /// Initializes a new instance of the <see cref="SubscriptionDataSource"/> class.
61  /// </summary>
62  /// <param name="source">The subscription's data source location</param>
63  /// <param name="transportMedium">The transport medium to be used to retrieve the subscription's data from the source</param>
64  public SubscriptionDataSource(string source, SubscriptionTransportMedium transportMedium)
65  : this(source, transportMedium, FileFormat.Csv)
66  {
67  }
68 
69  /// <summary>
70  /// Initializes a new instance of the <see cref="SubscriptionDataSource"/> class.
71  /// </summary>
72  /// <param name="source">The subscription's data source location</param>
73  /// <param name="transportMedium">The transport medium to be used to retrieve the subscription's data from the source</param>
74  /// <param name="format">The format of the data within the source</param>
75  public SubscriptionDataSource(string source, SubscriptionTransportMedium transportMedium, FileFormat format)
76  : this(source, transportMedium, format, null)
77  {
78  }
79 
80  /// <summary>
81  /// Initializes a new instance of the <see cref="SubscriptionDataSource"/> class with <see cref="SubscriptionTransportMedium.Rest"/>
82  /// including the specified header values
83  /// </summary>
84  /// <param name="source">The subscription's data source location</param>
85  /// <param name="transportMedium">The transport medium to be used to retrieve the subscription's data from the source</param>
86  /// <param name="format">The format of the data within the source</param>
87  /// <param name="headers">The headers to be used for this source</param>
88  public SubscriptionDataSource(string source, SubscriptionTransportMedium transportMedium, FileFormat format, IEnumerable<KeyValuePair<string, string>> headers)
89  {
90  Source = source;
91  Format = format;
92  TransportMedium = transportMedium;
93  Headers = headers?.ToList() ?? _empty;
94  }
95 
96  /// <summary>
97  /// Indicates whether the current object is equal to another object of the same type.
98  /// </summary>
99  /// <returns>
100  /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
101  /// </returns>
102  /// <param name="other">An object to compare with this object.</param>
103  public bool Equals(SubscriptionDataSource other)
104  {
105  if (ReferenceEquals(null, other)) return false;
106  if (ReferenceEquals(this, other)) return true;
107  return string.Equals(Source, other.Source)
108  && TransportMedium == other.TransportMedium
109  && Headers.SequenceEqual(other.Headers);
110  }
111 
112  /// <summary>
113  /// Determines whether the specified instance is equal to the current instance.
114  /// </summary>
115  /// <returns>
116  /// true if the specified object is equal to the current object; otherwise, false.
117  /// </returns>
118  /// <param name="obj">The object to compare with the current object. </param><filterpriority>2</filterpriority>
119  public override bool Equals(object obj)
120  {
121  if (ReferenceEquals(null, obj)) return false;
122  if (ReferenceEquals(this, obj)) return true;
123  if (obj.GetType() != GetType()) return false;
124  return Equals((SubscriptionDataSource) obj);
125  }
126 
127  /// <summary>
128  /// Serves as a hash function for a particular type.
129  /// </summary>
130  /// <returns>
131  /// A hash code for the current <see cref="T:System.Object"/>.
132  /// </returns>
133  /// <filterpriority>2</filterpriority>
134  public override int GetHashCode()
135  {
136  unchecked
137  {
138  return ((Source != null ? Source.GetHashCode() : 0)*397) ^ (int) TransportMedium;
139  }
140  }
141 
142  /// <summary>
143  /// Indicates whether the current object is equal to another object of the same type.
144  /// </summary>
145  /// <param name="left">The <see cref="SubscriptionDataSource"/> instance on the left of the operator</param>
146  /// <param name="right">The <see cref="SubscriptionDataSource"/> instance on the right of the operator</param>
147  /// <returns>True if the two instances are considered equal, false otherwise</returns>
149  {
150  return Equals(left, right);
151  }
152 
153  /// <summary>
154  /// Indicates whether the current object is not equal to another object of the same type.
155  /// </summary>
156  /// <param name="left">The <see cref="SubscriptionDataSource"/> instance on the left of the operator</param>
157  /// <param name="right">The <see cref="SubscriptionDataSource"/> instance on the right of the operator</param>
158  /// <returns>True if the two instances are not considered equal, false otherwise</returns>
160  {
161  return !Equals(left, right);
162  }
163 
164  /// <summary>
165  /// Returns a string that represents the current object.
166  /// </summary>
167  /// <returns>
168  /// A string that represents the current object.
169  /// </returns>
170  /// <filterpriority>2</filterpriority>
171  public override string ToString()
172  {
173  return Invariant($"{TransportMedium}: {Format} {Source}");
174  }
175 
176  /// <summary>
177  /// Gets the default transport medium for the specified source
178  /// </summary>
179  private static SubscriptionTransportMedium GetDefaultSubscriptionTransportMedium(string source)
180  {
181  if (source.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
182  source.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
183  {
184  return SubscriptionTransportMedium.RemoteFile;
185  }
186  return SubscriptionTransportMedium.LocalFile;
187  }
188  }
189 }