Modelling FX options in LUSID

Prev Next

You can model a currency options contract as an instrument of type FxOption in LUSID. See all supported instruments.

Note there is an accompanying Jupyter Notebook that demonstrates many of the operations and concepts in this article. The Notebook contains two examples with different settlement types; this article concentrates on option 1 (settling with FX delivery).

Mastering an instrument

There are numerous tools you can use to master a FxOption 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 FxOption. For more information on these fields, select FxOption from the definition dropdown in the UpsertInstruments API reference, or alternatively examine the FxOption schema:

Note: Unlike an equity option, there is no need to master an underlying instrument.

The following example masters a FxOption call on the EUR domestic currency with a strike of 1.205 and a 30D maturity, settling with FX delivery and a non-digital payoff:

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": "EUR/USD FX Option",
    "identifiers": {
      "ClientInternal": {
        "value": "EURUSD FX Option",
      }
    },
    "definition": {
      "instrumentType": "FxOption",
      "startDate": "2021-01-20T00:00:00.0000000+00:00",
      "domCcy": "EUR",
      "fgnCcy": "USD",
      "strike": 1.205,
      "exerciseType": "European",
      "isCallNotPut": "true",
      "isDeliveryNotCash": "true",
      "isPayoffDigital": "false",
      "optionMaturityDate": "2021-02-19T00:00:00.0000000+00:00",
      "optionSettlementDate": "2021-02-21T00:00:00.0000000+00:00",
    }
  }
}'

Note the following about this example:

  • The instrument is mastered in a custom instrument scope (specified in the URL).

  • The identifiers object is set to reference a ClientInternal unique identifier.

  • The exerciseType is European but it could be American.

  • The instrument is unitised; the domAmount and fgnAmount fields are omitted (default to 1) and the quantity of contracts purchased is specified on the transaction (see below).

  • The premium object is also omitted and we recommend this is also booked on the transaction.

  • For a call option, the strike is the EUR/USD exchange rate that must be exceeded (1.205 in this example) in order to profit. For a put option, the EUR/USD exchange rate must fall below the strike in order to profit.

Providing the request is successful, the response:

  • Confirms the globally-unique LUID of the instrument.

  • 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": {
    "request_id_1": {
      "scope": "MyCustomInstrScope",
      "lusidInstrumentId": "LUID_00003DGB",
      "name": "EUR/USD FX Option",
      "identifiers": {
        "ClientInternal": "EURUSD FX Option",
        "LusidInstrumentId": "LUID_00003DGB"
      },
      "properties": [],
      "instrumentDefinition": {
        "startDate": "2021-01-20T00:00:00.0000000+00:00",
        "domCcy": "EUR",
        "fgnCcy": "USD",
        "strike": 1.205,
        "barriers": [],
        "exerciseType": "European",
        "isCallNotPut": true,
        "isDeliveryNotCash": true,
        "isPayoffDigital": false,
        "optionMaturityDate": "2021-02-19T00:00:00.0000000+00:00",
        "optionSettlementDate": "2021-02-21T00:00:00.0000000+00:00",
        "payoutStyle": "None",
        "touches": [],
        "instrumentType": "FxOption"
      },
      "state": "Active",
      "assetClass": "FX",
      "domCcy": "EUR",
      "relationships": []
    }
  },
  ...
}

Booking a transaction to establish a position

Once an EquityOption 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": "fxop-eurusd-buy-01",
    "type": "StockIn",
    "instrumentIdentifiers": {
      "instrument/default/LusidInstrumentId": "LUID_00003DGB"
    },
    "transactionDate": "2021-01-20T00:00:00.0000000+00:00",
    "settlementDate": "2021-01-22T00:00:00.0000000+00:00",
    "units": 1000000,
    "transactionPrice": {
      "price": 0.02,
      "type": "Price"
    },
    "totalConsideration": {
      "amount": 20000,
      "currency": "EUR"
    }
  }
}'

Note the following:

  • This example uses the built-in StockIn transaction type, but you can create your own transaction type to represent FX option purchases if you wish.

  • The units field records the number of contracts purchased.

  • The transactionPrice.price field records the premium per contract.

  • The totalConsideration.amount field records the total premium paid: 0.02 * 1000000 = 20000.

You can confirm your position at any time by calling the GetHoldings API with the appropriate LUID:

curl -X GET "https://<your-domain>.lusid.com/api/api/transactionportfolios/<scope>/<code>/holdings?filter=instrumentUid%20eq%20%27LUID_00003DGB%27"
   -H "Authorization: Bearer <your-API-access-token>"

Valuing your position

To value your FX option position, you must first load the following market data into LUSID:

  • EUR/USD FX spot rates into the LUSID quote store. These are required for any date on which you want to value the option, and to convert spot cash between the different currencies in the option.

  • EUR and USD discount curves into the LUSID complex market data store. You must create and upsert two OIS curves, one for EUR and one for USD; these curves can be constructed from spot instruments, forwards, or discounts. Take special notice of the discount curve keys when loaded into the store, for example EUR/EUROIS and USD/USDOIS, as you will need to specify these in the recipe when pricing the FX option.

  • At-the-money forward volatilities in the LUSID complex market data store. You must create and upsert a volatility curve comprising a set of at-the-money forward volatility rates for each tenor in the market data.

For a demonstration of loading all these types of market data into LUSID, see section 4 of the accompanying Jupyter Notebook.

Once this market data is loaded you can create a valuation recipe to drive the valuation of the FX option. In the recipe, you must reference the market data and specify the BlackScholes pricing model. This is the classic option valuation model returning price, delta, Gamma, Rho, Theta, and Vega ("the Greeks"). Section 5 of the Notebook demonstrates how to create a recipe to value a FX option.

Section 6 of the Notebook shows how to value the FX option on the trade date (20 January 2021). With the market data and valuation recipe in place, you can call the GetValuation API to return its present value (shown in the Market Value columns in the Notebook). If you chose to book the option premium on the instrument, this is included in the valuation until the premium settlement date has been reached, at which point the value drops out. The delta (shown in Valuation/Delta columns in the Notebook) indicates how much the option price would change with a change in the underlying. For options that are far out-of-the-money, the delta tends towards 0. For options that are far in-the-money, the delta tends towards 1. For an at-the-money option, the delta is around 0.5. 

You can call the GetValuation API again for trade date + 3 days to roll the FX option forward beyond the premium settlement date to value the FX option without the premium.

Assessing risk

LUSID calculates exposure for a FX option contract as QTY * FX Spot * Delta.

You can use LUSID to calculate first and second order risks from the option contract itself. Contact Technical Support if you need more information.

Managing P&L on a regular basis

For FX options, P&L is managed cumulatively for the lifetime of the contract. As shown in section 6 of the accompanying Jupyter Notebook, the example contract described here is shown as the first line entry. The Market Value column in the table shows the (lifetime) unrealised contract gain or loss.

As the instrument is a call option, it only has value at expiry if the EUR/USD forward rate rises above the strike of 1.205. When this occurs, the intrinsic value of the option on the expiry date is the difference between the EUR/USD forward rate and the strike rate, multiplied by the number of contracts. If the EUR/USD forward rate falls below the strike rate at expiry, the value of the holding is 0 (zero).

Typically, a call FX option is bought, as in this case, when it is thought the base currency (EUR) will strengthen against the quote currency (USD) over the period to maturity; this can yield unlimited upside. When the base currency weakens against the quote currency, the loss is limited to the premium that has already been paid.

Closing your position and booking cash settlements

As the instrument nears maturity, you must make decisions. If an option is in-the-money, it is common for a buyer to notify the seller that the position should be exercised.

You can monitor the contract during its lifetime in several ways:

These LUSID features help you mitigate the risk of missing exercise dates or closing out open positions.

The first example FX option 1 in the Notebook expires on 19 February 2021. As shown in section 7 of the accompanying Jupyter Notebook, if you call the GetValuation API again to value the contract on the expiry date the Valuation/Delta field has a value of either 0 or 1, indicating: 

  • 1: You can create a FX forward for EUR/USD with a strike rate of 1.205, as the option is in-the-money at maturity.

  • 0: You cannot create a FX forward for EUR/USD as the option is out-of-the-money at maturity.

When the FX option is in-the-money and you want to take physical delivery (or netted cash) depending on the settlement type agreed, it is important to note:

  1. 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 instrument (or cash flow), link it to the contract or instrument in question, and upsert it to the portfolio.
    For now, you must do this manually by using either the Manage Cashflows dashboard in the LUSID web app, or by calling the GetUpsertablePortfolioCashFlows API on the exercise date to  return and upsert the imminent cashflows into LUSID as transactions. Section 7.1 of the Notebook shows the resulting cash flows for taking physical delivery; two cash flows are generated, a total consideration of 1,000,000.00 in EUR for the domestic currency and a total consideration of -1,205,000.00 in USD for the foreign currency. For the netted cash scenario, a single cash flow is generated: this is calculated as the difference between the exercise and strike rates multiplied by the number of contracts when the option is in-the-money, and is 0 (zero) when the option is out-of-the-money.

  2. 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.