--- title: "Modelling vanilla fixed-rate bonds in LUSID" slug: "modelling-fixed-rate-vanilla-bonds-in-lusid" updated: 2026-10-26T15:21:29Z published: 2026-10-26T15:21:29Z canonical: "support.lusid.com/modelling-fixed-rate-vanilla-bonds-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 vanilla fixed-rate bonds in LUSID You can model a simple fixed-rate bond as an instrument of type `Bond` in LUSID. [See all supported instruments](/v1/docs/what-instruments-does-lusid-support). | **Kind of bond** | **LUSID instrument type** | **More information** | | --- | --- | --- | | Fixed rate with regular coupons (only the first can be irregular) Zero coupon | `Bond` | Continue reading this article | | Fixed rate with irregular coupons (other than the first) Floating rate Fixed-to-floating rate Municipal Callable Puttable Sinkable Convertible | `ComplexBond` | [Read this dedicated article](/v1/docs/modelling-complex-bonds-in-lusid) | | Mortgage-backed security (MBS) | [Read this dedicated article](/v1/docs/modelling-mortgage-backed-securities-in-lusid) | | PIK | [Read this dedicated article](/v1/docs/modelling-pik-bonds-in-lusid) | | Inflation-linked | `InflationLinkedBond` | [Read this dedicated article](/v1/docs/modelling-inflation-linked-bonds-in-lusid) | The rest of this article explains the lifecycle of a vanilla government bond issue with a regular coupon schedule and fixed principal. There is also an [accompanying Jupyter Notebook](https://github.com/finbourne/finbourne-notebooks/blob/main/V1/features/instruments/Bond.ipynb) that further demonstrates many of the operations and concepts. ## Mastering an instrument > **Note**: You should use the [ComplexBond](/v1/docs/modelling-complex-bonds-in-lusid) instrument type if your coupon schedule is irregular. The `Bond` instrument type can only accept an irregular first coupon period; all other coupons must be regular. There are [numerous tools](/v1/docs/how-do-i-master-an-instrument) you can use to master an instrument of type `Bond` 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 `Bond`. For more information on these fields, examine the [Bond](https://www.lusid.com/docs/api/lusid/schemas/Bond) schema, or select **Bond** from the **definition** dropdown in the [API documentation](https://www.lusid.com/docs/api/lusid/endpoints/instruments/UpsertInstruments): ![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/Bond.png?sv=2026-02-06&spr=https&st=2026-11-04T02%3A00%3A42Z&se=2026-11-04T03%3A00%3A42Z&sr=c&sp=r&sig=gP1ZgcRlYU1tlcqF%2FK2J0luISErauZUmpD6zKo80y7A%3D) For example, the following call to the [UpsertInstruments](https://www.lusid.com/docs/api/lusid/endpoints/instruments/UpsertInstruments) API masters a UK gilt in a custom [instrument scope](/v1/docs/understanding-instrument-scopes) using a FIGI [unique identifier](/v1/docs/what-are-unique-and-non-unique-identifiers). Note the fields specified below are the ***minimum required*** to master an instrument of type `Bond`: ```json curl -X POST "https://.lusid.com/api/api/instruments?scope=mycustominstrscope"   -H "Content-Type: application/json-patch+json"   -H "Authorization: Bearer "   -d '{  "upsert-request-1": {    "name": "UKT 0 ⅜ 10/22/26",    "identifiers": {"Figi": {"value": "BBG00ZF1T9P5"}},    "definition": {      "instrumentType": "Bond",      "startDate": "2016-10-22T10:00:00.0000000+00:00",      "maturityDate": "2026-10-22T10:00:00.0000000+00:00",      "domCcy": "GBP",      "couponRate": 0.00375,      "principal": 1,      "flowConventions": {        "currency": "GBP",        "paymentFrequency": "6M",        "dayCountConvention": "Actual365",        "rollConvention": "22",        "businessDayConvention": "Following"      },      "tradingConventions": {        "priceScaleFactor": 100      }    }  } }' ``` Note the following: - The `instrumentType` must be `Bond`. - The `startDate` should be the accrual start date; that is, the date from which interest is calculated. - The maximum `maturityDate` is 31 December 2140. - The `couponRate` should be expressed as a decimal rather than a percentage, so a bond paying: - 10% should have a `couponRate` of `0.1` - 2.5% should have a `couponRate` of `0.025` - 0.375% should have a `couponRate` of `0.00375`. - The `principal` can be any number, but we advise setting it to `1` to unitise the security and specifying the face or purchase amount [on the transaction](/v1/docs/modelling-fixed-rate-vanilla-bonds-in-lusid#booking-a-transaction-to-establish-a-position). - The `flowConventions` object stores all the information necessary to determine [payment schedules](/v1/docs/flow-conventions-and-index-conventions#specifying-a-flow-convention). - The `tradingConventions.priceScaleFactor` field is set to `100` so bond prices can be expressed as a percentage of par. LUSID only applies it to a quote with no `scaleFactor` of its own, and only if your recipe sets the `useInstrumentScaleFactorAsDefault` recipe option. Otherwise, load each quote with a `scaleFactor` of `100`; see [scaling a market price](/v1/docs/scaling-a-market-price). - If you omit the `exDividendConfiguration` object, a bond has no ex-dividend period. - If you omit the `roundingConventions` array, no [rounding conventions](/v1/docs/how-does-lusid-handle-rounding-conventions) are applied at the instrument level. - If the first coupon payment is irregular, specify the `firstCouponPayDate` field. 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_00003DS1",      "name": "UKT 0 ⅜ 10/22/26",      "identifiers": {        "LusidInstrumentId": "LUID_00003DS1",        "Figi": "BBG00ZF1T9P5"      },      "properties": [],      "instrumentDefinition": {        "startDate": "2016-10-22T10:00:00.0000000+00:00",        "maturityDate": "2026-10-22T10:00:00.0000000+00:00",        "domCcy": "GBP",        "flowConventions": {          "currency": "GBP",          "paymentFrequency": "6M",          "dayCountConvention": "Actual365",          "rollConvention": "22",          "businessDayConvention": "Following",          "paymentCalendars": [],          "resetCalendars": [],          "settleDays": 0,          "resetDays": 0,          "leapDaysIncluded": true,          "accrualDateAdjustment": "Adjusted",        },        "principal": 1,        "couponRate": 0.00375,        "identifiers": {},        "calculationType": "Standard",        "roundingConventions": [],        "tradingConventions": {          "priceScaleFactor": 100,          "minimumOrderSize": 0,          "minimumOrderIncrement": 0        },        "instrumentType": "Bond"      },      "state": "Active",      "assetClass": "Credit",      "domCcy": "GBP",      "relationships": []    }  },  ... } ``` ### Understanding how LUSID determines coupon periods LUSID uses the information in the [flow convention](/v1/docs/flow-conventions-and-index-conventions) to build a payment schedule. It implicitly assumes the *last* coupon period is regular, and counts back from the maturity date according to the payment frequency. > **Note**: Any bond with an irregular last coupon period must be mastered using the `ComplexBond` instrument type. [More information](/v1/docs/modelling-complex-bonds-in-lusid). If the bond has an irregular *first* coupon period you can set the optional `firstCouponPayDate` field to create either a long or short first coupon period. ## 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). As mentioned above, we recommend unitising bond instruments and specifying the face or purchase amount on transactions. For example, the following call to the [BatchUpsertTransactions](https://www.lusid.com/docs/api#operation/BatchUpsertTransactions) API acquires 75,000,000 units of a UK gilt uniquely identified by its LUID: ```json curl -X POST 'https://.lusid.com/api/api/transactionportfolios/FixedIncome/UK/transactions/$batchUpsert?successMode=Partial&preserveProperties=true'  -H 'Content-Type: application/json-patch+json'  -H 'Authorization: Bearer '  -d '{  "transactionRequest-1": {    "transactionId": "uk_gilt_purchase_001",    "type": "BuyBond",    "instrumentIdentifiers": {"Instrument/default/LusidInstrumentId": "LUID_00003DS1"},    "transactionDate": "2024-02-22T00:00:00.0000000+00:00",    "settlementDate": "2024-02-25T00:00:00.0000000+00:00",    "units": 75000000,    "transactionPrice": {      "price": 102,      "type": "CleanPrice"    },    "totalConsideration": {      "amount": 0,      "currency": "GBP"    }  } }' ``` Note the following: - The `type` field invokes a custom `BuyBond` [transaction type](/v1/docs/what-is-a-transaction-type) to confer a particular economic impact (see below). - The `units` field specifies the face or purchase amount. - The `transactionPrice` object records the clean market price (not including bond interest)as a percentage of par. This is used by LUSID to automatically calculate the gross consideration (see below). - The `totalConsideration` object: - Sets the settlement currency to `GBP`. - Specifies a cost of `0` to enable LUSID to automatically derive the total consideration (see below). - LUSID has a [transaction fee engine](/v1/docs/transaction-fees-and-capitalisation) to help calculate fees and either capitalise or expense them. > **Note**: This example assumes the transaction, settlement and portfolio currencies are the same. If not, you can [specify exchange rates](/v1/docs/transactions-and-exchange-rates). You might create a `BuyBond` transaction type as follows: ```json curl -X PUT 'https://.lusid.com/api/api/transactionconfiguration/types/default/BuyBond?scope=default'  -H 'Content-Type: application/json-patch+json'  -H 'Authorization: Bearer '  -d '{  "aliases": [    {      "type": "BuyBond",      "description": "Transaction type for bond purchases",      "transactionClass": "Trading",      "transactionRoles": "LongLonger",      "isDefault": false    }  ],  "movements": [    {      "name": "Increase units of security",      "movementTypes": "StockMovement",      "side": "Side1",      "direction": 1    },    {      "name": "Decrease cash balance",      "movementTypes": "CashCommitment",      "side": "Side2",      "direction": -1    },    {      "name": "Report bond interest bought as a flow of value out of the security",      "movementTypes": "Carry",      "side": "BondInterest",      "direction": -1    }  ],  "calculations": [    {      "type": "Txn:BondInterest"    },    {      "type": "Txn:GrossConsideration"    },    {      "type": "DeriveTotalConsideration",      "formula": "Txn:GrossConsideration + Txn:TotalFees"    }  ] }' ``` Note the following: - The `Txn:BondInterest` [calculation](/v1/docs/what-is-a-transaction-type-calculation#txnbondinterest) automatically calculates the amount of bond interest bought or sold and stores the result in the `Transaction/default/BondInterest` system property, available for use in sides. - If a clean price is specified, the `Txn:GrossConsideration` [calculation](/v1/docs/what-is-a-transaction-type-calculation#txngrossconsideration) automatically calculates gross consideration according to the formula `(price * units) + Txn:BondInterest`, and stores the result in the `Transaction/default/GrossConsideration` system property. - The `DeriveTotalConsideration` [calculation](/v1/docs/what-is-a-transaction-type-calculation#derivetotalconsideration) automatically calculates total consideration according to the given, user-defined formula, which in this case sums gross consideration and total fees; this is stored as the `totalConsideration.amount` of the transaction. - The `StockMovement` uses the [built-in](https://support.lusid.com/docs/what-built-in-transaction-types-and-sides-are-provided-with-lusid#builtin-sides) `Side1` side to establish a holding in the instrument with the specified number of units at a cost derived from the total consideration. - The `CashCommitment` movement uses the built-in `Side2` to decrease the instrument currency holding by the total consideration. - The `Carry` movement uses a custom `BondInterest` side to record a flow of value out of the instrument equivalent to the interest purchased. You might create a `BondInterest` custom side as follows: ```json curl -X PUT 'https://.lusid.com/api/api/transactionconfiguration/sides/BondInterest?scope=default'  -H 'Content-Type: application/json-patch+json'  -H 'Authorization: Bearer '  -d '{  "security": "Txn:LusidInstrumentId",  "currency": "Txn:TradeCurrency",  "rate": "Txn:TradeToPortfolioRate",  "units": "Txn:Units",  "amount": "Txn:BondInterest" }' ``` Note this is the same as `Side1` except the `amount` field is set to `Txn:BondInterest` instead of `Txn:TradeAmount`. ### Confirming positions We can [generate a holdings report](/v1/docs/how-do-i-generate-a-holdings-report) for the settlement date to see the impact of the transaction on security and cash holdings: ![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image(902).png?sv=2026-02-06&spr=https&st=2026-11-04T02%3A00%3A42Z&se=2026-11-04T03%3A00%3A42Z&sr=c&sp=r&sig=gP1ZgcRlYU1tlcqF%2FK2J0luISErauZUmpD6zKo80y7A%3D) ### Auditing LUSID’s calculations of transaction amounts We can examine [output transactions](/v1/docs/input-and-output-transactions) automatically generated by LUSID up to the settlement date to audit calculated amounts: ![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image(903).png?sv=2026-02-06&spr=https&st=2026-11-04T02%3A00%3A42Z&se=2026-11-04T03%3A00%3A42Z&sr=c&sp=r&sig=gP1ZgcRlYU1tlcqF%2FK2J0luISErauZUmpD6zKo80y7A%3D) ## Valuing your position To value your position, work through our [valuation checklist](/v1/docs/valuation-checklist). > [!WARNING] > **Important**: By default, LUSID values a `Bond` using the `ConstantTimeValueOfMoney` pricing model and a `ComplexBond` or `InflationLinkedBond` using `SimpleStatic`. We no longer recommend either model; please [change the pricing model](/v1/docs/recipes-changing-the-default-pricing-models-for-instrument-types) to one of the those below. ### Choosing a pricing model Find your kind of bond in the first column to see which pricing models can value it: | Kind of bond | `BondLookupPricer` | `Discounting` | `HullWhite1F` | `InflationForward` | | --- | --- | --- | --- | --- | | `Bond` | ✅ | ✅ | ✅ | N/A | | `ComplexBond`: fixed, stepped or amortising | ✅ | ✅ | ✅ | N/A | | `ComplexBond`: callable or puttable | ✅ (ignores optionality) | ✅ (ignores optionality) | ✅ (values optionality) | N/A | | `ComplexBond`: floating rate | ✅ | ✅ | ✅ for simple floaters only (1) | N/A | | `ComplexBond`: floating rate using annualised direct rates | ✅ | N/A | N/A | N/A | | `ComplexBond`: mortgage- or asset-backed (MBS/ABS) | ✅ | N/A | N/A | N/A | | `ComplexBond`: PIK, convertible or multi-currency | ✅ | ✅ | N/A | N/A | | `InflationLinkedBond` | ✅ | N/A | N/A | ✅ (2) | (1) Resets in advance, with no compounding, caps or floors. (2) For risk, scenarios and rich/cheap analysis; we recommend `BondLookupPricer` for book valuation. ### Pricing models in detail | [Pricing model](/v1/docs/recipes-changing-the-default-pricing-models-for-instrument-types) | [PV calculation](/v1/docs/how-does-lusid-calculate-pv) | Market data required | [Selected available metrics](/v1/docs/what-is-a-metric) | Notes | | --- | --- | --- | --- | --- | | Type | Store | [Recipe key(s)](/v1/docs/recipes-locating-market-data#more-information-on-the-key-field) | | `BondLookupPricer` | Market price multiplied by outstanding principal, plus accrued interest. For a MBS, outstanding principal reflects the pool factor. For an `InflationLinkedBond`, the price is also multiplied by the index ratio, unless the [calculation type](/v1/docs/modelling-inflation-linked-bonds-in-lusid#valuing-your-position)'s price already includes indexation. | 1. [Market price](/v1/docs/how-do-i-upload-a-market-price-or-fx-spot-rate-to-the-quote-store) for the bond 2. Plus, for a floating-rate `ComplexBond`: [interest rate fixings](/v1/docs/how-do-i-load-an-interest-rate-fixing-into-the-lusid-quote-store) 3. `InflationLinkedBond`: [inflation fixings](/v1/docs/how-do-i-upload-an-inflation-fixing-to-the-lusid-quote-store) 4. MBS: a pool factor 5. For spread metrics or the `spreadAnchoredRisk` model option for any bond, a [discount factor curve](/v1/docs/categories-of-complex-market-data) | 1. Quote 2. Quote 3. Quote 4. Quote 5. CMD | 1. `Quote.*.*` 2. `Quote.*.*` 3. `Inflation.*.*` 4. `Quote.*.*` 5. `Rates.<CCY>.<CCY>OIS` | `Valuation/PV` `Valuation/InstrumentPV` `Valuation/Accrued` `Analytic/YieldToMaturity` `Analytic/ModifiedDuration` `Analytic/ZSpread` `Valuation/Diagnostics/BondLookupPricer/Methodology` | Load the price with a quote type of `Price` (treated as clean) or `DirtyPrice`. Other quote types are rejected. A Brazil `InflationLinkedBond` must use `DirtyPrice`. See the model options below. | | `Discounting` | Sum of future cashflows, each discounted on the funding curve for the bond's currency. Floating coupons not yet fixed are projected off the curve for the schedule's index. Does not use a market price. | 1. [Discount factor curve](/v1/docs/categories-of-complex-market-data) 2. Plus, for a floating-rate `ComplexBond`: a [projection curve](/v1/docs/categories-of-complex-market-data) per floating schedule 3. Floating-rate `ComplexBond`: [fixings](/v1/docs/how-do-i-load-an-interest-rate-fixing-into-the-lusid-quote-store) already set on or before the valuation date | 1. CMD 2. CMD 3. Quote | 1. `Rates.<CCY>.<CCY>OIS` 2. `Rates.<CCY>.<Tenor>.<IndexName>` 3. `Quote.*.*` | `Valuation/PV` `Valuation/InstrumentPV` `Valuation/Accrued` `Analytic/YieldToMaturity` `Analytic/ModifiedDuration` `Valuation/Diagnostics/DiscountCurve/Name` (`Bond` only) | Ignores call and put optionality. Yields and durations are solved from the model's own PV. If you do not load a projection curve, LUSID projects off the discount curve instead. | | `HullWhite1F` | Values the bond on an interest rate lattice fitted to the discount curve, taking account of any call or put dates. Floating coupons are projected off the same curve. | 1. [Discount factor curve](/v1/docs/categories-of-complex-market-data) 2. Plus, for a floating-rate `ComplexBond`: [fixings](/v1/docs/how-do-i-load-an-interest-rate-fixing-into-the-lusid-quote-store) already set on or before the valuation date 3. For OAS and effective metrics only, a [market price](/v1/docs/how-do-i-upload-a-market-price-or-fx-spot-rate-to-the-quote-store) | 1. CMD 2. Quote 3. Quote | 1. `Rates.<CCY>.<CCY>OIS` 2. `Quote.*.*` 3. `Quote.*.*` | `Valuation/PV` `Valuation/Accrued` `Analytic/OAS` `Analytic/EffectiveDuration` `Analytic/EffectiveConvexity` `Analytic/EffectiveCS01` `Analytic/EffectiveKeyRateDuration` | Uses a default volatility and mean reversion unless you set them in the model options below. If LUSID declines a bond this model does not support, it can fall back to another model; see the notes below. | | `InflationForward` | Projects the inflation index off the inflation curve (using published fixings where available), then discounts each cashflow on the discount curve. | 1. Inflation curve 2. [Discount factor curve](/v1/docs/categories-of-complex-market-data) 3. Historic inflation fixings | 1. CMD 2. CMD 3. Quote | 1. `Inflation.InflationCurve.<IndexName>` 2. `Rates.<CCY>.<CCY>OIS` 3. `Inflation.*.*` | `Valuation/PV` `Valuation/Accrued` `Valuation/Diagnostics/Inflation/ForwardIndex` | Intended for risk, scenarios and rich/cheap analysis. A `Ratio` or `RatioAccruedOnly` bond must have a `baseCPI`. | | `OverrideOnlyPricer` | N/A | N/A | N/A | Uses external valuation results held in the [Structured Result Store](/v1/docs/what-is-structured-result-data). | ### Notes - **Price quotes and scale factors.** LUSID divides a price by the quote's own `scaleFactor`. If you load a bond price such as `102` with no scale factor, LUSID only uses the instrument's `tradingConventions.priceScaleFactor` instead if you set the `useInstrumentScaleFactorAsDefault` [recipe option](/v1/docs/recipes-changing-default-recipe-options). Otherwise the bond is valued 100 times too high. To be safe, load bond prices with a `scaleFactor` of `100`. - **Fixings.** A floating-rate `ComplexBond` needs every fixing whose reset date is on or before the valuation date, whichever model you use. - **Pool factors.** An MBS needs a pool factor for the valuation date. Under `BondLookupPricer`, you can set the `defaultPoolFactorsToUnity` [recipe option](/v1/docs/recipes-changing-default-recipe-options) to treat a missing pool factor as `1`. - **Discount curves.** By default, LUSID discounts on the `<CCY>OIS` curve. To use a different curve for a currency, set the `fundingCurveByCurrency` [recipe option](/v1/docs/recipes-changing-default-recipe-options). - **Falling back when a model declines a bond.** If `HullWhite1F` cannot value a particular bond (for example, an MBS), it declines it. Set the `allowFallbackOnModelDecline` [recipe option](/v1/docs/recipes-changing-default-recipe-options) to have LUSID try the next matching model rule instead of failing. ### Pricing model options You can set the following options for pricing models: - `BondLookupPricer`: Se the `spreadAnchoredRisk` [model option](/v1/docs/fine-tuning-pricing-models-with-model-options#bondlookupmodeloptions) to `true` to value the bond off the discount curve at a constant spread, taken from a credit spread curve or a `ZSpread` quote, instead of the market price. Use this to get non-zero interest rate and credit spread risk; it requires the discount curve. `cs01BumpWidth` sets the bump width used to calculate `Analytic/CS01/Central` (default 1bp). - `HullWhite1F`: Set the following [model options](/v1/docs/fine-tuning-pricing-models-with-model-options#hullwhitemodeloptions) to override the default values: `meanReversion` (default `0.03`), `volatility` (default `0.008`), `latticeSteps` (default `200`), and per-currency overrides in `meanReversionByCurrency` and `volatilityByCurrency`. ## Assessing risk > **Required prior reading**: [Valuing your position](/v1/docs/modelling-fixed-rate-vanilla-bonds-in-lusid#valuing-your-position) LUSID publishes an [exposure calculation](/v1/docs/how-does-lusid-calculate-exposure) that you can request when valuing your position. The following risk-aware pricing models produce analytic measures (such as yields, durations and spreads) and risk measures (sensitivities to market data): - **Analytic measures** (`Analytic/*`) are solved from a price. That is the market price only under `BondLookupPricer`; every other model solves them from its own calculated value, as shown in the **Priced off** column below. A yield or z-spread is only a market measure if it is priced off the market. - **Risk measures** (`Risk/*`) are calculated by bumping each curve the pricing model uses, then revaluing the bond. Every curve the model uses therefore produces the full family of measures for its asset class; the table below shows a selection. If a model does not use a particular curve, the result for that curve is blank, not zero. - **Aliases**: `Risk/Rates/Pv01` and `Risk/Rates/Br01` are the same as `Risk/Rates/Delta/Central/Parallel`, and `Risk/Rates/Krd` is the same as `Risk/Rates/Delta/Central/PointWise`. - **Curves only**: LUSID never bumps quotes or published fixings, only curves. | Risk-aware pricing model | Additional market data required | Priced off | Available metrics | Notes | | --- | --- | --- | --- | --- | | `Analytic` domain | `Risk` domain | | `BondLookupPricer` | Optional discount factor curve in CMD Store | Market price | `Analytic/YieldToMaturity` `Analytic/YieldToWorst` `Analytic/ModifiedDuration` `Analytic/MacaulayDuration` `Analytic/Convexity` `Analytic/Theta` `Analytic/ZSpread` `Analytic/SpreadDuration` `Analytic/CS01` `Analytic/CS01/Central` Plus, for a floating-rate `ComplexBond`: `Analytic/DiscountMargin` `Analytic/DiscountMarginToWorst` Plus, for a callable or puttable `ComplexBond`: `Analytic/YieldToCall` `Analytic/YieldToPut` `Analytic/ZSpreadToWorst` `Analytic/SpreadDurationToWorst` `Analytic/SpreadWorkoutDate` | None meaningful. `Risk/*` metrics return zero, because the bond is valued from its market price. | `Analytic/ZSpread` and the other spread measures need the discount factor curve; without it they return an error. To get risk measures, enable the `spreadAnchoredRisk` model option. `Analytic/YieldToWorst` covers call dates and maturity only. For the yield if the bond is put, request `Analytic/YieldToPut`. | | `BondLookupPricer` with the `spreadAnchoredRisk` model option, using a ZSpread quote | 1. ZSpread quote in Quote Store 2. Discount factor curve in CMD Store 3. A Rate-typed `Quote` rule in your recipe, placed after the Price rule, to find the ZSpread quote. | Model value at the quoted spread | As above | `Risk/Rates/Pv01` `Risk/Rates/Krd` `Risk/Rates/Gamma/Parallel` `Risk/Rates/Difference/Ladder` `Risk/Credit/Delta/Central/Parallel` `Risk/Credit/Delta/Central/PointWise` `Risk/Credit/Gamma/Parallel` `Risk/Credit/Difference/Ladder` Plus, for an `InflationLinkedBond`: `Risk/Inflation/Delta/Central/Parallel` `Risk/Inflation/Delta/Central/PointWise` `Risk/Inflation/Gamma/Parallel` `Risk/Inflation/Difference/Ladder` | LUSID builds a flat credit spread curve from the ZSpread quote, with a single point at the bond's maturity, and bumps that curve to calculate credit risk. As a result, point-wise credit risk falls entirely on that one point. `Analytic/ZSpread` returns the spread you supplied. | | `BondLookupPricer` with the `spreadAnchoredRisk` model option, using a credit spread curve | 1. Credit spread curve in CMD Store, stored per bond as `CreditSpreadCurve/<LUID>`, recipe key `Credit.CreditSpreadCurve` (or `Credit.CreditSpreadCurve.ClientInternal` and so on, to key on a different identifier) 2. Discount factor curve in CMD Store 3. A Rate-typed `Quote` rule in your recipe, placed after the Price rule. You need this even if you do not load a ZSpread quote; without it, every metric fails. If you put it before the Price rule, other bonds valued with the same recipe fail. | Model value at the curve's spread | As above | `Risk/Rates/Pv01` `Risk/Rates/Krd` `Risk/Rates/Gamma/Parallel` `Risk/Rates/Difference/Ladder` `Risk/Credit/Delta/Central/Parallel` `Risk/Credit/Delta/Central/PointWise` `Risk/Credit/Gamma/Parallel` `Risk/Credit/Difference/Ladder` Plus, for an `InflationLinkedBond`: `Risk/Inflation/Delta/Central/Parallel` `Risk/Inflation/Delta/Central/PointWise` `Risk/Inflation/Gamma/Parallel` `Risk/Inflation/Difference/Ladder` | If you provide both a ZSpread quote and a credit spread curve, LUSID uses the curve. LUSID reads a single spread from the curve at the bond's maturity, so point-wise credit risk falls only on the curve points either side of maturity. A CDS-style `Credit.*.*.*.*` rule does not match the credit spread curve. | | `Discounting` | N/A | Model value off the discount curve | As for `BondLookupPricer` | `Risk/Rates/Pv01` `Risk/Rates/Krd` `Risk/Rates/Gamma/Parallel` `Risk/Rates/Difference/Ladder` | `Analytic/ZSpread` is close to zero, because the bond is discounted on the same curve, so it is not meaningful. For a floating-rate `ComplexBond`, the projection curve's risk appears separately from that of the discount curve. | | `HullWhite1F` | Market price in Quote Store, for OAS and effective metrics | OAS and effective metrics: market price. All other analytics: model value. | `Analytic/OAS` `Analytic/EffectiveDuration` `Analytic/EffectiveConvexity` `Analytic/EffectiveCS01` `Analytic/EffectiveKeyRateDuration` Plus the analytics listed for `BondLookupPricer` | `Risk/Rates/Pv01` `Risk/Rates/Krd` `Risk/Rates/Gamma/Parallel` `Risk/Rates/Difference/Ladder` | The effective metrics account for call and put dates. Yields, `Analytic/ModifiedDuration` and `Analytic/Convexity` do not. Volatility and mean reversion are model options rather than market data, so there is no volatility risk. | | `InflationForward` | N/A | Model value off the inflation and discount curves | `Analytic/YieldToMaturity` `Analytic/ModifiedDuration` `Analytic/MacaulayDuration` `Analytic/Convexity` `Analytic/Theta` | `Risk/Rates/Pv01` `Risk/Rates/Krd` `Risk/Rates/Gamma/Parallel` `Risk/Rates/Difference/Ladder` `Risk/Inflation/Delta/Central/Parallel` `Risk/Inflation/Delta/Central/PointWise` `Risk/Inflation/Gamma/Parallel` `Risk/Inflation/Difference/Ladder` | Spread measures such as `Analytic/ZSpread` are refused, because they would be circular. | Note the following: - **Units and signs.** Risk measures are the change in value for a 1bp move, in the curve's own currency. A long bond has a negative `Risk/Rates/Pv01`. `Analytic/CS01` is reported as a positive number, whereas `Analytic/CS01/Central` and `Analytic/EffectiveCS01` are negative for a long bond. - **Key rate buckets.** To choose your own key rate buckets, pass at least two tenors in the metric's `options`, for example `{"key": "Risk/Rates/Krd", "op": "Value", "options": {"Buckets": "1Y,5Y,10Y"}}`. - **Bump sizes.** To change the bump size or the shifts used for ladders, set the `riskBumpOptions` recipe option, for example `deltaShift` or `ladderShiftOverrides`. - **Risk engine.** Risk for bonds is always calculated by bumping curves. Setting the `riskEngine` recipe option to `Adjoint` or `Parity` makes no difference for bonds. - **Carry.** `Risk/All/Difference/Carry` returns the change in value from today to the next business day, using today's market data. LUSID rolls the bond's discount and projection curves forward a day at constant maturity, so the result includes rolldown. This works whether you load the curves as `DiscountFactorCurveData` or `YieldCurveData`. If LUSID can't roll every curve the valuation uses, it rolls none of them, and the result reflects the passage of time only. Under plain `BondLookupPricer`, carry reflects one day's accrued interest only, because the price does not change. Carry is not available for a floating-rate `ComplexBond` that needs a new fixing on the next business day, such as one that compounds an overnight rate daily, because LUSID values the next day with today's market data. ## Monitoring the lifecycle of the instrument A `Bond` 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 `Bond`. 2. Create transaction types to determine the economic impact of the transactions automatically generated by `Bond` events. **Recommended reading**: [Handling instrument events for bonds](/v1/docs/handling-bond-coupon-principal-and-maturity-instrument-lifecycle-events) The following events are automatically emitted by LUSID but there are many more available to [manually load](/v1/docs/understanding-instrument-lifecycle-events-emitted-by-lusid#bond-complexbond-and-inflationlinkedbond-but-excluding-mbs) to impact the lifecycle, such as `EarlyRedemptionEvent` and `BondDefaultEvent`. | **Instrument event** | Event emission criteria | **Effect of default transaction template** | | --- | --- | --- | | `BondCouponEvent` | Automatically emitted by LUSID each time a bond coupon is due. | One transaction is automatically generated for a cash amount. | | `BondPrincipalEvent` | Automatically emitted by LUSID on the maturity date, though processed before `MaturityEvent`. | One transaction is automatically generated for a cash amount. | | `MaturityEvent` | Automatically emitted by LUSID on the maturity date. | One transaction is automatically generated for all units at zero cost to reduce the holding to zero. |