Ensuring different transaction codes have the same economic impact

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

“As a data controller, I load transactions from two providers that use a different transaction code to signal the same economic activity. I want to ensure that LUSID applies a uniform economic impact when generating holdings.”

Note: 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, contact support.

Imagine we source transactions from two providers: Societe Generale and Deutsche Bank.

SG labels an equity purchase with a code of Acheter; DB labels an equity purchase with a code of Kaufen.

We can modify the built-in Buy transaction type to model this behavior by appending an alias for each of Acheter and Kaufen.

When transactions are upserted into a portfolio with any of the Buy, Acheter or Kaufen transaction types, the economic impact is the same: LUSID increases an equity holding by the number of units, and decreases a cash holding by the total consideration. However, we haven't altered the format or lineage of the imported data in any way, so it remains meaningful to the originating system.

Examining the source file

Let's assume we have amalgamated a stream of transactions from SG and DB into a single CSV file, each with a particular txn_code:

We can see that:

  • The first transaction has a transaction code of FundsIn, which we can map directly to the built-in FundsIn transaction type to deposit £500 in the portfolio.

  • The second transaction is from SG and has a transaction code of Acheter to signal a purchase of 50 BP shares at a cost of £250.

  • The third transaction is from DB and has a transaction code of Kaufen to signal a purchase of 25 BP shares at a cost of £125.

When all trades have settled, we would expect LUSID to generate a holdings report with 75 BP shares and £125.

Modelling the transaction type

We want to change the aliases component of the built-in Buy transaction type to have the following definition. The movements of Buy are unchanged, and so omitted below. See the full definition of this transaction type.

Transaction type component

Alias #1

Alias #2

Alias #3

Alias

Type

Buy

Acheter

Kaufen

Description

Purchase

Purchase from Societe Generale

Purchase from Deutsche Bank

Source

default

default

default

Class

Basic

Basic

Basic

Role

LongLonger

LongLonger

LongLonger

Modifying the built-in Buy transaction type

We can call the SetTransactionType API to change the built-in Buy transaction type.

Note: The PUT SetTransactionType API operates differently to the standard PUSH Upsert* model used elsewhere in LUSID. The transaction type is replaced rather than updated, so it's important to specify the entire definition each time.

We should first retrieve the existing definition of the Buy transaction type to make sure we recreate it correctly:

  1. Call the GetTransactionType API to retrieve the definition of Buy (which is in the default source and scope).

  2. Append the aliases for Kaufen and Acheter to the alias for Buy, retaining all the other settings.

  3. Call the SetTransactionType API to replace the existing definition in LUSID.

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 your web app to examine the new definition for Buy (with Acheter and Kaufen aliases) on the System Settings > Transaction Types dashboard:

Loading transactions into LUSID

We can now call the UpsertTransactions API to load our transaction source file into a portfolio.

We map the txn_code column in the source file to the type field on each transaction, safe in the knowledge that LUSID will apply the same economic impact to Acheter and Kaufen as to Buy.

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 examine the Type of each transaction on the Transactions dashboard:

Generating a holdings report

We can now call the GetHoldings API for any date after the settlement date to generate a holdings report.

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 examine the Holdings dashboard.

As expected, after all trades have settled, LUSID generates a holdings report with 75 BP shares and £125: