Lean  $LEAN_TAG$
Delta.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 MathNet.Numerics.Distributions;
18 using Python.Runtime;
19 using QuantConnect.Data;
20 
22 {
23  /// <summary>
24  /// Option Delta indicator that calculate the delta of an option
25  /// </summary>
26  /// <remarks>sensitivity of option price relative to $1 of underlying change</remarks>
28  {
29  /// <summary>
30  /// Initializes a new instance of the Delta class
31  /// </summary>
32  /// <param name="name">The name of this indicator</param>
33  /// <param name="option">The option to be tracked</param>
34  /// <param name="riskFreeRateModel">Risk-free rate model</param>
35  /// <param name="dividendYieldModel">Dividend yield model</param>
36  /// <param name="mirrorOption">The mirror option for parity calculation</param>
37  /// <param name="optionModel">The option pricing model used to estimate Delta</param>
38  /// <param name="ivModel">The option pricing model used to estimate IV</param>
39  public Delta(string name, Symbol option, IRiskFreeInterestRateModel riskFreeRateModel, IDividendYieldModel dividendYieldModel, Symbol mirrorOption = null,
40  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
41  : base(name, option, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, ivModel)
42  {
43  }
44 
45  /// <summary>
46  /// Initializes a new instance of the Delta class
47  /// </summary>
48  /// <param name="option">The option to be tracked</param>
49  /// <param name="riskFreeRateModel">Risk-free rate model</param>
50  /// <param name="dividendYieldModel">Dividend yield model</param>
51  /// <param name="mirrorOption">The mirror option for parity calculation</param>
52  /// <param name="optionModel">The option pricing model used to estimate Delta</param>
53  /// <param name="ivModel">The option pricing model used to estimate IV</param>
54  public Delta(Symbol option, IRiskFreeInterestRateModel riskFreeRateModel, IDividendYieldModel dividendYieldModel, Symbol mirrorOption = null,
55  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
56  : this($"Delta({option},{mirrorOption},{optionModel})", option, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, ivModel)
57  {
58  }
59 
60  /// <summary>
61  /// Initializes a new instance of the Delta class
62  /// </summary>
63  /// <param name="name">The name of this indicator</param>
64  /// <param name="option">The option to be tracked</param>
65  /// <param name="riskFreeRateModel">Risk-free rate model</param>
66  /// <param name="dividendYieldModel">Dividend yield model</param>
67  /// <param name="mirrorOption">The mirror option for parity calculation</param>
68  /// <param name="optionModel">The option pricing model used to estimate Delta</param>
69  /// <param name="ivModel">The option pricing model used to estimate IV</param>
70  public Delta(string name, Symbol option, PyObject riskFreeRateModel, PyObject dividendYieldModel, Symbol mirrorOption = null,
71  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
72  : base(name, option, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, ivModel)
73  {
74  }
75 
76  /// <summary>
77  /// Initializes a new instance of the Delta class
78  /// </summary>
79  /// <param name="option">The option to be tracked</param>
80  /// <param name="riskFreeRateModel">Risk-free rate model</param>
81  /// <param name="dividendYieldModel">Dividend yield model</param>
82  /// <param name="mirrorOption">The mirror option for parity calculation</param>
83  /// <param name="optionModel">The option pricing model used to estimate Delta</param>
84  /// <param name="ivModel">The option pricing model used to estimate IV</param>
85  public Delta(Symbol option, PyObject riskFreeRateModel, PyObject dividendYieldModel, Symbol mirrorOption = null,
86  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
87  : this($"Delta({option},{mirrorOption},{optionModel})", option, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, ivModel)
88  {
89  }
90 
91  /// <summary>
92  /// Initializes a new instance of the Delta class
93  /// </summary>
94  /// <param name="name">The name of this indicator</param>
95  /// <param name="option">The option to be tracked</param>
96  /// <param name="riskFreeRateModel">Risk-free rate model</param>
97  /// <param name="dividendYield">Dividend yield, as a constant</param>
98  /// <param name="mirrorOption">The mirror option for parity calculation</param>
99  /// <param name="optionModel">The option pricing model used to estimate Delta</param>
100  /// <param name="ivModel">The option pricing model used to estimate IV</param>
101  public Delta(string name, Symbol option, IRiskFreeInterestRateModel riskFreeRateModel, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
102  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
103  : base(name, option, riskFreeRateModel, dividendYield, mirrorOption, optionModel, ivModel)
104  {
105  }
106 
107  /// <summary>
108  /// Initializes a new instance of the Delta class
109  /// </summary>
110  /// <param name="option">The option to be tracked</param>
111  /// <param name="riskFreeRateModel">Risk-free rate model</param>
112  /// <param name="dividendYield">Dividend yield, as a constant</param>
113  /// <param name="mirrorOption">The mirror option for parity calculation</param>
114  /// <param name="optionModel">The option pricing model used to estimate Delta</param>
115  /// <param name="ivModel">The option pricing model used to estimate IV</param>
116  public Delta(Symbol option, IRiskFreeInterestRateModel riskFreeRateModel, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
117  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
118  : this($"Delta({option},{mirrorOption},{optionModel})", option, riskFreeRateModel, dividendYield, mirrorOption, optionModel, ivModel)
119  {
120  }
121 
122  /// <summary>
123  /// Initializes a new instance of the Delta class
124  /// </summary>
125  /// <param name="name">The name of this indicator</param>
126  /// <param name="option">The option to be tracked</param>
127  /// <param name="riskFreeRateModel">Risk-free rate model</param>
128  /// <param name="dividendYield">Dividend yield, as a constant</param>
129  /// <param name="mirrorOption">The mirror option for parity calculation</param>
130  /// <param name="optionModel">The option pricing model used to estimate Delta</param>
131  /// <param name="ivModel">The option pricing model used to estimate IV</param>
132  public Delta(string name, Symbol option, PyObject riskFreeRateModel, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
133  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
134  : base(name, option, riskFreeRateModel, dividendYield, mirrorOption, optionModel, ivModel)
135  {
136  }
137 
138  /// <summary>
139  /// Initializes a new instance of the Delta class
140  /// </summary>
141  /// <param name="option">The option to be tracked</param>
142  /// <param name="riskFreeRateModel">Risk-free rate model</param>
143  /// <param name="dividendYield">Dividend yield, as a constant</param>
144  /// <param name="mirrorOption">The mirror option for parity calculation</param>
145  /// <param name="optionModel">The option pricing model used to estimate Delta</param>
146  /// <param name="ivModel">The option pricing model used to estimate IV</param>
147  public Delta(Symbol option, PyObject riskFreeRateModel, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
148  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
149  : this($"Delta({option},{mirrorOption},{optionModel})", option, riskFreeRateModel, dividendYield, mirrorOption, optionModel, ivModel)
150  {
151  }
152 
153  /// <summary>
154  /// Initializes a new instance of the Delta class
155  /// </summary>
156  /// <param name="name">The name of this indicator</param>
157  /// <param name="option">The option to be tracked</param>am>
158  /// <param name="riskFreeRate">Risk-free rate, as a constant</param>
159  /// <param name="dividendYield">Dividend yield, as a constant</param>
160  /// <param name="mirrorOption">The mirror option for parity calculation</param>
161  /// <param name="optionModel">The option pricing model used to estimate Delta</param>
162  /// <param name="ivModel">The option pricing model used to estimate IV</param>
163  public Delta(string name, Symbol option, decimal riskFreeRate = 0.05m, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
164  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
165  : base(name, option, riskFreeRate, dividendYield, mirrorOption, optionModel, ivModel)
166  {
167  }
168 
169  /// <summary>
170  /// Initializes a new instance of the Delta class
171  /// </summary>
172  /// <param name="option">The option to be tracked</param>
173  /// <param name="riskFreeRate">Risk-free rate, as a constant</param>
174  /// <param name="dividendYield">Dividend yield, as a constant</param>
175  /// <param name="mirrorOption">The mirror option for parity calculation</param>
176  /// <param name="optionModel">The option pricing model used to estimate Delta</param>
177  /// <param name="ivModel">The option pricing model used to estimate IV</param>
178  public Delta(Symbol option, decimal riskFreeRate = 0.05m, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
179  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
180  : this($"Delta({option},{mirrorOption},{optionModel})", option, riskFreeRate, dividendYield, mirrorOption, optionModel, ivModel)
181  {
182  }
183 
184  // Calculate the Delta of the option
185  protected override decimal CalculateGreek(decimal timeTillExpiry)
186  {
187  var math = OptionGreekIndicatorsHelper.DecimalMath;
188 
189  switch (_optionModel)
190  {
191  case OptionPricingModelType.BinomialCoxRossRubinstein:
192  var upFactor = math(Math.Exp, ImpliedVolatility * math(Math.Sqrt, timeTillExpiry / OptionGreekIndicatorsHelper.Steps));
193  if (upFactor == 1)
194  {
195  // provide a small step to estimate delta
196  upFactor = 1.00001m;
197  }
198 
199  var sU = UnderlyingPrice * upFactor;
200  var sD = UnderlyingPrice / upFactor;
201 
202  var fU = OptionGreekIndicatorsHelper.CRRTheoreticalPrice(
203  ImpliedVolatility, sU, Strike, timeTillExpiry, RiskFreeRate, DividendYield, Right);
204  var fD = OptionGreekIndicatorsHelper.CRRTheoreticalPrice(
205  ImpliedVolatility, sD, Strike, timeTillExpiry, RiskFreeRate, DividendYield, Right);
206 
207  return (fU - fD) / (sU - sD);
208 
209  case OptionPricingModelType.ForwardTree:
210  var discount = math(Math.Exp, (RiskFreeRate - DividendYield) * timeTillExpiry / OptionGreekIndicatorsHelper.Steps);
211  upFactor = math(Math.Exp, ImpliedVolatility * math(Math.Sqrt, timeTillExpiry / OptionGreekIndicatorsHelper.Steps)) * discount;
212  if (upFactor == 1)
213  {
214  // provide a small step to estimate delta
215  upFactor = 1.00001m;
216  }
217  var downFactor = math(Math.Exp, -ImpliedVolatility * math(Math.Sqrt, timeTillExpiry / OptionGreekIndicatorsHelper.Steps)) * discount;
218  if (downFactor == 1)
219  {
220  // provide a small step to estimate delta
221  downFactor = 0.99999m;
222  }
223 
224  sU = UnderlyingPrice * upFactor;
225  sD = UnderlyingPrice * downFactor;
226 
227  fU = OptionGreekIndicatorsHelper.ForwardTreeTheoreticalPrice(
228  ImpliedVolatility, sU, Strike, timeTillExpiry, RiskFreeRate, DividendYield, Right);
229  fD = OptionGreekIndicatorsHelper.ForwardTreeTheoreticalPrice(
230  ImpliedVolatility, sD, Strike, timeTillExpiry, RiskFreeRate, DividendYield, Right);
231 
232  return (fU - fD) / (sU - sD);
233 
234  case OptionPricingModelType.BlackScholes:
235  default:
236  var norm = new Normal();
237  var d1 = OptionGreekIndicatorsHelper.CalculateD1(UnderlyingPrice, Strike, timeTillExpiry, RiskFreeRate, DividendYield, ImpliedVolatility);
238 
239  decimal wholeShareDelta;
240  if (Right == OptionRight.Call)
241  {
242  wholeShareDelta = math(norm.CumulativeDistribution, d1);
243  }
244  else
245  {
246  wholeShareDelta = -math(norm.CumulativeDistribution, -d1);
247  }
248 
249  return wholeShareDelta * math(Math.Exp, -DividendYield * timeTillExpiry);
250  }
251  }
252  }
253 }