Lean  $LEAN_TAG$
OptionGreekIndicatorBase.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 Python.Runtime;
18 using QuantConnect.Data;
19 using QuantConnect.Python;
20 
22 {
23  /// <summary>
24  /// To provide a base class for option greeks indicator
25  /// </summary>
27  {
28  /// <summary>
29  /// Cache of the current value of the greek
30  /// </summary>
31  protected decimal _greekValue;
32 
33  /// <summary>
34  /// Gets the implied volatility of the option
35  /// </summary>
36  public ImpliedVolatility ImpliedVolatility { get; set; }
37 
38  /// <summary>
39  /// Initializes a new instance of the OptionGreeksIndicatorBase class
40  /// </summary>
41  /// <param name="name">The name of this indicator</param>
42  /// <param name="option">The option to be tracked</param>
43  /// <param name="riskFreeRateModel">Risk-free rate model</param>
44  /// <param name="dividendYieldModel">Dividend yield model</param>
45  /// <param name="mirrorOption">The mirror option for parity calculation</param>
46  /// <param name="optionModel">The option pricing model used to estimate the Greek</param>
47  /// <param name="ivModel">The option pricing model used to estimate IV</param>
48  /// <param name="period">The lookback period of historical volatility</param>
49  protected OptionGreeksIndicatorBase(string name, Symbol option, IRiskFreeInterestRateModel riskFreeRateModel, IDividendYieldModel dividendYieldModel,
50  Symbol mirrorOption = null, OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null, int period = 2)
51  : base(name, option, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, period)
52  {
53  ivModel = ivModel ?? optionModel;
54  WarmUpPeriod = period;
55  ImpliedVolatility = new ImpliedVolatility(name + "_IV", option, riskFreeRateModel, dividendYieldModel, mirrorOption, (OptionPricingModelType)ivModel, period);
56  }
57 
58  /// <summary>
59  /// Initializes a new instance of the OptionGreeksIndicatorBase class
60  /// </summary>
61  /// <param name="name">The name of this indicator</param>
62  /// <param name="option">The option to be tracked</param>
63  /// <param name="riskFreeRateModel">Risk-free rate model</param>
64  /// <param name="dividendYield">Dividend yield, as a constant</param>
65  /// <param name="mirrorOption">The mirror option for parity calculation</param>
66  /// <param name="optionModel">The option pricing model used to estimate the Greek</param>
67  /// <param name="ivModel">The option pricing model used to estimate IV</param>
68  /// <param name="period">The lookback period of historical volatility</param>
69  protected OptionGreeksIndicatorBase(string name, Symbol option, IRiskFreeInterestRateModel riskFreeRateModel, decimal dividendYield = 0.0m,
70  Symbol mirrorOption = null, OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null, int period = 2)
71  : this(name, option, riskFreeRateModel, new ConstantDividendYieldModel(dividendYield), mirrorOption, optionModel, ivModel, period)
72  {
73  }
74 
75  /// <summary>
76  /// Initializes a new instance of the OptionGreeksIndicatorBase class
77  /// </summary>
78  /// <param name="name">The name of this indicator</param>
79  /// <param name="option">The option to be tracked</param>
80  /// <param name="riskFreeRate">Risk-free rate, as a constant</param>
81  /// <param name="dividendYield">Dividend yield, as a constant</param>
82  /// <param name="mirrorOption">The mirror option for parity calculation</param>
83  /// <param name="optionModel">The option pricing model used to estimate the Greek</param>
84  /// <param name="ivModel">The option pricing model used to estimate IV</param>
85  /// <param name="period">The lookback period of historical volatility</param>
86  protected OptionGreeksIndicatorBase(string name, Symbol option, decimal riskFreeRate = 0.05m, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
87  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null, int period = 2)
88  : this(name, option, new ConstantRiskFreeRateInterestRateModel(riskFreeRate), new ConstantDividendYieldModel(dividendYield),
89  mirrorOption, optionModel, ivModel, period)
90  {
91  }
92 
93  /// <summary>
94  /// Initializes a new instance of the OptionGreeksIndicatorBase class
95  /// </summary>
96  /// <param name="name">The name of this indicator</param>
97  /// <param name="option">The option to be tracked</param>
98  /// <param name="riskFreeRateModel">Risk-free rate model</param>
99  /// <param name="dividendYieldModel">Dividend yield model</param>
100  /// <param name="mirrorOption">The mirror option for parity calculation</param>
101  /// <param name="optionModel">The option pricing model used to estimate the Greek</param>
102  /// <param name="ivModel">The option pricing model used to estimate IV</param>
103  /// <param name="period">The lookback period of historical volatility</param>
104  protected OptionGreeksIndicatorBase(string name, Symbol option, PyObject riskFreeRateModel, PyObject dividendYieldModel, Symbol mirrorOption = null,
105  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null, int period = 2)
106  : this(name, option, RiskFreeInterestRateModelPythonWrapper.FromPyObject(riskFreeRateModel),
107  DividendYieldModelPythonWrapper.FromPyObject(dividendYieldModel), mirrorOption, optionModel, ivModel, period)
108  {
109  }
110 
111  /// <summary>
112  /// Initializes a new instance of the OptionGreeksIndicatorBase class
113  /// </summary>
114  /// <param name="name">The name of this indicator</param>
115  /// <param name="option">The option to be tracked</param>
116  /// <param name="riskFreeRateModel">Risk-free rate model</param>
117  /// <param name="dividendYield">Dividend yield, as a constant</param>
118  /// <param name="mirrorOption">The mirror option for parity calculation</param>
119  /// <param name="optionModel">The option pricing model used to estimate the Greek</param>
120  /// <param name="ivModel">The option pricing model used to estimate IV</param>
121  /// <param name="period">The lookback period of historical volatility</param>
122  protected OptionGreeksIndicatorBase(string name, Symbol option, PyObject riskFreeRateModel, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
123  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null, int period = 2)
124  : this(name, option, RiskFreeInterestRateModelPythonWrapper.FromPyObject(riskFreeRateModel),
125  new ConstantDividendYieldModel(dividendYield), mirrorOption, optionModel, ivModel, period)
126  {
127  }
128 
129  /// <summary>
130  /// Gets a flag indicating when this indicator is ready and fully initialized
131  /// </summary>
132  public override bool IsReady => ImpliedVolatility.IsReady;
133 
134  /// <summary>
135  /// Computes the next value of the option greek indicator
136  /// </summary>
137  /// <param name="input">The input given to the indicator</param>
138  /// <returns>The input is returned unmodified.</returns>
139  protected override decimal ComputeNextValue(IndicatorDataPoint input)
140  {
141  var time = input.EndTime;
142  var inputSymbol = input.Symbol;
143 
144  if (inputSymbol == _optionSymbol)
145  {
146  ImpliedVolatility.Update(input);
147  Price.Update(time, input.Price);
148  }
149  else if (inputSymbol == _oppositeOptionSymbol)
150  {
151  ImpliedVolatility.Update(input);
152  OppositePrice.Update(time, input.Price);
153  }
154  else if (inputSymbol == _underlyingSymbol)
155  {
156  ImpliedVolatility.Update(input);
157  UnderlyingPrice.Update(time, input.Price);
158  }
159  else
160  {
161  throw new ArgumentException("The given symbol was not target or reference symbol");
162  }
163 
164  if (Price.Current.Time == UnderlyingPrice.Current.Time)
165  {
166  if (UseMirrorContract)
167  {
168  if (Price.Current.Time != OppositePrice.Current.Time)
169  {
170  return _greekValue;
171  }
172  }
173 
176 
177  var timeTillExpiry = Convert.ToDecimal((Expiry - time).TotalDays / 365);
178  _greekValue = timeTillExpiry < 0 ? 0 : CalculateGreek(timeTillExpiry);
179  }
180 
181  return _greekValue;
182  }
183 
184  // Calculate the greek of the option
185  protected virtual decimal CalculateGreek(decimal timeTillExpiry)
186  {
187  throw new NotImplementedException("'CalculateGreek' method must be implemented");
188  }
189 
190  /// <summary>
191  /// Resets this indicator and all sub-indicators
192  /// </summary>
193  public override void Reset()
194  {
196  base.Reset();
197  }
198  }
199 }