Getting started: Setting up and valuing a simple IBOR

LUSID is an API-first, SaaS-native investment data management platform.

To get started, we'll explore fundamental principles and demonstrate core capabilities by using LUSID to perform the following task:

“As a UK asset manager, I run a single portfolio containing UK equities and investment-grade vanilla bonds, and additionally maintain a cash position. The portfolio contains around 20 positions and trades around 5 positions a week. I want to view the asset allocation (equities vs. bonds vs. cash) on a daily basis.”

We'll see how to:

  • Model this scenario in LUSID using entities such as instruments, portfolios, transactions and more.

  • Load trade and market data into LUSID.

  • Generate positions and assemble the information required to value the portfolio on a per asset class basis.

You can examine and run the complete code sample for this exercise from this Jupyter Notebook, providing you have suitable access control permissions. This should automatically be the case if you set up your own LUSID domain (more on that below). If you are informed you do not have a license to perform a particular operation, please contact support.

Populating the LUSID instrument master

The first task is to create one instrument modelling each equity and bond we want to hold in our portfolio. Note the following about instruments:

  • The LUSID instrument master is a central repository that every portfolio in LUSID accesses. You can optionally partition the instrument master into protected scopes, perhaps to hide sensitive contractual information encapsulated in derivative instruments.

  • An instrument is an economic definition. Every instrument must have a name and at least one market identifier, such as a FIGI or ISIN. Other fields are specific to the type of asset, for example coupon rate and payment frequency for bonds. You can of course add properties to instruments to store as much additional information as you like.

  • We provide templates to help you model equities, different types of bond, swaps, options, CFDs, FX forwards and more.

  • Your LUSID domain is prepopulated with a basket of standard currencies, so there is already a GBP currency instrument; you don't need to model currencies explicitly.

  • When you create an instrument, LUSID automatically generates a LUID (LUSID Unique ID), an internal identifier that is guaranteed to be unique and never change.

  • Every transaction you upsert into LUSID must be booked with an identifier (such as a FIGI, ISIN or LUID) that enables LUSID to resolve it to a mastered instrument, in order to guarantee an accurate position.

Read our instrument documentation.

Let's assume we have a CSV file exported from a database containing information about our assets:

For each equity and bond in the file, we need to call the LUSID UpsertInstruments API and provide a suitable economic definition from the available information.

Step 1 of the accompanying Jupyter Notebook demonstrates how to do this using the LUSID Python SDK. You can execute the Notebook in Jupyterhub for your LUSID domain and then sign in to the web app to see the results on the Instruments dashboard, available from the left-hand Data Management menu:

Creating a portfolio

The next task is to create a portfolio to store transactions for the instruments we want to hold, from which LUSID can generate positions. Note the following about portfolios:

  • There are different types of portfolio. We need to create a transaction portfolio.

  • A portfolio must be given a creation date that precedes the date of the first transaction we intend to load into it.

  • You have the option to specify sub-holding keys when you create a portfolio that subsequently enable you to partition individual positions, for example equities into different investment strategies, or cash balances into different types such as income and margin, and so on.

Read our portfolio documentation.

We need to call the LUSID CreatePortfolio API, specifying a suitable scope and code, and name and base currency.

Step 2 of the accompanying Jupyter Notebook demonstrates how to do this using the LUSID Python SDK. You can execute the Notebook in Jupyterhub for your LUSID domain and then sign in to the web app to see the portfolio on the Data Management > Portfolios dashboard.

Setting initial positions

The next task is to set initial positions for the instruments in our portfolio (including an initial cash position). There are two ways of doing this:

  • If we have access to a stream of historical transactions, we can call the LUSID UpsertTransactions API to load them and then have LUSID automatically generate positions from the results of buys and sells.

  • If not, we can call the LUSID SetHoldings API to set positions explicitly.

Read our transaction documentation.

Step 3 of the accompanying Jupyter Notebook demonstrates how to call the SetHoldings API using the LUSID Python SDK. You can execute the Notebook in Jupyterhub for your LUSID domain and then sign in to the web app to see the results on the Dashboard > Transactions:

Generating holdings

The next task is to ask LUSID to generate holdings (positions) for the instruments in our portfolio. Note the following about holdings:

  • LUSID generates a holding on-the-fly by decomposing all the events impacting a particular instrument into their underlying economic movements: these events can be transactions (buys and sells), any manual holdings adjustments you have made, and any corporate actions that affect that instrument (such as a stock split).

  • Each event has a transaction type that controls how and when the holding is updated, whether the effect is positive or negative, and whether other holdings are impacted. For example, the built-in Buy transaction type increases an equity holding by the number of units purchased, and simultaneously decreases your cash holding by the total consideration. You can of course configure transaction types to specify your own economic impacts.

  • A cash holding in a particular currency may therefore be determined by events impacting cash directly (such as an injection of funds using the built-in FundsIn transaction type), but also by events impacting other holdings, including other cash holdings.

  • By default, LUSID reports a single holding of type ‘position’ for non-cash instruments (such as equities and bonds), though you can change this using sub-holding keys. For cash, LUSID reports holdings of different types over time to reflect lifecycle events: ‘cash balance' for settled cash, ’cash commitment' for future payments, ‘cash receivable’ for expected income, and so on.

Read our holdings documentation.

We need to call the LUSID GetHoldings API, specifying the scope and code of the portfolio to generate.

Step 4 of the accompanying Jupyter Notebook demonstrates how to do this using the LUSID Python SDK. You can execute the Notebook in Jupyterhub for your LUSID domain and then sign in to the web app to see the current positions on the Dashboard > Holdings:

Valuing the portfolio

The final task is to configure LUSID to value the positions in our portfolio, aggregating up to asset class. Note the following about valuation:

  • LUSID requires market data to begin the pricing operation. For vanilla equities, this can simply be the current mid price sourced from a data vendor, but more complex instruments typically require complex market data such as FX rates or discount or interest rate curves.

  • Some instruments have lifecycles and/or cashflow implications that affect valuation. For example, a bond's value is affected both by its market price and the interest accrued to date, and has a maturity date after which the instrument drops out of valuations.

  • You must create a recipe that tells LUSID where to find market data, and which pricing model(s) and methodology to use to perform the valuation.

  • You must specify aggregation rules that tell LUSID how to report information in a meaningful way. It's possible to aggregate by properties you've created yourself, but in this case we can also take advantage of a built-in system property (the AssetClass queryable key) to aggregate our valuations by asset class (equities vs. bonds vs. cash).

Read our valuation documentation.

Once market data, a recipe and aggregation rules are in place, we can call the LUSID GetValuation API to actually perform the valuation.

Steps 5 and 6 of the accompanying Jupyter Notebook demonstrate how to do this using the LUSID Python SDK. You can execute the Notebook in Jupyterhub for your LUSID domain and then sign in to the web app to see aggregated valuations on the Dashboard > Valuations.

Note to see the dashboard as it is below, you need to click the cog icon (highlighted middle right), choose Add column, select the Queryable Key with an Address Key of Instrument/AssetClass (value), drag it to the grouping position (highlighted left) and set the Effective date to 01/01/2022 (highlighted top right).