Mastering an instrument
There are numerous methods 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 of identifiers
, and the facility to store extra information 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 API Reference:
For example, the following call to the UpsertInstruments API masters an E-mini S&P futures contract in a custom instrument scope using a ClientInternal
unique identifier:
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": "ESHS",
"contractMonth": "H",
"contractSize": 50,
"exchangeCode": "GLOBEX",
"deliveryType": "Cash"
},
"contracts": 1,
"markToMarketEvent": {
calendarCode: "USD"
},
"refSpotPrice": 0,
}
}
}'
Note the following:
The
instrumentType
must beFuture
.The nested
definition.identifiers
should be set to an empty object:{}
.The
contractCode
must be valid for the exchange.The
contracts
field should be set to1
and the amount bought or sold specified on the transaction.The
deliveryType
defaults toPhysical
but should be set toCash
if you want to handle instrument events.refSpotPrice
should be0
(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 for 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": {
"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": "ESHS",
"contractMonth": "H",
"contractSize": 50,
"country": "",
"description": "",
"exchangeCode": "GLOBEX",
"exchangeName": "",
"tickerStep": 0,
"unitValue": 0,
"deliveryType": "Cash"
},
"contracts": 1,
"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 to record the acquisition of a quantity in a particular transaction portfolio. For example, the following call to the BatchUpsertTransactions API acquires 10 contracts of an instrument identified by LUID:
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 customBuyFuture
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.
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 BuyFuture
transaction type as follows:
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
Txn:NotionalInterest
transaction type calculation automatically calculates the notional amount and stores the result in theTransaction/default/NotionalAmount
system property, for use in theNotionalPurchase
custom side (see below).The
Txn:GrossConsideration
calculation sets the gross consideration to zero for transactions that increase a future position, and stores the result in theTransaction/default/GrossConsideration
system property.The
DeriveTotalConsideration
calculation calculatestotalConsideration.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:
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 Side1
except:
The
amount
field is set toTxn:TotalConsideration
instead ofTxn:TradeAmount
.The
notionalAmount
field is set to theTransaction/default/NotionalAmount
system property, to handle LUSID’s calculation of notional amount.
Confirming positions
You can call the GetHoldings API to see the impact of the transaction on security and cash holdings, for example using the LUSID web app:
Auditing LUSID’s transaction type calculations
You can call the BuildTransactions API to audit LUSID’s notional amount, gross consideration and total consideration calculations, for example using the LUSID web app in Output mode:
Valuing your position
To value your position, work through our valuation checklist. For a demonstration, see sections 4 and 5 of the accompanying Jupyter Notebook.
Note: The default pricing model is
SimpleStatic
. We recommend changing it toConstantTimeValueOfMoney
. See how to do this.
Pricing model | Status | Notes |
---|---|---|
| Available | Recommended. Sets the PV to the unrealised gain whether you choose to realise it daily or not (see below). |
| Available | Calculates market value according to the formula |
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.
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 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
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 in response to these events, and recommendations for transaction types that deliver appropriate economic impacts. More information.
Contact us to turn this feature on in your environment. The following events are available for instruments of type Future
:
Instrument event type | Effect of LUSID default transaction template | Recommendations for transaction types |
---|---|---|
| A transaction is automatically generated each weekday, with the total consideration reflecting the daily gain/loss. | |
| Note: LUSID only emits events for cash settlement. Physical settlement must be handled manually. A transaction is automatically generated on the future's maturity date with the total realised gain/loss calculated. |
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 API directly.
You can call the 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.