Lean  $LEAN_TAG$
HistoryRequestFactory.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 NodaTime;
20 using QuantConnect.Util;
21 
22 namespace QuantConnect.Data
23 {
24  /// <summary>
25  /// Helper class used to create new <see cref="HistoryRequest"/>
26  /// </summary>
27  public class HistoryRequestFactory
28  {
29  private readonly IAlgorithm _algorithm;
30 
31  /// <summary>
32  /// Creates a new instance
33  /// </summary>
34  /// <param name="algorithm">The algorithm instance to use</param>
36  {
37  _algorithm = algorithm;
38  }
39 
40  /// <summary>
41  /// Creates a new history request
42  /// </summary>
43  /// <param name="subscription">The config </param>
44  /// <param name="startAlgoTz">History request start time in algorithm time zone</param>
45  /// <param name="endAlgoTz">History request end time in algorithm time zone</param>
46  /// <param name="exchangeHours">Security exchange hours</param>
47  /// <param name="resolution">The resolution to use. If null will use <see cref="SubscriptionDataConfig.Resolution"/></param>
48  /// <param name="fillForward">True to fill forward missing data, false otherwise</param>
49  /// <param name="extendedMarketHours">True to include extended market hours data, false otherwise</param>
50  /// <param name="dataMappingMode">The contract mapping mode to use for the security history request</param>
51  /// <param name="dataNormalizationMode">The price scaling mode to use for the securities history</param>
52  /// <param name="contractDepthOffset">The continuous contract desired offset from the current front month.
53  /// For example, 0 will use the front month, 1 will use the back month contract</param>
54  /// <returns>The new <see cref="HistoryRequest"/></returns>
56  DateTime startAlgoTz,
57  DateTime endAlgoTz,
58  SecurityExchangeHours exchangeHours,
59  Resolution? resolution,
60  bool? fillForward = null,
61  bool? extendedMarketHours = null,
62  DataMappingMode? dataMappingMode = null,
63  DataNormalizationMode? dataNormalizationMode = null,
64  int? contractDepthOffset = null)
65  {
66  resolution ??= subscription.Resolution;
67 
68  var dataType = subscription.Type;
69 
70  // if we change resolution the data type can change, for example subscription being Tick type and resolution daily
71  // data type here won't be Tick anymore, but TradeBar/QuoteBar
72  if (resolution.Value != subscription.Resolution && LeanData.IsCommonLeanDataType(dataType))
73  {
74  dataType = LeanData.GetDataType(resolution.Value, subscription.TickType);
75  }
76 
77  var fillForwardResolution = subscription.FillDataForward ? resolution : null;
78  if (fillForward != null)
79  {
80  fillForwardResolution = fillForward.Value ? resolution : null;
81  }
82 
83  var request = new HistoryRequest(subscription,
84  exchangeHours,
85  startAlgoTz.ConvertToUtc(_algorithm.TimeZone),
86  endAlgoTz.ConvertToUtc(_algorithm.TimeZone))
87  {
88  DataType = dataType,
89  Resolution = resolution.Value,
90  FillForwardResolution = fillForwardResolution,
91  TickType = subscription.TickType
92  };
93 
94  if (extendedMarketHours != null)
95  {
96  request.IncludeExtendedMarketHours = extendedMarketHours.Value;
97  }
98 
99  if (dataMappingMode != null)
100  {
101  request.DataMappingMode = dataMappingMode.Value;
102  }
103 
104  if (dataNormalizationMode != null)
105  {
106  request.DataNormalizationMode = dataNormalizationMode.Value;
107  }
108 
109  if (contractDepthOffset != null)
110  {
111  request.ContractDepthOffset = (uint)Math.Abs(contractDepthOffset.Value);
112  }
113 
114  return request;
115  }
116 
117 
118  /// <summary>
119  /// Gets the start time required for the specified bar count in terms of the algorithm's time zone
120  /// </summary>
121  /// <param name="symbol">The symbol to select proper <see cref="SubscriptionDataConfig"/> config</param>
122  /// <param name="periods">The number of bars requested</param>
123  /// <param name="resolution">The length of each bar</param>
124  /// <param name="exchange">The exchange hours used for market open hours</param>
125  /// <param name="dataTimeZone">The time zone in which data are stored</param>
126  /// <param name="extendedMarketHours">
127  /// True to include extended market hours data, false otherwise.
128  /// If not passed, the config will be used to determined whether to include extended market hours.
129  /// </param>
130  /// <returns>The start time that would provide the specified number of bars ending at the algorithm's current time</returns>
131  public DateTime GetStartTimeAlgoTz(
132  Symbol symbol,
133  int periods,
134  Resolution resolution,
135  SecurityExchangeHours exchange,
136  DateTimeZone dataTimeZone,
137  bool? extendedMarketHours = null)
138  {
139  var isExtendedMarketHours = false;
140  // hour resolution does no have extended market hours data
141  if (resolution != Resolution.Hour)
142  {
143  if (extendedMarketHours.HasValue)
144  {
145  isExtendedMarketHours = extendedMarketHours.Value;
146  }
147  else
148  {
149  var configs = _algorithm.SubscriptionManager
150  .SubscriptionDataConfigService
151  .GetSubscriptionDataConfigs(symbol);
152  isExtendedMarketHours = configs.IsExtendedMarketHours();
153  }
154  }
155 
156  var timeSpan = resolution.ToTimeSpan();
157  // make this a minimum of one second
158  timeSpan = timeSpan < Time.OneSecond ? Time.OneSecond : timeSpan;
159 
160  var localStartTime = Time.GetStartTimeForTradeBars(
161  exchange,
162  _algorithm.UtcTime.ConvertFromUtc(exchange.TimeZone),
163  timeSpan,
164  periods,
165  isExtendedMarketHours,
166  dataTimeZone);
167  return localStartTime.ConvertTo(exchange.TimeZone, _algorithm.TimeZone);
168  }
169  }
170 }