Views:

Related resources:

Explanation

Tutorials

How-to guides

Providing you are a LUSID user with sufficient access control permissions, you can create an instrument to model a bond in the LUSID instrument master. You can then:

Note: If you are the LUSID domain owner, you are automatically assigned the built-in lusid-administrator role, which has all the permissions necessary to perform the operations in this article.

There are many different types of bond, from convertibles to asset-backed to inflation-linked. For the purposes of this article, we concentrate on vanilla government bond issues with a regular coupon schedule and fixed principal. There is also an accompanying Jupyter Notebook that further demonstrates many of the operations and concepts.

Creating an instrument

LUSID's instrument model is designed with reference to ISDA CDM and FpML, and bonds constitute an integral part of this instrument model.

To create an instrument modelling a bond, call the LUSID UpsertInstruments API and specify a definition with an instrumentType of Bond and a suitable coupon rate, initial accrual date, and maturity date. Your FlowConventions object should define repeatable characteristics for coupon payments. For more information on constructing a suitable economic definition, examine the API documentation and choose Bond from the dropdown box:

For example, providing you have a valid API access token, you could run the following command in your LUSID domain to create an instrument for a UK Gilt 1.5% 2047:

curl -X POST "https://<your-domain>.lusid.com/api/api/instruments"
   -H "Authorization: Bearer <your-API-access-token>"
   -H "Content-Type: application/json"
   -d '{"upsert-request-1": {
    "name": "UK Gilt 1.5 2047",
    "identifiers": {
      "ClientInternal": {
        "value": "UK_Gilt_2047-identifier"
        }
      },
    "definition": {
      "instrumentType": "Bond",
      "startDate": "2016-09-21T10:00:00.0000000+00:00",
      "maturityDate": "2047-07-22T10:00:00.0000000+00:00",
      "identifiers": {},
      "flowConventions": {
        "currency": "GBP",
        "paymentFrequency": "6M",
        "dayCountConvention": "Act365",
        "rollConvention": "1",
        "paymentCalendars": ["GBP","LON"],
        "resetCalendars": [],
        "resetDays": 2,
        "businessDayConvention": "ModifiedFollowing"
      },
      "domCcy": "GBP",
      "couponRate": 0.015,
      "principal": 1
    }
  }
}'

Note the following:

  • You could set principal to any value, but we advise setting it to 1 to unitise the security and specify the face or purchase amount on the transaction (see the section below).
  • The couponRate should be a number rather than a percentage, so for example 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
  • settleDays is defined as the 'number of good business days' after startDate. When the payment dates and accrual periods are generated, it is this date, and not startDate, that is used as the starting point for schedule generation. Increasing settleDays pushes forward the start of the first accrual period and, depending on the StubType settings, the payment dates. Setting it to 0 uses startDate as the starting point for schedule generation.
  • resetDays is defined as the 'number of good business days' between determination and payment of reset. Note this is ignored for vanilla fixed-rate bonds, but is relevant for floating rate bonds using the ComplexBond template. This determines the number of days between a reset (or fixing, for example a LIBOR fixing) and the start of the coupon accrual period. It should be a positive number, typically 1 or 2, and means that the LIBOR fixing that number of days before the start of a coupon is used to generate the coupon payment amount.
  • For more information on the other fields in a flow convention, see this article.

Providing the request is valid, the response contains an extra identifier, LUID_00003D57. This is because LUSID automatically generates a LUSID instrument ID (or LUID) for every instrument that is guaranteed to be unique and never change. You can use this LUID to reference the instrument in subsequent API calls:

{
    "values": {
        "upsert-request-1": {
            "href": "https://jamleed.lusid.com/api/api/instruments/LusidInstrumentId/LUID_00003D57",
            "lusidInstrumentId": "LUID_00003D57",
            "version": {
                "effectiveFrom": "0001-01-01T00:00:00.0000000+00:00",
                "asAtDate": "2021-11-12T09:05:21.5639990+00:00"
            },
            "name": "UK Gilt 1.5 2047",
            "identifiers": {
                "ClientInternal": "UK_Gilt_2047-identifier",
                "LusidInstrumentId": "LUID_00003D57"
            },
            "properties": [],
            "instrumentDefinition": {
                "startDate": "2016-09-21T10:00:00.0000000+00:00",
                "maturityDate": "2047-07-22T10:00:00.0000000+00:00",
                "domCcy": "GBP",
                "flowConventions": {
                    "currency": "GBP",
                    "paymentFrequency": "6M",
                    "dayCountConvention": "Act365",
                    "rollConvention": "1",
                    "paymentCalendars": ["GBP","LON"],
                    "resetCalendars": [],
                    "settleDays": 0,
                    "resetDays": 2,
                    "businessDayConvention": "ModifiedFollowing"
                },
                "principal": 1.0,
                "couponRate": 0.015,
                "identifiers": {},
                "calculationType": "Standard",
                "instrumentType": "Bond"
            },
            "state": "Active",
            "assetClass": "Credit",
            "domCcy": "GBP"
        }
    },
    ...
}

Booking a transaction to establish a position

Once the instrument is mastered, you can call the LUSID UpsertTransactions API to purchase a quantity of the bond in a particular portfolio. As mentioned above, you should create unitised bond instruments by setting the principal to 1 and then specifying the transaction amount as the face value traded.

The example below has a position (unit) size of 75,000,000 and assumes a market price of 102 and no accrued interest for simplicity (so interest is not reflected in the total consideration). Therefore, the clean price, which is net of accrual and the dirty price, which includes it, are the same:

curl -X POST "https://<your-domain>.lusid.com/api/api/transactionportfolios/<scope>/<code>/transactions"
   -H "Authorization: Bearer <your-API-access-token>"
   -H "Content-Type: application/json"
   -d '[
      {
        "transactionId": "uk_gilt_2047_purchase_001",
        "type": "Buy",
        "instrumentIdentifiers": {
          "instrument/default/LusidInstrumentId": "LUID_00003D57"
        },
        "transactionDate": "2021-10-15T00:00:00.0000000+00:00",
        "settlementDate": "2021-10-16T00:00:00.0000000+00:00",
        "units": 75000000,
        "transactionPrice": {
          "price": 102,
          "type": "Price"
        },
        "totalConsideration": {
          "amount": 76500000,
          "currency": "GBP"
        },
        "transactionCurrency": "GBP",
        "exchangeRate": 1,
        "properties": {},
        "counterpartyId": "",
        "source": ""
    }
]'

Note this transaction uses the default Buy transaction type, but you could define your own custom transaction type to represent bond purchases if you wish.

You can confirm your position at any time by calling the LUSID GetHoldings API with the appropriate LUID:

curl -X GET "https://<your-domain>.lusid.com/api/api/transactionportfolios/<scope>/<code>/holdings?filter=instrumentUid%20eq%20'LUID_00003D57'"
   -H "Authorization: Bearer <your-API-access-token>"

Valuing your position

To value your position, you should first load suitable market data into LUSID and then create a valuation recipe. For demonstrations of these operations, see sections 4 and 5 of the accompanying Jupyter Notebook.

In your recipe, you can choose between two valuation models. Specify:

  • SimpleStatic to calculate the value according to the formula: price/100 * face value + coupon accrual, as demonstrated in the Jupyter Notebook. This model only requires a price uploaded against your bond identifier. LUSID then produces a present value (PV) that is the sum of the clean proceeds and the coupon accrual to date. 
  • Discounting to use a particular 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 Technical Support if you need more information.

Managing PV, accrual and P&L on a daily basis

The present value (PV) of a bond using the SimpleStatic model is determined from its price/100 * face value + coupon accrual. The P&L is the difference between the PV at the start and end of the period in question.

The accrual of the coupon depends on the day basis and coupon period defined when creating the instrument. In most cases, this increases in amount until the payment date, at which point it resets to 0 and starts to accrue again the next day.

In section 5 of the accompanying Jupyter Notebook, you can see the P&L and accrual changing between days 1 and 2. From here, we jump forward to the day before the coupon payment date; we now have one day remaining until the coupon payment is due. After payment, you can observe the accrued returns to 0 the following day. There is no date when the accrued appears as the full value of the coupon because it is assumed to be paid the day its period completes.

Changing your position

You can call the LUSID UpsertTransactions API to sell a quantity of a bond at any time to reduce your position. The following example shows the sale of all 75,000,000 units of the UK Gilt 1.5% 2047; the total consideration omits any calculation of accrued interest for simplicity:

curl -X POST "https://<your-domain>.lusid.com/api/api/transactionportfolios/<scope>/<code>/transactions"
   -H "Authorization: Bearer <your-API-access-token>"
   -H "Content-Type: application/json"
   -d '[
      {
        "transactionId": "uk_gilt_2047_purchase_002",
        "type": "Sell",
        "instrumentIdentifiers": {
          "instrument/default/LusidInstrumentId": "LUID_00003D57"
        },
        "transactionDate": "2021-10-21T00:00:00.0000000+00:00",
        "settlementDate": "2021-10-22T00:00:00.0000000+00:00",
        "units": 75000000,
        "transactionPrice": {
          "price": 105,
          "type": "Price"
        },
        "totalConsideration": {
          "amount": 78750000,
          "currency": "GBP"
        },
        "transactionCurrency": "GBP",
        "exchangeRate": 1,
        "properties": {},
        "counterpartyId": "",
        "source": ""
    }
]'

Monitoring the lifecycle of the instrument

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

You can monitor the upcoming cashflows for a bond in several ways:

These tools are helpful in bringing predictability to your cash receipts. For a demonstration, see section 6 of the accompanying Jupyter Notebook.

When an instrument cashflow or maturity event occurs in LUSID, it's important to note two things: 

  1. The cashflows are assumed to have been paid but are not presently auto-generated as such. This means the instrument or cashflow from the instrument drops out of your valuation. We will shortly implement ‘automatic settlement’, so that you can choose to auto-generate the appropriate cashflow or instrument, link it to the contract or instrument in question, and upsert it to the portfolio.

    For now, this must be done manually, using either the Manage Cashflows dashboard in the LUSID web app, or by calling the LUSID GetUpsertablePortfolioCashFlows API, which returns imminent cashflows as upsertable DTOs ready to push into LUSID as transactions. If you’d like to track the total cash position of the instrument, upsert cashflows with the same strategy tag you used for the main position at the time of booking. When you view the PV, you can then group by strategy tag.
  2. An instrument cannot ‘expire’ in LUSID; it is still available post-maturity, although the valuation is 0. If you set your holding to 0, it will no longer appear in reports unless you are deliberately backdating.