In this tutorial we’ll create three transaction portfolios with different capitalisation treatments for fees incurred by the same equity purchase transaction, and examine the impact on cost and P&L.
AllCap portfolio: All four transaction fees are capitalised
AllNonCap portfolio: No transaction fees are capitalised (that is, all are expensed)
Mixed portfolio: Broker and exchange fees are capitalised; clearing and NFA fees are expensed.
The four fees are calculated as a percentage of gross consideration as follows:
Broker fee: 5%
Exchange fee: 2%
Clearing fee: 2.5%
NFA fee: 0.5%
Note: For an implementation using the Python SDK, see this Jupyter Notebook.
Creating a transaction fee type for each fee
We must create a transaction fee type for each fee that determines:
The formula by which LUSID should calculate the fee amount
Whether the calculation is always performed, or subject to a condition
A storage location for the result, which must be a property in the
Transactiondomain that LUSID automatically populates on the output transaction.
For example, for the Broker fee:
{
"displayName": "Broker fee",
"calculation": {
"formula": "Properties[Transaction/default/GrossConsideration] * 0.05"
},
"condition": "True",
"txnPropertyKey": "Transaction/Fees/Broker"
}Adding a calculation for each fee to the transaction type
Imagine we have a BuyWithFees transaction type for equity purchases that calculates:
Gross consideration as units * price in settlement currency. From this, LUSID automatically calculates gross trade amount in transaction currency.
Total consideration as gross consideration + total fees in settlement currency. From this, LUSID automatically calculates trade amount in transaction currency. More about transaction amounts.
This transaction type currently has two movements:
The
StockMovementusesSide1to increase an asset holding by the number of units at a cost of the trade amount.The
CashCommitmentusesSide2to decrease a cash holding by the total consideration. More about built-in sides.
We must add a Fee calculation to the transaction type for each fee to determine whether it is capitalised or expensed. Note that LUSID automatically:
Includes capitalised fees in the trade amount. Since we are using
Side1, this means capitalised fees are added to the cost basis of the asset holding.Does not include expensed fees in the trade amount, so again using
Side1this means they do not impact the asset cost basis. Instead, we recommend adding aCarrymovement to the transaction type to yield the correct P&L accounting treatment.Calculates fee totals and stores the results for use in other calculations and operations as follows:
Fee total
System property
Shortcut
All fees
Transaction/default/TotalFeesTxn:TotalFeesAll capitalised fees
Transaction/default/TotalCapitalisedFeesTxn:TotalCapitalisedFeesAll expensed fees
Transaction/default/TotalNonCapitalisedFeesTxn:TotalNonCapitalisedFees
Our amended BuyWithFees transaction type might look like this:
{
"aliases": [
{
"type": "BuyWithFees",
"description": "Transaction type for equity purchases with fees",
"transactionClass": "Trading",
"transactionRoles": "LongLonger",
"isDefault": false
}
],
"movements": [
{
"name": "Increase asset units and cost",
"movementTypes": "StockMovement",
"side": "Side1",
"direction": 1
},
{
"name": "Decrease cash units and cost",
"movementTypes": "CashCommitment",
"side": "Side2",
"direction": -1
},
{
"name": "Report expensed fees as P&L",
"movementTypes": "Carry",
"side": "CarryNonCapFees",
"direction": -1
}
],
"calculations": [
{
"type": "Txn:GrossConsideration"
},
{
"type": "DeriveTotalConsideration",
"formula": "Txn:GrossConsideration + Txn:TotalFees"
},
{
"type": "Fee",
"transactionFeeId": {
"scope": "Fees",
"code": "Broker"
},
"transactionFeeCapitalisation": {
"capitalisation": "Conditional",
"capitalisedCondition": "Portfolio.Properties[Portfolio/Fees/Status] neq 'AllNonCap'"
}
},
{
"type": "Fee",
"transactionFeeId": {
"scope": "Fees",
"code": "Exchange"
},
"transactionFeeCapitalisation": {
"capitalisation": "Conditional",
"capitalisedCondition": "Portfolio.Properties[Portfolio/Fees/Status] neq 'AllNonCap'"
}
},
{
"type": "Fee",
"transactionFeeId": {
"scope": "Fees",
"code": "Clearing"
},
"transactionFeeCapitalisation": {
"capitalisation": "Conditional",
"capitalisedCondition": "Portfolio.Properties[Portfolio/Fees/Status] eq 'AllCap'"
}
},
{
"type": "Fee",
"transactionFeeId": {
"scope": "Fees",
"code": "NFA"
},
"transactionFeeCapitalisation": {
"capitalisation": "Conditional",
"capitalisedCondition": "Portfolio.Properties[Portfolio/Fees/Status] eq 'AllCap'"
}
}
]
}The Carry movement uses a custom CarryNonCapFees side to report expensed fees only as P&L (see the units and amount fields):
{
"security": "Txn:LusidInstrumentId",
"currency": "Txn:TradeCurrency",
"rate": "Txn:TradeToPortfolioRate",
"units": "Txn:TotalNonCapitalisedFees",
"amount": "Txn:TotalNonCapitalisedFees"
}Loading transactions into portfolios and examining the results
Imagine we load an equity purchase transaction with the following characteristics into each of our three portfolios:
Units: 10
Price: 10
Gross consideration: 100
Total fees: 10
Total consideration: 110
For a demonstration, see the Jupyter Notebook.
Holdings
The total consideration (cost of the cash movement) is -110 in all three portfolios.
The trade amount is calculated from gross consideration plus total capitalised fees (expensed fees are excluded), so the asset cost differs in each portfolio (in yellow):

Output transactions
Fee totals are stored in Transaction system properties and automatically populated on output transactions:

Valuation
Given no other price or FX movement, Total P&L is the same in all portfolios but the breakdown between Market P&L (capitalised fees) and Other P&L (expensed fees) is different:

A2B report
Capitalised fees are reported as CapGains; expensed fees as Carry:

Journal entry lines
Capitalised fees are reported as unrealised gain/loss and so LUSID generates journal entry lines with a sourceType of LusidValuation at period end in addition to LusidTransaction lines on trade and settlement dates:



Trial balance
All ledgers balance but the DR (debit) and CR (credit) amounts differ:
