Skip to content

Commit

Permalink
Add OptionPricingModelType, as option for greeks & IV estimation
Browse files Browse the repository at this point in the history
  • Loading branch information
LouisSzeto committed Jan 9, 2024
1 parent 89a598a commit e479c36
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 14 deletions.
30 changes: 17 additions & 13 deletions Indicators/ImpliedVolatility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class ImpliedVolatility : BarIndicator, IIndicatorWarmUpPeriodProvider
private BaseDataConsolidator _consolidator;
private RateOfChange _roc;
private decimal _impliedVolatility;
private bool _binomial;
private OptionPricingModelType _optionModel;

/// <summary>
/// Gets the expiration time of the option
Expand Down Expand Up @@ -77,9 +77,10 @@ public class ImpliedVolatility : BarIndicator, IIndicatorWarmUpPeriodProvider
/// <param name="option">The option to be tracked</param>am>
/// <param name="riskFreeRate">The risk free rate</param>
/// <param name="period">The lookback period of historical volatility</param>
/// <param name="binomial">Should option priced under binomial model?</param>
public ImpliedVolatility(Symbol option, decimal riskFreeRate = 0.05m, int period = 252, bool binomial = false)
: this($"IV({option.Value},{riskFreeRate},{period},{binomial})", option, riskFreeRate, period, binomial)
/// <param name="optionModel">The option pricing model used to estimate IV</param>
public ImpliedVolatility(Symbol option, decimal riskFreeRate = 0.05m, int period = 252,
OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes)
: this($"IV({option.Value},{riskFreeRate},{period},{optionModel})", option, riskFreeRate, period, optionModel)
{
}

Expand All @@ -90,8 +91,9 @@ public ImpliedVolatility(Symbol option, decimal riskFreeRate = 0.05m, int period
/// <param name="option">The option to be tracked</param>
/// <param name="riskFreeRate">The risk free rate</param>
/// <param name="period">The lookback period of historical volatility</param>
/// <param name="binomial">Should option priced under binomial model?</param>
public ImpliedVolatility(string name, Symbol option, decimal riskFreeRate = 0.05m, int period = 252, bool binomial = false)
/// <param name="optionModel">The option pricing model used to estimate IV</param>
public ImpliedVolatility(string name, Symbol option, decimal riskFreeRate = 0.05m, int period = 252,
OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes)
: base(name)
{
var sid = option.ID;
Expand All @@ -103,7 +105,7 @@ public ImpliedVolatility(string name, Symbol option, decimal riskFreeRate = 0.05
_optionSymbol = option;
_underlyingSymbol = option.Underlying;
_roc = new(1);
_binomial = binomial;
_optionModel = optionModel;

Strike = sid.StrikePrice;
Expiry = sid.Date;
Expand Down Expand Up @@ -172,14 +174,16 @@ protected override decimal ComputeNextValue(IBaseDataBar input)

// Calculate the theoretical option price
private decimal TheoreticalPrice(decimal volatility, decimal spotPrice, decimal strikePrice, decimal timeToExpiration, decimal riskFreeRate,
OptionRight optionType, bool binomial = false)
OptionRight optionType, OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes)
{
if (binomial)
switch (optionModel)
{
return OptionGreekIndicatorsHelper.CRRTheoreticalPrice(volatility, spotPrice, strikePrice, timeToExpiration, riskFreeRate, optionType);
case OptionPricingModelType.BinomialCoxRossRubinstein:
return OptionGreekIndicatorsHelper.CRRTheoreticalPrice(volatility, spotPrice, strikePrice, timeToExpiration, riskFreeRate, optionType);
case OptionPricingModelType.BlackScholes:
default:
return OptionGreekIndicatorsHelper.BlackTheoreticalPrice(volatility, spotPrice, strikePrice, timeToExpiration, riskFreeRate, optionType);
}
// IV is calculated under BSM framework in default
return OptionGreekIndicatorsHelper.BlackTheoreticalPrice(volatility, spotPrice, strikePrice, timeToExpiration, riskFreeRate, optionType);
}

// Calculate the IV of the option
Expand All @@ -189,7 +193,7 @@ private decimal CalculateIV(DateTime time)
var spotPrice = UnderlyingPrice.Current.Value;
var timeToExpiration = Convert.ToDecimal((Expiry - time).TotalDays) / 365m;

Func<decimal, decimal> f = (vol) => TheoreticalPrice(vol, spotPrice, Strike, timeToExpiration, RiskFreeRate, Right, _binomial);
Func<decimal, decimal> f = (vol) => TheoreticalPrice(vol, spotPrice, Strike, timeToExpiration, RiskFreeRate, Right, _optionModel);
return OptionGreekIndicatorsHelper.BrentApproximation(f, price, 0.01m, 1.0m);
}

Expand Down
32 changes: 32 additions & 0 deletions Indicators/OptionPricingModelType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace QuantConnect.Indicators
{
/// <summary>
/// Defines different types of option pricing model
/// </summary>
public enum OptionPricingModelType
{
/// <summary>
/// Vanilla Black Scholes Model
/// </summary>
BlackScholes,
/// <summary>
/// The Cox-Ross-Rubinstein binomial tree model (CRR model)
/// </summary>
BinomialCoxRossRubinstein
}
}
2 changes: 1 addition & 1 deletion Tests/Indicators/ImpliedVolatilityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public void ComparesIVOnCRRModel(decimal price, decimal spotPrice, OptionRight r
{
// Under CRR framework
var symbol = Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, right, 450m, _reference.AddDays(expiry));
var indicator = new ImpliedVolatility(_symbol, 0.04m, binomial: true);
var indicator = new ImpliedVolatility(_symbol, 0.04m, optionModel: OptionPricingModelType.BinomialCoxRossRubinstein);

var optionTradeBar = new TradeBar(_reference, _symbol, price, price, price, price, 0m);
var spotTradeBar = new TradeBar(_reference, _underlying, spotPrice, spotPrice, spotPrice, spotPrice, 0m);
Expand Down

0 comments on commit e479c36

Please sign in to comment.