Performing operations on metrics

Prev Next

Every metric has a supportedOperations list that you can see when you call the GetAllQueryableKeys API. For example, Valuation/PV is defined as follows:

{
  "addressKey": "Valuation/PV",
  "description": "The present value of a holding of an instrument, at a point in time, in the settlement currency if applicable, otherwise domestic currency. Includes accrued interest",
  "displayName": "PV",
  "type": "Result0D",
  "flattenedType": "Decimal",
  "scalesWithHoldingQuantity": true,
  "supportedOperations": "Sum,DefaultSum,Proportion,Average,Count,Min,Max,Value,Append,SumOfPositiveValues,SumOfNegativeValues,SumOfAbsoluteValues,ProportionOfAbsoluteValues,SumCumulativeInAdvance,SumCumulativeInArrears",
  "lifeCycleStatus": "Experimental"
}

When you request a metric in a valuation report, you pair its key with one operation in the op field. You can always request a metric's Value. Text, date and true/false metrics also support Count. Numeric metrics support the full set of operations below.

How operations work

Each operation is applied to a group of rows:

  • If you specify groupBy in the valuation request, each group is the set of holdings that share the same values for your groupBy metrics. LUSID returns one row per group.

  • If you omit groupBy, LUSID returns one row per holding. The whole report is treated as a single group: operations such as Sum calculate a grand total and repeat it on every row.

  • If your valuation schedule spans several dates, the whole report covers every date. For example, with no groupBy, Sum adds up values across all the dates. To get one total per date, group by Valuation/EffectiveAt.

  • Proportion operations always divide by the total for the whole report, not by the total for the row's own group.

  • Filters are applied first. Operations only see the rows that pass any filters you specify in your valuation request.

Available operations

Consider the following portfolio with five positions, valued without groupBy. In portfolio currency (Valuation/PvInPortfolioCcy), their values are 1000, 1000, 800, 400 and -200 (a short position), so the total is 3000:

Operation

What LUSID calculates

Example result for Tesco (800)

Value

The metric's value for the row. In a grouped row, LUSID only returns a value if it's the same for every holding in the group. Otherwise the cell is empty.

800

Sum

The total of all values in the group.

3000

DefaultSum

Behaves like Sum if you specify groupBy, and like Value if you don't.

800

Average

The total divided by the number of values in the group.

600

Count

The number of values in the group.

5

Min

The smallest value in the group.

-200

Max

The largest value in the group.

1000

SumOfPositiveValues

The total of the positive values only (for example, long positions).

3200

SumOfNegativeValues

The total of the negative values only (for example, short positions).

-200

SumOfAbsoluteValues

The total ignoring signs, so that long and short positions both add. This is useful for gross exposure.

3400

Proportion

The group's total divided by the total for the whole report. Results across the report add up to 1.

0.267 (800 ÷ 3000)

ProportionOfAbsoluteValues

The group's total ignoring signs, divided by the whole report's total ignoring signs.

0.235 (800 ÷ 3400)

SumCumulativeInAdvance

A running total down the grouped rows, including the current row. Only meaningful with groupBy.

—

SumCumulativeInArrears

A running total down the grouped rows, excluding the current row. It's empty for the first row. Only meaningful with groupBy.

—

LUSID names each result column after the operation and metric, for example DefaultSum(Valuation/PvInPortfolioCcy). The exception is Value, which uses the metric key on its own.

Summing values in different currencies

LUSID cannot sum amounts in different currencies. If you request Sum, Average, Min or Max for a metric such as Valuation/PV and a group contains both GBP and USD amounts, LUSID leaves the cell empty. It also adds a message to the row's Aggregation/Errors metric, for example:

metadata mismatch Dim:0,Units:(USD) != Dim:0,Units:(GBP).

To total amounts across currencies, use a version of the metric that LUSID converts to a single currency:

  • *InPortfolioCcy metrics, such as Valuation/PvInPortfolioCcy and Valuation/ExposureInPortfolioCcy, are safe to total within one portfolio. They're also safe across portfolios that share a base currency.

  • *InReportCcy metrics, such as Valuation/PvInReportCcy, are always safe to total, including across portfolios with different base currencies, providing you set reportCurrency in your valuation request.

Note: LUSID only checks currencies. Plain numbers have no unit, so LUSID adds them without warning. For example, Sum of Holding/default/Units across a whole portfolio returns a number that mixes shares of different equities with units of cash. Only sum units when you've grouped by instrument.

Calculating totals, proportions and weights

There are four ways to report portfolio totals, and the percentage each holding contributes, in a valuation report:

  • Operations (Sum, Proportion and so on): flexible, and they follow your grouping and filters.

  • Total metrics (Valuation/TotalPortfolio* and Valuation/TotalGroup*): one whole-portfolio or whole-group total on every row, unaffected by filters.

  • Weight metrics (Valuation/Weight and the Aggregation/*Weight metrics): a holding's or group's exposure as a share of the whole portfolio.

  • Subtotals: set the equipWithSubtotals field in your valuation request to add a subtotal row for each group and a grand-total row to a grouped report, calculated using the operations specified.

Which approach to use

You want…

Use

Example metrics

A total for the portfolio, or for each group in your report

The Sum operation, grouping by Valuation/EffectiveAt for one row per date

{"key": "Valuation/PvInPortfolioCcy", "op": "Sum"}

Each holding's or group's share of the report total

The Proportion operation

{"key": "Valuation/PvInPortfolioCcy", "op": "Proportion"}

The whole-portfolio total alongside every holding row, even if you filter the report

A total metric with Value

{"key": "Valuation/TotalPortfolioPvInPortfolioCcy", "op": "Value"}

The total for a portfolio group alongside every row

A group total metric with Value, valuing the portfolio group

{"key": "Valuation/TotalGroupPvInReportCcy", "op": "Value"}

Each holding's net exposure as a share of total portfolio PV

Valuation/Weight

{"key": "Valuation/Weight", "op": "Value"}

Net or gross exposure weights for each group

Aggregation/NetExposureWeight or Aggregation/GrossExposureWeight

{"key": "Aggregation/GrossExposureWeight", "op": "Value"}

Group totals and a grand total in the same report

groupBy with equipWithSubtotals set to true, and the Sum operation

"groupBy": ["Valuation/PV/Ccy"], "equipWithSubtotals": true with {"key": "Valuation/PvInPortfolioCcy", "op": "Sum"}

Total metrics

LUSID calculates each total metric from every holding in the portfolio before it applies your filters or groupBy. It then reports the same figure on every row for that portfolio and date. This makes the total useful for showing the whole portfolio's value next to a filtered selection of holdings, or as the denominator in a derived property.

Metric

Total of…

Portfolio

Valuation/TotalPortfolioPvInPortfolioCcy

Valuation/PvInPortfolioCcy

Valuation/TotalPortfolioPvInReportCcy

Valuation/PvInReportCcy

Valuation/TotalPortfolioExposureInPortfolioCcy

Valuation/ExposureInPortfolioCcy

Valuation/TotalPortfolioExposureInReportCcy

Valuation/ExposureInReportCcy

Valuation/TotalPortfolioExposureMSCIInPortfolioCcy

Valuation/ExposureMSCIInPortfolioCcy

Valuation/TotalPortfolioExposureMSCIInReportCcy

Valuation/ExposureMSCIInReportCcy

Portfolio group

Valuation/TotalGroupPvInPortfolioCcy

Valuation/PvInPortfolioCcy

Valuation/TotalGroupPvInReportCcy

Valuation/PvInReportCcy

Valuation/TotalGroupExposureInPortfolioCcy

Valuation/ExposureInPortfolioCcy

Valuation/TotalGroupExposureInReportCcy

Valuation/ExposureInReportCcy

Valuation/TotalGroupExposureMSCIInPortfolioCcy

Valuation/ExposureMSCIInPortfolioCcy

Valuation/TotalGroupExposureMSCIInReportCcy

Valuation/ExposureMSCIInReportCcy

Note the following:

  • Request total metrics with Value. Because every row already carries the full total, Sum multiplies it by the number of rows. For example, in a group of three holdings, Sum of a 3000 total returns 9000.

  • "Group" means a portfolio group, not a groupBy group. TotalGroup* metrics are only populated when you value a portfolio group. If you value single portfolios, they're empty.

  • For group totals in portfolio currency, every portfolio in the group must share a base currency. Otherwise the cell is empty and Aggregation/Errors reports Mixed currencies in total. If base currencies differ, use the *InReportCcy metric and set reportCurrency in your valuation request.

  • *InReportCcy metrics need a report currency. If you don't set reportCurrency, they come back empty.

  • One failure empties the total. If any holding fails to value, the total is empty. To leave failed holdings out of the total instead, set the IgnoreErrors metric option to true, for example {"key": "Valuation/TotalPortfolioPvInPortfolioCcy", "op": "Value", "options": {"IgnoreErrors": true}}.

For example, valuing a GBP portfolio worth 3000 with a filter that keeps only its UK equity and GBP cash holdings returns:

Holding

Valuation/PvInPortfolioCcy

Proportion(Valuation/PvInPortfolioCcy)

Valuation/TotalPortfolioPvInPortfolioCcy

UK equity

1000

0.556

3000

UK equity (short)

-200

-0.111

3000

GBP cash

1000

0.556

3000

Proportion measures each holding against the 1800 that passed the filter. The total metric still reports the whole portfolio.

Weight metrics

Valuation/Weight reports each holding's exposure in portfolio currency divided by the total PV of the whole portfolio. For a reference portfolio, it's the holding's units divided by the portfolio's total units.

The Aggregation weight metrics apply the same calculation to each row of your report. If you group your report, they add up each group first:

Metric

What LUSID calculates for each row or group

Aggregation/NetExposureWeight

Sum of Valuation/ExposureInPortfolioCcy ÷ Valuation/TotalPortfolioPvInPortfolioCcy

Aggregation/GrossExposureWeight

Sum of absolute Valuation/ExposureInPortfolioCcy ÷ Valuation/TotalPortfolioPvInPortfolioCcy

Aggregation/NetExposureWeightMSCI

As NetExposureWeight, using Valuation/ExposureMSCIInPortfolioCcy

Aggregation/GrossExposureWeightMSCI

As GrossExposureWeight, using Valuation/ExposureMSCIInPortfolioCcy

Note the following:

  • Request these metrics with Value. LUSID calculates them for each group itself.

  • Aggregation/NetExposureWeight gives the same result as Sum of Valuation/Weight, and Aggregation/GrossExposureWeight as SumOfAbsoluteValues of Valuation/Weight.

  • Set the Benchmark metric option to true to calculate the weight using the portfolio's benchmark instead.

Subtotals

Set equipWithSubtotals to true in your valuation request to add subtotal rows to a grouped report. LUSID adds one row for each value at each groupBy level except the last, and one grand-total row. In each extra row, the groupBy metrics being totalled show __ALL__.

LUSID calculates every extra row from the holdings underneath it, using the operations you request. For example, valuing a GBP portfolio of five holdings grouped by currency and then by instrument returns:

Valuation/PV/Ccy

Instrument/default/Name

Sum(Valuation/PvInPortfolioCcy)

Average(Valuation/PvInPortfolioCcy)

Count(Valuation/PvInPortfolioCcy)

Proportion(Valuation/PvInPortfolioCcy)

GBP

UK equity

1000

1000

1

0.333

USD

US equity

800

800

1

0.267

GBP

UK equity (short)

-200

-200

1

-0.067

GBP

GBP cash

1000

1000

1

0.333

USD

USD cash

400

400

1

0.133

GBP

__ALL__

1800

600

3

0.6

USD

__ALL__

1200

600

2

0.4

__ALL__

__ALL__

3000

600

5

1

Note the following:

  • equipWithSubtotals has no effect without groupBy.

  • LUSID returns the subtotal and grand-total rows after all the other rows, not next to the group they total.

  • Operations work on the holdings underneath each row, not on the rows above it. For example, the GBP subtotal's Average is 1800 divided by three holdings. Proportion still divides by the total for the whole report, so the grand-total row shows 1.

  • Total metrics and weight metrics work as usual: Valuation/TotalPortfolioPvInPortfolioCcy shows the portfolio total on every row, and Aggregation/NetExposureWeight shows each row's share, 1 on the grand-total row.

  • Value is empty on subtotal rows for most metrics, because the holdings underneath have different values.

  • Don't use SumCumulativeInAdvance or SumCumulativeInArrears with subtotals. On a subtotal row, they show the running total from the last holding in the group, not a meaningful figure.

Other Aggregation metrics

Metric

Notes

Aggregation/Errors

Lists any errors for the row, such as a holding that failed to value or a currency mismatch. LUSID adds it to any row with errors, even if you don't request it.

Aggregation/NetExposureFraction, Aggregation/GrossExposureFraction and their MSCI versions

Older versions of the weight metrics. They divide by the total Valuation/PV in holding currency, so they only work for single-currency portfolios. We recommend the weight metrics instead.

Aggregation/MacaulayDuration

For duration, we recommend the Analytic/MacaulayDuration metric instead.

Aggregation/VaR/Histogram, Aggregation/VaR/Statistic

Experimental. For value at risk, we recommend the Analytic/var/HistoricalVaR and Analytic/var/DeltaNormalVaR metrics instead.