A movement is a component of a transaction type that updates the units and cost of a holding. This can either be a security holding (a position in an equity, bond, swap, option and so on) or a currency holding.
A transaction type must have at least one movement, and can have two or more. For example, the built-in Buy transaction type provided with LUSID—intended to signal a purchase of an instrument such as an equity—has two movements, a StockMovement and a CashCommitment. For each transaction upserted to a portfolio with a transaction type of Buy, LUSID automatically:
Applies the
StockMovementto increase the quantity and cost of the security holding (ie. BP or MSFT) by the number of units purchased and the transaction cost.Applies the
CashCommitmentto decrease a holding in the settlement currency (ie. GBP or USD) by the total consideration.
Understand how LUSID uses transaction types to generate holdings.
A movement has the following fields, some mandatory and some optional.
name field
Optional. Specifies a name for the movement.
movementTypes field
Mandatory. Must be one of the built-in movement types controlling how and when a holding is updated.
direction field
Mandatory. Controls whether the update is an increase or decrease. Allowed values are 1 and -1.
If transactions have unsigned units and amounts then 1 signals an increase and -1 signals a decrease. However, the opposite is true if units and amounts are signed. So for example if a sell transaction is for -30 units, then 1 signals a decrease.
side field
A side is a plug-and-play component that determines which holding is impacted and what attributes of transactions contribute to the change.
Allowed values are either the built-in sides provided with LUSID (currently Side1, Side2, BondInt and Side2WithoutBondInterest), or you can create your own custom sides.
condition field
Optional. By default, a movement always occurs for every transaction belonging to a transaction type.
You can make a movement conditional so that it only occurs for particular transactions, or for transactions in particular portfolios.
You can use LUSID's filter syntax to include any field or property from a portfolio or transaction in the condition, including the transaction’s underlying instrument type. And you can chain expressions using the and and or operators if necessary.
Example | Movement only occurs if a transaction... |
|---|---|
| Is in an equity. |
| Has a total consideration of more than 2000. |
| Is for 100 units or more and records broker commission. |
| Is in a GBP portfolio. |
| Is in a 2024 portfolio managed by John Doe or Jane Doe. |
| Is for 100 units or more in a 2024 portfolio. |
mappings field
Optional. Allocates one or more sub-holding keys (SHKs) to override or supplement strategy tags applied directly to transactions.
Specify a 3-stage propertyKey representing a SHK registered with the parent portfolio, and one of the following options:
Mapping option | Data type | Explanation |
|---|---|---|
| String | Sets the SHK to a new, static value. For an example, see this tutorial on breaking out broker commission as a separate cash holding. |
| String | Maps the SHK from the value of an existing transaction property, for example |
| String | Uses Mustache template syntax to map the SHK from the value of an existing:
Note the Mustache syntax means you can optionally mix text and variables, for example
|
| Boolean | Specify |
movementOptions field
Optional. A comma-separated list of options to configure the movement. The following are available:
Option | Notes |
|---|---|
| Applicability: Specify this option to override LUSID's standard logic and:
This is different to LUSID's default closing behavior, which is to scale the holding cost and calculate realised gain/loss. This option can be used to adjust the units of holdings without impacting the cost, perhaps to model a 1-for-2 reverse stock split by loading a transaction that halves the number of units but with a total consideration of zero:
Note that taxlots are not supported. |
| More information coming soon. |
| Applicability: Specify this option to calculate realised gain/loss without actually effecting a sale. See example use cases for FxForwards and for bonds. |
settlementDayOverride field
Optional. For any movement type that impacts holdings on settlement date, overrides contractual settlement dates specified in transactions and uses dates in the specified custom property added to those transactions instead.
This field must be set to the 3-stage key of a custom property in the Transaction domain, for example Transaction/myscope/mysettlementdate. Note the underlying property type must have a data type that itself has a primitive value type of DateTime. See how to set this up.
Note if a particular transaction does not have a property of this type, or the property value does not resolve to a valid date and time, then the contractual settlement date for the transaction is used.
Note: A more intuitive and configurable way to override contractual settlement dates using settlement instructions is now available.
properties field
Optional. This can be any number of:
Custom properties to extend the data model and store extra information about movements. These properties must be from the
TransactionConfigurationdomain.System properties that are valid for movements.