To model a bond you must first choose the correct LUSID instrument type. See all instrument types.
Kind of bond | LUSID instrument type | More information |
Fixed rate with regular coupons (only the first can be irregular) Zero coupon | Bond | This article. |
Fixed rate with irregular coupons (other than the first) Floating rate Fixed-to-floating rate Municipal Callable Puttable Sinkable Convertible Mortgage-backed security (MBS) | ComplexBond | Click here. |
Inflation-linked | InflationLinkedBond | Click here. |
The remainder of this article explains the lifecycle of a vanilla government bond issue with a regular coupon schedule and fixed principal:
- Mastering the instrument in the LUSID Security Master.
- Booking a transaction in a portfolio to record a purchase of a quantity of that bond, and establishing a holding (position).
- Valuing your position at any time using different models.
- Examining the exposure of that position in combination with your other holdings.
- Managing PV, accrual and P&L on a daily basis.
- Monitoring the lifecycle of the instrument and automating the process of booking cash settlements.
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 Bond
instrument type can only accept an irregular first coupon period; all other coupons must be regular.
There are numerous methods 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, select Bond from the instrumentType dropdown in the API documentation:
Alternatively, consult the SDK class reference documentation (the content is the same).
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" } } } }'
Note the following:
- The
instrumentType
must beBond
. - 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
of0.1
- 2.5% should have a
couponRate
of0.025
- 0.375% should have a
couponRate
of0.00375
.
- 10% should have a
- The
principal
can be any number, but we advise setting it to1
to unitise the security and specifying the face or purchase amount on the transaction. - The
flowConventions
object stores all the information necessary to determine coupon periods, accrued interest amounts and payment dates:- The
paymentFrequency
field can be any tenor, in this case6M
to signify twice yearly. Supported day count conventions. - The
rollConvention
field should count back from the maturity date, so in this case22
for a bond maturing on 22 October, which means the coupon dates are 22 October and 22 April each year. We also recommend setting abusinessDayConvention
to determine what should happen if this is not a good business day. More information on roll and business day conventions. Note business days in LUSID are determined by holiday calendars. - The
accrualDateAdjustment
field is optional and defaults toAdjusted
. This is suitable for European treasury bonds but for US treasury bonds we recommendUnadjusted
. - The
settleDays
field in a flow convention is deprecated, andresetDays
is ignored for fixed-rate bonds. Thescope
andcode
fields can be ignored unless you are loading a flow convention from a library.
- The
- If you do not specify an
exDividendConfiguration
object, a bond has no ex-dividend period. - If the first coupon payment is irregular, specify the
firstCouponPayDate
field.
Providing the request is successful, the response:
- Confirms the globally-unique LUID for the instrument (highlighted in red below)
- Generates extra fields that are stored as part of the instrument definition and can be filtered on (in yellow)
- Supplies default values for fields not explicitly specified in the request (in green):
{ "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": [], "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 ComplexBond
instrument 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 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": "StockIn", "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": "Price" }, "totalConsideration": { "amount": 76594777.40, "currency": "GBP" }, "properties": { "Transaction/default/BondInterest": { "key": "Transaction/default/BondInterest", "value": { "metricValue": { "value": 94777.40, "unit": "" } } } } }, }'
Note the following:
- The
type
field invokes the built-inStockIn
transaction type for simplicity, but you can create your own custom transaction type to determine the economic impact of bond purchases if you wish, perhaps using theBondInt
andSide2WithoutBondInterest
built-in sides designed for bond transactions. - The
units
field specifies the face or purchase amount. - The
totalConsideration.amount
field sets the settlement currency to GBP and specifies the total amount. This can be based upon the clean price but we recommend the dirty price; see below. - We recommend adding the
BondInterest
system property to bond transactions to record the amount of interest bought or sold. LUSID uses this property to calculate the clean price and makes it available on sides to help you customise the economic impact of bond transactions. - The
transactionPrice
object is optional and not used for cost calculations in LUSID. If the transaction currency is different to the settlement currency, specify thetransactionCurrency
andexchangeRate
fields; otherwise LUSID considers the transaction and settlement currencies to be the same. If the transaction currency is different to the portfolio currency, add theTradeToPortfolioRate
system property. More information.
You can confirm your position in a portfolio by calling the GetHoldings API; here the response is transformed to a Pandas dataframe for clarity:
Valuing your position
To value your position, work through our valuation checklist. For a demonstration, see sections 5 and 6 of the accompanying Jupyter Notebook.
The following pricing models are suitable for instruments of type Bond
; note your choice impacts the market data required, the LUSID store in which to load it, and the composition of your recipe.
Note: The default model for bonds is currently ConstantTimeValueOfMoney
. You should change this to one of the alternatives below. See how to do this.
Pricing model | Status | Notes |
BondLookupPricer | Coming soon | |
SimpleStatic | Available | Calculates market value according to the formula price / scaling factor * principal * units . Only requires a market price uploaded with an appropriate scaling factor reflecting par, for example 100. LUSID then produces a present value (PV) that is the sum of the clean proceeds and the coupon accrual to date. |
Discounting | Available | Uses a discount curve to value your bond rather than taking the market price. This is more commonly used for portfolio or risk analysis. Clean proceeds and coupon accrual are still calculated but by different means. |
Assessing risk
LUSID supports both analytic and bump and valuation mechanisms for assessing risk; contact us if you need more information.
Managing PV, accrual and P&L on a daily basis
LUSID can report many hundreds of metrics in a valuation report. For a demonstration, see section 6 of the accompanying Jupyter Notebook.
Note the following:
Valuation/PV*
metrics calculate PV according to a formula specific to the pricing model. For bothBondLookupPricer
andSimpleStatic
this isprice / scaling factor * principal * units + accrual
.Valuation/CleanPV*
metrics calculate PV minus accrual.Valuation/Accrued*
metrics calculate accrual 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 theValuation/Diagnostics/Accrual/*
metrics to diagnose accrual calculations.Valuation/PnL/*
metrics calculate unrealised profit/loss as the difference between the PV at the start and end of the valuation period. Note these metrics are currently being replaced by dedicatedProfitAndLoss/*
metrics with windowing capabilities.Analytic/*
metrics calculate yield to maturity and duration.
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
LUSID is transitioning to a system where it automatically emits lifecycle events for bonds. We provide default transaction templates that you can use as-is to automatically generate transactions in impacted portfolios, and recommendations for transaction types that deliver appropriate economic impacts. More information.
Contact us to turn this feature on in your environment. The following events are available for instruments of type Bond
:
Instrument event type | Effect of LUSID default transaction template | Recommendation for your transaction type |
BondCoupon | 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. |
BondPrincipal | 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. | |
Maturity | A single transaction is automatically generated on the bond's maturity date, settling at the same time. The total consideration is set to zero. |
In the LUSID web app you can use Dashboard > Transactions in Output mode with a suitable window to monitor historical and future transactions, or alternatively call the BuildTransactions API directly. For example, in the picture below:
- Transactions in red represent historical bond coupon payments for the UK gilt mastered in this article with respect to a date 'today' of 26 February 2024;
- Transactions in green represent future bond coupon payments, the return of principal, and close-out of the position upon maturity:
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 API directly. Note the recipe you specify must currently be set to use the ConstantTimeValueOfMoney
pricing model for bonds.
You can call the GetUpsertablePortfolioCashFlows API to return imminent cashflows as upsertable DTOs ready to manually load into LUSID as input transactions.