Greeks and Implied Volatility

Indicators

Introduction

This page explains the most popular Option indicators and how to use them with LEAN.

Parameters

The following table describes the arguments that the automatic Option indicators methods accept:

ArgumentData TypeDescriptionDefault Value
symbolSymbolThe contract to use when calculating the indicator values.
mirrorOptionmirror_optionSymbolThe mirror contract to use in parity type calculations.nullNone
riskFreeRaterisk_free_ratedecimalfloat The risk-free interest rate. If you don't provide a value, the default value is the US primary credit rate from the Interest Rate Provider Model. nullNone
dividendYielddividend_yielddecimalfloat The dividend yield rate. If you don't provide a value, the default value comes from the Dividend Yield Provider Model. nullNone
optionModeloption_modelOptionPricingModelType The Option pricing model that's used to calculate the Greeks. If you don't provide a value, the default value is OptionPricingModelType.BlackScholes for European Options or OptionPricingModelType.BinomialCoxRossRubinstein for American Options. nullNone
resolutionResolution The resolution of the indicator data. If you don't provide a value, the default value is the resolution of the subscription you have for the Option contract(s). nullNone

To perform implied volatility (IV) smoothing with a put-call pair, pass one of the contracts as the symbol argument and pass the other contract in the pair as the mirrorOptionmirror_option argument. The default IV smoothing method uses the one contract in the pair that's at-the-money or out-of-money to calculate the IV. To change the smoothing function, call the SetSmoothingFunctionset_smoothing_function method of the ImpliedVolatility class/property.

Several different Option pricing models are supported to calculate the IV and Greeks. The following table describes the OptionPricingModelType enumeration members:

Implied Volatility

Implied volatility, , is the market's expectation for the future volatility of an asset and is implied by the price of the assets's Options contracts. You can't observe it in the market but you can derive it from the price of an Option. For more information about implied volatility, see Implied Volatility.

Automatic Indicators

To create an automatic indicator for implied volatility, call the QCAlgorithm.IVQCAlgorithm.iv method with the Option contract Symbolsymbol object(s).

private Symbol _spy;
private List<Symbol> _impliedvolatilitys = new();

public override void Initialize()
{
    // Subscribe to the underlying
    _spy = AddEquity("SPY", dataNormalizationMode=DataNormalizationMode.Raw).Symbol;
    
    // Set up a scheduled event to select contract and create Greeks indicator daily before market open
    Schedule.On(
        DateRules.EveryDay(_spy),
        TimeRules.At(9, 0),
        UpdateContractsAndGreeks
    );
}

private void UpdateContractsAndGreeks()
{
    // Get all tradable option contracts
    var contractList = OptionChainProvider.GetOptionContractList(_spy, Time).ToList();
    // You can do further filtering here

    // Iterate all expiries
    foreach (var expiry in contractList.Select(x => x.ID.Date).Distinct())
    {
        var contractsByExpiry = contractList.Where(x => x.ID.Date == expiry).ToList();

        // Iterate all strike prices among the contracts of the same expiry
        foreach (var strike in contractsByExpiry.Select(x => x.ID.StrikePrice).Distinct())
        {
            var contractsByStrike = contractsByExpiry.Where(x => x.ID.StrikePrice == strike).ToList();

            // Get the call and put respectively
            var call = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Call);
            var put = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Put);
            // Skip if either call or put not exist
            if (call == null || put == null) continue;

            // Create subscriptions to both contract
            call = AddOptionContract(call).Symbol;
            put = AddOptionContract(put).Symbol;

            // Create the automatic-updating ImpliedVolatility indicator
            var callImpliedVolatility = IV(call, put);
            var putImpliedVolatility = IV(put, call);
            // Add to list of indicator
            _impliedvolatilitys.Add(callImpliedVolatility);
            _impliedvolatilitys.Add(putImpliedVolatility);
        }
    }
}

public override void OnData(Slice slice)
{
    // Access the ImpliedVolatility indicator of each contract
    foreach (var impliedvolatility in _impliedvolatilitys)
    {
        Log($"{impliedvolatility.OptionSymbol}::{impliedvolatility.Current.EndTime}::{impliedvolatility.Current.Value}");
    }
}
def initialize(self) -> None:
    # List to hold Greeks indicators
    self.impliedvolatilitys = []

    # Subscribe to the underlying
    self.spy = self.add_equity("SPY", data_normalization_mode=DataNormalizationMode.RAW).symbol

    # Set up a scheduled event to select contract and create Greeks indicator daily before market open
    self.schedule.on(
        self.date_rules.every_day(self.spy),
        self.time_rules.at(9, 0),
        self.update_contracts_and_greeks
    )

def update_contracts_and_greeks(self) -> None:
    # Get all tradable option contracts
    contract_list = self.option_chain_provider.get_option_contract_list(self.spy, self.time)
    # You can do further filtering here

    # Iterate all expiries
    for expiry in set(x.id.date for x in contract_list):
        contract_by_expiry = [x for x in contract_list if x.id.date == expiry]
        
        # Iterate all strike prices among the contracts of the same expiry
        for strike in set(x.id.strike_price for x in contract_by_expiry):
            contract_by_strike = [x for x in contract_by_expiry if x.id.strike_price == strike]
        
            # Get the call and put respectively
            call = next(filter(lambda x: x.id.option_right == OptionRight.CALL, contract_by_strike))
            put = next(filter(lambda x: x.id.option_right == OptionRight.PUT, contract_by_strike))
            # Skip if either call or put not exist
            if not call or not put:
                continue
            
            # Create subscriptions to both contract
            call = self.add_option_contract(call).symbol
            put = self.add_option_contract(put).symbol
        
            # Create the automatic-updating ImpliedVolatility indicator
            call_impliedvolatility = self.iv(call, put)
            put_impliedvolatility = self.iv(put, call)
            # Add to list of indicator
            self.impliedvolatilitys.extend([call_impliedvolatility, put_impliedvolatility])
        
def on_data(self, slice: Slice) -> None:
    # Access the ImpliedVolatility indicator of each contract
    for impliedvolatility in self.impliedvolatilitys:
        self.log(f"{impliedvolatility.option_symbol}::{impliedvolatility.current.end_time}::{impliedvolatility.current.value}")

The follow table describes the arguments that the IViv method accepts in addition to the standard parameters:

ArgumentData TypeDescriptionDefault Value
periodintThe number of periods to use when calculating the historical volatility for comparison.252

For more information about the IViv method, see Using IV Indicator.

Manual Indicators

To create a manual indicator for implied volatility, call the ImpliedVolatility constructor.

private Symbol _spy;
private DividendYieldProvider _dividendYieldProvider;
private List<Symbol> _impliedvolatilitys = new();
// Define the option pricing model
private readonly OptionPricingModelType _optionPricingModel = OptionPricingModelType.ForwardTree;

public override void Initialize()
{
    // Subscribe to the underlying
    _spy = AddEquity("SPY", dataNormalizationMode=DataNormalizationMode.Raw).Symbol;
    // Set up dividend yield provider for the underlying
    _dividendYieldProvider = new(_spy);
    
    // Set up a scheduled event to select contract and create Greeks indicator daily before market open
    Schedule.On(
        DateRules.EveryDay(_spy),
        TimeRules.At(9, 0),
        UpdateContractsAndGreeks
    );
}

private void UpdateContractsAndGreeks()
{
    // Get all tradable option contracts
    var contractList = OptionChainProvider.GetOptionContractList(_spy, Time).ToList();
    // You can do further filtering here

    // Iterate all expiries
    foreach (var expiry in contractList.Select(x => x.ID.Date).Distinct())
    {
        var contractsByExpiry = contractList.Where(x => x.ID.Date == expiry).ToList();

        // Iterate all strike prices among the contracts of the same expiry
        foreach (var strike in contractsByExpiry.Select(x => x.ID.StrikePrice).Distinct())
        {
            var contractsByStrike = contractsByExpiry.Where(x => x.ID.StrikePrice == strike).ToList();

            // Get the call and put respectively
            var call = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Call);
            var put = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Put);
            // Skip if either call or put not exist
            if (call == null || put == null) continue;

            // Create subscriptions to both contract
            call = AddOptionContract(call).Symbol;
            put = AddOptionContract(put).Symbol;

            // Create the manual-updating ImpliedVolatility indicator
            var callImpliedVolatility = new ImpliedVolatility(call, RiskFreeInterestRateModel, _dividendYieldProvider, put, _optionPricingModel);
            var putImpliedVolatility = new ImpliedVolatility(put, RiskFreeInterestRateModel, _dividendYieldProvider, call, _optionPricingModel);
            // Add to list of indicator
            _impliedvolatilitys.Add(callImpliedVolatility);
            _impliedvolatilitys.Add(putImpliedVolatility);
        }
    }
}

public override void OnData(Slice slice)
{
    // Iterate indicators
    foreach (var impliedvolatilityIndicator in _impliedvolatilitys)
    {
        var option = impliedvolatilityIndicator.OptionSymbol;
        var mirrorRight = option.ID.OptionRight == OptionRight.Call ? OptionRight.Put : OptionRight.Call;
        var mirror = QuantConnect.Symbol.CreateOption(option.Underlying.Value, Market.USA, OptionStyle.American, mirrorRight, option.ID.StrikePrice, option.ID.Date);

        // Check if price data available for both contracts and the underlying
        if (slice.QuoteBars.ContainsKey(option) && slice.QuoteBars.ContainsKey(mirror) && slice.Bars.ContainsKey(_spy))
        {
            // Update the indicator
            impliedvolatilityIndicator.Update(new IndicatorDataPoint(option, slice.QuoteBars[option].EndTime, slice.QuoteBars[option].Close));
            impliedvolatilityIndicator.Update(new IndicatorDataPoint(mirror, slice.QuoteBars[mirror].EndTime, slice.QuoteBars[mirror].Close));
            impliedvolatilityIndicator.Update(new IndicatorDataPoint(_spy, slice.Bars[_spy].EndTime, slice.Bars[_spy].Close));

            // Get the current value
            var impliedvolatility = impliedvolatilityIndicator.Current.Value;
        }
    }
}
def initialize(self) -> None:
    # List to hold Greeks indicators
    self.impliedvolatilitys = []

    # Subscribe to the underlying
    self.spy = self.add_equity("SPY", data_normalization_mode=DataNormalizationMode.RAW).symbol
    # Set up dividend yield provider for the underlying
    self.dividend_yield_provider = DividendYieldProvider(self.spy)
    # Define the option pricing model
    self.option_pricing_model = OptionPricingModelType.FORWARD_TREE

    # Set up a scheduled event to select contract and create Greeks indicator daily before market open
    self.schedule.on(
        self.date_rules.every_day(self.spy),
        self.time_rules.at(9, 0),
        self.update_contracts_and_greeks
    )

def update_contracts_and_greeks(self) -> None:
    # Get all tradable option contracts
    contract_list = self.option_chain_provider.get_option_contract_list(self.spy, self.time)
    # You can do further filtering here

    # Iterate all expiries
    for expiry in set(x.id.date for x in contract_list):
        contract_by_expiry = [x for x in contract_list if x.id.date == expiry]
        
        # Iterate all strike prices among the contracts of the same expiry
        for strike in set(x.id.strike_price for x in contract_by_expiry):
            contract_by_strike = [x for x in contract_by_expiry if x.id.strike_price == strike]
        
            # Get the call and put respectively
            call = next(filter(lambda x: x.id.option_right == OptionRight.CALL, contract_by_strike))
            put = next(filter(lambda x: x.id.option_right == OptionRight.PUT, contract_by_strike))
            # Skip if either call or put not exist
            if not call or not put:
                continue
            
            # Create subscriptions to both contract
            call = self.add_option_contract(call).symbol
            put = self.add_option_contract(put).symbol
        
            # Create the manual-updating ImpliedVolatility indicator
            call_impliedvolatility = ImpliedVolatility(call, self.risk_free_interest_rate_model, self.dividend_yield_provider, put, self.option_pricing_model)
            put_impliedvolatility = ImpliedVolatility(put, self.risk_free_interest_rate_model, self.dividend_yield_provider, call, self.option_pricing_model)
            # Add to list of indicator
            self.impliedvolatilitys.extend([call_impliedvolatility, put_impliedvolatility])
        
def on_data(self, slice: Slice) -> None:
    # Iterate indicators
    for impliedvolatility_indicator in self.impliedvolatilitys:
        option = impliedvolatility_indicator.option_symbol
        mirror_right = OptionRight.Call if option.id.option_right == OptionRight.PUT else OptionRight.PUT
        mirror = Symbol.create_option(option.underlying.value, Market.USA, OptionStyle.AMERICAN, mirror_right, option.id.strike_price, option.id.date)
    
        # Check if price data available for both contracts and the underlying
        if option in slice.quote_bars and mirror in slice.quote_bars and self.spy in slice.bars:
            # Update the indicator
            impliedvolatility_indicator.update(IndicatorDataPoint(option, slice.quote_bars[option].end_time, slice.quote_bars[option].close))
impliedvolatility_indicator.update(IndicatorDataPoint(mirror, slice.quote_bars[mirror].end_time, slice.quote_bars[mirror].close)) impliedvolatility_indicator.update(IndicatorDataPoint(self.spy, slice.bars[self.spy].end_time, slice.bars[self.spy].close)) # Get the current value impliedvolatility = impliedvolatility_indicator.current.value;

For more information about the ImpliedVolatility constructor, see Using IV Indicator.

Volatility Smoothing

The default IV smoothing method uses the one contract in the pair that's at-the-money or out-of-money to calculate the IV. To change the smoothing function, pass a mirrorOptionmirror_option argument to the IViv method or ImpliedVolatility constructor and then call the SetSmoothingFunctionset_smoothing_function method of the resulting ImpliedVolatility object. The follow table describes the arguments of the custom function:

ArgumentData TypeDescription
ivdecimalfloatThe IV of the Option contract.
mirrorIvmirror_ivdecimalfloatThe IV of the mirror Option contract.

The method must return a decimalfloat as the smoothened IV.

private ImpliedVolatility _iv;

public override void Initialize()
{
    var option = QuantConnect.Symbol.CreateOption("AAPL", Market.USA, OptionStyle.American, OptionRight.Put, 505m, new DateTime(2014, 6, 27));
    AddOptionContract(option);

    var mirrorOption = QuantConnect.Symbol.CreateOption("AAPL", Market.USA, OptionStyle.American, OptionRight.Call, 505m, new DateTime(2014, 6, 27));
    AddOptionContract(mirrorOption);

    _iv = IV(option, mirrorOption);
    // example: take average of the call-put pair
    _iv.SetSmoothingFunction((iv, mirrorIv) => (iv + mirrorIv) * 0.5m);
}
def initialize(self):
    option = Symbol.create_option("AAPL", Market.USA, OptionStyle.AMERICAN, OptionRight.PUT, 505, datetime(2014, 6, 27))
    self.add_option_contract(option)

    mirror_option = Symbol.create_option("AAPL", Market.USA, OptionStyle.AMERICAN, OptionRight.CALL, 505, datetime(2014, 6, 27))
    self.add_option_contract(mirror_option)

    self._iv = self.iv(option, mirror_option)
    # Example: The average of the call-put pair.
    self._iv.set_smoothing_function(lambda iv, mirror_iv: (iv + mirror_iv) * 0.5)

Delta

Delta, , is the rate of change of the Option price with respect to the price of the underlying asset. It measures the first-order sensitivity of the price to a movement in underlying price. For example, an Option delta of 0.4 means that if the underlying asset moves by 1%, then the value of the Option moves by 0.4 × 1% = 0.4%. For more information about delta, see Delta.

Automatic Indicators

To create an automatic indicator for delta, call the QCAlgorithm.DQCAlgorithm.d method with the Option contract Symbolsymbol object(s).

private Symbol _spy;
private List<Symbol> _deltas = new();

public override void Initialize()
{
    // Subscribe to the underlying
    _spy = AddEquity("SPY", dataNormalizationMode=DataNormalizationMode.Raw).Symbol;
    
    // Set up a scheduled event to select contract and create Greeks indicator daily before market open
    Schedule.On(
        DateRules.EveryDay(_spy),
        TimeRules.At(9, 0),
        UpdateContractsAndGreeks
    );
}

private void UpdateContractsAndGreeks()
{
    // Get all tradable option contracts
    var contractList = OptionChainProvider.GetOptionContractList(_spy, Time).ToList();
    // You can do further filtering here

    // Iterate all expiries
    foreach (var expiry in contractList.Select(x => x.ID.Date).Distinct())
    {
        var contractsByExpiry = contractList.Where(x => x.ID.Date == expiry).ToList();

        // Iterate all strike prices among the contracts of the same expiry
        foreach (var strike in contractsByExpiry.Select(x => x.ID.StrikePrice).Distinct())
        {
            var contractsByStrike = contractsByExpiry.Where(x => x.ID.StrikePrice == strike).ToList();

            // Get the call and put respectively
            var call = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Call);
            var put = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Put);
            // Skip if either call or put not exist
            if (call == null || put == null) continue;

            // Create subscriptions to both contract
            call = AddOptionContract(call).Symbol;
            put = AddOptionContract(put).Symbol;

            // Create the automatic-updating Delta indicator
            var callDelta = D(call, put);
            var putDelta = D(put, call);
            // Add to list of indicator
            _deltas.Add(callDelta);
            _deltas.Add(putDelta);
        }
    }
}

public override void OnData(Slice slice)
{
    // Access the Delta indicator of each contract
    foreach (var delta in _deltas)
    {
        Log($"{delta.OptionSymbol}::{delta.Current.EndTime}::{delta.Current.Value}");
    }
}
def initialize(self) -> None:
    # List to hold Greeks indicators
    self.deltas = []

    # Subscribe to the underlying
    self.spy = self.add_equity("SPY", data_normalization_mode=DataNormalizationMode.RAW).symbol

    # Set up a scheduled event to select contract and create Greeks indicator daily before market open
    self.schedule.on(
        self.date_rules.every_day(self.spy),
        self.time_rules.at(9, 0),
        self.update_contracts_and_greeks
    )

def update_contracts_and_greeks(self) -> None:
    # Get all tradable option contracts
    contract_list = self.option_chain_provider.get_option_contract_list(self.spy, self.time)
    # You can do further filtering here

    # Iterate all expiries
    for expiry in set(x.id.date for x in contract_list):
        contract_by_expiry = [x for x in contract_list if x.id.date == expiry]
        
        # Iterate all strike prices among the contracts of the same expiry
        for strike in set(x.id.strike_price for x in contract_by_expiry):
            contract_by_strike = [x for x in contract_by_expiry if x.id.strike_price == strike]
        
            # Get the call and put respectively
            call = next(filter(lambda x: x.id.option_right == OptionRight.CALL, contract_by_strike))
            put = next(filter(lambda x: x.id.option_right == OptionRight.PUT, contract_by_strike))
            # Skip if either call or put not exist
            if not call or not put:
                continue
            
            # Create subscriptions to both contract
            call = self.add_option_contract(call).symbol
            put = self.add_option_contract(put).symbol
        
            # Create the automatic-updating Delta indicator
            call_delta = self.d(call, put)
            put_delta = self.d(put, call)
            # Add to list of indicator
            self.deltas.extend([call_delta, put_delta])
        
def on_data(self, slice: Slice) -> None:
    # Access the Delta indicator of each contract
    for delta in self.deltas:
        self.log(f"{delta.option_symbol}::{delta.current.end_time}::{delta.current.value}")

The follow table describes the arguments that the D method accepts in addition to the standard parameters:

ArgumentData TypeDescriptionDefault Value
ivModeliv_modelOptionPricingModelType The Option pricing model to use to estimate the IV when calculating Delta. If you don't provide a value, the default value is to match the optionModeloption_model parameter. nullNone

For more information about the D method, see Using D Indicator.

Manual Indicators

To create a manual indicator for delta, call the Delta constructor.

private Symbol _spy;
private DividendYieldProvider _dividendYieldProvider;
private List<Symbol> _deltas = new();
// Define the option pricing model
private readonly OptionPricingModelType _optionPricingModel = OptionPricingModelType.ForwardTree;

public override void Initialize()
{
    // Subscribe to the underlying
    _spy = AddEquity("SPY", dataNormalizationMode=DataNormalizationMode.Raw).Symbol;
    // Set up dividend yield provider for the underlying
    _dividendYieldProvider = new(_spy);
    
    // Set up a scheduled event to select contract and create Greeks indicator daily before market open
    Schedule.On(
        DateRules.EveryDay(_spy),
        TimeRules.At(9, 0),
        UpdateContractsAndGreeks
    );
}

private void UpdateContractsAndGreeks()
{
    // Get all tradable option contracts
    var contractList = OptionChainProvider.GetOptionContractList(_spy, Time).ToList();
    // You can do further filtering here

    // Iterate all expiries
    foreach (var expiry in contractList.Select(x => x.ID.Date).Distinct())
    {
        var contractsByExpiry = contractList.Where(x => x.ID.Date == expiry).ToList();

        // Iterate all strike prices among the contracts of the same expiry
        foreach (var strike in contractsByExpiry.Select(x => x.ID.StrikePrice).Distinct())
        {
            var contractsByStrike = contractsByExpiry.Where(x => x.ID.StrikePrice == strike).ToList();

            // Get the call and put respectively
            var call = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Call);
            var put = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Put);
            // Skip if either call or put not exist
            if (call == null || put == null) continue;

            // Create subscriptions to both contract
            call = AddOptionContract(call).Symbol;
            put = AddOptionContract(put).Symbol;

            // Create the manual-updating Delta indicator
            var callDelta = new Delta(call, RiskFreeInterestRateModel, _dividendYieldProvider, put, _optionPricingModel);
            var putDelta = new Delta(put, RiskFreeInterestRateModel, _dividendYieldProvider, call, _optionPricingModel);
            // Add to list of indicator
            _deltas.Add(callDelta);
            _deltas.Add(putDelta);
        }
    }
}

public override void OnData(Slice slice)
{
    // Iterate indicators
    foreach (var deltaIndicator in _deltas)
    {
        var option = deltaIndicator.OptionSymbol;
        var mirrorRight = option.ID.OptionRight == OptionRight.Call ? OptionRight.Put : OptionRight.Call;
        var mirror = QuantConnect.Symbol.CreateOption(option.Underlying.Value, Market.USA, OptionStyle.American, mirrorRight, option.ID.StrikePrice, option.ID.Date);

        // Check if price data available for both contracts and the underlying
        if (slice.QuoteBars.ContainsKey(option) && slice.QuoteBars.ContainsKey(mirror) && slice.Bars.ContainsKey(_spy))
        {
            // Update the indicator
            deltaIndicator.Update(new IndicatorDataPoint(option, slice.QuoteBars[option].EndTime, slice.QuoteBars[option].Close));
            deltaIndicator.Update(new IndicatorDataPoint(mirror, slice.QuoteBars[mirror].EndTime, slice.QuoteBars[mirror].Close));
            deltaIndicator.Update(new IndicatorDataPoint(_spy, slice.Bars[_spy].EndTime, slice.Bars[_spy].Close));

            // Get the current value
            var delta = deltaIndicator.Current.Value;
        }
    }
}
def initialize(self) -> None:
    # List to hold Greeks indicators
    self.deltas = []

    # Subscribe to the underlying
    self.spy = self.add_equity("SPY", data_normalization_mode=DataNormalizationMode.RAW).symbol
    # Set up dividend yield provider for the underlying
    self.dividend_yield_provider = DividendYieldProvider(self.spy)
    # Define the option pricing model
    self.option_pricing_model = OptionPricingModelType.FORWARD_TREE

    # Set up a scheduled event to select contract and create Greeks indicator daily before market open
    self.schedule.on(
        self.date_rules.every_day(self.spy),
        self.time_rules.at(9, 0),
        self.update_contracts_and_greeks
    )

def update_contracts_and_greeks(self) -> None:
    # Get all tradable option contracts
    contract_list = self.option_chain_provider.get_option_contract_list(self.spy, self.time)
    # You can do further filtering here

    # Iterate all expiries
    for expiry in set(x.id.date for x in contract_list):
        contract_by_expiry = [x for x in contract_list if x.id.date == expiry]
        
        # Iterate all strike prices among the contracts of the same expiry
        for strike in set(x.id.strike_price for x in contract_by_expiry):
            contract_by_strike = [x for x in contract_by_expiry if x.id.strike_price == strike]
        
            # Get the call and put respectively
            call = next(filter(lambda x: x.id.option_right == OptionRight.CALL, contract_by_strike))
            put = next(filter(lambda x: x.id.option_right == OptionRight.PUT, contract_by_strike))
            # Skip if either call or put not exist
            if not call or not put:
                continue
            
            # Create subscriptions to both contract
            call = self.add_option_contract(call).symbol
            put = self.add_option_contract(put).symbol
        
            # Create the manual-updating Delta indicator
            call_delta = Delta(call, self.risk_free_interest_rate_model, self.dividend_yield_provider, put, self.option_pricing_model)
            put_delta = Delta(put, self.risk_free_interest_rate_model, self.dividend_yield_provider, call, self.option_pricing_model)
            # Add to list of indicator
            self.deltas.extend([call_delta, put_delta])
        
def on_data(self, slice: Slice) -> None:
    # Iterate indicators
    for delta_indicator in self.deltas:
        option = delta_indicator.option_symbol
        mirror_right = OptionRight.Call if option.id.option_right == OptionRight.PUT else OptionRight.PUT
        mirror = Symbol.create_option(option.underlying.value, Market.USA, OptionStyle.AMERICAN, mirror_right, option.id.strike_price, option.id.date)
    
        # Check if price data available for both contracts and the underlying
        if option in slice.quote_bars and mirror in slice.quote_bars and self.spy in slice.bars:
            # Update the indicator
            delta_indicator.update(IndicatorDataPoint(option, slice.quote_bars[option].end_time, slice.quote_bars[option].close))
delta_indicator.update(IndicatorDataPoint(mirror, slice.quote_bars[mirror].end_time, slice.quote_bars[mirror].close)) delta_indicator.update(IndicatorDataPoint(self.spy, slice.bars[self.spy].end_time, slice.bars[self.spy].close)) # Get the current value delta = delta_indicator.current.value;

For more information about the Delta constructor, see Using D Indicator.

Volatility Smoothing

The default IV smoothing method uses the one contract in the pair that's at-the-money or out-of-money to calculate the IV. To change the smoothing function, pass a mirrorOptionmirror_option argument to the indicator method or constructor and then call the SetSmoothingFunctionset_smoothing_function method of the ImpliedVolatility property of the indicator.

// Example: Average IV of the call-put pair.
_delta.ImpliedVolatility.SetSmoothingFunction((iv, mirrorIv) => (iv + mirrorIv) * 0.5m);
# Example: Average IV of the call-put pair.
self._delta.implied_volatility.set_smoothing_function(lambda iv, mirror_iv: (iv + mirror_iv) * 0.5)

For more information about the IV smoothing function, see Implied Volatility.

Gamma

Gamma, , is the rate of change of the portfolio's delta with respect to the underlying asset's price. It represents the second-order sensitivity of the Option to a movement in the underlying asset's price. For more information about Gamma, see Gamma.

Automatic Indicators

To create an automatic indicator for gamma, call the QCAlgorithm.GQCAlgorithm.g method with the Option contract Symbolsymbol object(s).

private Symbol _spy;
private List<Symbol> _gammas = new();

public override void Initialize()
{
    // Subscribe to the underlying
    _spy = AddEquity("SPY", dataNormalizationMode=DataNormalizationMode.Raw).Symbol;
    
    // Set up a scheduled event to select contract and create Greeks indicator daily before market open
    Schedule.On(
        DateRules.EveryDay(_spy),
        TimeRules.At(9, 0),
        UpdateContractsAndGreeks
    );
}

private void UpdateContractsAndGreeks()
{
    // Get all tradable option contracts
    var contractList = OptionChainProvider.GetOptionContractList(_spy, Time).ToList();
    // You can do further filtering here

    // Iterate all expiries
    foreach (var expiry in contractList.Select(x => x.ID.Date).Distinct())
    {
        var contractsByExpiry = contractList.Where(x => x.ID.Date == expiry).ToList();

        // Iterate all strike prices among the contracts of the same expiry
        foreach (var strike in contractsByExpiry.Select(x => x.ID.StrikePrice).Distinct())
        {
            var contractsByStrike = contractsByExpiry.Where(x => x.ID.StrikePrice == strike).ToList();

            // Get the call and put respectively
            var call = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Call);
            var put = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Put);
            // Skip if either call or put not exist
            if (call == null || put == null) continue;

            // Create subscriptions to both contract
            call = AddOptionContract(call).Symbol;
            put = AddOptionContract(put).Symbol;

            // Create the automatic-updating Gamma indicator
            var callGamma = G(call, put);
            var putGamma = G(put, call);
            // Add to list of indicator
            _gammas.Add(callGamma);
            _gammas.Add(putGamma);
        }
    }
}

public override void OnData(Slice slice)
{
    // Access the Gamma indicator of each contract
    foreach (var gamma in _gammas)
    {
        Log($"{gamma.OptionSymbol}::{gamma.Current.EndTime}::{gamma.Current.Value}");
    }
}
def initialize(self) -> None:
    # List to hold Greeks indicators
    self.gammas = []

    # Subscribe to the underlying
    self.spy = self.add_equity("SPY", data_normalization_mode=DataNormalizationMode.RAW).symbol

    # Set up a scheduled event to select contract and create Greeks indicator daily before market open
    self.schedule.on(
        self.date_rules.every_day(self.spy),
        self.time_rules.at(9, 0),
        self.update_contracts_and_greeks
    )

def update_contracts_and_greeks(self) -> None:
    # Get all tradable option contracts
    contract_list = self.option_chain_provider.get_option_contract_list(self.spy, self.time)
    # You can do further filtering here

    # Iterate all expiries
    for expiry in set(x.id.date for x in contract_list):
        contract_by_expiry = [x for x in contract_list if x.id.date == expiry]
        
        # Iterate all strike prices among the contracts of the same expiry
        for strike in set(x.id.strike_price for x in contract_by_expiry):
            contract_by_strike = [x for x in contract_by_expiry if x.id.strike_price == strike]
        
            # Get the call and put respectively
            call = next(filter(lambda x: x.id.option_right == OptionRight.CALL, contract_by_strike))
            put = next(filter(lambda x: x.id.option_right == OptionRight.PUT, contract_by_strike))
            # Skip if either call or put not exist
            if not call or not put:
                continue
            
            # Create subscriptions to both contract
            call = self.add_option_contract(call).symbol
            put = self.add_option_contract(put).symbol
        
            # Create the automatic-updating Gamma indicator
            call_gamma = self.g(call, put)
            put_gamma = self.g(put, call)
            # Add to list of indicator
            self.gammas.extend([call_gamma, put_gamma])
        
def on_data(self, slice: Slice) -> None:
    # Access the Gamma indicator of each contract
    for gamma in self.gammas:
        self.log(f"{gamma.option_symbol}::{gamma.current.end_time}::{gamma.current.value}")

The follow table describes the arguments that the G method accepts in addition to the standard parameters:

ArgumentData TypeDescriptionDefault Value
ivModeliv_modelOptionPricingModelType The Option pricing model to use to estimate the IV when calculating Gamma. If you don't provide a value, the default value is to match the optionModeloption_model parameter. nullNone

For more information about the G method, see Using G Indicator.

Manual Indicators

To create a manual indicator for gamma, call the Gamma constructor.

private Symbol _spy;
private DividendYieldProvider _dividendYieldProvider;
private List<Symbol> _gammas = new();
// Define the option pricing model
private readonly OptionPricingModelType _optionPricingModel = OptionPricingModelType.ForwardTree;

public override void Initialize()
{
    // Subscribe to the underlying
    _spy = AddEquity("SPY", dataNormalizationMode=DataNormalizationMode.Raw).Symbol;
    // Set up dividend yield provider for the underlying
    _dividendYieldProvider = new(_spy);
    
    // Set up a scheduled event to select contract and create Greeks indicator daily before market open
    Schedule.On(
        DateRules.EveryDay(_spy),
        TimeRules.At(9, 0),
        UpdateContractsAndGreeks
    );
}

private void UpdateContractsAndGreeks()
{
    // Get all tradable option contracts
    var contractList = OptionChainProvider.GetOptionContractList(_spy, Time).ToList();
    // You can do further filtering here

    // Iterate all expiries
    foreach (var expiry in contractList.Select(x => x.ID.Date).Distinct())
    {
        var contractsByExpiry = contractList.Where(x => x.ID.Date == expiry).ToList();

        // Iterate all strike prices among the contracts of the same expiry
        foreach (var strike in contractsByExpiry.Select(x => x.ID.StrikePrice).Distinct())
        {
            var contractsByStrike = contractsByExpiry.Where(x => x.ID.StrikePrice == strike).ToList();

            // Get the call and put respectively
            var call = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Call);
            var put = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Put);
            // Skip if either call or put not exist
            if (call == null || put == null) continue;

            // Create subscriptions to both contract
            call = AddOptionContract(call).Symbol;
            put = AddOptionContract(put).Symbol;

            // Create the manual-updating Gamma indicator
            var callGamma = new Gamma(call, RiskFreeInterestRateModel, _dividendYieldProvider, put, _optionPricingModel);
            var putGamma = new Gamma(put, RiskFreeInterestRateModel, _dividendYieldProvider, call, _optionPricingModel);
            // Add to list of indicator
            _gammas.Add(callGamma);
            _gammas.Add(putGamma);
        }
    }
}

public override void OnData(Slice slice)
{
    // Iterate indicators
    foreach (var gammaIndicator in _gammas)
    {
        var option = gammaIndicator.OptionSymbol;
        var mirrorRight = option.ID.OptionRight == OptionRight.Call ? OptionRight.Put : OptionRight.Call;
        var mirror = QuantConnect.Symbol.CreateOption(option.Underlying.Value, Market.USA, OptionStyle.American, mirrorRight, option.ID.StrikePrice, option.ID.Date);

        // Check if price data available for both contracts and the underlying
        if (slice.QuoteBars.ContainsKey(option) && slice.QuoteBars.ContainsKey(mirror) && slice.Bars.ContainsKey(_spy))
        {
            // Update the indicator
            gammaIndicator.Update(new IndicatorDataPoint(option, slice.QuoteBars[option].EndTime, slice.QuoteBars[option].Close));
            gammaIndicator.Update(new IndicatorDataPoint(mirror, slice.QuoteBars[mirror].EndTime, slice.QuoteBars[mirror].Close));
            gammaIndicator.Update(new IndicatorDataPoint(_spy, slice.Bars[_spy].EndTime, slice.Bars[_spy].Close));

            // Get the current value
            var gamma = gammaIndicator.Current.Value;
        }
    }
}
def initialize(self) -> None:
    # List to hold Greeks indicators
    self.gammas = []

    # Subscribe to the underlying
    self.spy = self.add_equity("SPY", data_normalization_mode=DataNormalizationMode.RAW).symbol
    # Set up dividend yield provider for the underlying
    self.dividend_yield_provider = DividendYieldProvider(self.spy)
    # Define the option pricing model
    self.option_pricing_model = OptionPricingModelType.FORWARD_TREE

    # Set up a scheduled event to select contract and create Greeks indicator daily before market open
    self.schedule.on(
        self.date_rules.every_day(self.spy),
        self.time_rules.at(9, 0),
        self.update_contracts_and_greeks
    )

def update_contracts_and_greeks(self) -> None:
    # Get all tradable option contracts
    contract_list = self.option_chain_provider.get_option_contract_list(self.spy, self.time)
    # You can do further filtering here

    # Iterate all expiries
    for expiry in set(x.id.date for x in contract_list):
        contract_by_expiry = [x for x in contract_list if x.id.date == expiry]
        
        # Iterate all strike prices among the contracts of the same expiry
        for strike in set(x.id.strike_price for x in contract_by_expiry):
            contract_by_strike = [x for x in contract_by_expiry if x.id.strike_price == strike]
        
            # Get the call and put respectively
            call = next(filter(lambda x: x.id.option_right == OptionRight.CALL, contract_by_strike))
            put = next(filter(lambda x: x.id.option_right == OptionRight.PUT, contract_by_strike))
            # Skip if either call or put not exist
            if not call or not put:
                continue
            
            # Create subscriptions to both contract
            call = self.add_option_contract(call).symbol
            put = self.add_option_contract(put).symbol
        
            # Create the manual-updating Gamma indicator
            call_gamma = Gamma(call, self.risk_free_interest_rate_model, self.dividend_yield_provider, put, self.option_pricing_model)
            put_gamma = Gamma(put, self.risk_free_interest_rate_model, self.dividend_yield_provider, call, self.option_pricing_model)
            # Add to list of indicator
            self.gammas.extend([call_gamma, put_gamma])
        
def on_data(self, slice: Slice) -> None:
    # Iterate indicators
    for gamma_indicator in self.gammas:
        option = gamma_indicator.option_symbol
        mirror_right = OptionRight.Call if option.id.option_right == OptionRight.PUT else OptionRight.PUT
        mirror = Symbol.create_option(option.underlying.value, Market.USA, OptionStyle.AMERICAN, mirror_right, option.id.strike_price, option.id.date)
    
        # Check if price data available for both contracts and the underlying
        if option in slice.quote_bars and mirror in slice.quote_bars and self.spy in slice.bars:
            # Update the indicator
            gamma_indicator.update(IndicatorDataPoint(option, slice.quote_bars[option].end_time, slice.quote_bars[option].close))
gamma_indicator.update(IndicatorDataPoint(mirror, slice.quote_bars[mirror].end_time, slice.quote_bars[mirror].close)) gamma_indicator.update(IndicatorDataPoint(self.spy, slice.bars[self.spy].end_time, slice.bars[self.spy].close)) # Get the current value gamma = gamma_indicator.current.value;

For more information about the Gamma constructor, see Using G Indicator.

Volatility Smoothing

The default IV smoothing method uses the one contract in the pair that's at-the-money or out-of-money to calculate the IV. To change the smoothing function, pass a mirrorOptionmirror_option argument to the indicator method or constructor and then call the SetSmoothingFunctionset_smoothing_function method of the ImpliedVolatility property of the indicator.

// Example: Average IV of the call-put pair.
_gamma.ImpliedVolatility.SetSmoothingFunction((iv, mirrorIv) => (iv + mirrorIv) * 0.5m);
# Example: Average IV of the call-put pair.
self._gamma.implied_volatility.set_smoothing_function(lambda iv, mirror_iv: (iv + mirror_iv) * 0.5)

For more information about the IV smoothing function, see Implied Volatility.

Vega

Vega, , is the rate of change in the value of the Option with respect to the volatility of the underlying asset. For more information about vega, see Vega.

Automatic Indicators

To create an automatic indicator for vega, call the QCAlgorithm.VQCAlgorithm.v method with the Option contract Symbolsymbol object(s).

private Symbol _spy;
private List<Symbol> _vegas = new();

public override void Initialize()
{
    // Subscribe to the underlying
    _spy = AddEquity("SPY", dataNormalizationMode=DataNormalizationMode.Raw).Symbol;
    
    // Set up a scheduled event to select contract and create Greeks indicator daily before market open
    Schedule.On(
        DateRules.EveryDay(_spy),
        TimeRules.At(9, 0),
        UpdateContractsAndGreeks
    );
}

private void UpdateContractsAndGreeks()
{
    // Get all tradable option contracts
    var contractList = OptionChainProvider.GetOptionContractList(_spy, Time).ToList();
    // You can do further filtering here

    // Iterate all expiries
    foreach (var expiry in contractList.Select(x => x.ID.Date).Distinct())
    {
        var contractsByExpiry = contractList.Where(x => x.ID.Date == expiry).ToList();

        // Iterate all strike prices among the contracts of the same expiry
        foreach (var strike in contractsByExpiry.Select(x => x.ID.StrikePrice).Distinct())
        {
            var contractsByStrike = contractsByExpiry.Where(x => x.ID.StrikePrice == strike).ToList();

            // Get the call and put respectively
            var call = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Call);
            var put = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Put);
            // Skip if either call or put not exist
            if (call == null || put == null) continue;

            // Create subscriptions to both contract
            call = AddOptionContract(call).Symbol;
            put = AddOptionContract(put).Symbol;

            // Create the automatic-updating Vega indicator
            var callVega = V(call, put);
            var putVega = V(put, call);
            // Add to list of indicator
            _vegas.Add(callVega);
            _vegas.Add(putVega);
        }
    }
}

public override void OnData(Slice slice)
{
    // Access the Vega indicator of each contract
    foreach (var vega in _vegas)
    {
        Log($"{vega.OptionSymbol}::{vega.Current.EndTime}::{vega.Current.Value}");
    }
}
def initialize(self) -> None:
    # List to hold Greeks indicators
    self.vegas = []

    # Subscribe to the underlying
    self.spy = self.add_equity("SPY", data_normalization_mode=DataNormalizationMode.RAW).symbol

    # Set up a scheduled event to select contract and create Greeks indicator daily before market open
    self.schedule.on(
        self.date_rules.every_day(self.spy),
        self.time_rules.at(9, 0),
        self.update_contracts_and_greeks
    )

def update_contracts_and_greeks(self) -> None:
    # Get all tradable option contracts
    contract_list = self.option_chain_provider.get_option_contract_list(self.spy, self.time)
    # You can do further filtering here

    # Iterate all expiries
    for expiry in set(x.id.date for x in contract_list):
        contract_by_expiry = [x for x in contract_list if x.id.date == expiry]
        
        # Iterate all strike prices among the contracts of the same expiry
        for strike in set(x.id.strike_price for x in contract_by_expiry):
            contract_by_strike = [x for x in contract_by_expiry if x.id.strike_price == strike]
        
            # Get the call and put respectively
            call = next(filter(lambda x: x.id.option_right == OptionRight.CALL, contract_by_strike))
            put = next(filter(lambda x: x.id.option_right == OptionRight.PUT, contract_by_strike))
            # Skip if either call or put not exist
            if not call or not put:
                continue
            
            # Create subscriptions to both contract
            call = self.add_option_contract(call).symbol
            put = self.add_option_contract(put).symbol
        
            # Create the automatic-updating Vega indicator
            call_vega = self.v(call, put)
            put_vega = self.v(put, call)
            # Add to list of indicator
            self.vegas.extend([call_vega, put_vega])
        
def on_data(self, slice: Slice) -> None:
    # Access the Vega indicator of each contract
    for vega in self.vegas:
        self.log(f"{vega.option_symbol}::{vega.current.end_time}::{vega.current.value}")

The follow table describes the arguments that the V method accepts in addition to the standard parameters:

ArgumentData TypeDescriptionDefault Value
ivModeliv_modelOptionPricingModelType The Option pricing model to use to estimate the IV when calculating Vega. If you don't provide a value, the default value is to match the optionModeloption_model parameter. nullNone

For more information about the V method, see Using V Indicator.

Manual Indicators

To create a manual indicator for vega, call the Vega constructor.

private Symbol _spy;
private DividendYieldProvider _dividendYieldProvider;
private List<Symbol> _vegas = new();
// Define the option pricing model
private readonly OptionPricingModelType _optionPricingModel = OptionPricingModelType.ForwardTree;

public override void Initialize()
{
    // Subscribe to the underlying
    _spy = AddEquity("SPY", dataNormalizationMode=DataNormalizationMode.Raw).Symbol;
    // Set up dividend yield provider for the underlying
    _dividendYieldProvider = new(_spy);
    
    // Set up a scheduled event to select contract and create Greeks indicator daily before market open
    Schedule.On(
        DateRules.EveryDay(_spy),
        TimeRules.At(9, 0),
        UpdateContractsAndGreeks
    );
}

private void UpdateContractsAndGreeks()
{
    // Get all tradable option contracts
    var contractList = OptionChainProvider.GetOptionContractList(_spy, Time).ToList();
    // You can do further filtering here

    // Iterate all expiries
    foreach (var expiry in contractList.Select(x => x.ID.Date).Distinct())
    {
        var contractsByExpiry = contractList.Where(x => x.ID.Date == expiry).ToList();

        // Iterate all strike prices among the contracts of the same expiry
        foreach (var strike in contractsByExpiry.Select(x => x.ID.StrikePrice).Distinct())
        {
            var contractsByStrike = contractsByExpiry.Where(x => x.ID.StrikePrice == strike).ToList();

            // Get the call and put respectively
            var call = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Call);
            var put = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Put);
            // Skip if either call or put not exist
            if (call == null || put == null) continue;

            // Create subscriptions to both contract
            call = AddOptionContract(call).Symbol;
            put = AddOptionContract(put).Symbol;

            // Create the manual-updating Vega indicator
            var callVega = new Vega(call, RiskFreeInterestRateModel, _dividendYieldProvider, put, _optionPricingModel);
            var putVega = new Vega(put, RiskFreeInterestRateModel, _dividendYieldProvider, call, _optionPricingModel);
            // Add to list of indicator
            _vegas.Add(callVega);
            _vegas.Add(putVega);
        }
    }
}

public override void OnData(Slice slice)
{
    // Iterate indicators
    foreach (var vegaIndicator in _vegas)
    {
        var option = vegaIndicator.OptionSymbol;
        var mirrorRight = option.ID.OptionRight == OptionRight.Call ? OptionRight.Put : OptionRight.Call;
        var mirror = QuantConnect.Symbol.CreateOption(option.Underlying.Value, Market.USA, OptionStyle.American, mirrorRight, option.ID.StrikePrice, option.ID.Date);

        // Check if price data available for both contracts and the underlying
        if (slice.QuoteBars.ContainsKey(option) && slice.QuoteBars.ContainsKey(mirror) && slice.Bars.ContainsKey(_spy))
        {
            // Update the indicator
            vegaIndicator.Update(new IndicatorDataPoint(option, slice.QuoteBars[option].EndTime, slice.QuoteBars[option].Close));
            vegaIndicator.Update(new IndicatorDataPoint(mirror, slice.QuoteBars[mirror].EndTime, slice.QuoteBars[mirror].Close));
            vegaIndicator.Update(new IndicatorDataPoint(_spy, slice.Bars[_spy].EndTime, slice.Bars[_spy].Close));

            // Get the current value
            var vega = vegaIndicator.Current.Value;
        }
    }
}
def initialize(self) -> None:
    # List to hold Greeks indicators
    self.vegas = []

    # Subscribe to the underlying
    self.spy = self.add_equity("SPY", data_normalization_mode=DataNormalizationMode.RAW).symbol
    # Set up dividend yield provider for the underlying
    self.dividend_yield_provider = DividendYieldProvider(self.spy)
    # Define the option pricing model
    self.option_pricing_model = OptionPricingModelType.FORWARD_TREE

    # Set up a scheduled event to select contract and create Greeks indicator daily before market open
    self.schedule.on(
        self.date_rules.every_day(self.spy),
        self.time_rules.at(9, 0),
        self.update_contracts_and_greeks
    )

def update_contracts_and_greeks(self) -> None:
    # Get all tradable option contracts
    contract_list = self.option_chain_provider.get_option_contract_list(self.spy, self.time)
    # You can do further filtering here

    # Iterate all expiries
    for expiry in set(x.id.date for x in contract_list):
        contract_by_expiry = [x for x in contract_list if x.id.date == expiry]
        
        # Iterate all strike prices among the contracts of the same expiry
        for strike in set(x.id.strike_price for x in contract_by_expiry):
            contract_by_strike = [x for x in contract_by_expiry if x.id.strike_price == strike]
        
            # Get the call and put respectively
            call = next(filter(lambda x: x.id.option_right == OptionRight.CALL, contract_by_strike))
            put = next(filter(lambda x: x.id.option_right == OptionRight.PUT, contract_by_strike))
            # Skip if either call or put not exist
            if not call or not put:
                continue
            
            # Create subscriptions to both contract
            call = self.add_option_contract(call).symbol
            put = self.add_option_contract(put).symbol
        
            # Create the manual-updating Vega indicator
            call_vega = Vega(call, self.risk_free_interest_rate_model, self.dividend_yield_provider, put, self.option_pricing_model)
            put_vega = Vega(put, self.risk_free_interest_rate_model, self.dividend_yield_provider, call, self.option_pricing_model)
            # Add to list of indicator
            self.vegas.extend([call_vega, put_vega])
        
def on_data(self, slice: Slice) -> None:
    # Iterate indicators
    for vega_indicator in self.vegas:
        option = vega_indicator.option_symbol
        mirror_right = OptionRight.Call if option.id.option_right == OptionRight.PUT else OptionRight.PUT
        mirror = Symbol.create_option(option.underlying.value, Market.USA, OptionStyle.AMERICAN, mirror_right, option.id.strike_price, option.id.date)
    
        # Check if price data available for both contracts and the underlying
        if option in slice.quote_bars and mirror in slice.quote_bars and self.spy in slice.bars:
            # Update the indicator
            vega_indicator.update(IndicatorDataPoint(option, slice.quote_bars[option].end_time, slice.quote_bars[option].close))
vega_indicator.update(IndicatorDataPoint(mirror, slice.quote_bars[mirror].end_time, slice.quote_bars[mirror].close)) vega_indicator.update(IndicatorDataPoint(self.spy, slice.bars[self.spy].end_time, slice.bars[self.spy].close)) # Get the current value vega = vega_indicator.current.value;

For more information about the Vega constructor, see Using V Indicator.

Volatility Smoothing

The default IV smoothing method uses the one contract in the pair that's at-the-money or out-of-money to calculate the IV. To change the smoothing function, pass a mirrorOptionmirror_option argument to the indicator method or constructor and then call the SetSmoothingFunctionset_smoothing_function method of the ImpliedVolatility property of the indicator.

// Example: Average IV of the call-put pair.
_vega.ImpliedVolatility.SetSmoothingFunction((iv, mirrorIv) => (iv + mirrorIv) * 0.5m);
# Example: Average IV of the call-put pair.
self._vega.implied_volatility.set_smoothing_function(lambda iv, mirror_iv: (iv + mirror_iv) * 0.5)

For more information about the IV smoothing function, see Implied Volatility.

Theta

Theta, , is the rate of change of the value of the Option with respect to the passage of time. It is also known to as the time decay of an Option. For more information about theta, see Theta.

Automatic Indicators

To create an automatic indicator for theta, call the QCAlgorithm.TQCAlgorithm.t method with the Option contract Symbolsymbol object(s).

private Symbol _spy;
private List<Symbol> _thetas = new();

public override void Initialize()
{
    // Subscribe to the underlying
    _spy = AddEquity("SPY", dataNormalizationMode=DataNormalizationMode.Raw).Symbol;
    
    // Set up a scheduled event to select contract and create Greeks indicator daily before market open
    Schedule.On(
        DateRules.EveryDay(_spy),
        TimeRules.At(9, 0),
        UpdateContractsAndGreeks
    );
}

private void UpdateContractsAndGreeks()
{
    // Get all tradable option contracts
    var contractList = OptionChainProvider.GetOptionContractList(_spy, Time).ToList();
    // You can do further filtering here

    // Iterate all expiries
    foreach (var expiry in contractList.Select(x => x.ID.Date).Distinct())
    {
        var contractsByExpiry = contractList.Where(x => x.ID.Date == expiry).ToList();

        // Iterate all strike prices among the contracts of the same expiry
        foreach (var strike in contractsByExpiry.Select(x => x.ID.StrikePrice).Distinct())
        {
            var contractsByStrike = contractsByExpiry.Where(x => x.ID.StrikePrice == strike).ToList();

            // Get the call and put respectively
            var call = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Call);
            var put = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Put);
            // Skip if either call or put not exist
            if (call == null || put == null) continue;

            // Create subscriptions to both contract
            call = AddOptionContract(call).Symbol;
            put = AddOptionContract(put).Symbol;

            // Create the automatic-updating Theta indicator
            var callTheta = T(call, put);
            var putTheta = T(put, call);
            // Add to list of indicator
            _thetas.Add(callTheta);
            _thetas.Add(putTheta);
        }
    }
}

public override void OnData(Slice slice)
{
    // Access the Theta indicator of each contract
    foreach (var theta in _thetas)
    {
        Log($"{theta.OptionSymbol}::{theta.Current.EndTime}::{theta.Current.Value}");
    }
}
def initialize(self) -> None:
    # List to hold Greeks indicators
    self.thetas = []

    # Subscribe to the underlying
    self.spy = self.add_equity("SPY", data_normalization_mode=DataNormalizationMode.RAW).symbol

    # Set up a scheduled event to select contract and create Greeks indicator daily before market open
    self.schedule.on(
        self.date_rules.every_day(self.spy),
        self.time_rules.at(9, 0),
        self.update_contracts_and_greeks
    )

def update_contracts_and_greeks(self) -> None:
    # Get all tradable option contracts
    contract_list = self.option_chain_provider.get_option_contract_list(self.spy, self.time)
    # You can do further filtering here

    # Iterate all expiries
    for expiry in set(x.id.date for x in contract_list):
        contract_by_expiry = [x for x in contract_list if x.id.date == expiry]
        
        # Iterate all strike prices among the contracts of the same expiry
        for strike in set(x.id.strike_price for x in contract_by_expiry):
            contract_by_strike = [x for x in contract_by_expiry if x.id.strike_price == strike]
        
            # Get the call and put respectively
            call = next(filter(lambda x: x.id.option_right == OptionRight.CALL, contract_by_strike))
            put = next(filter(lambda x: x.id.option_right == OptionRight.PUT, contract_by_strike))
            # Skip if either call or put not exist
            if not call or not put:
                continue
            
            # Create subscriptions to both contract
            call = self.add_option_contract(call).symbol
            put = self.add_option_contract(put).symbol
        
            # Create the automatic-updating Theta indicator
            call_theta = self.t(call, put)
            put_theta = self.t(put, call)
            # Add to list of indicator
            self.thetas.extend([call_theta, put_theta])
        
def on_data(self, slice: Slice) -> None:
    # Access the Theta indicator of each contract
    for theta in self.thetas:
        self.log(f"{theta.option_symbol}::{theta.current.end_time}::{theta.current.value}")

The follow table describes the arguments that the T method accepts in addition to the standard parameters:

ArgumentData TypeDescriptionDefault Value
ivModeliv_modelOptionPricingModelType The Option pricing model to use to estimate the IV when calculating theta. If you don't provide a value, the default value is to match the optionModeloption_model parameter. nullNone

For more information about the T method, see Using T Indicator.

Manual Indicators

To create a manual indicator for theta, call the Theta constructor.

private Symbol _spy;
private DividendYieldProvider _dividendYieldProvider;
private List<Symbol> _thetas = new();
// Define the option pricing model
private readonly OptionPricingModelType _optionPricingModel = OptionPricingModelType.ForwardTree;

public override void Initialize()
{
    // Subscribe to the underlying
    _spy = AddEquity("SPY", dataNormalizationMode=DataNormalizationMode.Raw).Symbol;
    // Set up dividend yield provider for the underlying
    _dividendYieldProvider = new(_spy);
    
    // Set up a scheduled event to select contract and create Greeks indicator daily before market open
    Schedule.On(
        DateRules.EveryDay(_spy),
        TimeRules.At(9, 0),
        UpdateContractsAndGreeks
    );
}

private void UpdateContractsAndGreeks()
{
    // Get all tradable option contracts
    var contractList = OptionChainProvider.GetOptionContractList(_spy, Time).ToList();
    // You can do further filtering here

    // Iterate all expiries
    foreach (var expiry in contractList.Select(x => x.ID.Date).Distinct())
    {
        var contractsByExpiry = contractList.Where(x => x.ID.Date == expiry).ToList();

        // Iterate all strike prices among the contracts of the same expiry
        foreach (var strike in contractsByExpiry.Select(x => x.ID.StrikePrice).Distinct())
        {
            var contractsByStrike = contractsByExpiry.Where(x => x.ID.StrikePrice == strike).ToList();

            // Get the call and put respectively
            var call = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Call);
            var put = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Put);
            // Skip if either call or put not exist
            if (call == null || put == null) continue;

            // Create subscriptions to both contract
            call = AddOptionContract(call).Symbol;
            put = AddOptionContract(put).Symbol;

            // Create the manual-updating Theta indicator
            var callTheta = new Theta(call, RiskFreeInterestRateModel, _dividendYieldProvider, put, _optionPricingModel);
            var putTheta = new Theta(put, RiskFreeInterestRateModel, _dividendYieldProvider, call, _optionPricingModel);
            // Add to list of indicator
            _thetas.Add(callTheta);
            _thetas.Add(putTheta);
        }
    }
}

public override void OnData(Slice slice)
{
    // Iterate indicators
    foreach (var thetaIndicator in _thetas)
    {
        var option = thetaIndicator.OptionSymbol;
        var mirrorRight = option.ID.OptionRight == OptionRight.Call ? OptionRight.Put : OptionRight.Call;
        var mirror = QuantConnect.Symbol.CreateOption(option.Underlying.Value, Market.USA, OptionStyle.American, mirrorRight, option.ID.StrikePrice, option.ID.Date);

        // Check if price data available for both contracts and the underlying
        if (slice.QuoteBars.ContainsKey(option) && slice.QuoteBars.ContainsKey(mirror) && slice.Bars.ContainsKey(_spy))
        {
            // Update the indicator
            thetaIndicator.Update(new IndicatorDataPoint(option, slice.QuoteBars[option].EndTime, slice.QuoteBars[option].Close));
            thetaIndicator.Update(new IndicatorDataPoint(mirror, slice.QuoteBars[mirror].EndTime, slice.QuoteBars[mirror].Close));
            thetaIndicator.Update(new IndicatorDataPoint(_spy, slice.Bars[_spy].EndTime, slice.Bars[_spy].Close));

            // Get the current value
            var theta = thetaIndicator.Current.Value;
        }
    }
}
def initialize(self) -> None:
    # List to hold Greeks indicators
    self.thetas = []

    # Subscribe to the underlying
    self.spy = self.add_equity("SPY", data_normalization_mode=DataNormalizationMode.RAW).symbol
    # Set up dividend yield provider for the underlying
    self.dividend_yield_provider = DividendYieldProvider(self.spy)
    # Define the option pricing model
    self.option_pricing_model = OptionPricingModelType.FORWARD_TREE

    # Set up a scheduled event to select contract and create Greeks indicator daily before market open
    self.schedule.on(
        self.date_rules.every_day(self.spy),
        self.time_rules.at(9, 0),
        self.update_contracts_and_greeks
    )

def update_contracts_and_greeks(self) -> None:
    # Get all tradable option contracts
    contract_list = self.option_chain_provider.get_option_contract_list(self.spy, self.time)
    # You can do further filtering here

    # Iterate all expiries
    for expiry in set(x.id.date for x in contract_list):
        contract_by_expiry = [x for x in contract_list if x.id.date == expiry]
        
        # Iterate all strike prices among the contracts of the same expiry
        for strike in set(x.id.strike_price for x in contract_by_expiry):
            contract_by_strike = [x for x in contract_by_expiry if x.id.strike_price == strike]
        
            # Get the call and put respectively
            call = next(filter(lambda x: x.id.option_right == OptionRight.CALL, contract_by_strike))
            put = next(filter(lambda x: x.id.option_right == OptionRight.PUT, contract_by_strike))
            # Skip if either call or put not exist
            if not call or not put:
                continue
            
            # Create subscriptions to both contract
            call = self.add_option_contract(call).symbol
            put = self.add_option_contract(put).symbol
        
            # Create the manual-updating Theta indicator
            call_theta = Theta(call, self.risk_free_interest_rate_model, self.dividend_yield_provider, put, self.option_pricing_model)
            put_theta = Theta(put, self.risk_free_interest_rate_model, self.dividend_yield_provider, call, self.option_pricing_model)
            # Add to list of indicator
            self.thetas.extend([call_theta, put_theta])
        
def on_data(self, slice: Slice) -> None:
    # Iterate indicators
    for theta_indicator in self.thetas:
        option = theta_indicator.option_symbol
        mirror_right = OptionRight.Call if option.id.option_right == OptionRight.PUT else OptionRight.PUT
        mirror = Symbol.create_option(option.underlying.value, Market.USA, OptionStyle.AMERICAN, mirror_right, option.id.strike_price, option.id.date)
    
        # Check if price data available for both contracts and the underlying
        if option in slice.quote_bars and mirror in slice.quote_bars and self.spy in slice.bars:
            # Update the indicator
            theta_indicator.update(IndicatorDataPoint(option, slice.quote_bars[option].end_time, slice.quote_bars[option].close))
theta_indicator.update(IndicatorDataPoint(mirror, slice.quote_bars[mirror].end_time, slice.quote_bars[mirror].close)) theta_indicator.update(IndicatorDataPoint(self.spy, slice.bars[self.spy].end_time, slice.bars[self.spy].close)) # Get the current value theta = theta_indicator.current.value;

For more information about the Theta constructor, see Using T Indicator.

Volatility Smoothing

The default IV smoothing method uses the one contract in the pair that's at-the-money or out-of-money to calculate the IV. To change the smoothing function, pass a mirrorOptionmirror_option argument to the indicator method or constructor and then call the SetSmoothingFunctionset_smoothing_function method of the ImpliedVolatility property of the indicator.

// Example: Average IV of the call-put pair.
_theta.ImpliedVolatility.SetSmoothingFunction((iv, mirrorIv) => (iv + mirrorIv) * 0.5m);
# Example: Average IV of the call-put pair.
self._theta.implied_volatility.set_smoothing_function(lambda iv, mirror_iv: (iv + mirror_iv) * 0.5)

For more information about the IV smoothing function, see Implied Volatility.

Rho

Rho, , is the rate of change of the value of a derivative with respect to the interest rate.  It is usually small and not a big issue in practice unless the Option is deep in-the-money and has a long horizon. In this case, the interest rate matters because you need to discount a larger cash flow over a longer horizon. For more information about rho, see Rho.

Automatic Indicators

To create an automatic indicator for rho, call the QCAlgorithm.RQCAlgorithm.r method with the Option contract Symbolsymbol object(s).

private Symbol _spy;
private List<Symbol> _rhos = new();

public override void Initialize()
{
    // Subscribe to the underlying
    _spy = AddEquity("SPY", dataNormalizationMode=DataNormalizationMode.Raw).Symbol;
    
    // Set up a scheduled event to select contract and create Greeks indicator daily before market open
    Schedule.On(
        DateRules.EveryDay(_spy),
        TimeRules.At(9, 0),
        UpdateContractsAndGreeks
    );
}

private void UpdateContractsAndGreeks()
{
    // Get all tradable option contracts
    var contractList = OptionChainProvider.GetOptionContractList(_spy, Time).ToList();
    // You can do further filtering here

    // Iterate all expiries
    foreach (var expiry in contractList.Select(x => x.ID.Date).Distinct())
    {
        var contractsByExpiry = contractList.Where(x => x.ID.Date == expiry).ToList();

        // Iterate all strike prices among the contracts of the same expiry
        foreach (var strike in contractsByExpiry.Select(x => x.ID.StrikePrice).Distinct())
        {
            var contractsByStrike = contractsByExpiry.Where(x => x.ID.StrikePrice == strike).ToList();

            // Get the call and put respectively
            var call = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Call);
            var put = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Put);
            // Skip if either call or put not exist
            if (call == null || put == null) continue;

            // Create subscriptions to both contract
            call = AddOptionContract(call).Symbol;
            put = AddOptionContract(put).Symbol;

            // Create the automatic-updating Rho indicator
            var callRho = R(call, put);
            var putRho = R(put, call);
            // Add to list of indicator
            _rhos.Add(callRho);
            _rhos.Add(putRho);
        }
    }
}

public override void OnData(Slice slice)
{
    // Access the Rho indicator of each contract
    foreach (var rho in _rhos)
    {
        Log($"{rho.OptionSymbol}::{rho.Current.EndTime}::{rho.Current.Value}");
    }
}
def initialize(self) -> None:
    # List to hold Greeks indicators
    self.rhos = []

    # Subscribe to the underlying
    self.spy = self.add_equity("SPY", data_normalization_mode=DataNormalizationMode.RAW).symbol

    # Set up a scheduled event to select contract and create Greeks indicator daily before market open
    self.schedule.on(
        self.date_rules.every_day(self.spy),
        self.time_rules.at(9, 0),
        self.update_contracts_and_greeks
    )

def update_contracts_and_greeks(self) -> None:
    # Get all tradable option contracts
    contract_list = self.option_chain_provider.get_option_contract_list(self.spy, self.time)
    # You can do further filtering here

    # Iterate all expiries
    for expiry in set(x.id.date for x in contract_list):
        contract_by_expiry = [x for x in contract_list if x.id.date == expiry]
        
        # Iterate all strike prices among the contracts of the same expiry
        for strike in set(x.id.strike_price for x in contract_by_expiry):
            contract_by_strike = [x for x in contract_by_expiry if x.id.strike_price == strike]
        
            # Get the call and put respectively
            call = next(filter(lambda x: x.id.option_right == OptionRight.CALL, contract_by_strike))
            put = next(filter(lambda x: x.id.option_right == OptionRight.PUT, contract_by_strike))
            # Skip if either call or put not exist
            if not call or not put:
                continue
            
            # Create subscriptions to both contract
            call = self.add_option_contract(call).symbol
            put = self.add_option_contract(put).symbol
        
            # Create the automatic-updating Rho indicator
            call_rho = self.r(call, put)
            put_rho = self.r(put, call)
            # Add to list of indicator
            self.rhos.extend([call_rho, put_rho])
        
def on_data(self, slice: Slice) -> None:
    # Access the Rho indicator of each contract
    for rho in self.rhos:
        self.log(f"{rho.option_symbol}::{rho.current.end_time}::{rho.current.value}")

The follow table describes the arguments that the R method accepts in addition to the standard parameters:

ArgumentData TypeDescriptionDefault Value
ivModeliv_modelOptionPricingModelType The Option pricing model to use to estimate the IV when calculating rho If you don't provide a value, the default value is to match the optionModeloption_model parameter. nullNone

Manual Indicators

To create a manual indicator for rho, call the Rho constructor.

private Symbol _spy;
private DividendYieldProvider _dividendYieldProvider;
private List<Symbol> _rhos = new();
// Define the option pricing model
private readonly OptionPricingModelType _optionPricingModel = OptionPricingModelType.ForwardTree;

public override void Initialize()
{
    // Subscribe to the underlying
    _spy = AddEquity("SPY", dataNormalizationMode=DataNormalizationMode.Raw).Symbol;
    // Set up dividend yield provider for the underlying
    _dividendYieldProvider = new(_spy);
    
    // Set up a scheduled event to select contract and create Greeks indicator daily before market open
    Schedule.On(
        DateRules.EveryDay(_spy),
        TimeRules.At(9, 0),
        UpdateContractsAndGreeks
    );
}

private void UpdateContractsAndGreeks()
{
    // Get all tradable option contracts
    var contractList = OptionChainProvider.GetOptionContractList(_spy, Time).ToList();
    // You can do further filtering here

    // Iterate all expiries
    foreach (var expiry in contractList.Select(x => x.ID.Date).Distinct())
    {
        var contractsByExpiry = contractList.Where(x => x.ID.Date == expiry).ToList();

        // Iterate all strike prices among the contracts of the same expiry
        foreach (var strike in contractsByExpiry.Select(x => x.ID.StrikePrice).Distinct())
        {
            var contractsByStrike = contractsByExpiry.Where(x => x.ID.StrikePrice == strike).ToList();

            // Get the call and put respectively
            var call = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Call);
            var put = contractsByStrike.SingleOrDefault(x => x.ID.OptionRight == OptionRight.Put);
            // Skip if either call or put not exist
            if (call == null || put == null) continue;

            // Create subscriptions to both contract
            call = AddOptionContract(call).Symbol;
            put = AddOptionContract(put).Symbol;

            // Create the manual-updating Rho indicator
            var callRho = new Rho(call, RiskFreeInterestRateModel, _dividendYieldProvider, put, _optionPricingModel);
            var putRho = new Rho(put, RiskFreeInterestRateModel, _dividendYieldProvider, call, _optionPricingModel);
            // Add to list of indicator
            _rhos.Add(callRho);
            _rhos.Add(putRho);
        }
    }
}

public override void OnData(Slice slice)
{
    // Iterate indicators
    foreach (var rhoIndicator in _rhos)
    {
        var option = rhoIndicator.OptionSymbol;
        var mirrorRight = option.ID.OptionRight == OptionRight.Call ? OptionRight.Put : OptionRight.Call;
        var mirror = QuantConnect.Symbol.CreateOption(option.Underlying.Value, Market.USA, OptionStyle.American, mirrorRight, option.ID.StrikePrice, option.ID.Date);

        // Check if price data available for both contracts and the underlying
        if (slice.QuoteBars.ContainsKey(option) && slice.QuoteBars.ContainsKey(mirror) && slice.Bars.ContainsKey(_spy))
        {
            // Update the indicator
            rhoIndicator.Update(new IndicatorDataPoint(option, slice.QuoteBars[option].EndTime, slice.QuoteBars[option].Close));
            rhoIndicator.Update(new IndicatorDataPoint(mirror, slice.QuoteBars[mirror].EndTime, slice.QuoteBars[mirror].Close));
            rhoIndicator.Update(new IndicatorDataPoint(_spy, slice.Bars[_spy].EndTime, slice.Bars[_spy].Close));

            // Get the current value
            var rho = rhoIndicator.Current.Value;
        }
    }
}
def initialize(self) -> None:
    # List to hold Greeks indicators
    self.rhos = []

    # Subscribe to the underlying
    self.spy = self.add_equity("SPY", data_normalization_mode=DataNormalizationMode.RAW).symbol
    # Set up dividend yield provider for the underlying
    self.dividend_yield_provider = DividendYieldProvider(self.spy)
    # Define the option pricing model
    self.option_pricing_model = OptionPricingModelType.FORWARD_TREE

    # Set up a scheduled event to select contract and create Greeks indicator daily before market open
    self.schedule.on(
        self.date_rules.every_day(self.spy),
        self.time_rules.at(9, 0),
        self.update_contracts_and_greeks
    )

def update_contracts_and_greeks(self) -> None:
    # Get all tradable option contracts
    contract_list = self.option_chain_provider.get_option_contract_list(self.spy, self.time)
    # You can do further filtering here

    # Iterate all expiries
    for expiry in set(x.id.date for x in contract_list):
        contract_by_expiry = [x for x in contract_list if x.id.date == expiry]
        
        # Iterate all strike prices among the contracts of the same expiry
        for strike in set(x.id.strike_price for x in contract_by_expiry):
            contract_by_strike = [x for x in contract_by_expiry if x.id.strike_price == strike]
        
            # Get the call and put respectively
            call = next(filter(lambda x: x.id.option_right == OptionRight.CALL, contract_by_strike))
            put = next(filter(lambda x: x.id.option_right == OptionRight.PUT, contract_by_strike))
            # Skip if either call or put not exist
            if not call or not put:
                continue
            
            # Create subscriptions to both contract
            call = self.add_option_contract(call).symbol
            put = self.add_option_contract(put).symbol
        
            # Create the manual-updating Rho indicator
            call_rho = Rho(call, self.risk_free_interest_rate_model, self.dividend_yield_provider, put, self.option_pricing_model)
            put_rho = Rho(put, self.risk_free_interest_rate_model, self.dividend_yield_provider, call, self.option_pricing_model)
            # Add to list of indicator
            self.rhos.extend([call_rho, put_rho])
        
def on_data(self, slice: Slice) -> None:
    # Iterate indicators
    for rho_indicator in self.rhos:
        option = rho_indicator.option_symbol
        mirror_right = OptionRight.Call if option.id.option_right == OptionRight.PUT else OptionRight.PUT
        mirror = Symbol.create_option(option.underlying.value, Market.USA, OptionStyle.AMERICAN, mirror_right, option.id.strike_price, option.id.date)
    
        # Check if price data available for both contracts and the underlying
        if option in slice.quote_bars and mirror in slice.quote_bars and self.spy in slice.bars:
            # Update the indicator
            rho_indicator.update(IndicatorDataPoint(option, slice.quote_bars[option].end_time, slice.quote_bars[option].close))
rho_indicator.update(IndicatorDataPoint(mirror, slice.quote_bars[mirror].end_time, slice.quote_bars[mirror].close)) rho_indicator.update(IndicatorDataPoint(self.spy, slice.bars[self.spy].end_time, slice.bars[self.spy].close)) # Get the current value rho = rho_indicator.current.value;

For more information about the Rho constructor, see Using R Indicator.

Volatility Smoothing

The default IV smoothing method uses the one contract in the pair that's at-the-money or out-of-money to calculate the IV. To change the smoothing function, pass a mirrorOptionmirror_option argument to the indicator method or constructor and then call the SetSmoothingFunctionset_smoothing_function method of the ImpliedVolatility property of the indicator.

// Example: Average IV of the call-put pair.
_rho.ImpliedVolatility.SetSmoothingFunction((iv, mirrorIv) => (iv + mirrorIv) * 0.5m);
# Example: Average IV of the call-put pair.
self._rho.implied_volatility.set_smoothing_function(lambda iv, mirror_iv: (iv + mirror_iv) * 0.5)

For more information about the IV smoothing function, see Implied Volatility.

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: