--- title: "Modelling credit default swap indexes (CDX) in LUSID" slug: "modelling-cds-index-instruments-in-lusid" tags: ["credit default swap"] updated: 2026-10-09T10:01:04Z published: 2026-10-09T10:01:04Z canonical: "support.lusid.com/modelling-cds-index-instruments-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 credit default swap indexes (CDX) in LUSID You can model an exchange-traded credit default swap index (CDX) contract as an instrument of type `CdsIndex` in LUSID. [See all supported instruments](/v1/docs/what-instruments-does-lusid-support). > **Note**: Most of the information in this article also applies to a single name CDS contract, except the LUSID instrument type is `CreditDefaultSwap`. Also, a CDS instrument may have `protectStartDay` set to `true`, which excludes the trade date from accrued interest (see below). ## Mastering an instrument There are [numerous tools](/v1/docs/how-do-i-master-an-instrument) you can use to master a `CdsIndex` 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 `CdsIndex`. For more information on these fields, examine the [CdsIndex](https://www.lusid.com/docs/api/lusid/schemas/CdsIndex/) schema or select **CdsIndex** from the **definition** dropdown in the [UpsertInstruments](https://www.lusid.com/docs/api/lusid/endpoints/instruments/UpsertInstruments) API reference: ![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image(633).png?sv=2026-02-06&spr=https&st=2026-11-04T02%3A00%3A55Z&se=2026-11-04T03%3A00%3A55Z&sr=c&sp=r&sig=DPnAjzDzcwqGCEZCkpyCoAFSGhd4Rf6Mt5aQ8AxJHvQ%3D) In this tutorial, we’ll master a [Markit-iTraxx-Crossover](https://www.ice.com/products/28687613/Markit-iTraxx-Crossover) contract by calling the `UpsertInstruments` API as follows: ```json curl -X POST 'https://.lusid.com/api/api/instruments?scope=MyCustomInstrScope'   -H 'Content-Type: application/json-patch+json'   -H 'Authorization: Bearer '   -d '{  "request_id_1": {    "name": "Markit iTraxx Crossover Series 41 5Y",    "identifiers": {      "ClientInternal": {"value": "MarkitiTraxxCrossoverSeries415Y"}    },     "definition": {       "instrumentType": "CdsIndex",       "identifiers": {},       "startDate": "2024-03-20T00:00:00.0000000+00:00",       "maturityDate": "2029-06-20T00:00:00.0000000+00:00",       "notional": 1,       "couponRate": 0.05,       "flowConventions": {         "currency": "EUR",         "paymentFrequency": "6M",         "dayCountConvention": "Actual360",         "rollConvention": "20",        "businessDayConvention": "F",        "paymentCalendars": ["EUR"]       }     }  } }' ``` Note the following: - We’ve chosen to master this instrument in a [custom instrument scope](/v1/docs/understanding-instrument-scopes) (specified in the URL). - The `identifiers` field uniquely identifies the instrument using a `ClientInternal` [identifier](/v1/docs/what-are-unique-and-non-unique-identifiers). - In the economic `definition` object: - The `instrumentType` must be `CdsIndex`. - The nested `identifiers` object should be empty: `{}`. - The `notional` should be unitised (set to `1`) and the amount bought or sold specified on the transaction. - The `couponRate` representing the premium payment should be expressed as a decimal rather than a percentage, so: - 5% should have a `couponRate` of `0.05` - 1% should have a `couponRate` of `0.01`, and so on. - The `flowConventions` field must reference a `CdsFlowConventions` object storing all the information necessary to determine [premium payment periods and dates](/v1/docs/flow-conventions-and-index-conventions): - The `paymentFrequency` field can be any [tenor](/v1/docs/specifying-tenors-in-lusid), in this case `6M` to signify twice yearly. [Supported day count conventions](/v1/docs/day-count-conventions-supported-by-lusid). - The `rollConvention` field can specify a fixed day (for example `IMM` or `EndOfMonth`) or alternatively a number representing a day of the month. We also recommend setting a `businessDayConvention` to determine what should happen if this is not a good business day. [More information on roll and business day conventions](/v1/docs/roll-conventions-and-business-day-conventions). Note good business days in LUSID are determined by [holiday calendars](/v1/docs/using-calendars-in-lusid). - The `settleDays` and `resetDays` fields are optional. The `scope` and `code` fields can be ignored unless you are loading a CDS flow convention from a library. - The `basket` field is now optional and there is no need to identity the underlying CDS trades in the index. - The `protectionDetailSpecification` field is optional. Its `protectStartDay` setting controls whether the trade date counts towards the accrued interest a transaction pays or receives. It defaults to `false`, meaning protection starts the day after the trade and the trade date is included. Set it to `true` if protection starts on the trade date itself; the trade date is then excluded. > **Note**: LUSID implicitly creates [protection and payment legs](/v1/docs/how-does-lusid-handle-instrument-legs) for a CDX instrument but note the recommended `CdsLookupPricer` pricing model does not yet value the legs separately. 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: ```json {  "values": {    "request_id_1": {      "scope": "MyCustomInstrScope",      "lusidInstrumentId": "LUID_00003EDB",      "name": "Markit iTraxx Crossover Series 41 5Y",      "identifiers": {        "LusidInstrumentId": "LUID_00003EDB",        "ClientInternal": "MarkitiTraxxCrossoverSeries415Y"      },      "properties": [],      "instrumentDefinition": {        "startDate": "2024-03-20T00:00:00.0000000+00:00",        "maturityDate": "2029-06-20T00:00:00.0000000+00:00",        "flowConventions": {          "rollFrequency": "6M",          "currency": "EUR",          "paymentFrequency": "6M",          "dayCountConvention": "Actual360",          "rollConvention": "20",          "paymentCalendars": ["EUR"],          "resetCalendars": [],          "settleDays": 0,          "resetDays": 0,          "businessDayConvention": "F"        },        "couponRate": 0.05,        "identifiers": {},        "basket": {          "basketName": {            "index": "unknown",            "name": "unknown",            "region": "unknown",            "seriesId": 10000000          },          "basketType": "Credits",          "weightedInstruments": {            "instruments": []          },          "instrumentType": "Basket"        },        "notional": 1,        "additionalPayments": [],        "instrumentType": "CdsIndex"      },      "state": "Active",      "assetClass": "Credit",      "domCcy": "EUR",      "relationships": []    }  }  ... } ``` ## Booking a transaction to establish a position Once an instrument is mastered, we can [book a transaction](/v1/docs/how-do-i-create-or-update-a-transaction) to record the acquisition of a quantity in a suitable portfolio, for example by calling the `BatchUpsertTransactions` API as follows: ```json curl -X POST 'https://.lusid.com/api/api/transactionportfolios/FixedIncome/EMEA/transactions/$batchUpsert?successMode=Partial&preserveProperties=true'  -H 'Content-Type: application/json-patch+json'  -H 'Authorization: Bearer '  -d '{  "transactionRequest-1": {    "transactionId": "cdx_purchase_001",    "type": "BuyProtection",    "instrumentIdentifiers": {"Instrument/default/ClientInternal": "MarkitiTraxxCrossoverSeries415Y"},    "transactionDate": "2024-09-20T00:00:00.0000000+00:00",    "settlementDate": "2024-09-25T00:00:00.0000000+00:00",    "units": 100000,    "transactionPrice": {      "price": 102,      "type": "Price"    },    "totalConsideration": {      "currency": "EUR",      "amount": 0    }  } }' ``` Note the following: - The `instrumentIdentifiers` field uses the `ClientInternal` identifier to resolve the transaction to the correct CDX instrument (but it could use the LUID). - The `type` field invokes a custom `BuyProtection` [transaction type](/v1/docs/what-is-a-transaction-type) to confer a particular economic impact on the transaction (see below). - The `units` field specifies the purchase amount, in this case `100000`. - The `transactionPrice` object records the market price as a par-like Markit price of `102`. LUSID converts this to a rate using `(100 - price) / 100`, so `(100 - 102) / 100 = -0.02`. Note you can enter the rate explicitly if you want but the `transactionPrice.type` should still be `Price`. Note also: - The impact of a transaction for an above-par price such as `102` is to both receive cash *and* accrued interest (that is, a rebate on the premium for purchasing part-way through a period). - The impact of a transaction for a below par price such as `98` (which as a rate is `(100 - 98) / 100 = 0.02`) is to *pay* cash but receive accrued interest. - The `totalConsideration` object: - Sets the settlement currency to `EUR`. - Sets the amount to `0` to trigger LUSID’s calculation of total consideration using the `BuyProtection` transaction type (see below). > **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). We can call the [SetTransactionType](https://www.lusid.com/docs/api#operation/SetTransactionType) API to create a `BuyProtection` transaction type as follows: ```json curl -X PUT 'https://.lusid.com/api/api/transactionconfiguration/types/default/BuyProtection?scope=default'  -H 'Content-Type: application/json-patch+json'  -H 'Authorization: Bearer '  -d '{  "aliases": [    {      "type": "BuyProtection",      "description": "Transaction type for CDX purchases",      "transactionClass": "CreditDefaultSwap",      "transactionRoles": "Longer",      "isDefault": false    }  ],  "movements": [    {      "name": "Increase units of security",      "movementTypes": "StockMovement",      "side": "Protection",      "direction": 1    },    {      "name": "Decrease cash balance",      "movementTypes": "CashCommitment",      "side": "Side2",      "direction": -1    },    {      "name": "Report bought/sold interest",      "movementTypes": "Carry",      "side": "Accrued",      "direction": -1    }  ],  "calculations": [    {      "type": "Txn:BondInterest"    },    {      "type": "Txn:GrossConsideration"    },    {      "type": "DeriveTotalConsideration",      "formula": "Txn:GrossConsideration"    }  ] }' ``` Note the following: - The `StockMovement` uses a `Protection` custom side (see below) to establish a `CdsIndex` holding with a particular number of units and cost. - The `CashCommitment` movement uses the [built-in](https://support.lusid.com/docs/what-built-in-transaction-types-and-sides-are-provided-with-lusid#builtin-sides) `Side2` to decrease a cash holding by the total consideration. - The `Carry` movement uses an `Accrued` custom side (see below) to record a flow of value in an [A2B report](/v1/docs/creating-an-a2b-report-to-understand-how-valuations-change-over-time). - The [transaction type calculations](/v1/docs/what-is-a-transaction-type-calculation#txnbondinterest-calculation) trigger LUSID to calculate accrued interest and gross and total consideration. LUSID calculates accrued interest from the start of the current premium period up to and including the trade date (or up to the day before, if `protectStartDay` is `true`). | `Protection` custom side | `Accrued` custom side | | --- | --- | | ```json { "security": "Txn:LusidInstrumentId", "currency": "Txn:TradeCurrency", "rate": "Txn:TradeToPortfolioRate", "units": "Txn:Units", "amount": "BaseOnSeparateBondInterest" } ``` | ```json { "security": "Txn:LusidInstrumentId", "currency": "Txn:SettlementCurrency", "rate": "SettledToPortfolioRate", "units": "0", "amount": "Txn:BondInterest" } ``` | | 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 `BaseOnSeparateBondInterest` instead of `Txn:TradeAmount`. | This is similar to the built-in `Side2` except the `units` field is set to `0` and `amount` carries just the accrued interest. | ### Confirming positions on the settlement date We can navigate to **Portfolio Management > Holdings** in the LUSID web app to call the [GetHoldings](https://www.lusid.com/docs/api/lusid/endpoints/transaction-portfolios/GetHoldings/) API on the settlement date and, since we bought at an above-par price of 102, see that we have: - 100,000 units of the CDX instrument holding with a negative cost of `-2000` - A EUR currency holding with a positive amount reflecting both cash (above par) and accrued interest (premium rebate) received: `2000 + 1291.67 = 3291.67` ![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image-VIEN9VM4.png?sv=2026-02-06&spr=https&st=2026-11-04T02%3A00%3A55Z&se=2026-11-04T03%3A00%3A55Z&sr=c&sp=r&sig=DPnAjzDzcwqGCEZCkpyCoAFSGhd4Rf6Mt5aQ8AxJHvQ%3D) If instead we had bought at a below-par price of 98, we would have: - 100,000 units of the CDX instrument holding with a positive cost - A EUR currency holding with a negative amount reflecting the net of cash paid (below par) and accrued interest received (premium rebate): `-2000 + 1291.67 = -708.33` ![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image-PPJMZWI8.png?sv=2026-02-06&spr=https&st=2026-11-04T02%3A00%3A55Z&se=2026-11-04T03%3A00%3A55Z&sr=c&sp=r&sig=DPnAjzDzcwqGCEZCkpyCoAFSGhd4Rf6Mt5aQ8AxJHvQ%3D) ### Auditing LUSID’s calculations of transaction amounts We can navigate to **Portfolio Management > Transactions** in **Output** mode to call the [BuildTransactions](https://www.lusid.com/docs/api/lusid/endpoints/transaction-portfolios/BuildTransactions/) API with a suitable window to examine the output transaction that generated the above-par holdings (click to enlarge): ![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image-60P9RER9.png?sv=2026-02-06&spr=https&st=2026-11-04T02%3A00%3A55Z&se=2026-11-04T03%3A00%3A55Z&sr=c&sp=r&sig=DPnAjzDzcwqGCEZCkpyCoAFSGhd4Rf6Mt5aQ8AxJHvQ%3D) ## Valuing your position To value your position, work through our [valuation checklist](/v1/docs/valuation-checklist). The following [pricing models](/v1/docs/what-pricing-models-can-i-use-in-my-valuation) are available for instruments of type `CdsIndex`. Note your choice impacts the market data required and the composition of your recipe. | **Pricing model** | **Notes** | | --- | --- | | `CdsLookupPricer` | **Recommended**. This pricing model extends `SimpleStatic` to consume either a price or a rate, and also projects cashflows. You can load a quotes as either: - A par-like Markit price of (for example) `102` or `98` using a `quoteType` of `Price`. LUSID calculates clean PV as `(units * notional * ((100 - price) / 100)) / scale factor`. - As a rate of (for example) `-0.02` or `0.02` using a `quoteType` of `Rate`. LUSID calculates clean PV as `(units * notional * rate) / scale factor`. In either case, LUSID calculates PV as `clean PV + accrued interest`. | | `SimpleStatic` | This is currently the default. We recommend changing it to `CdsLookupPricer` in your recipe. [See how to do this](/v1/docs/recipes-changing-the-default-pricing-models-for-instrument-types). | For example, to value our holding using `CdsLookupPricer` on 10 July 2026 using a par-like Markit price: 1. [Load a quote](/v1/docs/how-do-i-upload-a-market-price-or-fx-spot-rate-to-the-quote-store) into a particular scope (specified in the URL) with `effectiveAt` as the valuation date and a `scaleFactor` of `1`: ```json curl -X POST 'https://mydomain.lusid.com/api/api/quotes/MyCdxQuotes'  -H 'Authorization: Bearer myAPIAccessToken'  -H 'Content-Type: application/json-patch+json'  -d '{    "Quote-0001": {      "quoteId": {        "quoteSeriesId": {          "provider": "Lusid",          "instrumentIdType": "ClientInternal",          "instrumentId": "MarkitiTraxxCrossoverSeries415Y",          "quoteType": "Price",          "field": "mid"        },        "effectiveAt": "2026-07-10T00:00:00Z"      },      "metricValue": {"value": 102, "unit": "EUR"},      "scaleFactor": 1    }  }' ``` 2. [Create a recipe](/v1/docs/how-do-i-create-or-generate-a-recipe) to locate this market data and change the pricing model, for example: ```json curl -X POST 'https://mydomain.lusid.com/api/api/recipes'  -H 'Content-Type: application/json-patch+json'  -H 'Authorization: Bearer myAPIAccessToken'  -d '{  "configurationRecipe": {    "scope": "MyRecipes",    "code": "MyBasicRecipe",    "market": {      "marketRules": [        {          "key": "Quote.ClientInternal.*",          "dataScope": "MyCdxQuotes",          "supplier": "Lusid",          "quoteType": "Price",          "field": "mid"        }      ]    },    "pricing": {      "modelRules": [        {          "instrumentType": "CdsIndex",          "modelName": "CdsLookupPricer"        }      ]    }  } }' ``` 3. [Generate a valuation report](/v1/docs/how-do-i-perform-a-valuation) with appropriate metrics, for example: ![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image-CPYHQF96.png?sv=2026-02-06&spr=https&st=2026-11-04T02%3A00%3A55Z&se=2026-11-04T03%3A00%3A55Z&sr=c&sp=r&sig=DPnAjzDzcwqGCEZCkpyCoAFSGhd4Rf6Mt5aQ8AxJHvQ%3D) ## 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. ## Monitoring the lifecycle of the instrument A `CdsIndex` instrument is tightly integrated into LUSID’s [instrument event framework](/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 `CdsIndex`. 2. Create transaction types to determine the economic impact of the transactions automatically generated by `CdsIndex` events. **Recommended reading**: [Handling instrument events for credit default swaps](/v1/docs/handling-premium-and-credit-events-for-cdx-instruments) | **Instrument event type** | Event emission criteria | **If emitted, default transaction template generates…** | | --- | --- | --- | | `CreditPremiumCashFlowEvent` | This event is automatically emitted by LUSID each time a premium is due. | A transaction for the premium payment amount. | | `ProtectionPayoutCashFlowEvent` | This event is **not automatically emitted** by LUSID. It can be triggered by manually loading a `CdxCreditEvent` into a suitable corporate action source. | A transaction for the protection payout amount. | | `MaturityEvent` | This event is automatically emitted by LUSID on the maturity date of the instrument. | A transaction for all the units in the holding at zero cost of zero. |