Valuing a fund: Calculating GAV, NAV and other pricing data

You can value a fund at any time. LUSID calculates:

  • GAV from dealing (subscriptions and redemptions) plus P&L.

  • NAV, which is GAV minus any accrued fees for the fund.

For more information about LUSID’s pricing calculations, see the final section of this article.

Generating an ad-hoc fund valuation

You can call the GetValuationPointData API with an arbitrary datetime to value the fund at that point in time. Note no data is persisted using this method.

For example, to value a fund at exactly 5pm UTC on 4 June 2024, pass the scope and code of the fund to value in the URL and, in the body of the request, an end date that is a valid LUSID datetime:

curl -X POST 'https://<your-domain>.lusid.com/api/api/funds/Abor/ValuationPointDemo/valuationpoints'
  -H 'Content-Type: application/json-patch+json'
  -H 'Authorization: Bearer <your-API-access-token>'
  -d '{
  "end": {
    "date": "2024-06-04T17:00:00Z"
  }
}'

The response below is transformed to a table for clarity. Note the type and status; no data is persisted and there is no guarantee this datetime will generate the same result in future, since the underlying data might change:

Publishing an official fund valuation

Publication is a workflow with checks and balances.

You must first create a valuation point. This is an accounting diary entry with a type of ValuationPoint and an initial status of Estimate. You use the diary entry to value the fund at the specified point in time and check the estimated figures. If the figures are correct, you accept the estimate and ask LUSID to assess whether anything has changed in the meantime:

  • If nothing has changed, LUSID moves the status to Final and persists all the data associated with the valuation, so the result is reproducible. Note LUSID also automatically generates transactions to accrue and settle any fees added to the fund at this point.

  • If something has changed, LUSID alerts you by moving the status to Candidate, enabling you to check again.

Example: Valuing a fund at 5pm from the perspective of 7pm

The goal is to value a fund at 5pm. Typically, however, not all relevant data enters the system on time. Since LUSID is bitemporal, we can value the fund with an effective at datetime of 5pm but an as at datetime of 7pm, thereby allowing two hours for applicable data to flow in.

7pm

To get started, we call the UpsertDiaryEntryTypeValuationPoint API, passing in the scope and code of the fund to value in the URL and, in the body of the request:

  • A diaryEntryCode that is unique among all diary entries of type ValuationPoint for this fund.

  • Optionally, a meaningful name.

  • Optionally, an effectiveAt at which to value the fund, in this case 5pm. If you omit this field, LUSID uses the current system datetime.

  • Optionally, a queryAsAt at which to query the system. This can be the same as effectiveAt, or any subsequent datetime. In most circumstances, we recommend omitting this parameter to use the current system datetime of the API call (see below).

  • Optionally in the properties collection, any number of custom properties from the DiaryEntry domain to extend the data model.

Consider the following example, of a call made at 7pm to create a valuation point with a unique diaryEntryCode of 04June2024-5pm-asAt7pm that values a fund at exactly 5pm UTC on 4 June 2024 using all the data the system knows about at the time of the API call:

curl -X POST 'https://<your-domain>.lusid.com/api/api/funds/Abor/ValuationPointDemo/valuationpoints/$upsert'  
  -H 'Content-Type: application/json-patch+json'
  -H 'Authorization: Bearer <your-API-access-token>'
  -d '{
  "diaryEntryCode": "04June2024-5pm-asAt7pm",
  "effectiveAt": "2024-06-04T17:00:00Z"
}'

We can call the ListDiaryEntries API for the ABOR underlying the fund to examine the valuation point. Note the status is Estimate, the effectiveAt is 5pm, the queryAsAt is 7pm plus a few milliseconds, and the previousEntryTime is the system minimum datetime, since this is the first valuation point created for this fund:

7.01pm

As soon as possible after creating the valuation point, we call the GetValuationPointData API with a diaryEntry of 04June2024-5pm-asAt7pm to value the fund at 5pm using all the data the system knows about at 7pm plus a few milliseconds, for example:

curl -X POST 'https://<your-domain>.lusid.com/api/api/funds/Abor/ValuationPointDemo/valuationpoints'
  -H 'Content-Type: application/json-patch+json'
  -H 'Authorization: Bearer <your-API-access-token>'
  -d '{
  "end": {
    "diaryEntry": "04June2024-5pm-asAt7pm"
  }
}'

Providing the request is successful, the response contains the estimated fund value. Note fund fees are omitted in this example for simplicity, so GAV and NAV are the same:

7:15pm

A few minutes later, having checked the GAV and NAV figures, we call the AcceptEstimateValuationPoint API with a diaryEntry of 04June2024-5pm-asAt7pm, for example:

curl -X POST 'https://<your-domain>.lusid.com/api/api/funds/Abor/ValuationPointDemo/valuationpoints/$acceptestimate'
  -H 'Content-Type: application/json-patch+json'
  -H 'Authorization: Bearer <your-API-access-token>'
  -d '{
  "end": {
    "diaryEntry": "04June2024-5pm-asAt7pm"
  }
}'

LUSID moves the status of the valuation point to either Candidate or Final; we recommend checking the response carefully:

  • If nothing has changed to alter the fund's 5pm value between 7pm (the queryAsAt time of the valuation point) and 7:15pm (the acceptance time), LUSID moves the valuation point status to Final and persists the data. There is nothing more to do:
     

  • If something has changed between 7pm and 7:15pm (for example, a backdated transaction has been inserted, or an item of market data corrected) such that GAV/NAV figures are different, LUSID moves the valuation point status to Candidate instead. Note the response does not currently show the new GAV/NAV figures; this may change in future:
     
    If this occurs, we recommend the following actions:

    1. Call UpsertDiaryEntryTypeValuationPoint again to create a new Estimate valuation point with the same effectiveAt datetime of 5pm but a queryAsAt time subsequent to the change, for example 7:15pm. In the following example, the diaryEntryCode is set to 04June2024-5pm-asAt715pm; note the previousEntryTime is set to the effectiveAt datetime of the earlier 04June2024-5pm-asAt7pm valuation point:
       

    2. Call GetValuationPointData again with the new diaryEntry of 04June2024-5pm-asAt715pm to show the changed GAV/NAV, in this example 2,020:
       

    3. Perform one of the following operations:

      • If you consider the original estimate of 2,000 correct, call the FinaliseCandidateValuationPoint API with the original diaryEntry of 04June2024-5pm-asAt7pm to move its status to Final and persist the original data.

      • If you consider the new estimate of 2,020 correct, call AcceptEstimateValuationPoint again with the new diaryEntry of 04June2024-5pm-asAt715pm to begin the acceptance process again.

      Note you can delete unwanted valuation points by calling the DeleteValuationPoint API.