How does LUSID handle instrument legs?

Many types of instrument supported by LUSID have one or more cash flow legs. You may find it useful to view the cash flows from an individual leg, or to see the contribution of a particular leg to the overall valuation of your holding in an instrument. You can also add properties to store extra information about legs; these properties are independent of any added to the instrument as a whole.

For some types of instrument, legs are explicitly defined when you master an instrument of that type in LUSID. For others, there are no explicit leg objects in economic definitions, but LUSID implicitly creates legs for the purpose of categorising cash flows.

Whether explicitly defined or implicitly created, all instruments with cash flow legs have a leg identifier that describes the purpose of the leg, and a leg index that defines the order. The order is significant if you want to view cash flows for, individually value, or add properties to a particular leg.

Note: Leg cash flows are not available when using the SimpleStatic pricing model, which is the default for most instruments with legs. See how to change the pricing model.

Instrument type

Leg index

Leg identifier

Description

Economic definition

Explicit or implicit?

Leg object hierarchy if explicit

CapFloor

1

Pay or Receive

Cash flows representing the pay or receive leg.

Explicit

FloatingLeg→LegDefinition

CdsIndex

1

ProtectionLeg

Payments made by the protection seller in case of default across all CDS instruments in the index.

Implicit

N/A

2

PremiumLeg

The premium payments made by the protection buyer across all CDS instruments in the index.

CreditDefaultSwap

1

ProtectionLeg

Cash flows occurring in the case of default.

Implicit

N/A

2

PremiumLeg

The premium payments made by the protection buyer.

EquitySwap

1

EquityLeg

Cash flows relating to the performance of the underlying equity.

Implicit

N/A

2

FundingLeg

The funding leg of the swap.

Explicit

FundingLeg→LegDefinition

3

EquityDividendLeg

Cash flows relating to dividend payments on the underlying equity (optional).

Implicit

N/A

FundingLeg

1

Pay or Receive

Cash flows representing the pay or receive leg

Explicit

LegDefinition

FxForward

1

DomesticLeg

Cash flows in the domestic currency of the forward.

Implicit

N/A

2

ForeignLeg

Cash flows in the foreign currency of the forward (not present for non-deliverable forwards).

FxSwap

1

FarDomesticLeg

Cash flows in the domestic currency for the far forward.

Implicit

N/A

2

FarForeignLeg

Cash flows in the foreign currency for the far forward (not present for non-deliverable forwards).

3

NearDomesticLeg

Cash flows in the domestic currency for the near forward.

4

NearForeignLeg

Cash flows in the foreign currency for the near forward (not present for non-deliverable forwards).

InflationSwap

1

InflationLeg

Cash flows with a rate relating to an underlying inflation index.

Explicit

InflationLeg

2

FixedLeg

Cash flows with a fixed rate.

FixedLeg→LegDefinition

InterestRateSwap

(also InterestRateSwaption)

1

Pay or Receive

Cash flows representing the pay or receive leg.

Explicit

Legs 1 and 2 can both be FixedLeg, both be FloatingLeg, or one of each.

2

Receive or Pay

Cash flows representing the opposite receive or pay leg.

3

AdditionalPayments

Cash flows relating to any additional payments (optional).

Implicit

N/A

TotalReturnSwap

1

AssetLeg

Cash flows relating to the returns generated by an underlying bond.

Explicit

AssetLeg

2

FundingLeg

The funding leg of the swap.

FundingLeg→LegDefinition

3

AdditionalPayments

Optional cash flows relating to any additional payments.

Array of AdditionalPayment

Example: A 6m EUR/USD FxForward

Consider the example of a FxForward instrument mastered in LUSID with the following economic definition:

{
  "startDate": "2023-01-20T00:00:00.0000000+00:00",
  "maturityDate": "2023-07-22T00:00:00.0000000+00:00",
  "domAmount": 1000000,
  "domCcy": "EUR",
  "fgnAmount": -1215520.25,
  "fgnCcy": "USD",
  "isNdf": false,
  "instrumentType": "FxForward"
}

As per the table above, LUSID implicitly creates two cash flow legs for a non-deliverable FxForward:

FxForward

1

DomesticLeg

Cash flows in the domestic currency of the forward.

2

ForeignLeg

Cash flows in the foreign currency of the forward (not present for non-deliverable forwards).

Viewing leg-level cash flows

You can view leg-level cash flows for the FxForward providing you have:

  1. Loaded suitable market data into a LUSID market data store. More information.

  2. Created a recipe nominating a pricing model and rules for retrieving that market data. More information.

To view cash flows, call the GetInstrumentPaymentDiary API, or sign in to the LUSID web app, navigate to Data Management > Instruments, locate the FxForward and open the Payments screen. Here, the response is transformed to a table with some columns renamed or removed for clarity:

Viewing leg-level valuation results

You can view leg-level valuation results for a holding in the FxForward providing you have:

  1. Loaded suitable market data into a LUSID market data store. More information.

  2. Created a recipe nominating a pricing model and rules for retrieving that market data. More information.

  3. Set the produceSeparateResultForLinearOtcLegs option to True in that recipe. More information.

To perform a valuation, call the GetValuation API, or sign in to the LUSID web app and navigate to Dashboard > Valuations. You can specify the Valuation/LegIdentifier and Valuation/LegIndex metrics in order to confirm which leg is which:

Adding leg-level properties

You can add properties to legs to extend the data model. Note the following:

  • The underlying property type must be a multi-value string property type in the Leg domain with a collectionType of Array.

  • The order in which property values are specified in the array must match the leg index order.

The first step is to create a suitable property type using the CreatePropertyDefinition API, for example with a 3-stage property key of Leg/ExampleScope/Region:

curl -X POST "https://<your-domain>.lusid.com/api/api/propertydefinitions"
 -H "Authorization: Bearer <your-API-access-token>"
 -H "Content-Type: application/json-patch+json"
 -d '{
   "domain": "Leg",
   "scope": "ExampleScope",
   "code": "Region",
   "displayName": "Leg region property type for FxForwards",
   "dataTypeId": {"scope": "system", "code": "string"},
   "lifeTime": "Perpetual",
   "constraintStyle": "Collection",
   "collectionType": "Array",
}'

Then, you can add property values of this type to the FxForward using the BatchUpsertInstrumentProperties API:

curl -X POST "https://<your-domain>.lusid.com/api/api/instruments/$batchupsertproperties?scope=default&successMode=Partial'"
 -H "Authorization: Bearer <your-API-access-token>"
 -H "Content-Type: application/json-patch+json"
 -d '{
  "1": {
    "identifierType": "LusidInstrumentId",
    "identifier": "LUID_00003DPG",
    "properties": [
      {
        "key": "Leg/ExampleScope/Region",
        "value": {
          "labelValueSet": {
            "values": [
              "Europe",
              "United States"
            ]
          }
        }
      }
    ]
  }
}'

LUSID assigns the first value in the array (Europe) to the first leg (DomesticLeg), and the second value to the second leg. If the property values in the array were reversed, the wrong regions would be assigned to legs. Note if you add more property values than there are legs, LUSID ignores the extra values.

If you perform a valuation using a recipe with produceSeparateResultForLinearOtcLegs option set to True and choose to include properties in the results, then leg-level property values are split but instrument-level property values are not. For example, here the FxForward has both a leg-level Leg/ExampleScope/Region property with split values and an instrument-level Instrument/ExampleScope/Region property with the same values unsplit:

Note: You can group valuation results by property values, or perform operations such as Sum, Proportion and Average on numeric property values, in the same way as metrics.

With produceSeparateResultForLinearOtcLegs set to False, neither leg-level nor instrument-level property values are split. Note also the Valuation/LegIdentifier and Valuation/LegIndex metrics do not return values: