Lean  $LEAN_TAG$
VolatilityModelExtensions.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.Collections.Generic;
18 using System.Linq;
19 
20 using NodaTime;
21 
22 using QuantConnect.Data;
24 
26 {
27  /// <summary>
28  /// Provides extension methods to volatility models
29  /// </summary>
30  public static class VolatilityModelExtensions
31  {
32  /// <summary>
33  /// Warms up the security's volatility model.
34  /// This can happen either on initialization or after a split or dividend is processed.
35  /// </summary>
36  /// <param name="volatilityModel">The volatility model to be warmed up</param>
37  /// <param name="historyProvider">The history provider to use to get historical data</param>
38  /// <param name="subscriptionManager">The subscription manager to use</param>
39  /// <param name="security">The security which volatility model is being warmed up</param>
40  /// <param name="utcTime">The current UTC time</param>
41  /// <param name="timeZone">The algorithm time zone</param>
42  /// <param name="liveMode">Whether the algorithm is in live mode</param>
43  /// <param name="dataNormalizationMode">The security subscribed data normalization mode</param>
44  public static void WarmUp(
45  this IVolatilityModel volatilityModel,
46  IHistoryProvider historyProvider,
47  SubscriptionManager subscriptionManager,
48  Security security,
49  DateTime utcTime,
50  DateTimeZone timeZone,
51  bool liveMode,
52  DataNormalizationMode? dataNormalizationMode = null)
53  {
54  volatilityModel.WarmUp(
55  historyProvider,
56  subscriptionManager,
57  security,
58  timeZone,
59  liveMode,
60  dataNormalizationMode,
61  () => volatilityModel.GetHistoryRequirements(security, utcTime));
62  }
63 
64  /// <summary>
65  /// Warms up the security's volatility model.
66  /// This can happen either on initialization or after a split or dividend is processed.
67  /// </summary>
68  /// <param name="volatilityModel">The volatility model to be warmed up</param>
69  /// <param name="historyProvider">The history provider to use to get historical data</param>
70  /// <param name="subscriptionManager">The subscription manager to use</param>
71  /// <param name="security">The security which volatility model is being warmed up</param>
72  /// <param name="utcTime">The current UTC time</param>
73  /// <param name="timeZone">The algorithm time zone</param>
74  /// <param name="resolution">The data resolution required for the indicator</param>
75  /// <param name="barCount">The bar count required to fully warm the indicator up</param>
76  /// <param name="liveMode">Whether the algorithm is in live mode</param>
77  /// <param name="dataNormalizationMode">The security subscribed data normalization mode</param>
78  public static void WarmUp(
79  this IndicatorVolatilityModel volatilityModel,
80  IHistoryProvider historyProvider,
81  SubscriptionManager subscriptionManager,
82  Security security,
83  DateTime utcTime,
84  DateTimeZone timeZone,
85  Resolution? resolution,
86  int barCount,
87  bool liveMode,
88  DataNormalizationMode? dataNormalizationMode = null)
89  {
90  volatilityModel.WarmUp(
91  historyProvider,
92  subscriptionManager,
93  security,
94  timeZone,
95  liveMode,
96  dataNormalizationMode,
97  () => volatilityModel.GetHistoryRequirements(security, utcTime, resolution, barCount));
98  }
99 
100  /// <summary>
101  /// Warms up the security's volatility model.
102  /// This can happen either on initialization or after a split or dividend is processed.
103  /// </summary>
104  /// <param name="volatilityModel">The volatility model to be warmed up</param>
105  /// <param name="algorithm">The algorithm running</param>
106  /// <param name="security">The security which volatility model is being warmed up</param>
107  /// <param name="resolution">The data resolution required for the indicator</param>
108  /// <param name="barCount">The bar count required to fully warm the indicator up</param>
109  /// <param name="dataNormalizationMode">The security subscribed data normalization mode</param>
110  public static void WarmUp(
111  this IndicatorVolatilityModel volatilityModel,
112  IAlgorithm algorithm,
113  Security security,
114  Resolution? resolution,
115  int barCount,
116  DataNormalizationMode? dataNormalizationMode = null)
117  {
118  volatilityModel.WarmUp(
119  algorithm.HistoryProvider,
120  algorithm.SubscriptionManager,
121  security,
122  algorithm.UtcTime,
123  algorithm.TimeZone,
124  resolution,
125  barCount,
126  algorithm.LiveMode,
127  dataNormalizationMode);
128  }
129 
130  private static void WarmUp(
131  this IVolatilityModel volatilityModel,
132  IHistoryProvider historyProvider,
133  SubscriptionManager subscriptionManager,
134  Security security,
135  DateTimeZone timeZone,
136  bool liveMode,
137  DataNormalizationMode? dataNormalizationMode,
138  Func<IEnumerable<HistoryRequest>> getHistoryRequirementsFunc)
139  {
140  if (historyProvider == null || security == null || volatilityModel == VolatilityModel.Null)
141  {
142  return;
143  }
144 
145  // start: this is a work around to maintain retro compatibility
146  // did not want to add IVolatilityModel.SetSubscriptionDataConfigProvider
147  // to prevent breaking existing user models.
148  var baseTypeModel = volatilityModel as BaseVolatilityModel;
149  baseTypeModel?.SetSubscriptionDataConfigProvider(subscriptionManager.SubscriptionDataConfigService);
150  // end
151 
152  // Warm up
153  var historyRequests = getHistoryRequirementsFunc().ToList();
154  if (liveMode || (dataNormalizationMode.HasValue && dataNormalizationMode == DataNormalizationMode.Raw))
155  {
156  // If we're in live mode or raw mode, we need to warm up the volatility model with scaled raw data
157  // to avoid jumps in volatility values due to price discontinuities on splits and dividends
158  foreach (var request in historyRequests)
159  {
160  request.DataNormalizationMode = DataNormalizationMode.ScaledRaw;
161  }
162  }
163 
164  var history = historyProvider.GetHistory(historyRequests, timeZone);
165  foreach (var slice in history)
166  {
167  foreach (var request in historyRequests)
168  {
169  if (slice.TryGet(request.DataType, security.Symbol, out var data))
170  {
171  volatilityModel.Update(security, data);
172  }
173  }
174  }
175  }
176  }
177 }