Creating a strategy-based transaction portfolio

In this tutorial we'll see how to use LUSID to perform the following task:

“As a portfolio manager, I want to load transactions from two systems, each with different transaction codes, into separate investment strategies in a portfolio. I want LUSID to calculate instrument holdings grouped by strategy, and understand LUSID's view of my positions on trade date vs settlement date.”

We'll see how to:

  • Create a portfolio with a sub-holding key (SHK) that enables transactions to be separated into different investment strategies.

  • Configure transaction types to recognise new transaction codes and determine their economic impact.

  • Load transactions from each system into the appropriate investment strategy.

  • Calculate holdings in both equities and cash from the history of transactions, grouped by investment strategy.

  • Interpret LUSID's holding calculations on trade date and settlement date.

You can examine and run the complete code sample for this exercise from this Jupyter Notebook, providing you have suitable access control permissions. This can most easily be achieved by assigning your LUSID user the built-in lusid-administrator role, which should already be the case if you are the domain owner. If you are informed you do not have a license to perform a particular operation, please contact support

Examining the transaction source files

Let's assume we have a set of transactions from two different systems, SystemA and SystemB.

SystemA

SystemB

We can see that:

  • Each source file contains an initial cash injection and a stream of equity purchases.

  • BP has been purchased in both source files.

  • SystemA uses the transaction code 'BuyEQ' to signal an equity purchase; SystemB uses 'Acheter'.

  • The trade date is 1 March 2022 but trades do not settle until 3 March 2022.

Creating a portfolio

The first task is to create a portfolio with a sub-holding key (SHK).

A SHK is actually a custom property, defined in the standard way. It is registered with a portfolio and, when applied to transactions in that portfolio, automatically causes LUSID to group transactions (and subsequently instrument holdings) by property value rather than construct a total for each instrument in the portfolio as a whole.

For example, we'll apply a property value of 'Growth' to transactions sourced from SystemA, and a property value of 'Income' to transactions sourced from SystemB. When we request a holdings calculation, LUSID automatically calculates positions separately for the 'Growth' and 'Income' strategies.

A portfolio can have any number of SHKs, which must be registered when the portfolio is created. Note also the creation date of a portfolio must precede the date of any transactions we intend to load into it.

For a general introduction to portfolios in LUSID, read our portfolio documentation.

Creating a property definition for the SHK

Since a SHK is a property, the first step is to create a property definition. To do this, call the LUSID CreatePropertyDefinition API, supplying a display name, data type and 3-stage property key, for example Transaction/FBNUniversity/InvestmentStrategy:

  • The first stage of the key is the domain (entity) to which the property belongs. For a SHK, this is actually Transaction, not Portfolio, since the property is applied to transactions in the portfolio rather than to the portfolio itself.

  • The second stage is a scope (or namespace) for the property. This can be any intuitive string; we can make it the same as the containing portfolio.

  • The third stage is a code for the property, which must be unique within the scope. Again, this can be any intuitive string; we can use it to record the purpose of the SHK.

Step 3.1 of the accompanying Jupyter Notebook demonstrates how to do this using the LUSID Python SDK.

Creating the portfolio and registering the SHK

We can now call the LUSID CreatePortfolio API, specifying a suitable scope, code, name and base currency, and registering the SHK.

Step 3.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 Portfolios dashboard, available from the left-hand Data Management menu:

Configuring transaction types to determine economic impacts

Each system uses a different transaction code to signal an equity purchase: SystemA uses 'BuyEQ', while SystemB uses 'Acheter'.

LUSID has a built-in Buy transaction type that, when applied to a transaction such as an equity purchase in a portfolio, automatically causes:

  • Your holding in the equity instrument to increase by the number of units bought.

  • Your trade date cash position in the transaction currency to decrease by the total consideration.

We want the 'BuyEQ' and 'Acheter' codes to have the same economic impact. We can therefore add two new transaction types to the built-in set using the LUSID CreateConfigurationTransactionType API, specifying a new alias for each but re-using the movements and sides from the built-in Buy type. Read our transaction type documentation.

Note: The cash injection in each source file has a transaction code that already matches the built-in FundsIn transaction type. The economic impact of this type is simply to increase your cash position in the transaction currency, without affecting any other instrument.

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 new BuyEQ and Acheter transaction types listed on the System Settings > Transaction Types dashboard:

Loading transactions into investment strategies

We want to load transactions from SystemA into the 'Growth' investment strategy, and transactions from SystemB into the 'Income' strategy.

We can call the LUSID UpsertTransactions API for each source file in turn, adding the SHK property to each transaction with the appropriate strategy as the property value.

Step 5 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 transactions on the Dashboard > Transactions. Note the Investment strategy SHK column is denoted by a purple ‘S’ icon, and that BP is transacted in both the Growth and Income strategies (highlighted):

Calculating holdings grouped by strategy on the trade date

LUSID automatically calculates a holding for each instrument in a portfolio on-the-fly by decomposing all the transactions that affect that instrument into their underlying economic movements, as determined by their transaction type. We have defined the BuyEQ and Acheter transaction types to have the dual effect of increasing equity positions and decreasing cash amounts.

Because the SHK is registered with the portfolio, and because we have labelled transactions with the SHK property, LUSID automatically groups holdings by investment strategy when we call the LUSID GetHoldings API. By default, LUSID uses today's date for this calculation, but we can pass in an explicit date of 1 March 2022 to examine LUSID's view of holdings after trades have executed but before they have settled.  

Step 6 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 holdings on the Dashboard > Holdings. Note that to see the view as it is in the picture below, you must:

  • Use the Effective datetime picker (highlighted top right) to request LUSID's holding calculation on 1 March.

  • Drag the Investment strategy SHK column to the grouping row (highlighted top left) to group by strategy.

We can see that (for example) our position in BP is split over two strategies rather than a total given for the portfolio as a whole. Note also that Units and Settled Units differ for equities, and that cash lines with a Holding Type of Cash Commitment reflect the amount due for equity purchases. Cash lines with a Holding Type of Cash Balance still contain the initial amounts injected into each strategy:

Calculating holdings again post-settlement date

If we call the LUSID GetHoldings API with today's date (or any date after 3 March 2022) we can see that LUSID calculates holdings differently. Step 7 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 holdings on the Dashboard > Holdings, making sure the Effective datetime picker is set to latest. Positions are still grouped by strategy, but equity units have settled and cash balances reflect the fact that cash has been disbursed:

Summary

In this tutorial, we've seen how to:

  • Use SHKs to separate transactions (and subsequently instrument holdings) in a portfolio into strategies rather than calculate totals for the portfolio as a whole.

  • Create new transaction types to determine the economic impact of transactions with particular codes.

  • Request holdings calculations at different times, and interpret holding types to understand LUSID's different views of positions on trade date and settlement date.