Lean  $LEAN_TAG$
OptionPriceModels.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 QLNet;
17 using System;
18 using System.Linq;
19 using Fasterflect;
20 
22 {
23  using PricingEngineFuncEx = Func<Symbol, GeneralizedBlackScholesProcess, IPricingEngine>;
24 
25  /// <summary>
26  /// Static class contains definitions of major option pricing models that can be used in LEAN
27  /// </summary>
28  /// <remarks>
29  /// To introduce particular model into algorithm add the following line to the algorithm's Initialize() method:
30  ///
31  /// option.PriceModel = OptionPriceModels.BjerksundStensland(); // Option pricing model of choice
32  ///
33  /// </remarks>
34  public static class OptionPriceModels
35  {
36  private const int _timeStepsBinomial = 100;
37  private const int _timeStepsFD = 100;
38 
39  /// <summary>
40  /// Creates pricing engine by engine type name.
41  /// </summary>
42  /// <param name="priceEngineName">QL price engine name</param>
43  /// <param name="riskFree">The risk free rate</param>
44  /// <param name="allowedOptionStyles">List of option styles supported by the pricing model. It defaults to both American and European option styles</param>
45  /// <returns>New option price model instance of specific engine</returns>
46  public static IOptionPriceModel Create(string priceEngineName, decimal riskFree, OptionStyle[] allowedOptionStyles = null)
47  {
48  var type = AppDomain.CurrentDomain.GetAssemblies()
49  .Where(a => !a.IsDynamic)
50  .SelectMany(a => a.GetTypes())
51  .Where(s => s.Implements(typeof(IPricingEngine)))
52  .FirstOrDefault(t => t.FullName?.EndsWith(priceEngineName, StringComparison.InvariantCulture) == true);
53 
54  return new QLOptionPriceModel(process => (IPricingEngine)Activator.CreateInstance(type, process),
55  riskFreeRateEstimator: new ConstantQLRiskFreeRateEstimator(riskFree),
56  allowedOptionStyles: allowedOptionStyles);
57  }
58 
59  /// <summary>
60  /// Pricing engine for European vanilla options using analytical formula.
61  /// QuantLib reference: http://quantlib.org/reference/class_quant_lib_1_1_analytic_european_engine.html
62  /// </summary>
63  /// <returns>New option price model instance</returns>
65  {
66  return new QLOptionPriceModel(process => new AnalyticEuropeanEngine(process),
67  allowedOptionStyles: new[] { OptionStyle.European });
68  }
69 
70  /// <summary>
71  /// Barone-Adesi and Whaley pricing engine for American options (1987)
72  /// QuantLib reference: http://quantlib.org/reference/class_quant_lib_1_1_barone_adesi_whaley_approximation_engine.html
73  /// </summary>
74  /// <returns>New option price model instance</returns>
76  {
77  return new QLOptionPriceModel(process => new BaroneAdesiWhaleyApproximationEngine(process),
78  allowedOptionStyles: new[] { OptionStyle.American });
79  }
80 
81  /// <summary>
82  /// Bjerksund and Stensland pricing engine for American options (1993)
83  /// QuantLib reference: http://quantlib.org/reference/class_quant_lib_1_1_bjerksund_stensland_approximation_engine.html
84  /// </summary>
85  /// <returns>New option price model instance</returns>
87  {
88  return new QLOptionPriceModel(process => new BjerksundStenslandApproximationEngine(process),
89  allowedOptionStyles: new[] { OptionStyle.American });
90  }
91 
92  /// <summary>
93  /// Pricing engine for European vanilla options using integral approach.
94  /// QuantLib reference: http://quantlib.org/reference/class_quant_lib_1_1_integral_engine.html
95  /// </summary>
96  /// <returns>New option price model instance</returns>
97  public static IOptionPriceModel Integral()
98  {
99  return new QLOptionPriceModel(process => new IntegralEngine(process),
100  allowedOptionStyles: new[] { OptionStyle.European });
101  }
102 
103  /// <summary>
104  /// Pricing engine for European and American options using finite-differences.
105  /// QuantLib reference: http://quantlib.org/reference/class_quant_lib_1_1_f_d_european_engine.html
106  /// </summary>
107  /// <returns>New option price model instance</returns>
109  {
110  PricingEngineFuncEx pricingEngineFunc = (symbol, process) =>
111  symbol.ID.OptionStyle == OptionStyle.American
112  ? new FDAmericanEngine(process, _timeStepsFD, _timeStepsFD - 1)
113  : new FDEuropeanEngine(process, _timeStepsFD, _timeStepsFD - 1);
114 
115  return new QLOptionPriceModel(pricingEngineFunc);
116  }
117 
118  /// <summary>
119  /// Pricing engine for European and American vanilla options using binomial trees. Jarrow-Rudd model.
120  /// QuantLib reference: http://quantlib.org/reference/class_quant_lib_1_1_f_d_european_engine.html
121  /// </summary>
122  /// <returns>New option price model instance</returns>
124  {
125  return new QLOptionPriceModel(process => new BinomialVanillaEngine<JarrowRudd>(process, _timeStepsBinomial));
126  }
127 
128 
129  /// <summary>
130  /// Pricing engine for European and American vanilla options using binomial trees. Cox-Ross-Rubinstein(CRR) model.
131  /// QuantLib reference: http://quantlib.org/reference/class_quant_lib_1_1_f_d_european_engine.html
132  /// </summary>
133  /// <returns>New option price model instance</returns>
135  {
136  return new QLOptionPriceModel(process => new BinomialVanillaEngine<CoxRossRubinstein>(process, _timeStepsBinomial));
137  }
138 
139  /// <summary>
140  /// Pricing engine for European and American vanilla options using binomial trees. Additive Equiprobabilities model.
141  /// QuantLib reference: http://quantlib.org/reference/class_quant_lib_1_1_f_d_european_engine.html
142  /// </summary>
143  /// <returns>New option price model instance</returns>
145  {
146  return new QLOptionPriceModel(process => new BinomialVanillaEngine<AdditiveEQPBinomialTree>(process, _timeStepsBinomial));
147  }
148 
149  /// <summary>
150  /// Pricing engine for European and American vanilla options using binomial trees. Trigeorgis model.
151  /// QuantLib reference: http://quantlib.org/reference/class_quant_lib_1_1_f_d_european_engine.html
152  /// </summary>
153  /// <returns>New option price model instance</returns>
155  {
156  return new QLOptionPriceModel(process => new BinomialVanillaEngine<Trigeorgis>(process, _timeStepsBinomial));
157  }
158 
159  /// <summary>
160  /// Pricing engine for European and American vanilla options using binomial trees. Tian model.
161  /// QuantLib reference: http://quantlib.org/reference/class_quant_lib_1_1_f_d_european_engine.html
162  /// </summary>
163  /// <returns>New option price model instance</returns>
165  {
166  return new QLOptionPriceModel(process => new BinomialVanillaEngine<Tian>(process, _timeStepsBinomial));
167  }
168 
169  /// <summary>
170  /// Pricing engine for European and American vanilla options using binomial trees. Leisen-Reimer model.
171  /// QuantLib reference: http://quantlib.org/reference/class_quant_lib_1_1_f_d_european_engine.html
172  /// </summary>
173  /// <returns>New option price model instance</returns>
175  {
176  return new QLOptionPriceModel(process => new BinomialVanillaEngine<LeisenReimer>(process, _timeStepsBinomial));
177  }
178 
179  /// <summary>
180  /// Pricing engine for European and American vanilla options using binomial trees. Joshi model.
181  /// QuantLib reference: http://quantlib.org/reference/class_quant_lib_1_1_f_d_european_engine.html
182  /// </summary>
183  /// <returns>New option price model instance</returns>
185  {
186  return new QLOptionPriceModel(process => new BinomialVanillaEngine<Joshi4>(process, _timeStepsBinomial));
187  }
188 
189  }
190 }