You can model an exchange-traded options contract as an instrument of type ExchangeTradedOption in LUSID. See all supported instruments.
Mastering an instrument
There are numerous tools you can use to master an ExchangeTradedOption in the LUSID Security Master.
Some fields are common to all types of instrument, such as an intuitive name, the requirement to specify a set of identifiers, and the facility to store extra information as properties.
Fields in the economic definition object are specific to ExchangeTradedOption. For more information on these fields, select ExchangeTradedOption from the definition dropdown in the UpsertInstruments API reference:
.png?sv=2022-11-02&spr=https&st=2025-10-29T03%3A29%3A25Z&se=2025-10-29T03%3A49%3A25Z&sr=c&sp=r&sig=f%2BWM9uEqN%2FxYBFfWiFXPq4JKtZZvSK9uI%2BhC9sv8O80%3D)
Specifying the underlying instrument
If the asset underlying an ExchangeTradedOption is:
An equity or an exchange-traded future, the recommended approach is to master it as a separate, dedicated instrument in LUSID and provide a reference to a
MasteredInstrument. If you do this, instrument events are available. See the rest of this article for more information.A bond, interest rate, index, commodity or any other type of asset, the only option is to provide an inline definition as part of the
ExchangeTradedOption. Instrument events are not available.
Mastering an ExchangeTradedOption instrument
The following example masters a European call option on BMW shares that is itself already mastered as an instrument of type Equity in LUSID:
curl -X POST 'https://mydomain.lusid.com/api/api/instruments?scope=MyCustomInstrScope'
-H 'Content-Type: application/json-patch+json'
-H 'Authorization: Bearer myAPIAccessToken'
-d '{"upsert-request-1": {
"name": "BMW GR Equity OMON",
"identifiers": {"ClientInternal": {"value": "ETO_BMW_2024-03-21_European_Physical_Call"}},
"definition": {
"instrumentType": "ExchangeTradedOption",
"startDate": "2025-01-01T00:00:00.0000000+00:00",
"contractDetails": {
"domCcy": "EUR",
"strike": 80,
"contractSize": 100,
"country": "DE",
"deliveryType": "Physical",
"description": "BMW GR Equity OMON",
"exchangeCode": "Eurex",
"exerciseDate": "2025-03-21T00:00:00.0000000+00:00",
"exerciseType": "European",
"optionCode": "BMW",
"optionType": "Call",
"underlying": {
"instrumentType": "MasteredInstrument",
"identifiers": {"Instrument/default/Isin": "DE0005190003"}
},
"underlyingCode": "MyIDForBMWQuotes"
},
"contracts": 1,
"refSpotPrice": 0
}
}
}'Note the following:
The
ExchangeTradedOptioninstrument is mastered in a custom instrument scope (specified in the URL).Its
identifiersobject is set to reference aClientInternalunique identifier.startDateis a mandatory field but note it is not subsequently used by LUSID.contractSizeis set to the number of underlying units per contract as specified by the exchange.deliveryTypecan bePhysical(if you intend to take delivery of the underlying) orCash.exerciseTypecan beAmericanorEuropean.optionTypecan bePutorCall.The
underlyingobject must either:Have the
underlying.instrumentTypefield set toMasteredInstrumentif the underlying is already mastered in LUSID as anEquityor aFuture, and theunderlying.identifiersobject set to an identifier for that instrument, in this case an ISIN. Note the underlying must reside in the same instrument scope as theExchangeTradedOption, or else in thedefaultinstrument scope.Be populated with a full inline economic definition if the underlying is any other type of asset.
underlyingCodecan be set to any intuitive string that represents a market data identifier for the underlying instrument in the LUSID Quote Store (required for valuation).contractsshould be set to1and the amount bought or sold specified on the transaction.refSpotPriceshould be set to0unless otherwise directed by FINBOURNE Technical Support.
Providing the request is successful, the response:
Confirms the globally-unique LUID of the
ExchangeTradedOptioninstrument (in this caseLUID_00003E8Z).Confirms the LUID of the underlying
MasteredInstrumentproviding LUSID is able to resolve it correctly (in this caseLUID_00003E90). If not, the unknown instrument is returned.Generates extra fields that are stored as part of the instrument definition and can be filtered on.
Supplies default values for fields not explicitly specified in the request:
{
"values": {
"upsert-request-1": {
"scope": "MyCustomInstrScope",
"lusidInstrumentId": "LUID_00003E8Z",
"name": "BMW GR Equity OMON",
"identifiers": {
"ClientInternal": "ETO_BMW_2024-03-21_European_Physical_Call",
"LusidInstrumentId": "LUID_00003E8Z"
},
"properties": [],
"instrumentDefinition": {
"startDate": "2025-01-01T00:00:00.0000000+00:00",
"contractDetails": {
"domCcy": "EUR",
"strike": 80,
"contractSize": 100,
"country": "DE",
"deliveryType": "Physical",
"description": "BMW GR Equity OMON",
"exchangeCode": "Eurex",
"exerciseDate": "2025-03-21T00:00:00.0000000+00:00",
"exerciseType": "European",
"optionCode": "BMW",
"optionType": "Call",
"underlying": {
"identifiers": {
"Instrument/default/Isin": "DE0005190003"
},
"masteredDomCcy": "EUR",
"masteredInstrumentType": "Equity",
"masteredLusidInstrumentId": "LUID_00003E90",
"masteredName": "BMW",
"masteredScope": "MyCustomInstrScope",
"masteredAssetClass": "Equities",
"instrumentType": "MasteredInstrument"
},
"underlyingCode": "MyIDForBMWQuotes",
"deliveryDays": 0,
"businessDayConvention": "F",
"settlementCalendars": []
},
"contracts": 1,
"refSpotPrice": 0,
"tradingConventions": {
"priceScaleFactor": 1,
"minimumOrderSize": 0,
"minimumOrderIncrement": 0
},
"instrumentType": "ExchangeTradedOption"
},
"state": "Active",
"assetClass": "Unknown",
"domCcy": "EUR",
"relationships": []
}
},
...
}Booking a transaction to establish a position
Once an ExchangeTradedOption instrument is mastered, you can book a transaction to record the acquisition of a number of contracts in a particular transaction portfolio, for example:
curl -X POST 'https://mydomain.lusid.com/api/api/transactionportfolios/MyPortfolioScope/MyPortfolioCode/transactions/$batchUpsert?successMode=Partial&preserveProperties=true'
-H 'Content-Type: application/json-patch+json'
-H 'Authorization: Bearer myAPIAccessToken'
-d '{
"transactionRequest-1": {
"transactionId": "my_option_purchase_001",
"type": "BuyETO",
"instrumentIdentifiers": {"Instrument/default/LusidInstrumentId": "LUID_00003E8Z"},
"transactionDate": "2025-01-14T00:00:00.0000000+00:00",
"settlementDate": "2024-01-15T00:00:00.0000000+00:00",
"units": 1000,
"transactionPrice": {
"price": 3.13,
"type": "Price"
},
"totalConsideration": {
"amount": 0,
"currency": "EUR"
},
"properties": {
"Transaction/MyProperties/TradeCommission": {
"key": "Transaction/MyProperties/TradeCommission",
"value": {
"metricValue": {
"value": 170,
"unit": "EUR"
}
}
}
}
}
}'Note the following:
The
typefield invokes a customBuyETOtransaction type to confer a particular economic impact (see below).The
unitsfield specifies the number of contracts.The
transactionPriceobject records the market price of the options contract (not the underlying). This is used by LUSID to automatically calculate gross consideration (see below).The
totalConsiderationobject:Sets the settlement currency to
EUR.Specifies a cost of
0to enable LUSID to automatically derive total consideration (see below).
The trade commission for entering into the contract is recorded as a custom property.
Note: This example assumes the transaction, settlement and portfolio currencies are all the same. If not, you can specify exchange rates.
You might create a BuyETO transaction type as follows:
curl -X PUT 'https://mydomain.lusid.com/api/api/transactionconfiguration/types/default/BuyETO?scope=default'
-H 'Content-Type: application/json-patch+json'
-H 'Authorization: Bearer myAPIAccessToken'
-d '{
"aliases": [
{
"type": "BuyETO",
"description": "Transaction type for option purchases",
"transactionClass": "Basic",
"transactionRoles": "AllRoles",
"isDefault": false
}
],
"movements": [
{
"name": "Increase units by number purchased",
"movementTypes": "StockMovement",
"side": "Side1",
"direction": 1
},
{
"name": "Decrease cash by total cost of purchase, including commission",
"movementTypes": "CashCommitment",
"side": "Side2",
"direction": -1
}
],
"calculations": [
{
"type": "Txn:GrossConsideration"
},
{
"type": "DeriveTotalConsideration",
"formula": "Txn:GrossConsideration + Properties[Transaction/MyProperties/TradeCommission]"
}
]
}'Note the following:
The
StockMovementmovement sets the units of the holding to the number purchased in the transaction.The
CashCommitmentmovement decreases a cash balance by the total consideration.The
Txn:GrossConsiderationtransaction type calculation automatically calculates gross consideration (amount before fees) asprice * units * contract size, and stores the result in theTransaction/default/GrossConsiderationsystem property.The
DeriveTotalConsiderationtransaction type calculation automatically calculates thetotalConsideration.amountfield according to the given formula, which in this case sums gross consideration and commission.
Confirming positions
You can generate a holdings report to see the impact of the transaction on security and cash holdings, for example:
.png?sv=2022-11-02&spr=https&st=2025-10-29T03%3A29%3A25Z&se=2025-10-29T03%3A49%3A25Z&sr=c&sp=r&sig=f%2BWM9uEqN%2FxYBFfWiFXPq4JKtZZvSK9uI%2BhC9sv8O80%3D)
Auditing LUSID’s transaction type calculations
You can examine the output transaction automatically generated by LUSID to audit calculated amounts, for example:
.png?sv=2022-11-02&spr=https&st=2025-10-29T03%3A29%3A25Z&se=2025-10-29T03%3A49%3A25Z&sr=c&sp=r&sig=f%2BWM9uEqN%2FxYBFfWiFXPq4JKtZZvSK9uI%2BhC9sv8O80%3D)
Valuing your position
To value your position, work through our valuation checklist.
Pricing model | Notes |
|---|---|
| Recommended. This is the default. Calculates PV according to the formula
See below for an example. |
For example, to value a position in the European call option on BMW shares defined above using SimpleStatic:
Load two market prices into the LUSID Quote Store for the valuation date, in this case 11 February 2025:
curl -X POST 'https://mydomain.lusid.com/api/api/quotes/MyOptionQuotes' -H 'Authorization: Bearer myAPIAccessToken' -H 'Content-Type: application/json-patch+json' -d '{ "Quote-0001": { "quoteId": { "quoteSeriesId": { "provider": "Lusid", "instrumentIdType": "LusidInstrumentId", "instrumentId": "LUID_00003E8Z", "quoteType": "Price", "field": "mid" }, "effectiveAt": "2025-02-11T00:00:00Z" }, "metricValue": { "value": 3.15, "unit": "EUR" } }, "Quote-0002": { "quoteId": { "quoteSeriesId": { "provider": "Lusid", "instrumentIdType": "LusidInstrumentId", "instrumentId": "MyIDForBMWQuotes", "quoteType": "Price", "field": "mid" }, "effectiveAt": "2025-02-11T00:00:00Z" }, "metricValue": { "value": 82, "unit": "EUR" } } }'Note the following:
The first price is for the
ExchangeTradedOptioninstrument and the second for the underlyingEquityinstrument.Both are encapsulated in a
MyOptionQuotesquote scope (specified in the URL).The
instrumentIdTypefield isLusidInstrumentId.The
instrumentIdfield for:The
ExchangeTradedOptioninstrument is its LUID.The underlying
Equityinstrument is theunderlyingCodespecified in theExchangeTradedOptioninstrument definition, in this caseMyIDForBMWQuotes.
Create a recipe to locate this market data, for example:
curl -X POST 'https://mydomain.lusid.com/api/api/recipes' -H 'Content-Type: application/json-patch+json' -H 'Authorization: Bearer myAPIAccessToken' -d '{ "configurationRecipe": { "scope": "MyRecipes", "code": "MyBasicRecipe", "market": { "marketRules": [ { "key": "Quote.LusidInstrumentId.*", "dataScope": "MyOptionQuotes", "supplier": "Lusid", "quoteType": "Price", "field": "mid" } ] } } }'Note the following:
The
keyfield has a prefix ofQuote.LusidInstrumentId.and a suffix of*(wildcard) to find prices keyed by both LUID andunderlyingCode.The
dataScopefield matches the quote scope in which prices are encapsulated in the LUSID Quote Store.The other fields match their respective quote fields exactly (values are case-sensitive).
Generate a valuation report with appropriate metrics, for example:
.png?sv=2022-11-02&spr=https&st=2025-10-29T03%3A29%3A25Z&se=2025-10-29T03%3A49%3A25Z&sr=c&sp=r&sig=f%2BWM9uEqN%2FxYBFfWiFXPq4JKtZZvSK9uI%2BhC9sv8O80%3D)
Assessing risk
For more on how LUSID calculates exposure, see this article.
LUSID supports both analytic and bump and valuation mechanisms for assessing risk; contact Technical Support if you need more information.
Monitoring the lifecycle of the instrument
An ExchangeTradedOption has an exercise date specified when you master that instrument. If you do not exercise the option on or before that date, the instrument ‘expires’.
Note: An instrument in LUSID is still available post-expiry, although the valuation is zero. If you set your holding to zero it no longer appears in reports unless you are deliberately backdating.
Handling automatic lifecycle events
LUSID is transitioning to a system where it automatically emits lifecycle events for supported instruments. We provide default transaction templates that you can use as-is to automatically generate transactions in impacted portfolios, and recommendations for transaction types that deliver appropriate economic impacts.
Contact us to turn this feature on in your environment. The following events are available for an ExchangeTradedOption:
Instrument event type | Event emission criteria | If emitted, effect of LUSID default transaction template | Recommendations for transaction types |
|---|---|---|---|
| This event is not automatically emitted by LUSID. If your holding is in the money, it can be triggered by loading an event instruction, providing the | One transaction is automatically generated with the realised gain. | |
| This event is not automatically emitted by LUSID. If your holding is in the money, it can be triggered by loading an event instruction, providing the | Two transactions are automatically generated, one for the | |
| This event is automatically emitted by LUSID on the expiry date, but only if either | One transaction is automatically generated setting the option holding to zero and realising a loss. |
Manually loading settlement transactions
If you do not want to turn on automatic instrument lifecycle events you can continue to monitor upcoming cashflows using Dashboards > CashLadder in the LUSID web app, or by calling the GetPortfolioCashLadder API directly.
You can call the GetUpsertablePortfolioCashFlows API to  return imminent cashflows as upsertable DTOs ready to manually load into LUSID as input transactions.