Providing you are a LUSID user with sufficient access control permissions, you can create an instrument to model an equity option (also known as a stock option) in the LUSID instrument master. You can then:
- Book a transaction in a portfolio to record a purchase of a number of contracts, and establish a holding (position)
- Value your position at any time using different models
- Examine the exposure of that position in combination with your other holdings
- Monitor the contract until maturity and automate the process of booking cash settlements.
You can also model rights and warrants using this model too.
Note: If you are the LUSID domain owner, you are automatically assigned the built-in lusid-administrator role, which has all the permissions necessary to perform the operations in this article.
Note there is an accompanying Jupyter Notebook that demonstrates many of the operations and concepts in this article.
Creating an underlying equity instrument
Before you can create an equity option instrument, you must first separately master the underlying equity instrument if this has not been done already. See Modelling equities in LUSID for instructions.
Creating an equity option instrument
LUSID's instrument model is designed with reference to ISDA CDM and FpML, and equity options constitute an integral part of this instrument model.
To create an instrument modelling an equity option, call the LUSID UpsertInstruments API and specify a definition with an instrumentType of EquityOption, a start date and maturity date, whether the option is a call (buy) or put (sell), and an identifier for the separately-mastered underlying equity instrument.
For more information on constructing a suitable economic definition, examine the API documentation and choose EquityOption from the dropdown box:
For example, providing you have a valid API access token, you could run the following command in your LUSID domain to create an equity option instrument for a call to buy Amazon shares, where Amazon is separately mastered in LUSID with (in this case) a LUID of LUID_OJJG8ERA:
-H "Authorization: Bearer <your-API-access-token"
-H "Content-Type: application/json-patch+json"
-d '{"upsert-request-1": {
"name": "Amazon equity option",
"identifiers": {
"ClientInternal": {
"value": "Amazon-equity-option"
}
},
"definition": {
"instrumentType": "EquityOption",
"startDate": "2022-01-13T10:00:00.0000000+00:00",
"optionMaturityDate": "2022-02-13T10:00:00.0000000+00:00",
"optionSettlementDate": "2022-02-15T10:00:00.0000000+00:00",
"deliveryType": "Physical",
"optionType": "Call",
"strike": "3400",
"domCcy": "USD",
"underlyingIdentifier": "LusidInstrumentId",
"code": "LUID_OJJG8ERA"
}
}
}'
Note the following:
- The equity option instrument itself is unitised; the quantity of contracts is determined when you book a transaction (see below).
- For a call option, strike is the price that one Amazon share must exceed ($3400 in this example) in order to profit. For a put option, Amazon must fall below the strike price.
Providing the request is valid, the response contains an automatically-generated LUID (in this case, LUID_00003D69) for the equity option instrument that is guaranteed to be unique and never change. This LUID is of course different to that of the underlying Amazon instrument. You can use this LUID to reference the equity option instrument in subsequent API calls:
{
"values": {
"upsert-request-1": {
"href": "https://<your-domain>.lusid.com/api/api/instruments/LusidInstrumentId/LUID_00003D69?scope=default",
"scope": "default",
"lusidInstrumentId": "LUID_00003D69",
"version": {
"effectiveFrom": "0001-01-01T00:00:00.0000000+00:00",
"asAtDate": "2022-02-22T12:08:21.9617050+00:00"
},
"name": "Amazon equity option",
"identifiers": {
"LusidInstrumentId": "LUID_00003D69",
"ClientInternal": "Amazon-equity-option"
},
"properties": [],
"instrumentDefinition": {
"startDate": "2022-01-13T10:00:00.0000000+00:00",
"optionMaturityDate": "2022-02-13T10:00:00.0000000+00:00",
"optionSettlementDate": "2022-02-15T10:00:00.0000000+00:00",
"deliveryType": "Physical",
"optionType": "Call",
"strike": 3400.0,
"domCcy": "USD",
"underlyingIdentifier": "LusidInstrumentId",
"code": "LUID_OJJG8ERA",
"instrumentType": "EquityOption"
},
"state": "Active",
"assetClass": "Equities",
"domCcy": "USD"
}
},
...
}
Booking a transaction to establish a position
Once the instrument is mastered, you can call the LUSID UpsertTransactions API to purchase a quantity of the equity option instrument in a particular portfolio.
Specify the quantity of units (contracts) to buy, in this case 100. The transactionPrice is the premium per contract, in this case $220. The totalConsideration is therefore the quantity of contracts multiplied by the price, in this case $22,000:
-H "Authorization: Bearer <your-API-access-token>"
-H "Content-Type: application/json-patch+json"
-d '[ {
"transactionId": "eqop-amzl-buy-01",
"type": "Buy",
"instrumentIdentifiers": {
"instrument/default/LusidInstrumentId": "LUID_00003D69"
},
"transactionDate": "2022-01-14T00:00:00.0000000+00:00",
"settlementDate": "2022-01-16T00:00:00.0000000+00:00",
"units": 100,
"transactionPrice": {
"price": 220,
"type": "Price"
},
"totalConsideration": {
"amount": 22000.00,
"currency": "USD"
}
}
]'
Note this transaction uses the built-in Buy transaction type, but you could define your own custom transaction type to represent equity option purchases if you wish.
You can confirm your position at any time by calling the LUSID GetHoldings API with the appropriate LUID:
-H "Authorization: Bearer <your-API-access-token>"
Valuing your position
To value your position, you must load suitable market data into LUSID and then create a valuation recipe.
In your recipe, you can choose between two valuation models. Specify:
- ConstantTimeValueOfMoney to ignore the time value of an option, and report just the simple intrinsic value (or the payout if expiry was now). You only need load quotes for the underlying instrument to generate the valuation.
- BlackScholes to achieve the same effect, but to take into account the impact of time and other risk factors. This is the classic option valuation method and requires a yield curve to gather the discount factor and a volatility point or surface for the volatility input, in addition to quotes for the underlying instrument. The returns are available as follows: Price and Delta, Gamma, Rho, Theta and Vega ("the Greeks").
For a demonstration of loading quotes and the ConstantTimeValueOfMoney valuation model, see sections 4 and 5 of the accompanying Jupyter Notebook.
Assessing risk
LUSID calculates exposure for an equity option contract as Contract Size * Underlying Equity Price * Delta.
You can use LUSID to calculate first and second order risks from the option contract itself. Section 4 of the accompanying Jupyter Notebook shows the market data that you must create and save to LUSID first, and section 5 shows how to extract the values. Contact Technical Support if you need more information.
Managing P&L on a regular basis
For equity options, P&L is managed cumulatively for the lifetime of the contract. As demonstrated in section 5.3 of the accompanying Jupyter Notebook, the contract displays as a single line entry. The Present Value column in the valuation tables shows the (lifetime) unrealised contract gain.
The graph in section 5.3 shows how the value of the underlying Amazon stock changes over time. As the instrument is a call option, it only has value when the underlying stock price rises above the strike price of $3400. When this occurs, the option value is the difference between the price of the underlying and the strike price, multiplied by the number of contracts. When the underlying price falls below the strike price, the value of the instrument is zero.
Closing your position and booking cash settlements
An instrument representing an equity option contract has a maturity date that you specify when you create the instrument.
As the instrument nears maturity, you must make decisions. You may be able to close out during the life of the contract as part of a bilateral arrangement, or you may have to hold until maturity. If an option is “in the money" it is common for a buyer to notify the seller that the position should be exercised (contrast this with exchange-traded options where this is handled automatically by the exchange).
Once the contract has matured, the exercise price is input and final calculations made. See Section 6 of the accompanying Jupyter Notebook for a demonstration of settling our Amazon equity option held until maturity by booking a cash transaction for the cost (100 x $3400 = $340,000) followed by a transaction using the built-in StockIn transaction type for the number of “in the money” shares delivered.
You can monitor the contract during its lifetime in several ways:
- Use the Cash Ladder dashboard in the LUSID web app.
- Call the LUSID GetPortfolioCashLadder API directly.
- Schedule a job to create a regular report.
This mitigates the risk of missing exercise dates or closing out of open positions.
When an instrument cashflow or maturity event occurs in LUSID, it's important to note two things:
- The cashflows are assumed to have been paid but are not presently auto-generated as such. This means the instrument or cashflow from the instrument drops out of your valuation. We will shortly implement ‘automatic settlement’, so that you can choose to auto-generate the appropriate cashflow or instrument, link it to the contract or instrument in question, and upsert it to the portfolio.
For now, this must be done manually, using either the Manage Cashflows dashboard in the LUSID web app, or by calling the LUSID GetUpsertablePortfolioCashFlows API, which returns imminent cashflows as upsertable DTOs ready to push into LUSID as transactions. If you’d like to track the position P&L of the instrument, you need to upsert settlement amounts with the same strategy tag you used for the main position at the time of booking. When you view your PV, you can then group by strategy tag. - An instrument cannot ‘expire’ in LUSID; it is still available post-maturity, although the valuation is 0. If you set your holding to 0, it will no longer appear in reports unless you are deliberately backdating. For a demonstration, see section 7.3 of the Jupyter Notebook.