Lean  $LEAN_TAG$
Rho.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 Rho indicator that calculate the rho of an option
25  /// </summary>
26  /// <remarks>sensitivity of option price on interest rate changes</remarks>
28  {
29  /// <summary>
30  /// Initializes a new instance of the Rho 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 Rho</param>
38  /// <param name="ivModel">The option pricing model used to estimate IV</param>
39  public Rho(string name, Symbol option, IRiskFreeInterestRateModel riskFreeRateModel, IDividendYieldModel dividendYieldModel, Symbol mirrorOption = null,
40  OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null)
41  : base(name, option, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, ivModel)
42  {
43  }
44 
45  /// <summary>
46  /// Initializes a new instance of the Rho 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 Rho</param>
53  /// <param name="ivModel">The option pricing model used to estimate IV</param>
54  public Rho(Symbol option, IRiskFreeInterestRateModel riskFreeRateModel, IDividendYieldModel dividendYieldModel, Symbol mirrorOption = null,
55  OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null)
56  : this($"Rho({option},{mirrorOption},{GetOptionModel(optionModel, option.ID.OptionStyle)})", option, riskFreeRateModel,
57  dividendYieldModel, mirrorOption, optionModel, ivModel)
58  {
59  }
60 
61  /// <summary>
62  /// Initializes a new instance of the Rho class
63  /// </summary>
64  /// <param name="name">The name of this indicator</param>
65  /// <param name="option">The option to be tracked</param>
66  /// <param name="riskFreeRateModel">Risk-free rate model</param>
67  /// <param name="dividendYieldModel">Dividend yield model</param>
68  /// <param name="mirrorOption">The mirror option for parity calculation</param>
69  /// <param name="optionModel">The option pricing model used to estimate Rho</param>
70  /// <param name="ivModel">The option pricing model used to estimate IV</param>
71  public Rho(string name, Symbol option, PyObject riskFreeRateModel, PyObject dividendYieldModel, Symbol mirrorOption = null,
72  OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null)
73  : base(name, option, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, ivModel)
74  {
75  }
76 
77  /// <summary>
78  /// Initializes a new instance of the Rho class
79  /// </summary>
80  /// <param name="option">The option to be tracked</param>
81  /// <param name="riskFreeRateModel">Risk-free rate model</param>
82  /// <param name="dividendYieldModel">Dividend yield model</param>
83  /// <param name="mirrorOption">The mirror option for parity calculation</param>
84  /// <param name="optionModel">The option pricing model used to estimate Rho</param>
85  /// <param name="ivModel">The option pricing model used to estimate IV</param>
86  public Rho(Symbol option, PyObject riskFreeRateModel, PyObject dividendYieldModel, Symbol mirrorOption = null,
87  OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null)
88  : this($"Rho({option},{mirrorOption},{GetOptionModel(optionModel, option.ID.OptionStyle)})", option, riskFreeRateModel,
89  dividendYieldModel, mirrorOption, optionModel, ivModel)
90  {
91  }
92 
93  /// <summary>
94  /// Initializes a new instance of the Rho 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="dividendYield">Dividend yield, as a constant</param>
100  /// <param name="mirrorOption">The mirror option for parity calculation</param>
101  /// <param name="optionModel">The option pricing model used to estimate Rho</param>
102  /// <param name="ivModel">The option pricing model used to estimate IV</param>
103  public Rho(string name, Symbol option, IRiskFreeInterestRateModel riskFreeRateModel, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
104  OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null)
105  : base(name, option, riskFreeRateModel, dividendYield, mirrorOption, optionModel, ivModel)
106  {
107  }
108 
109  /// <summary>
110  /// Initializes a new instance of the Rho class
111  /// </summary>
112  /// <param name="option">The option to be tracked</param>
113  /// <param name="riskFreeRateModel">Risk-free rate model</param>
114  /// <param name="dividendYield">Dividend yield, as a constant</param>
115  /// <param name="mirrorOption">The mirror option for parity calculation</param>
116  /// <param name="optionModel">The option pricing model used to estimate Rho</param>
117  /// <param name="ivModel">The option pricing model used to estimate IV</param>
118  public Rho(Symbol option, IRiskFreeInterestRateModel riskFreeRateModel, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
119  OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null)
120  : this($"Rho({option},{mirrorOption},{GetOptionModel(optionModel, option.ID.OptionStyle)})", option, riskFreeRateModel,
121  dividendYield, mirrorOption, optionModel, ivModel)
122  {
123  }
124 
125  /// <summary>
126  /// Initializes a new instance of the Rho class
127  /// </summary>
128  /// <param name="name">The name of this indicator</param>
129  /// <param name="option">The option to be tracked</param>
130  /// <param name="riskFreeRateModel">Risk-free rate model</param>
131  /// <param name="dividendYield">Dividend yield, as a constant</param>
132  /// <param name="mirrorOption">The mirror option for parity calculation</param>
133  /// <param name="optionModel">The option pricing model used to estimate Rho</param>
134  /// <param name="ivModel">The option pricing model used to estimate IV</param>
135  public Rho(string name, Symbol option, PyObject riskFreeRateModel, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
136  OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null)
137  : base(name, option, riskFreeRateModel, dividendYield, mirrorOption, optionModel, ivModel)
138  {
139  }
140 
141  /// <summary>
142  /// Initializes a new instance of the Rho class
143  /// </summary>
144  /// <param name="option">The option to be tracked</param>
145  /// <param name="riskFreeRateModel">Risk-free rate model</param>
146  /// <param name="dividendYield">Dividend yield, as a constant</param>
147  /// <param name="mirrorOption">The mirror option for parity calculation</param>
148  /// <param name="optionModel">The option pricing model used to estimate Rho</param>
149  /// <param name="ivModel">The option pricing model used to estimate IV</param>
150  public Rho(Symbol option, PyObject riskFreeRateModel, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
151  OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null)
152  : this($"Rho({option},{mirrorOption},{GetOptionModel(optionModel, option.ID.OptionStyle)})", option, riskFreeRateModel,
153  dividendYield, mirrorOption, optionModel, ivModel)
154  {
155  }
156 
157  /// <summary>
158  /// Initializes a new instance of the Rho class
159  /// </summary>
160  /// <param name="name">The name of this indicator</param>
161  /// <param name="option">The option to be tracked</param>am>
162  /// <param name="riskFreeRate">Risk-free rate, as a constant</param>
163  /// <param name="dividendYield">Dividend yield, as a constant</param>
164  /// <param name="mirrorOption">The mirror option for parity calculation</param>
165  /// <param name="optionModel">The option pricing model used to estimate Rho</param>
166  /// <param name="ivModel">The option pricing model used to estimate IV</param>
167  public Rho(string name, Symbol option, decimal riskFreeRate = 0.05m, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
168  OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null)
169  : base(name, option, riskFreeRate, dividendYield, mirrorOption, optionModel, ivModel)
170  {
171  }
172 
173  /// <summary>
174  /// Initializes a new instance of the Rho class
175  /// </summary>
176  /// <param name="option">The option to be tracked</param>
177  /// <param name="riskFreeRate">Risk-free rate, as a constant</param>
178  /// <param name="dividendYield">Dividend yield, as a constant</param>
179  /// <param name="mirrorOption">The mirror option for parity calculation</param>
180  /// <param name="optionModel">The option pricing model used to estimate Rho</param>
181  /// <param name="ivModel">The option pricing model used to estimate IV</param>
182  public Rho(Symbol option, decimal riskFreeRate = 0.05m, decimal dividendYield = 0.0m, Symbol mirrorOption = null,
183  OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null)
184  : this($"Rho({option},{mirrorOption},{GetOptionModel(optionModel, option.ID.OptionStyle)})", option, riskFreeRate, dividendYield,
185  mirrorOption, optionModel, ivModel)
186  {
187  }
188 
189  /// <summary>
190  /// Calculate the Rho of the option
191  /// </summary>
192  protected override decimal CalculateGreek(decimal timeTillExpiry)
193  {
194  var underlyingPrice = (double)UnderlyingPrice.Current.Value;
195  var strike = (double)Strike;
196  var timeTillExpiryDouble = (double)timeTillExpiry;
197  var riskFreeRate = (double)RiskFreeRate.Current.Value;
198  var dividendYield = (double)DividendYield.Current.Value;
199  var iv = (double)ImpliedVolatility.Current.Value;
200 
201  double result;
202 
203  switch (_optionModel)
204  {
205  case OptionPricingModelType.BinomialCoxRossRubinstein:
206  case OptionPricingModelType.ForwardTree:
207  // finite differencing method with 0.01% risk free rate changes
208  var deltaRho = 0.0001;
209 
210  var newPrice = 0d;
211  var price = 0d;
212  if (_optionModel == OptionPricingModelType.BinomialCoxRossRubinstein)
213  {
214  newPrice = OptionGreekIndicatorsHelper.CRRTheoreticalPrice(iv, underlyingPrice, strike, timeTillExpiryDouble, riskFreeRate + deltaRho, dividendYield, Right);
215  price = OptionGreekIndicatorsHelper.CRRTheoreticalPrice(iv, underlyingPrice, strike, timeTillExpiryDouble, riskFreeRate, dividendYield, Right);
216  }
217  else if (_optionModel == OptionPricingModelType.ForwardTree)
218  {
219  newPrice = OptionGreekIndicatorsHelper.ForwardTreeTheoreticalPrice(iv, underlyingPrice, strike, timeTillExpiryDouble, riskFreeRate + deltaRho, dividendYield, Right);
220  price = OptionGreekIndicatorsHelper.ForwardTreeTheoreticalPrice(iv, underlyingPrice, strike, timeTillExpiryDouble, riskFreeRate, dividendYield, Right);
221  }
222 
223  result = (newPrice - price) / deltaRho / 100d;
224  break;
225 
226  case OptionPricingModelType.BlackScholes:
227  default:
228  var norm = new Normal();
229  var d1 = OptionGreekIndicatorsHelper.CalculateD1(underlyingPrice, strike, timeTillExpiryDouble, riskFreeRate, dividendYield, iv);
230  var d2 = OptionGreekIndicatorsHelper.CalculateD2(d1, iv, timeTillExpiryDouble);
231  var discount = Math.Exp(-riskFreeRate * timeTillExpiryDouble);
232 
233  if (Right == OptionRight.Call)
234  {
235  result = strike * timeTillExpiryDouble * discount * norm.CumulativeDistribution(d2) / 100d;
236  }
237  else
238  {
239  result = -strike * timeTillExpiryDouble * discount * norm.CumulativeDistribution(-d2) / 100d;
240  }
241  break;
242  }
243 
244  return Convert.ToDecimal(result);
245  }
246  }
247 }
248