Lean  $LEAN_TAG$
Gamma.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 Gamma indicator that calculate the gamma of an option
25  /// </summary>
26  /// <remarks>derivative of option price change relative to $1 underlying changes</remarks>
28  {
29  /// <summary>
30  /// Initializes a new instance of the Gamma 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 Gamma</param>
38  /// <param name="ivModel">The option pricing model used to estimate IV</param>
39  public Gamma(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 Gamma 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 Gamma</param>
53  /// <param name="ivModel">The option pricing model used to estimate IV</param>
54  public Gamma(Symbol option, IRiskFreeInterestRateModel riskFreeRateModel, IDividendYieldModel dividendYieldModel, Symbol mirrorOption = null,
55  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
56  : this($"Gamma({option},{mirrorOption},{optionModel})", option, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, ivModel)
57  {
58  }
59 
60  /// <summary>
61  /// Initializes a new instance of the Gamma 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 Gamma</param>
69  /// <param name="ivModel">The option pricing model used to estimate IV</param>
70  public Gamma(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 Gamma 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 Gamma</param>
84  /// <param name="ivModel">The option pricing model used to estimate IV</param>
85  public Gamma(Symbol option, PyObject riskFreeRateModel, PyObject dividendYieldModel, Symbol mirrorOption = null,
86  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
87  : this($"Gamma({option},{mirrorOption},{optionModel})", option, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, ivModel)
88  {
89  }
90 
91  /// <summary>
92  /// Initializes a new instance of the Gamma 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 Gamma</param>
100  /// <param name="ivModel">The option pricing model used to estimate IV</param>
101  public Gamma(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 Gamma 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 Gamma</param>
115  /// <param name="ivModel">The option pricing model used to estimate IV</param>
116  public Gamma(Symbol option, IRiskFreeInterestRateModel riskFreeRateModel, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
117  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
118  : this($"Gamma({option},{mirrorOption},{optionModel})", option, riskFreeRateModel, dividendYield, mirrorOption, optionModel, ivModel)
119  {
120  }
121 
122  /// <summary>
123  /// Initializes a new instance of the Gamma 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 Gamma</param>
131  /// <param name="ivModel">The option pricing model used to estimate IV</param>
132  public Gamma(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 Gamma 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 Gamma</param>
146  /// <param name="ivModel">The option pricing model used to estimate IV</param>
147  public Gamma(Symbol option, PyObject riskFreeRateModel, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
148  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
149  : this($"Gamma({option},{mirrorOption},{optionModel})", option, riskFreeRateModel, dividendYield, mirrorOption, optionModel, ivModel)
150  {
151  }
152 
153  /// <summary>
154  /// Initializes a new instance of the Gamma 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 Gamma</param>
162  /// <param name="ivModel">The option pricing model used to estimate IV</param>
163  public Gamma(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 Gamma 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 Gamma</param>
177  /// <param name="ivModel">The option pricing model used to estimate IV</param>
178  public Gamma(Symbol option, decimal riskFreeRate = 0.05m, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
179  OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null)
180  : this($"Gamma({option},{mirrorOption},{optionModel})", option, riskFreeRate, dividendYield, mirrorOption, optionModel, ivModel)
181  {
182  }
183 
184  // Calculate the Gamma of the option
185  protected override decimal CalculateGreek(decimal timeTillExpiry)
186  {
187  var math = OptionGreekIndicatorsHelper.DecimalMath;
188 
189  switch (_optionModel)
190  {
191  case OptionPricingModelType.BlackScholes:
192  var norm = new Normal();
194 
195  // allow at least 1% IV
196  return math(norm.Density, -d1) / UnderlyingPrice / Math.Max(ImpliedVolatility, 0.01m) / math(Math.Sqrt, timeTillExpiry);
197 
198  case OptionPricingModelType.BinomialCoxRossRubinstein:
199  case OptionPricingModelType.ForwardTree:
200  var upFactor = math(Math.Exp, ImpliedVolatility * math(Math.Sqrt, timeTillExpiry / OptionGreekIndicatorsHelper.Steps));
201  if (upFactor == 1)
202  {
203  // provide a small step to estimate gamma
204  upFactor = 1.0001m;
205  }
206 
207  // Finite differncing approach
208  var sU = UnderlyingPrice * upFactor * upFactor;
209  var sD = UnderlyingPrice / upFactor / upFactor;
210 
211  var fU = 0m;
212  var fM = 0m;
213  var fD = 0m;
214  if (_optionModel == OptionPricingModelType.BinomialCoxRossRubinstein)
215  {
216  fU = OptionGreekIndicatorsHelper.CRRTheoreticalPrice(ImpliedVolatility, sU, Strike, timeTillExpiry, RiskFreeRate, DividendYield, Right);
217  fM = OptionGreekIndicatorsHelper.CRRTheoreticalPrice(ImpliedVolatility, UnderlyingPrice, Strike, timeTillExpiry, RiskFreeRate, DividendYield, Right);
218  fD = OptionGreekIndicatorsHelper.CRRTheoreticalPrice(ImpliedVolatility, sD, Strike, timeTillExpiry, RiskFreeRate, DividendYield, Right);
219  }
220  else if (_optionModel == OptionPricingModelType.ForwardTree)
221  {
222  fU = OptionGreekIndicatorsHelper.ForwardTreeTheoreticalPrice(ImpliedVolatility, sU, Strike, timeTillExpiry, RiskFreeRate, DividendYield, Right);
223  fM = OptionGreekIndicatorsHelper.ForwardTreeTheoreticalPrice(ImpliedVolatility, UnderlyingPrice, Strike, timeTillExpiry, RiskFreeRate, DividendYield, Right);
224  fD = OptionGreekIndicatorsHelper.ForwardTreeTheoreticalPrice(ImpliedVolatility, sD, Strike, timeTillExpiry, RiskFreeRate, DividendYield, Right);
225  }
226 
227  var gammaU = (fU - fM) / (sU - UnderlyingPrice);
228  var gammaD = (fM - fD) / (UnderlyingPrice - sD);
229 
230  return (gammaU - gammaD) * 2 / (sU - sD);
231 
232  default:
233  throw new Exception("Unrecognized Option Pricing Model");
234  }
235  }
236  }
237 }