Options Models

Pricing

Introduction

Option price models compute the theoretical price of Option contracts, their implied volatility (IV), and their Greek values. Theoretical prices can help you detect undervalued and overvalued contracts, IV can provide you insight into the upcoming volatility of the underlying security, and Greek values can help you hedge your portfolio.

Data Discrepancies

There are several ways for you to get the Greeks and IV values, but you may notice some discrepancies between them.

Greeks in Universe Selection

The Greeks and IV values in the universe filter function are the daily, pre-calculated values based on the end of the previous trading day. You can't customize the Greeks and IV values that the filter function receives.

Greeks in Chain Requests

The Greeks and IV values in the OptionUniverse objects that you get from calling the OptionChainoption_chain method are the daily, pre-calculated values based on the end of the previous trading day. You can't customize the Greeks and IV values that you get from this method.

Greeks in Data Events

The Greeks and IV values in the Slice that you get in the OnDataon_data method are the values from the Option price model. To customize the Greeks and IV values in the Slice, set a different price model.

Set Models

To set the pricing model of an Option, set its PriceModelprice_model property.

If you have access to the Option object when you subscribe to the Option universe or contract, you can set the price model immediately after you create the subscription.

public override Initialize()
{
    UniverseSettings.Asynchronous = true;
    var option = AddOption("SPY");
    // SPY options are American Options, in which IV and greeks more accurately calculated using Binomial model
    option.PriceModel = OptionPriceModels.BinomialCoxRossRubinstein();
}
def initialize(self):
    self.universe_settings.asynchronous = True
    option = self.add_option("SPY")
    # SPY options are American Options, in which IV and greeks more accurately calculated using Binomial model
    option.price_model = OptionPriceModels.binomial_cox_ross_rubinstein()

Otherwise, set the price model in a security initializer.

public class BrokerageModelExampleAlgorithm : QCAlgorithm
{
    public override void Initialize()
    {
        // In the Initialize method, set the security initializer to seed initial the prices and models of assets.
        SetSecurityInitializer(new MySecurityInitializer(BrokerageModel, new FuncSecuritySeeder(GetLastKnownPrices)));
    }
}

public class MySecurityInitializer : BrokerageModelSecurityInitializer
{
    public MySecurityInitializer(IBrokerageModel brokerageModel, ISecuritySeeder securitySeeder)
        : base(brokerageModel, securitySeeder) {}    
    public override void Initialize(Security security)
    {
        // First, call the superclass definition.
        // This method sets the reality models of each security using the default reality models of the brokerage model.
        base.Initialize(security);

        // Next, overwrite the price model
        if (security.Type == SecurityType.Option) // Option type
        {
            security.PriceModel = OptionPriceModels.BinomialCoxRossRubinstein();
        }    }
}
class BrokerageModelExampleAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        # In the Initialize method, set the security initializer to seed initial the prices and models of assets.
        self.set_security_initializer(MySecurityInitializer(self.brokerage_model, FuncSecuritySeeder(self.get_last_known_prices)))

# Outside of the algorithm class
class MySecurityInitializer(BrokerageModelSecurityInitializer):

    def __init__(self, brokerage_model: IBrokerageModel, security_seeder: ISecuritySeeder) -> None:
        super().__init__(brokerage_model, security_seeder)    
    def initialize(self, security: Security) -> None:
        # First, call the superclass definition.
        # This method sets the reality models of each security using the default reality models of the brokerage model.
        super().initialize(security)

        # Next, overwrite the price model
        if security.type == SecurityType.OPTION: # Option type
            security.price_model = OptionPriceModels.binomial_cox_ross_rubinstein()

Default Behavior

The default Option pricing model is the BinomialCoxRossRubinstein for American Options or BlackScholes for European Options.

Disable Pricing

To turn off the Option price model, use the CurrentPriceOptionPriceModel. This model sets the Greeks to 0, sets the IV to 0, and sets the theoretical price to the current price.

option.PriceModel = new CurrentPriceOptionPriceModel();
option.price_model = CurrentPriceOptionPriceModel()

Supported Models

LEAN supports the following Option price models.

ModelAmerican StyleEuropean Style
AdditiveEquiprobabilitiesgreen checkgreen check
BaroneAdesiWhaleygreen check
BinomialCoxRossRubinsteingreen checkgreen check
BinomialJarrowRuddgreen checkgreen check
BinomialJoshigreen checkgreen check
BinomialLeisenReimergreen checkgreen check
BinomialTiangreen checkgreen check
BinomialTrigeorgisgreen checkgreen check
BjerksundStenslandgreen check
BlackScholes
green check
CrankNicolsonFDgreen checkgreen check
Integral
green check

If you set the price model of an Option to a model with an incompatible style, LEAN throws an exception.

What are Greeks?

Option Greeks measure the exposure of Option price or Option delta to the movement of different factors such as the underlying price, time, and volatility. The Greeks are a function of implied volatility. For more information about them, see The Greek Letters.

LEAN also provides indicator implementations of Option Greeks. It provides higher flexibility on Option price model selection, volatility modeling, and allows IV smoothing through call-put pair. For details, see Option Indicators.

What Is Implied Volatility?

Implied volatility is the forecasted future volatility of a security. The Option price model uses the realized volatility to calculate the implied volatility. By default, it uses the formula from Brenner and Subrahmanyam (1988) as the initial guess for implied volatility.

\[ \frac{P}{S} \sqrt{\frac{2\pi}{T}} \]

where \(P\) is the Option contract price, \(S\) is the underlying price, and \(T\) is the time until Option expiration.

If the volatility model of the underlying security is ready, the price model uses its value as the initial guess for implied volatility and as an input to calculate the theoretical contract prices.

LEAN also provides an indicator implementation of implied volatility. It provides higher flexibility on Option price model selection, volatility modeling, and allows IV smoothing through call-put pair. For details, see Implied Volatility.

What Is Volatility Smile?

The "volatility smile" is a term used in finance to describe a particular shape that can be observed when plotting IV against strike prices for options that share the same expiration date. Typically, when you plot IVs against strike prices, the curve tends to be concave, resembling a smile. This means that options with strike prices significantly above or below the current market price of the underlying asset tend to have higher IV than options with strike prices closer to the current market price.

Several theories attempt to explain the existence of the volatility smile. One explanation is that it arises from adjustments to the classic Black-Scholes-Merton (BSM) model, which assumes that asset prices follow a log-normal distribution. The volatility smile suggests that the market anticipates a higher probability of extreme price movements (fat tails) than the BSM model predicts. Another explanation is related to market dynamics and the demand for hedging. During periods of heightened market volatility, the volatility smile tends to become steeper, indicating a greater disparity in implied volatilities across different strike prices. This means that options, particularly those with out-of-the-money strike prices, become more expensive as investors seek protection against potential market downturns or increased price fluctuations. As a result, the volatility smile can serve as a valuable tool for investors and traders to assess market sentiment and gauge the level of risk in their portfolios.

According to some volatility models, such as the Heston model, the IV smile/surface should exhibit a smooth pattern. Any deviations from this smoothness, such as non-smooth spikes or irregularities, may signal potential arbitrage opportunities for traders.

Volatility Smirk

However, in some cases, rather than a traditional U-shaped curve, traders may observe what's known as a "smirk." This smirk occurs when the implied volatilities for higher-strike options are lower than those for ATM and lower-strike options. This deviation from the typical volatility smile pattern indicates a market expectation of a significant downward movement in the underlying asset's price. Traders interpret this as a signal that investors are allocating funds towards options with higher probabilities of such downward movements, resulting in increased demand for lower-strike options.

What Is Volatility Smoothing?

Volatility smoothing refers to the creation of a smooth volatility smile/surface. Derivative like options are favorable for maket-making and arbitration trading, due to the existence of fair price modeling. In the contemporary domain of high-frequency trading, the efficiency of calculating IV and Greeks assumes paramount significance. Thus, the quest for swift and refined IV surface computation becomes an inevitable quest for traders. Rather than relying solely on conventional methods involving slow-paced sampling and continuous parameter recalibration, the adoption of approximation techniques and stationary state analyses gains traction, especially in the context of IV estimation.

Accuracy Consideration

The Law of One Price stipulates the existence of a singular fair price for any given underlying asset. Consequently, according to the principles of put-call parity, each strike price for European options at expiration should correspond to a unique IV value. Within the realm of the Black-Scholes-Merton (BSM) framework, for instance, the concept of put-call parity yields insights into the equivalence of IVs for call and put options at identical strike prices and expirations. This equivalence serves as the foundation for formulating objective function: $$ C(t,K) - P(t,K)=e^{(q-r)t} (S_T - K) \\\Rightarrow e^{(q-r)t} [S_T (\Phi(d_{+}^{call})+\Phi(-d_{+}^{put})) - K (\Phi(d_{-}^{call})+\Phi(-d_{-}^{put}))] = e^{(q-r)t} (S_T - K) \\\Rightarrow \Phi(d_{+}^{call})+\Phi(-d_{+}^{put}) = 1\ \text{and}\ \Phi(d_{-}^{call})+\Phi(-d_{-}^{put}) = 1 \\\Rightarrow d_{\pm}^{call}=d_{\pm}^{put} $$ Thus, we can formulate an objective function of $C_{market} + P_{market} = C_{BSM} + P_{BSM}$.

Alternatively, certain schools of thought contend that the bulk of historical volatility information is encapsulated within at-the-money (ATM) options, with any residual volatility attributable to the extrinsic value of the option. Consequently, a strategy focused on out-of-the-money (OTM) options for IV calculations gains traction.

Speed Consideration

In the realm of high-frequency trading, where split-second decisions are the norm, the traditional process of sampling, evaluating, recalibrating, and deriving implied volatility expectations is simply unfeasible. In response, traders and analysts increasingly turn to polynomial regression techniques as a pragmatic solution for IV modeling.

For example, $$ IV_t = \beta_0 + \beta_1 M + \beta_2 M^2 + \beta_3 (T-t) + \beta_4 (T-t)^2 + \beta_5 M(T-t) \\\text{where} M = ln(S_t/K) $$

Additionally, the utilization of advanced mathematical algorithms, such as the Fast Fourier Transform (FFT), enables the rapid computation of the entire Greek surface, enhancing speed and efficiency. While these approaches may entail minor trade-offs in terms of accuracy, the overarching objective remains the attainment of a seamlessly smooth implied volatility surface that fosters effective arbitrage strategies.

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: