You can model a simple fixed-rate bond as an instrument of type Bond in LUSID. See all supported instruments.
Kind of bond | LUSID instrument type | More information |
|---|---|---|
Fixed rate with regular coupons (only the first can be irregular) |
| Continue reading this article |
Fixed rate with irregular coupons (other than the first) |
| |
Mortgage-backed security (MBS) | ||
PIK | ||
Inflation-linked |
|
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 that further demonstrates many of the operations and concepts.
Mastering an instrument
Note: You should use the ComplexBond instrument type if your coupon schedule is irregular. The
Bondinstrument type can only accept an irregular first coupon period; all other coupons must be regular.
There are numerous tools 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 of identifiers, and the facility to store extra information as properties.
Fields in the economic definition object are specific to Bond. For more information on these fields, examine the Bond schema, or select Bond from the definition dropdown in the API documentation:

For example, the following call to the UpsertInstruments API masters a UK gilt in a custom instrument scope using a FIGI unique identifier. Note the fields specified below are the minimum required to master an instrument of type Bond:
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
instrumentTypemust beBond.The
startDateshould be the accrual start date; that is, the date from which interest is calculated.The maximum
maturityDateis 31 December 2140.The
couponRateshould be expressed as a decimal rather than a percentage, so a bond paying:10% should have a
couponRateof0.12.5% should have a
couponRateof0.0250.375% should have a
couponRateof0.00375.
The
principalcan be any number, but we advise setting it to1to unitise the security and specifying the face or purchase amount on the transaction.The
flowConventionsobject stores all the information necessary to determine payment schedules.The
tradingConventions.priceScaleFactorfield is set to100so bond prices can be expressed as a percentage of par. LUSID only applies it to a quote with noscaleFactorof its own, and only if your recipe sets theuseInstrumentScaleFactorAsDefaultpricing option. Otherwise, load each quote with ascaleFactorof100; see scaling a market price.If you omit the
exDividendConfigurationobject, a bond has no ex-dividend period.If you omit the
roundingConventionsarray, no rounding conventions are applied at the instrument level.If the first coupon payment is irregular, specify the
firstCouponPayDatefield.
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": {
"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 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
ComplexBondinstrument type. More information.
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 to record the acquisition of a quantity in a particular 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 API acquires 75,000,000 units of a UK gilt uniquely identified by its 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": "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
typefield invokes a customBuyBondtransaction type to confer a particular economic impact (see below).The
unitsfield specifies the face or purchase amount.The
transactionPriceobject 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
totalConsiderationobject:Sets the settlement currency to
GBP.Specifies a cost of
0to enable LUSID to automatically derive the total consideration (see below).
LUSID has a transaction fee engine 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.
You might create a BuyBond transaction type as follows:
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": "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:BondInterestcalculation automatically calculates the amount of bond interest bought or sold and stores the result in theTransaction/default/BondInterestsystem property, available for use in sides.If a clean price is specified, the
Txn:GrossConsiderationcalculation automatically calculates gross consideration according to the formula(price * units) + Txn:BondInterest, and stores the result in theTransaction/default/GrossConsiderationsystem property.The
DeriveTotalConsiderationcalculation 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 thetotalConsideration.amountof the transaction.The
StockMovementuses the built-inSide1side to establish a holding in the instrument with the specified number of units at a cost derived from the total consideration.The
CashCommitmentmovement uses the built-inSide2to decrease the instrument currency holding by the total consideration.The
Carrymovement uses a customBondInterestside to record a flow of value out of the instrument equivalent to the interest purchased.
You might create a BondInterest custom side as follows:
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 for the settlement date to see the impact of the transaction on security and cash holdings:
.png?sv=2026-02-06&spr=https&st=2026-10-14T22%3A27%3A53Z&se=2026-10-14T22%3A52%3A53Z&sr=c&sp=r&sig=o5TznsUei%2BsyfjQGZubhtRMPrKr1tU0mv3GZ3n%2BaDSw%3D)
Auditing LUSID’s calculations of transaction amounts
We can examine output transactions automatically generated by LUSID up to the settlement date to audit calculated amounts:
.png?sv=2026-02-06&spr=https&st=2026-10-14T22%3A27%3A53Z&se=2026-10-14T22%3A52%3A53Z&sr=c&sp=r&sig=o5TznsUei%2BsyfjQGZubhtRMPrKr1tU0mv3GZ3n%2BaDSw%3D)
Valuing your position
To value your position, work through our valuation checklist.
Important: By default, LUSID values a
Bondusing theConstantTimeValueOfMoneypricing model and aComplexBondorInflationLinkedBondusingSimpleStatic. We no longer recommend either model; please change the pricing model 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 |
|
|
|
|
|---|---|---|---|---|
| N/A | |||
| N/A | |||
| N/A | |||
| N/A | |||
| N/A | N/A | N/A | |
| N/A | N/A | N/A | |
| N/A | N/A | ||
| N/A | N/A |
(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
Market data required | Notes | |||||
|---|---|---|---|---|---|---|
Type | Store | |||||
| Market price multiplied by outstanding principal, plus accrued interest. For a MBS, outstanding principal reflects the pool factor. |
|
|
|
| Load the price with a quote type of See the model options below. |
| 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. |
|
|
|
| Ignores call and put optionality. Yields and durations are solved from the model's own PV. |
| 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. |
|
|
|
| Uses a default volatility and mean reversion unless you set them in the model options below. |
| Projects the inflation index off the inflation curve (using published fixings where available), then discounts each cashflow on the discount curve. |
|
|
|
| Intended for risk, scenarios and rich/cheap analysis. A |
| N/A | N/A | N/A | Uses external valuation results held in the Structured Result Store. | ||
Notes
Price quotes and scale factors. LUSID divides a price by the quote's own
scaleFactor. If you load a bond price such as102with no scale factor, LUSID only uses the instrument'stradingConventions.priceScaleFactorinstead if you set theuseInstrumentScaleFactorAsDefaultpricing option in your recipe. Otherwise the bond is valued 100 times too high. To be safe, load bond prices with ascaleFactorof100.Fixings. A floating-rate
ComplexBondneeds 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 thedefaultPoolFactorsToUnitypricing option in your recipe to treat a missing pool factor as1.Discount curves. By default, LUSID discounts on the
<CCY>OIScurve. To use a different curve for a currency, set thefundingCurveByCurrencypricing option in your recipe.Falling back when a model declines a bond. If
HullWhite1Fcannot value a particular bond (for example, an MBS), it declines it. Set theallowFallbackOnModelDeclinepricing option in your recipe to have LUSID try the next matching model rule instead of failing.
Model options
You can set the following in the modelOptions of a vendor model rule:
BondLookupPricer(BondLookupModelOptions):spreadAnchoredRiskset totruevalues the bond off the discount curve at a constant spread, taken from a credit spread curve or aZSpreadquote, instead of the market price. Use this to get non-zero interest rate and credit spread risk; it requires the discount curve.cs01BumpWidthsets the bump width used to calculateAnalytic/CS01/Central(default 1bp).HullWhite1F(HullWhiteModelOptions):meanReversion(default0.03),volatility(default0.008),latticeSteps(default200), and per-currency overrides inmeanReversionByCurrencyandvolatilityByCurrency.
Assessing risk
Required prior reading: Valuing your position
LUSID publishes an exposure calculation 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 underBondLookupPricer; 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/Pv01andRisk/Rates/Br01are the same asRisk/Rates/Delta/Central/Parallel, andRisk/Rates/Krdis the same asRisk/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 | |
|---|---|---|---|---|---|
|
| ||||
| Optional discount factor curve in CMD Store | Market price |
| None meaningful. |
To get risk measures, enable the
|
|
| Model value at the quoted spread | As above |
| 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. |
|
| Model value at the curve's spread | As above |
| If you provide both a ZSpread quote and a credit spread curve, LUSID uses the curve.
|
| N/A | Model value off the discount curve | As for |
|
For a floating-rate |
| Market price in Quote Store, for OAS and effective metrics | OAS and effective metrics: market price. All other analytics: model value. |
|
| The effective metrics account for call and put dates. Yields, Volatility and mean reversion are model options rather than market data, so there is no volatility risk. |
| N/A | Model value off the inflation and discount curves |
|
| Spread measures such as |
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/CS01is reported as a positive number, whereasAnalytic/CS01/CentralandAnalytic/EffectiveCS01are 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
riskBumpOptionspricing option in your recipe, for exampledeltaShiftorladderShiftOverrides.Risk engine. Risk for bonds is always calculated by bumping curves. Setting the
riskEnginepricing option toAdjointorParitymakes no difference for bonds.Carry.
Risk/All/Difference/Carryreturns the change in value from today to the next business day, using today's market data. If all the rates curves are yield curves, LUSID rolls them forward a day, so the result includes rolldown; otherwise it reflects the passage of time only. Under plainBondLookupPricer, carry reflects one day's accrued interest only, because the price does not change. Carry is not available for a floating-rateComplexBondor anInflationLinkedBond.
Monitoring the lifecycle of the instrument
A Bond is tightly integrated into LUSID’s instrument event framework. To enable this for your domain, you must:
Register a recipe with every portfolio holding a
Bond.Create transaction types to determine the economic impact of the transactions automatically generated by
Bondevents.
Recommended reading: Handling instrument events for bonds
The following events are automatically emitted by LUSID but there are many more available to manually load to impact the lifecycle, such as EarlyRedemptionEvent and BondDefaultEvent.
Instrument event | Event emission criteria | Effect of default transaction template |
|---|---|---|
| Automatically emitted by LUSID each time a bond coupon is due. | One transaction is automatically generated for a cash amount. |
| Automatically emitted by LUSID on the maturity date, though processed before | One transaction is automatically generated for a cash amount. |
| 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. |