Let's imagine we are preparing a fund with two share classes for launch.
We have already set up the underlying ABOR to have a single transaction portfolio.
Fund Z | ||
---|---|---|
Currency (of underlying ABOR) | GBP | |
Launch date | 2024-01-01 | |
Share class A | Share class B | |
Launch price | 1 | 1 |
Currency | GBP | USD |
Initial funding | £15000 | $5000 |
Identifying short code |
|
|
Mastering the share classes as instruments in the LUSID Security Master
We can call the UpsertInstruments API to master two instruments of type FundShareClass
with different currencies and other characteristics in a custom MyShareClassInstrumentScope
. More on mastering share classes.
curl -X POST 'https://<your-domain>.lusid.com/api/api/instruments?scope=MyShareClassInstrumentScope'
-H 'Content-Type: application/json-patch+json'
-H 'Authorization: Bearer <your-API-access-token>'
-d '{
"ephemeral-id-1": {
"name": "Share class A",
"identifiers": {
"ClientInternal": {"value": "ShareClassA-Id"}
},
"definition": {
"instrumentType": "FundShareClass",
"shortCode": "ShareClassA",
"fundShareClassType": "Income",
"distributionPaymentType": "Net",
"domCcy": "GBP",
"hedging": "None"
}
},
"ephemeral-id-2": {
"name": "Share class B",
"identifiers": {
"ClientInternal": {"value": "ShareClassB-Id"}
},
"definition": {
"instrumentType": "FundShareClass",
"shortCode": "ShareClassB",
"fundShareClassType": "Accumulation",
"distributionPaymentType": "Gross",
"domCcy": "USD",
"hedging": "ApplyHedging"
}
},
}'
Note that LUSID automatically generates a LUID for each mastered share class instrument that uniquely identifies it, for example:
Setting up unitisation rules in the fund configuration module
LUSID calculates fund GAV as follows:
GAV = Dealing + PnL
…where dealing is subscriptions into—and redemptions out of—the fund. The purpose of the fund configuration module is to identify which general ledger accounts store journal entry lines representing dealing and PnL amounts.
Imagine we have the following chart of accounts in the underlying ABOR:
We can call the CreateFundConfiguration API to create a module with a scope of MyFunds
and a code of StandardConfigModule
identifying the relevant accounts. More on creating fund configuration modules.
curl -X POST 'https://<your-domain>.lusid.com/api/api/fundconfigurations/MyFunds'
-H 'Content-Type: application/json-patch+json'
-H 'Authorization: Bearer <your-API-access-token>'
-d '{
"code": "StandardConfigModule",
"displayName": "Standard Fund Configuration",
"dealingFilters": [
{
"filterId": "SUBS",
"filter": "generalLedgerAccountCode eq '3-Subscriptions'"
},
{
"filterId": "REDS",
"filter": "generalLedgerAccountCode eq '4-Redemptions'"
}
],
"pnlFilters": [
{
"filterId": "PnL",
"filter": "generalLedgerAccountCode eq '5-PnL'"
}
],
"backOutFilters": []
}'
Creating the fund
We can now call the CreateFund API to create a fund with a scope of MyFunds
and a code of FundZ
that references the underlying ABOR, the fund configuration module, and the two share class instruments with their launch prices in the custom instrument scope. More on creating funds.
curl -X POST 'https://<your-domain>.lusid.com/api/api/funds/MyFunds'
-H 'Content-Type: application/json-patch+json'
-H 'Authorization: Bearer <your-API-access-token>'
-d '{
"code": "FundZ",
"displayName": "Growth Fund",
"description": "Fund for growth",
"aborId": {"scope": "MyAbors", "code": "StandardAbor"},
"fundConfigurationId": {
"scope": "MyFunds",
"code": "StandardConfigModule"
},
"shareClassInstrumentScopes": [
"MyShareClassInstrumentScope",
],
"shareClassInstruments": [
{
"instrumentIdentifiers": {
"Instrument/default/LusidInstrumentId": "LUID_00003E1X",
"launchPrice": 1,
}
},
{
"instrumentIdentifiers": {
"Instrument/default/LusidInstrumentId": "LUID_00003E1Y",
"launchPrice": 1,
}
}
],
"type": "Standalone",
"inceptionDate": "2024-01-01T00:00:00Z",
"decimalPlaces": 2,
"yearEndDate": {"day": 31, "month": 12}
}'
Assigning particular transactions to share classes
Transactions in the underlying portfolio that only apply to a particular share class must be explicitly assigned to that share class. Typically these are:
Subscription (funds in) and redemption (funds out) transactions (manually loaded into LUSID).
Certain share class-specific fee transactions (auto-generated by LUSID).
Distribution transactions.
Note: Transactions recording the purchase/sale of instruments typically do not belong to share classes but rather to the whole fund.
There are numerous ways to assign transactions to share classes and the following is just a recommendation.
Creating a property type to tag subscriptions and redemptions
We can call the CreatePropertyDefinition API to define a Transaction/MyFundProperties/ShareClass
custom property in preparation for tagging appropriate transactions (such as subscriptions and redemptions) with the shortCode
of the share class to which they belong:
curl -X POST 'https://<your-domain>.lusid.com/api/api/propertydefinitions"'
-H 'Authorization: Bearer <your-API-access-token>'
-H 'Content-Type: application/json-patch+json'
-d '{
"domain": "Transaction",
"scope": "MyFundProperties",
"code": "ShareClass",
"displayName": "Fund share class",
"dataTypeId": {"scope": "system", "code": "string"},
"lifeTime": "Perpetual",
"constraintStyle": "Property",
"propertyDescription": "Share class to which a transaction belongs"
}'
Creating suitable transaction types for subscriptions and redemptions
The most effective way to assign suitably-tagged subscription/redemption transactions to a share class is to use their respective transaction types to map the tagging custom property to the Transaction/default/ShareClassFundCode
system property. Note we only want to do this on the Capital
movement and not on the CashAccrual
movement.
We can call the SetTransactionType API to create suitable Subscription
and Redemption
transaction types in the default
scope and source, for example:
|
|
|
|
Registering the SHK with the underlying transaction portfolio
We must register the Transaction/default/ShareClassShortCode
system property as a sub-holding key (SHK) with the portfolio in the underlying ABOR in order to segregate share class-specific transactions from generic fund transactions (such as purchase and sale transactions).
We can call the PatchPortfolioDetails API to patch an existing portfolio with a scope of MyAbors
and code of Equities
as follows:
curl -X POST 'https://<your-domain>.lusid.com/api/api/transactionportfolios/MyAbors/Equities/details'
-H 'Authorization: Bearer <your-API-access-token>'
-H 'Content-Type: application/json-patch+json'
-d '[
{
"value": "Transaction/default/ShareClassShortCode",
"path": "/subHoldingKeys/-",
"op": "add"
}
]'
Note /-
at the end of "path": "/subHoldingKeys/-"
appends this SHK to the end of the list; otherwise, existing portfolio SHKs are overwritten.
Funding the fund at the start of Day 1
We can call the BatchUpsertTransactions API to upsert two subscription transactions and tag the share class to which they belong using the Transaction/MyFundProperties/ShareClass
custom property. The total considerations are:
£15000 for
ShareClassA
.$5000 for
ShareClassB
at a USD/GBP trade to portfolio rate of 0.75.
Subscription transaction for | Subscription transaction for |
|
|
Valuing the fund at the end of Day 1
Let’s imagine there has been a small change in the USD/GBP exchange rate during the day (from 0.75 to 0.8) but no other activity.
We can call the UpsertDiaryEntryTypeValuationPoint API and then the GetValuationPointData API to estimate the fund’s value at the end of the day. Note the response is large so it is broken down below into sections. More on valuing funds.
Fund valuation
Note the following:
This is the first fund valuation, so the
previousValuationPointData.nav
is 0.Fund
gav
ispreviousValuationPointData.nav
plus the sum of subscriptions/redemptions and P&L in this period: £0 + £18750 + £250 = £19000.Fund
nav
in this period is the same since no fees have yet been added to the fund.
"fundValuationPointData": {
"backOut": {},
"dealing": {
"SUBS": {
"value": 18750
},
"REDS": {
"value": 0
}
},
"pnL": {
"nonClassSpecificPnl": {
"PNL": {
"value": 250
}
},
"aggregatedClassPnl": {
"PNL": {
"value": 0
}
},
"totalPnl": {
"PNL": {
"value": 250
}
}
},
"gav": 19000,
"fees": {},
"nav": 19000,
"miscellaneous": {},
"previousValuationPointData": {
"nav": {
"amount": 0
}
}
}
Share class A valuation
£15000 was added to this share class (whose currency is the same as the fund currency). Note the following:
classDealingUnits
is total dealing units in this valuation period: 15000 (subscriptions) + 0 (redemptions) = 15000.classDealing
is the total value of these dealing units in fund currency: £15000 (subscriptions) + £0 (redemptions) = £15000.sharesInIssue
isclassDealingUnits
from the previous valuation period plusclassDealingUnits
in this period: 0 + 15000 = 15000.capitalRatio
is share class A’snav
from the previous valuation period plusclassDealing
in this period divided by the total of the same for all share classes in the fund: (£0 + £15000) / £18750 = 0.8 (this means thecapitalRatio
of share class B is 0.2).totalPnl
is total fund PnL apportioned to share class A usingcapitalRatio
: £250 × 0.8 = £200.gav
isclassDealing
plustotalPnl
: £15000 + £200 = £15200 (andnav
is the same since there are no fees).unitPrice
isnav
divided bysharesInIssue
: 15200 / 15000 = 1.013333.
"ShareClassA": {
"shareClassBreakdown": {
"backOut": {},
"dealing": {
"classDealing": {
"SUBS": {
"fundCurrencyAmount": 15000,
"shareClassCurrencyAmount": 15000
},
"REDS": {
"fundCurrencyAmount": 0,
"shareClassCurrencyAmount": 0
}
},
"classDealingUnits": {
"SUBS": {
"value": 15000
},
"REDS": {
"value": 0
}
}
},
"pnL": {
"apportionedNonClassSpecificPnl": {
"PNL": {
"fundCurrencyAmount": 200,
"shareClassCurrencyAmount": 200
}
},
"classPnl": {
"PNL": {
"fundCurrencyAmount": 0,
"shareClassCurrencyAmount": 0
}
},
"totalPnl": {
"PNL": {
"fundCurrencyAmount": 200,
"shareClassCurrencyAmount": 200
}
}
},
"gav": {
"fundCurrencyAmount": 15200,
"shareClassCurrencyAmount": 15200
},
"fees": {},
"nav": {
"fundCurrencyAmount": 15200,
"shareClassCurrencyAmount": 15200
},
"unitisation": {
"sharesInIssue": 15000,
"unitPrice": 1.013333,
"netDealingUnits": 15000
},
"miscellaneous": {},
"shareClassToFundFxRate": 1,
"capitalRatio": 0.8,
"previousShareClassBreakdown": {
"nav": {
"amount": {
"fundCurrencyAmount": 0,
"shareClassCurrencyAmount": 0
}
},
"shareClassToFundFxRate": 1
}
},
"shareClassDetails": {
"lusidInstrumentId": "LUID_00003E1X",
"instrumentScope": "MyShareClassInstrumentScope",
"domCurrency": "GBP",
"instrumentActive": true
}
}
Share class B valuation
$5000 was added to this share class at a USD/GBP rate of 0.75 = £3750. Note the following:
classDealingUnits
is total dealing units in this valuation period: 5000 (subscriptions) + 0 (redemptions) = 5000.classDealing
is the total value of these dealing units in fund currency: £3750 (subscriptions) + £0 (redemptions) = £3750.sharesInIssue
isclassDealingUnits
in the previous valuation period plusclassDealingUnits
in this period: 0 + 5000 = 5000.shareClassToFundFxRate
is the USD/GBP exchange rate at the valuation point: 0.8.capitalRatio
is share class B’snav
from the previous valuation period plusclassDealing
in this period divided by the total of the same for all share classes in the fund: (£0 + £3750) / £18750 = 0.2 (this means thecapitalRatio
of share class A is 0.8).totalPnl
is total fund PnL apportioned to share class B usingcapitalRatio
: £250 × 0.2 = £50.gav
isclassDealing
plustotalPnl
: £3750 + £50 = £3800 (andnav
is the same since there are no fees).unitPrice
isnav
divided bysharesInIssue
and further divided byshareClassToFundFxRate
to convert to share class currency: (3800 / 5000) / 0.8 = 0.95.
"ShareClassB": {
"shareClassBreakdown": {
"backOut": {},
"dealing": {
"classDealing": {
"SUBS": {
"fundCurrencyAmount": 3750,
},
"REDS": {
"fundCurrencyAmount": 0,
}
},
"classDealingUnits": {
"SUBS": {
"value": 5000
},
"REDS": {
"value": 0
}
}
},
"pnL": {
"apportionedNonClassSpecificPnl": {
"PNL": {
"fundCurrencyAmount": 50,
"shareClassCurrencyAmount": 62.5
}
},
"classPnl": {
"PNL": {
"fundCurrencyAmount": 0,
"shareClassCurrencyAmount": 0
}
},
"totalPnl": {
"PNL": {
"fundCurrencyAmount": 50,
"shareClassCurrencyAmount": 62.5
}
}
},
"gav": {
"fundCurrencyAmount": 3800,
"shareClassCurrencyAmount": 4750
},
"fees": {},
"nav": {
"fundCurrencyAmount": 3800,
"shareClassCurrencyAmount": 4750
},
"unitisation": {
"sharesInIssue": 5000,
"unitPrice": 0.95,
"netDealingUnits": 5000
},
"miscellaneous": {},
"shareClassToFundFxRate": 0.8,
"capitalRatio": 0.2,
"previousShareClassBreakdown": {
"nav": {
"amount": {
"fundCurrencyAmount": 0,
"shareClassCurrencyAmount": 0
}
},
"shareClassToFundFxRate": 1
}
},
"shareClassDetails": {
"lusidInstrumentId": "LUID_00003E1Y",
"instrumentScope": "MyShareClassInstrumentScope",
"domCurrency": "USD",
"instrumentActive": true
}
}