Options Models

Exercise

Introduction

If you exercise a long Option position or are assigned on your short Option position, LEAN processes an Option exercise order. The Option exercise model converts the Option exercise order into an OrderEvent.

Set Models

To set the exercise model of an Option, call the SetOptionExerciseModel method of the Option object.

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

// In Initialize
var option = AddOption("SPY");
option.SetOptionExerciseModel(new DefaultExerciseModel());
# In Initialize
option = AddOption("SPY")
option.SetOptionExerciseModel(DefaultExerciseModel())

Otherwise, set the assignment model in a security initializer.

// In Initialize
SetSecurityInitializer(new MySecurityInitializer(BrokerageModel, new FuncSecuritySeeder(GetLastKnownPrices)));

// Outside of the algorithm class
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 exercise model        
        if (security.Type == SecurityType.Option) // Option type
        {
            option.SetOptionExerciseModel(new DefaultExerciseModel());
        }    
    }
}
# In Initialize
self.SetSecurityInitializer(MySecurityInitializer(self.BrokerageModel, FuncSecuritySeeder(self.GetLastKnownPrices)))

# 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 exercise model        
        if security.Type == SecurityType.Option: # Option type
            option.SetOptionExerciseModel(DefaultExerciseModel())

Default Behavior

The default Option exercise model is the DefaultExerciseModel. The DefaultExerciseModel fills exercise orders to the full quantity with zero fees and applies an order tag to represent if the order is an exercise or assignment. To view the implementation of this model, see the LEAN GitHub repository.

Model Structure

Option exercise models should implement the IOptionExerciseModel interface. The IOptionExerciseModel interface must implement the OptionExercise method, which receives Option and OptionExerciseOrder objects and then returns a list of OrderEvent objects that contain the order fill information.

Option exercise models must implement the OptionExercise method, which receives Option and OptionExerciseOrder objects and then returns a list of OrderEvent objects that contain the order fill information.

public class MyExerciseModel : IOptionExerciseModel
{
    public override IEnumerable<OrderEvent> OptionExercise(Option option, OptionExerciseOrder order)
    {
        var inTheMoney = option.IsAutoExercised(option.Underlying.Close);
        var isAssignment = inTheMoney && option.Holdings.IsShort;

        yield return new OrderEvent(
            order.Id,
            option.Symbol,
            option.LocalTime.ConvertToUtc(option.Exchange.TimeZone),
            OrderStatus.Filled,
            Extensions.GetOrderDirection(order.Quantity),
            0.0m,
            order.Quantity,
            OrderFee.Zero,
            "Tag"
        ) { IsAssignment = isAssignment };
    }
}
class MyExerciseModel:
    def OptionExercise(self, option: Option, order: OptionExerciseOrder) -> List[OrderEvent]:
        in_the_money = option.IsAutoExercised(option.Underlying.Close)
        is_assignment = in_the_money and option.Holdings.IsShort

        order_event = OrderEvent(
            order.Id,
            option.Symbol,
            Extensions.ConvertToUtc(option.LocalTime, option.Exchange.TimeZone),
            OrderStatus.Filled,
            Extensions.GetOrderDirection(order.Quantity),
            0.0,
            order.Quantity,
            OrderFee.Zero,
            "Tag"
        )
        order_event.IsAssignment = is_assignment
        return [ order_event ]

OptionExerciseOrder objects have the following properties:

The following table describes the arguments of the OrderEvent constructor:

Argument Details

Argument: orderId

Id of the parent order

Data Type: int | Default Value: -

Argument: symbol

Asset Symbol

Data Type: Symbol | Default Value: -

Argument: utcTime

Date/time of this event

Data Type: DateTimedatetime | Default Value: -

Argument: direction

The direction of the order. The OrderDirection enumeration has the following members:

Data Type: OrderDirection | Default Value: Hold

Argument: fillPrice

Fill price information if applicable

Data Type: decimalfloat | Default Value: 0

Argument: fillQuantity

Fill quantity

Data Type: decimalfloat | Default Value: 0

Argument: orderFee

The order fee. You can use OrderFee.Zero or create an OrderFee object with a custom fee.

new OrderFee(new CashAmount(0.5m, "USD"));OrderFee(CashAmount(0.5, 'USD'))

Data Type: OrderFee | Default Value: -

Argument: message

Message from the exchange

Data Type: stringstr | Default Value: ""

OrderEvent objects have the following attributes:

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: