---
title: "Modelling exchange-traded futures in LUSID"
slug: "modelling-exchange-traded-futures-and-options-in-lusid"
updated: 2026-07-01T12:01:17Z
published: 2026-07-01T12:01:17Z
canonical: "support.lusid.com/modelling-exchange-traded-futures-and-options-in-lusid"
---

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

# Modelling exchange-traded futures in LUSID

You can model an exchange-traded futures contract as an instrument of type `Future` in LUSID. [See all supported instruments](/v1/docs/what-instruments-does-lusid-support).

> **See also**: This article on [instrument events](/v1/docs/handling-future-mark-to-market-and-expiry-events) and this [Jupyter Notebook implementation](https://github.com/finbourne/finbourne-notebooks/blob/main/V3/features/instrument-events/futures-and-instrument-events.ipynb).

## Mastering an instrument

There are [numerous tools](/v1/docs/how-do-i-master-an-instrument) you can use to master an instrument of type `Future` 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](/v1/docs/understanding-instrument-identifiers) of `identifiers`, and the facility to [store extra information](/v1/docs/properties) as `properties`.

Fields in the economic `definition` object are specific to `Future`. For more information on these fields, select **Future** from the definition dropdown in the [UpsertInstruments](https://www.lusid.com/docs/api/lusid/endpoints/instruments/UpsertInstruments) API reference, or alternatively examine the [Future](https://www.lusid.com/docs/api/lusid/schemas/Future/) schema:

![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image(373).png)

For example, the following call to the [UpsertInstruments](https://www.lusid.com/docs/api/lusid/endpoints/instruments/UpsertInstruments) API masters an E-mini S&P futures contract in a custom [instrument scope](/v1/docs/understanding-instrument-scopes) using a `ClientInternal` [unique identifier](/v1/docs/what-are-unique-and-non-unique-identifiers):

```json
curl -X POST 'https://<your-domain>.lusid.com/api/api/instruments?scope=MyCustomInstrScope'
   -H 'Content-Type: application/json-patch+json'
   -H 'Authorization: Bearer <your-API-access-token>'
   -d '{"upsert-request-1": {
    "name": "E-mini S&P500 March 2025",
    "identifiers": {
      "ClientInternal": {
        "value": "EminiS&P500March2025"
        }
      },
    "definition": {
      "instrumentType": "Future",
      "startDate": "2024-09-21T00:00:00.0000000+00:00",
      "maturityDate": "2025-03-21T17:30:00.0000000+00:00",
      "identifiers": {},
      "contractDetails": {
        "domCcy": "USD",
        "contractCode": "ESH5",
        "contractMonth": "H",
        "contractSize": 50,
        "exchangeCode": "GLOBEX",
        "deliveryType": "Cash"
      },
      "contracts": 1,
      "markToMarketConventions": {
        calendarCode: "USD"
      },
      "refSpotPrice": 0,
    }
  }
}'
```

Note the following:

- The `instrumentType` must be `Future`.
- The nested `definition.identifiers` should be set to an empty object: `{}`.
- The `contractCode` should be valid for the exchange.
- The `contracts` field should be set to `1` and the amount bought or sold specified on the transaction.
- The `deliveryType` defaults to `Physical` but should be set to `Cash` if you want to handle [instrument events](/v1/docs/handling-future-mark-to-market-and-expiry-events).
- `refSpotPrice` should be `0` (or omitted, since this is the default) unless directed otherwise by FINBOURNE Technical Support.

Providing the request is successful, the response:

- Confirms the globally-unique [LUID](/v1/docs/what-is-a-lusid-instrument-id-or-luid) for the instrument.
- Generates extra fields that are stored as part of the instrument definition and can be [filtered on](/v1/docs/filtering-information-retrieved-from-lusid).
- Supplies default values for fields not explicitly specified in the request.

For more information on the `calculationType` field for use with ASX and Brazilian B3 bond futures, see the [API reference documentation](https://www.lusid.com/docs/api/lusid/schemas/Future/) for that field.

```json
{
  "values": {
    "upsert-request-1": {
      "href": "https://<your-domain>.lusid.com/api/api/instruments/LusidInstrumentId/LUID_00003E7V?scope=MyCustomInstrScope",
      "scope": "MyCustomInstrScope",
      "lusidInstrumentId": "LUID_00003E7V",
      "name": "E-mini S&P500 March 2025",
      "identifiers": {
        "LusidInstrumentId": "LUID_00003E7V",
        "ClientInternal": "EminiS&P500March2025"
      },
      "properties": [],
      "instrumentDefinition": {
        "startDate": "2024-09-21T00:00:00.0000000+00:00",
        "maturityDate": "2025-03-21T17:30:00.0000000+00:00",
        "identifiers": {},
        "contractDetails": {
          "domCcy": "USD",
          "assetClass": "Unknown",
          "contractCode": "ESH5",
          "contractMonth": "H",
          "contractSize": 50,
          "country": "",
          "description": "",
          "exchangeCode": "GLOBEX",
          "exchangeName": "",
          "tickerStep": 0,
          "unitValue": 0,
          "deliveryType": "Cash"
        },
        "contracts": 1,
        "markToMarketConventions": {
          calendarCode: "USD"
        },
        "refSpotPrice": 0,
        "calculationType": "Invalid",
        "tradingConventions": {
          "priceScaleFactor": 1,
          "minimumOrderSize": 0,
          "minimumOrderIncrement": 0
        },
        "instrumentType": "Future"
      },
      "state": "Active",
      "assetClass": "Unknown",
      "domCcy": "USD",
      "relationships": []
    }
  },
  ...
}
```

## Booking a transaction to establish a position

Once an instrument is mastered, you can [book a transaction](/v1/docs/how-do-i-create-or-update-a-transaction) to record the acquisition of a quantity in a particular [transaction portfolio](/v1/docs/what-is-a-transaction-portfolio). For example, the following call to the [BatchUpsertTransactions](https://www.lusid.com/docs/api#operation/BatchUpsertTransactions) API acquires 10 contracts of an instrument identified by LUID:

```json
curl -X POST 'https://<your-domain>.lusid.com/api/api/transactionportfolios/FixedIncome/UK/transactions/$batchUpsert?successMode=Partial&preserveProperties=true'
  -H 'Content-Type: application/json-patch+json'
  -H 'Authorization: Bearer <your-API-access-token>'
  -d '{
  "transactionRequest-1": {
    "transactionId": "my_future_purchase_001",
    "type": "BuyFuture",
    "instrumentIdentifiers": {"Instrument/default/LusidInstrumentId": "LUID_00003E7V"},
    "transactionDate": "2024-09-25T09:00:00.0000000+00:00",
    "settlementDate": "2024-09-25T09:00:00.0000000+00:00",
    "units": 10,
    "transactionPrice": {
      "price": 6000,
      "type": "Price"
    },
    "totalConsideration": {
      "amount": 0,
      "currency": "USD"
    },
    "properties": {
      "Transaction/MyProperties/TradeCommission": {
        "key": "Transaction/MyProperties/TradeCommission",
        "value": {
          "metricValue": {
            "value": 50,
            "unit": "USD"
          }
        }
      }
    }
  }
}'
```

Note the following:

- The `type` field invokes a custom `BuyFuture` [transaction type](/v1/docs/what-is-a-transaction-type) to confer a particular economic impact (see below).
- The `units` field specifies the number of contracts.
- The `transactionPrice` object records the market price. This is used by LUSID to automatically calculate gross consideration (see below).
- The `totalConsideration` object:
  - Sets the settlement currency to `USD`.
  - Specifies a cost of `0` to enable LUSID to automatically derive total consideration (see below).
- The cost of entering into the contract is recorded as a [custom property](/v1/docs/properties).

> **Note**: This example assumes the transaction, settlement and portfolio currencies are all the same. If not, you can [specify exchange rates](/v1/docs/transactions-and-exchange-rates).

You might create a `BuyFuture` transaction type as follows:

```json
curl -X PUT 'https://<your-domain>.lusid.com/api/api/transactionconfiguration/types/default/BuyFuture?scope=default'
  -H 'Content-Type: application/json-patch+json'
  -H 'Authorization: Bearer <your-API-access-token>'
  -d '{
  "aliases": [
    {
      "type": "BuyFuture",
      "description": "Transaction type for future purchases",
      "transactionClass": "Basic",
      "transactionRoles": "AllRoles",
      "isDefault": false
    }
  ],
  "movements": [
    {
      "name": "Increase units",
      "movementTypes": "StockMovement",
      "side": "NotionalPurchase",
      "direction": 1
    },
    {
      "name": "Decrease cash",
      "movementTypes": "CashCommitment",
      "side": "Side2",
      "direction": -1
    }
  ],
  "calculations": [
    {
      "type": "Txn:NotionalAmount"
    },
    {
      "type": "Txn:GrossConsideration"
    },
    {
      "type": "DeriveTotalConsideration",
      "formula": "Txn:GrossConsideration + Properties[Transaction/MyProperties/TradeCommission]"
    }
  ]
}'
```

Note the following:

- The `StockMovement` references a `NotionalPurchase` custom side (see below).
- The `Txn:NotionalAmount` [transaction type calculation](/v1/docs/what-is-a-transaction-type-calculation#txnnotionalamount) automatically calculates the notional amount and stores the result in the `Transaction/default/NotionalAmount` system property, for use in the `NotionalPurchase` custom side.
- The `Txn:GrossConsideration` calculation [sets the gross consideration to zero](/v1/docs/what-is-a-transaction-type-calculation#txngrossconsideration) for transactions that increase a future position, and stores the result in the `Transaction/default/GrossConsideration` system property.
- The `DeriveTotalConsideration` calculation calculates `totalConsideration.amount` according to the given formula, which in this case sums gross consideration and fees; this is the total cost of the transaction.

You might create a `NotionalPurchase` custom side as follows:

```json
curl -X PUT 'https://<your-domain>.lusid.com/api/api/transactionconfiguration/sides/NotionalPurchase?scope=default'
  -H 'Content-Type: application/json-patch+json'
  -H 'Authorization: Bearer <your-API-access-token>'
  -d '{
  "security": "Txn:LusidInstrumentId",
  "currency": "Txn:TradeCurrency",
  "rate": "Txn:TradeToPortfolioRate",
  "units": "Txn:Units",
  "amount": "Txn:TotalConsideration",
  "notional": "Transaction/default/NotionalAmount"
}'
```

Note this is the same as the [built-in](https://support.lusid.com/docs/what-built-in-transaction-types-and-sides-are-provided-with-lusid#builtin-sides) `Side1` except:

- The `amount` field is set to `Txn:TotalConsideration` instead of `Txn:TradeAmount`.
- The `notionalAmount` field is set to the `Transaction/default/NotionalAmount` system property, to handle LUSID’s calculation of notional amount.

### Confirming positions

You can call the [GetHoldings](https://www.lusid.com/docs/api/#operation/GetHoldings) API to see the impact of the transaction on security and cash holdings, for example using the LUSID web app:

![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image(428).png)

### Auditing LUSID’s transaction type calculations

You can call the [BuildTransactions](https://www.lusid.com/docs/api/lusid/endpoints/transaction-portfolios/BuildTransactions/) API to audit LUSID’s notional amount, gross consideration and total consideration calculations, for example using the LUSID web app in **Output** mode:

![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image(429).png)

## Valuing your position

To value your position, work through our [valuation checklist](/v1/docs/valuation-checklist).

> **Note**: The default pricing model is `SimpleStatic`. We recommend changing it to `ConstantTimeValueOfMoney`. [See how to do this](/v1/docs/recipes-changing-the-default-pricing-models-for-instrument-types).

| **Pricing model** | **Status** | **Notes** |
| --- | --- | --- |
| `ConstantTimeValueOfMoney` | Available | Recommended. Sets the PV to the unrealised gain whether you choose to realise it daily or not (see below). |
| `SimpleStatic` | Available | Calculates market value according to the formula `quantity held * contract size * scaled price`. |

## Assessing risk

For more on how LUSID calculates exposure, see [this article](/v1/docs/how-does-lusid-calculate-exposure).

LUSID supports both analytic and bump and valuation mechanisms for assessing risk; [contact Technical Support](https://www.finbourne.com/contact) if you need more information.

## Managing P&L on a daily basis

You can choose between two models for managing P&L in a futures contract.

### Mark to market model

This 'close out' [mark to market](https://www.investopedia.com/terms/m/marktomarket.asp) model realises each day’s P&L by booking it as a cash amount and resetting the future’s cost price to today’s close (so the P&L is now 0). You can automate this process by handling the `FutureMarkToMarketEvent` instrument event (see below).

### Cumulative P&L model

This 'non-close out' model maintains P&L as unrealised. The PV shows the lifetime unrealised gain/loss.

## Monitoring the lifecycle of the instrument

An instrument representing a futures contract has a maturity date specified when you create that instrument.

As the instrument nears expiry, there are decisions to be made. Futures are almost always closed before last trade date, but you may choose to hold to maturity and take delivery of the underlying.

> **Note**: An instrument cannot ‘expire’ in LUSID; it is still available post-maturity, 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

A cash-settled `Future` instrument is tightly integrated into LUSID’s [instrument event framework](https://support.lusid.com/v1/docs/understanding-instrument-lifecycle-events-emitted-by-lusid). To enable this for your domain, you must:

1. Register a recipe with every portfolio holding a `Future`.
2. Create transaction types to determine the economic impact of the transactions automatically generated by `Future`events.

For much more information, see how to [handle instrument events](/v1/docs/handling-future-mark-to-market-and-expiry-events). Note that a physically-settled `Future` instrument does not support instrument events.

| **Instrument event** | Event emission criteria |  |
| --- | --- | --- |
| `FutureMarkToMarketEvent` | This event is automatically emitted each weekday at the time specified in the instrument definition, providing suitable market data can be found. | One transaction for a cash amount reflecting the daily gain/loss. |
| `FutureExpiryEvent` | This event is automatically emitted on the maturity date at the time specified in the instrument definition, providing suitable market data can be found. | One transaction that simultaneously reduces the holding in the `Future` instrument to zero and realises the final daily cash gain/loss. |

### Manually loading daily and final 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](https://www.lusid.com/docs/api/lusid/endpoints/transaction-portfolios/GetPortfolioCashLadder) API directly.

You can call the [GetUpsertablePortfolioCashFlows](https://www.lusid.com/docs/api/lusid/endpoints/transaction-portfolios/GetUpsertablePortfolioCashFlows) API to return imminent cashflows as upsertable DTOs ready to manually load into LUSID as input transactions.

> **Note:** We do not currently handle cheapest-to-deliver methods. Calendar rolls are booked as separate sells/buys.
