Documentation Index

Fetch the complete documentation index at: https://support.lusid.com/llms.txt

Use this file to discover all available pages before exploring further.

Handling exercise and expiry events for option instruments

Prev Next

You can model:

  • An exchange-traded options contract as an instrument of type ExchangeTradedOption in LUSID. See how to do this. Note instrument events are only available for ETOs with an underlying of Equity or Future. Other underlyings do not support instrument events.

  • An OTC equity options contract as an instrument of type EquityOption. See how to do this.

Note: This tutorial uses an ExchangeTradedOption instrument as an example but the information applies equally to EquityOption.

LUSID can emit the following instrument lifecycle events for ExchangeTradedOption and EquityOption, which you can handle to reduce workload and improve efficiency:

  • OptionExercisePhysicalEvent. This event is not automatically emitted by LUSID, but can be manually triggered to exercise an in-the-money physically-settled option at the strike price. More information.

  • OptionExerciseCashEvent. This event is not automatically emitted by LUSID, but can be manually triggered to exercise an in-the-money cash-settled option, providing an exercise price for the underlying has been loaded into the LUSID Quote Store. More information.

  • ExpiryEvent. This event is automatically emitted by LUSID on the expiry date, but only if you have chosen not to exercise. More information.

Mastering instruments and establishing positions

Imagine we have a options contract on BMW shares trading on the Eurex exchange with the following characteristics. See how to set this scenario up.

ExchangeTradedOption instrument

Purchase transaction

  • Contract size: 100

  • Contracts: 1

  • Strike price: 80

  • Start date: 15 Jan 2025

  • Maturity date: 21 Mar 2025

  • Units: 1000

  • Price (of option): 3.13

  • Fees: 0.17  1000 = 170

  • Cost: (1000  3.13 * 100) + 170 = 313,170

  • Transaction date: 13 Jan 2025

  • Settlement date: 16 Jan 2025

Exercising a physically-settled option

If the deliveryType of the ExchangeTradedOption is Physical, we can choose to exercise an in-the-money option by triggering LUSID to emit OptionExercisePhysicalEvent.

Note: No market data is required to exercise a physically-settled option. LUSID exercises at the strike price specified in the instrument definition.

To do this:

  1. Create a corporate action source and subscribe the portfolio to it. See how to do this.

  2. Create transaction types for the transactions automatically generated by OptionExercisePhysicalEvent. More information.

  3. Load an event instruction (not the event itself) into the portfolio to trigger OptionExercisePhysicalEvent on a particular date. More information.

Note: For an implementation using the Python SDK, see this Jupyter Notebook.

Creating suitable transaction types

To handle OptionExercisePhysicalEvent we must create at least two transaction types:

  • For any ExchangeTradedOption, we must create PhysicallySettledOptionExercise to reduce the units and cost of the exercised instrument down to zero, so it drops out of holding and valuation reports. See our recommendation.

  • If the optionType of the ExchangeTradedOption is Call, we must create CallOptionPhysicalExercise to buy the underlying instrument at the strike price. See our recommendation.

  • If the optionType of the ExchangeTradedOption is Put, we must create PutOptionPhysicalExercise to sell the underlying instrument at the strike price. See our recommendation.

Loading an event instruction to trigger OptionExercisePhysicalEvent

We can call the UpsertInstrumentEventInstructions API to load an event instruction (not the event itself) into the portfolio and trigger OptionExercisePhysicalEvent:

  • If the exerciseType of our option is American, we can exercise earlier than the expiry date of the option (21 March 2025) by specifying the entitlementDateInstructed field with an exercise date of (for example) 28 February 2025.

  • If the exerciseType is European, we can only exercise on the expiry date so the entitlementDateInstructed field is disabled.

{
    "instrumentEventInstructionId": "ExerciseAmericanCallOptionOnBMW-2025-02-28",
    "instrumentEventId": "LUID_00003EB8_OptionExercisePhysicalEvent_American",
    "instructionType": "ElectForHolding",
    "holdingId": 75498862,
    "electionKey": "exercise",
    "entitlementDateInstructed": "2025-02-28T00:00:00.0000000+00:00"
}

For more information on event instructions, see this article. Note the following:

  • The instrumentEventInstructionId can be any intuitive string that uniquely identifies this event instruction in this portfolio.

  • The instrumentEventId must be the unique identifier of the OptionExercisePhysicalEvent (see below for how to find this out).

  • The instructionType is ElectForHolding to apply the event to our option holding in the portfolio.

  • The holdingId must be the unique identifier for this holding (see below).

  • The electionKey must be exercise to trigger LUSID to emit the event.

  • The entitlementDateInstructed field is set to the date we wish to exercise (American options only).

To discover the instrumentEventId and holdingId, call the QueryApplicableInstrumentEvents API for the portfolio, for example:

{
  "values": [
    {
      "portfolioId": {"scope": "UKEquities", "code": "MyPortfolio"},
      "lusidInstrumentId": "LUID_00003EB8",
      "instrumentType": "ExchangeTradedOption",
      "instrumentEventType": "OptionExercisePhysicalEvent",
      "instrumentEventId": "LUID_00003EB8_OptionExercisePhysicalEvent_American"
      "holdingId": 75498862,
      ...

Examining the impact of OptionExercisePhysicalEvent on the portfolio

This example demonstrates exercising an in-the-money American call option early.

15 January

We can use the Portfolio Management > Holdings dashboard in the LUSID web app to call the GetHoldings API on the settlement date of the option purchase to see that we start with:

  • An option holding for 1000 units at a cost of 313,710

  • A currency holding for  -€313,710:

28 February

On 28 February we load the event instruction to exercise our option early and then examine holdings again:

  • The option holding has been removed since units and cost are now zero. Note there is no P&L associated with this movement.

  • A holding in the underlying BMW equity instrument has been established, with the units set to the number of BMW shares purchased (1000 × 100 = 100,000) and the cost to those shares at the strike price plus the cost of the option: (100,000 × 80) + 313,170 = 8,313,170.

  • The currency holding reflects the total cost of establishing the BMW holding: -€8,313,710:

We can use the Portfolio Management > Transactions dashboard in Output mode to call the BuildTransactions API with a suitable window to examine the output transactions generated by this event:

Exercising a cash-settled option

If the deliveryType of the ExchangeTradedOption is Cash, we can choose to exercise an in-the-money option by triggering LUSID to emit OptionExerciseCashEvent. To do this:

  1. Create a corporate action source and subscribe the portfolio to it. See how to do this.

  2. Create a CashSettledOptionExercise transaction type for the transaction automatically generated by OptionExerciseCashEvent to reduce the position of the option instrument down to zero and increase cash. See our recommendation.

  3. Load an event instruction (not the event itself) into the portfolio to trigger OptionExerciseCashEvent on a particular date. More information.

  4. Load an exercise price for the underlying instrument on that date into the LUSID Quote Store. More information.

Note: For an implementation using the Python SDK, see this Jupyter Notebook.

Loading an event instruction to trigger OptionExerciseCashEvent

We can call the UpsertInstrumentEventInstructions API to load an event instruction (not the event itself) into the portfolio and trigger OptionExerciseCashEvent:

  • If the exerciseType of our option is American, we can exercise earlier than the expiry date of the option (21 March 2025) by specifying the entitlementDateInstructed field with an exercise date of (for example) 28 February 2025.

  • If the exerciseType is European, we can only exercise on the expiry date so the entitlementDateInstructed field is disabled.

{
    "instrumentEventInstructionId": "ExerciseAmericanCallOptionOnBMW-2025-02-28",
    "instrumentEventId": "LUID_00003EB8_OptionExerciseCashEvent_American",
    "instructionType": "ElectForHolding",
    "holdingId": 75498862,
    "electionKey": "exercise",
    "entitlementDateInstructed": "2025-02-28T00:00:00.0000000+00:00"
}

For more information on event instructions, see this article. Note the following:

  • The instrumentEventInstructionId can be any intuitive string that uniquely identifies this event instruction in this portfolio.

  • The instrumentEventId must be the unique identifier of the OptionExerciseCashEvent (see below for how to find this out).

  • The instructionType is ElectForHolding to apply the event to our option holding in the portfolio.

  • The holdingId must be the unique identifier for this holding (see below).

  • The electionKey must be exercise to trigger LUSID to emit the event.

  • The entitlementDateInstructed field is set to the date we wish to exercise (American options only).

To discover the instrumentEventId and holdingId, call the QueryApplicableInstrumentEvents API for the portfolio, for example:

{
  "values": [
    {
      "portfolioId": {"scope": "UKEquities", "code": "MyPortfolio"},
      "lusidInstrumentId": "LUID_00003EB8",
      "instrumentType": "ExchangeTradedOption",
      "instrumentEventType": "OptionExerciseCashEvent",
      "instrumentEventId": "LUID_00003EB8_OptionExerciseCashEvent_American"
      "holdingId": 75498862,
      ...

Loading an exercise price for the underlying instrument on the exercise date

We must call the UpsertQuotes API to load an exercise price for the underlying BMW equity instrument into the LUSID Quote Store:

  • If the optionType of our option is Call, we must load an exercise price greater than the strike price specified in the option instrument definition (in our case 80), for example 85.

  • If the optionType is Put, we must load an exercise price lower than the strike price.

curl -X POST 'https://<your-domain>.lusid.com/api/api/quotes/MyOptionExercisePricesScope'
  -H 'Authorization: Bearer <your-API-access-token>'
  -H 'Content-Type: application/json-patch+json'
  -d '{
  "Quote-0001": {
    "quoteId": {
      "quoteSeriesId": {
        "provider": "Lusid",
        "instrumentIdType": "Isin",
        "instrumentId": "DE0005190003",
        "quoteType": "Price",
        "field": "mid"
      },
      "effectiveAt": "2025-02-28T00:00:00Z"
    },
    "metricValue": {
      "value": 85, "unit": "EUR"
    }
  },

Note the following:

  • We recommend exercise prices are loaded into a dedicated quote scope, for example MyOptionExercisePricesScope (specified in the URL).

  • The instrumentIdType must be Isin.

  • The instrumentId must be registered as an ISIN identifier for the underlying instrument.

  • The effectiveAt must be the exercise date, so 28 February 2025 for our American option. Note this must be the expiry date for a European option.

In order to locate this exercise price, the portfolio recipe must have a market rule with:

  • The key field set to Quote.Isin.* to look up quotes loaded with an ISIN identifier.

  • The dataScope field set to MyOptionExercisePricesScope to search the correct quote scope, for example:

"market": {
  "marketRules": [
    {
      "key": "Quote.Isin.*",
      "supplier": "Lusid",
      "dataScope": "MyOptionExercisePricesScope",
      "quoteType": "Price",
      "field": "mid",
      "quoteInterval": "1D.0D"
    },
    ...
  ]
}

Examining the impact of OptionExerciseCashEvent on the portfolio

This example demonstrates exercising an in-the-money American call option early.

15 January

We can use the Portfolio Management > Holdings dashboard in the LUSID web app to call the GetHoldings API on the settlement date of the option purchase to see that we start with:

  • An option holding for 1000 units at a cost of 313,710

  • A currency holding of -€313,710:

28 February

On 28 February we load the event instruction to exercise our option early and then examine holdings again:

  • The option holding has been removed since units are now zero.

  • The currency holding reflects the total consideration (1000 × 100 × 5 = 500000) added to the original negative cost:

We can use the Portfolio Management > Transactions dashboard in Output mode to call the BuildTransactions API with a suitable window to examine the output transaction generated by this event:

To audit P&L associated with this transaction, click the button at the end of the row (highlighted in yellow above):

Expiring an unexercised option

If we do not exercise an option before the maturity date specified in the instrument definition, LUSID automatically emits an ExpiryEvent. Note this event is not emitted if we do exercise.

To handle this event, we must create an Expiry transaction type. See our recommendation.

Examining the impact of ExpiryEvent on the portfolio

15 January

We can use the Portfolio Management > Holdings dashboard in the LUSID web app to call the GetHoldings API on the settlement date of the option purchase transaction to see that we start with:

  • An option holding for 1000 units at a cost of 313,710

  • A currency holding for  -€313,710:

21 March

If we fast-forward to the expiry date we can see that the option holding has been removed (units set to zero) and the currency holding is unchanged:

We can use the Portfolio Management > Transactions dashboard in Output mode to call the BuildTransactions API with a suitable window to examine the output transaction generated by this event:

To audit P&L associated with this transaction, click the button at the end of the row (highlighted in yellow above):