---
title: "Modelling vanilla fixed-rate bonds in LUSID"
slug: "modelling-fixed-rate-vanilla-bonds-in-lusid"
updated: 2026-05-12T13:51:00Z
published: 2026-05-12T13:51:00Z
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).

Note LUSID has dedicated instrument types for other kinds of bond:

| **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). |
| 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, 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)

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://<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": "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 without [scaling every quote](/v1/docs/scaling-a-market-price) loaded into LUSID.
- 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://<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": "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"
    },
    "properties": {
      "Transaction/MyProperties/TradeCommission": {
        "key": "Transaction/MyProperties/TradeCommission",
        "value": {
          "metricValue": {
            "value": 200.00,
            "unit": "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).
- The trade commission is recorded using a [custom property](/v1/docs/properties).

> **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://<your-domain>.lusid.com/api/api/transactionconfiguration/types/default/BuyBond?scope=default'
  -H 'Content-Type: application/json-patch+json'
  -H 'Authorization: Bearer <your-API-access-token>'
  -d '{
  "aliases": [
    {
      "type": "BuyBond",
      "description": "Transaction type for bond purchases",
      "transactionClass": "Basic",
      "transactionRoles": "AllRoles",
      "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 + Properties[Transaction/MyProperties/TradeCommission]"
    }
  ]
}'
```

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 in an [A2B report](/v1/docs/creating-an-a2b-report-to-understand-how-valuations-change-over-time) and [journal entry lines](/v1/docs/assigning-economic-activity-to-general-ledger-accounts-using-posting-rules).

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

```json
curl -X PUT 'https://<your-domain>.lusid.com/api/api/transactionconfiguration/sides/BondInterest?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: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)

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

## 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 `ComplexBond`. Note your choice impacts the market data required and the composition of your recipe:

- [BondLookupPricer](https://support.lusid.com/docs/what-pricing-models-can-i-use-in-my-valuation#instrumentspecific-pricing-models) (recommended)
- [SimpleStatic](https://support.lusid.com/docs/what-pricing-models-can-i-use-in-my-valuation#general-pricing-models)
- [Discounting](https://support.lusid.com/docs/what-pricing-models-can-i-use-in-my-valuation#general-pricing-models)

> **Note**: The default model for bonds is currently `ConstantTimeValueOfMoney`, but we no longer recommend using it. You should change this to one of the alternatives above. [See how to do this](/v1/docs/recipes-changing-the-default-pricing-models-for-instrument-types).

LUSID can report many hundreds of [metrics](/v1/docs/what-is-a-metric) in a valuation report. Note the following:

- `Valuation/PV*` metrics [calculate PV](/v1/docs/how-does-lusid-calculate-pv) according to a formula specific to the pricing model.
- `Valuation/Accrued*` metrics [calculate accrual](/v1/docs/how-does-lusid-calculate-accrued-interest) according to the flow convention defined in the underlying instrument. In most cases this increases in amount until the payment date, at which point it resets to zero and starts to accrue again the next day; there is no date on which the accrued appears as the full value of the coupon because it is assumed to be paid the day a period completes. You can use the `Valuation/Diagnostics/Accrual/*` metrics to [diagnose accrual calculations](/v1/docs/how-does-lusid-calculate-accrued-interest#diagnosing-calculations-in-valuation-reports).
- `Valuation/CleanPV*` metrics calculate PV minus accrual.
- `ProfitAndLoss/*` metrics [calculate unrealised profit/loss](/v1/docs/how-does-lusid-calculate-pl) as the difference between the PV at the start and end of the valuation period.
- `Analytic/*` metrics [calculate yield to maturity and duration](/v1/docs/how-does-lusid-calculate-yield-to-maturity-and-duration).

## Assessing risk

LUSID provides an [exposure calculation](/v1/docs/how-does-lusid-calculate-exposure) and supports both analytic and bump and valuation mechanisms for assessing risk.

## Monitoring the lifecycle of the instrument

Bonds typically produce a regular stream of cashflows and, upon maturity, return the final coupon and principal.

> **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 `Bond` 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 `Bond`.
2. Create transaction types to determine the economic impact of the transactions automatically generated by `Bond` events. [See our recommendations](/v1/docs/handling-bond-coupon-principal-and-maturity-instrument-lifecycle-events).

| **Instrument event type** | **Effect of event** | **More information** |
| --- | --- | --- |
| `BondCouponEvent` | A transaction is automatically generated for each bond coupon on its ex-dividend date, settling on its payment date. The total consideration is the coupon rate per unit scaled to the holding in a portfolio at that point in time. | [See this tutorial](/v1/docs/handling-bond-coupon-principal-and-maturity-instrument-lifecycle-events). |
| `BondPrincipalEvent` | A single transaction is automatically generated on the bond's maturity date, settling at the same time. The total consideration is set to the number of units held in a portfolio at that point in time. |
| `MaturityEvent` | A single transaction is automatically generated on the bond's maturity date, settling at the same time. The total consideration is set to zero. |

### Manually loading 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. Note the recipe you specify must currently be set to use the `ConstantTimeValueOfMoney` pricing model for bonds.

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.
