A transaction type must have a role and a class. Together, these enable you to group different transaction types together for reporting purposes.

For example, you can relate "buy", "purchase", "sellReverse", and "acheter" (from a system which uses French language) together as equivalent transaction types. This allows you to map these to a canonical "buy" in a transaction report.

Transaction type roles 

A transaction type must have at least one alias, and each alias has a transactionRoles field that expects one of the values below describing the economic effect of all transactions belonging to that transaction type.

At its core, every transaction will be taking the portfolio longer (+) or shorter (-) and will apply to a holding which is long or short (a flat position is considered long). 

Broadly speaking, there are three levels of granularity. At Level 1, we use a value of AllRoles to capture transaction codes which can either increase or decrease holding quantities. At Level 2, we differentiate between transactions which increase the holding quantity (with the Longer role) and transactions which reduce the holding quantity (with the Shorter role). Level 3 offers the most granularity. Here, for example, we differentiate between a long transaction which increases a long position (LongLonger) and a long transaction which reduces a short position (ShortLonger):

We can also plot the transaction roles on a graph. As you can see, LongLonger and ShortLonger are used to increase a portfolio's position, but they start from a different point in the portfolio:

Transaction type class

A transaction type must have at least one alias, and each alias has a transactionClass field that expects a value grouping together similar transactions from the same source.

For example, you might have a FX class to capture all FX transactions, or Swap to capture all transactions related to swaps (Pay Fixed, Receive Floating and so on). It is expected that there is only one transaction type for each role in each class. 

Example usage

By assigning your transaction types a role and class, LUSID is able to link similar transactions together for reporting purposes. In the example above, "buy", "purchase", "sellReverse", and "acheter" all originate from different data providers so transaction types are grouped in different sources. By assigning them the same role and class, LUSID can now produce a transaction report which maps the various transaction types to a single canonical set.

Some more example uses cases listed below:

Example 1: A fund with one source of data

  • Example scenario: A fund is loading transaction data from a single provider into LUSID, which is a set of files from their ABOR. The transaction data covers one long-only Equity fund. 
  • Proposed configuration: Put all transaction types from the external provider in the default source and give each a transactionRoles value of AllRoles. This is the default LUSID implementation.

Example 2: Mapping multiple codes to one common set for trade reporting

  • Example scenario: An asset manager is feeding LUSID with transaction data from multiple ABOR and IBOR systems. These systems have hundreds of codes to represent the same underlying set of movements. For examples, purchases are represented as all the following in the external data set: "BUY", "Purchase", "B", "Buy", "buy", "B123", "BuyLong". This creates a challenge for the Product Managers internally who want to present users of their trade reporting with a set single transaction type.
  • Proposed configuration:  We recommend using a separate source for each of the external data providers. By assigning a common set of classes and maintaining one role per class, you instruct LUSID to display the canonical codes when retrieving transactions.