Volatility

Key Concepts

Introduction

Volatility models measure the historical volatility of an asset. They are mostly used to calculate the volatility of the underlying security of an Option because the Greeks and implied volatility of Option contracts are a function of historical volatility. The historical volatility doesn't need to be the standard deviation of the asset prices. The various volatility models in LEAN each have a unique methodology to calculate volatility.

Set Models

To set the volatility model of the underlying security of an Option, set the VolatilityModel property of the Security object. The volatility model can have a different resolution than the underlying asset subscription.

// In Initialize
var underlyingSecurity= AddEquity("SPY");
underlyingSecurity.VolatilityModel = new StandardDeviationOfReturnsVolatilityModel(30);
# In Initialize
underlying_security = self.AddEquity("SPY")
underlying_security.VolatilityModel = StandardDeviationOfReturnsVolatilityModel(30)

You can also set the volatility model in a security initializer. If your algorithm has a universe of underlying assets, use the security initializer technique. In order to initialize single security subscriptions with the security initializer, call SetSecurityInitializer before you create the subscriptions.

// In Initialize
SetSecurityInitializer(CustomSecurityInitializer);
AddEquity("SPY");

private void CustomSecurityInitializer(Security security)
{
    if (security.Type == SecurityType.Equity)
    {
        security.VolatilityModel = new StandardDeviationOfReturnsVolatilityModel(30);
    }
}
# In Initialize
self.SetSecurityInitializer(self.CustomSecurityInitializer)
AddEquity("SPY")

def CustomSecurityInitializer(self, security: Security) -> None:
    if security.Type == SecurityType.Equity:
        security.VolatilityModel = StandardDeviationOfReturnsVolatilityModel(30)

To view all the pre-built volatility models, see Supported Models.

Default Behavior

The default underlying volatility model for Equity Options and Index Options is the StandardDeviationOfReturnsVolatilityModel based on 30 days of daily resolution data. The default underlying volatility model for Future Options is the NullVolatilityModel.

Model Structure

Volatility models should extend the BaseVolatilityModel class. Extensions of the BaseVolatilityModel class must have Update and GetHistoryRequirements methods and a Volatility property. The Update method receives Security and BaseData objects and then updates the Volatility. The GetHistoryRequirements method receives Security and DateTimedatetime objects and then returns a list of HistoryRequest objects that represent the history requests to warm up the model. Volatility models receive data at each time step in the algorithm to update their state.

public class MyVolatilityModel : BaseVolatilityModel
{
    public override decimal Volatility { get; }

    public override void SetSubscriptionDataConfigProvider(
        ISubscriptionDataConfigProvider subscriptionDataConfigProvider)
    {
        SubscriptionDataConfigProvider = subscriptionDataConfigProvider;
    }

    public override void Update(Security security, BaseData data)
    {
    }

    public override IEnumerable<HistoryRequest> GetHistoryRequirements(
        Security security,
        DateTime utcTime)
    {
        return base.GetHistoryRequirements(security, utcTime);
    }

    public IEnumerable<HistoryRequest> GetHistoryRequirements(
        Security security, 
        DateTime utcTime,
        Resolution? resolution,
        int barCount)
    {
        return base.GetHistoryRequirements(security, utcTime, resolution, barCount);
    }
}
class MyVolatilityModel(BaseVolatilityModel):
    Volatility: float = 0

    def SetSubscriptionDataConfigProvider(self,
         subscriptionDataConfigProvider: ISubscriptionDataConfigProvider) -> None:
        SubscriptionDataConfigProvider = subscriptionDataConfigProvider

    def Update(self, security: Security, data: BaseData) -> None:
        pass

    def GetHistoryRequirements(self,
         security: Security,
         utcTime: datetime,
         resolution: Resolution = None,
         barCount: int = None) -> List[HistoryRequest]:
        return super().GetHistoryRequirements(security, utcTime, resolution, barCount)

Warm Up Models

To get the Option pricing model to accurately calculate the implied volatility, Greeks, and theoretical prices, you need to warm up the volatility model on the underlying security. If you add all options with the AddOption method, set a warm-up period to warm up their volatility models. The warm-up period should provide the volatility models with enough data to compute their values.

// In Initialize
SetWarmUp(30, Resolution.Daily);

// In OnData
if (IsWarmingUp) return;
# In Initialize
self.SetWarmUp(30, Resolution.Daily)

# In OnData
if self.IsWarmingUp:
    return

If you have a dynamic universe of underlying assets and add Option contracts to your algorithm with the AddOptionContract method, you need to warm up the volatility model when the underlying asset enters your universe. We recommend you do this inside a security initializer.

// In Initialize
SetSecurityInitializer(CustomSecurityInitializer);

private void CustomSecurityInitializer(Security security)
{
    if (security.Type == SecurityType.Equity)
    {
        security.VolatilityModel = new StandardDeviationOfReturnsVolatilityModel(30);
        var history = History<TradeBar>(security.Symbol, 30, Resolution.Daily);
        foreach (var tradeBar in history)
        {
            security.VolatilityModel.Update(security, tradeBar);
        }
    }
}
# In Initialize
self.SetSecurityInitializer(self.CustomSecurityInitializer)

def CustomSecurityInitializer(self, security: Security) -> None:
    if security.Type == SecurityType.Equity:
        security.VolatilityModel = StandardDeviationOfReturnsVolatilityModel(30)
        trade_bars = self.History[TradeBar](security.Symbol, 30, Resolution.Daily)
        for trade_bar in trade_bars:
            security.VolatilityModel.Update(security, trade_bar)  

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: