Skip to main content

Overview

Tarvah’s calculation engine generates SQL window functions and aggregate expressions for common financial analytics patterns. Calculations are defined on the semantic model and automatically flow through to VDMs, experiments, and dashboards.

Supported Calculation Types

TypeSQL PatternUse Case
Percentage of Totalvalue / NULLIF(SUM(value) OVER (PARTITION BY ...), 0)Position weight in account, sector allocation
Weighted AverageSUM(value * weight) OVER (...) / NULLIF(SUM(weight) OVER (...), 0)Weighted yield, weighted ESG scores
PercentilePERCENTILE_CONT(n) WITHIN GROUP (ORDER BY value) OVER (...)Median analytics, distribution analysis
CustomUser-defined SQL with ${field} template referencesAny custom formula
All calculations use NULLIF(..., 0) for safe division and COALESCE for null-safe arithmetic.

Pre-built Templates

Nine templates are available out of the box. Templates are starting points, not constraints — they pre-populate the calculation type and suggest default field names (e.g., mkt_val, acct_cd), but you can override every field to match your model’s actual column names. The calculation engine resolves whatever field names you provide against your semantic model’s dimensions and measures.
Default fields are suggestions, not requirements. Every template shows default field names like mkt_val and acct_cd — these are pre-filled when you select the template but can be changed to any field in your model. The SQL pattern (percentage, weighted average, etc.) stays the same; only the column references change.

Percentage Templates

What it calculates: What percentage of the account’s total market value does this position represent?Default fields: valueField: mkt_val, partitionBy: [acct_cd]Generated SQL:
mkt_val / NULLIF(SUM(mkt_val) OVER (PARTITION BY acct_cd), 0)
Example: If account ACC001 has total market value of 10MandpositionAAPLis10M and position AAPL is 2M, the result is 0.20 (20%).
What it calculates: What percentage of the account does a particular category (e.g., sector) represent?Default fields: valueField: mkt_val, partitionBy: [acct_cd]Tip: Override partitionBy to ["acct_cd", "sector"] for intra-category percentages.Generated SQL (with sector partition):
mkt_val / NULLIF(SUM(mkt_val) OVER (PARTITION BY acct_cd, sector), 0)
What it calculates: What percentage of the account group’s total does this account represent?Default fields: valueField: mkt_val, partitionBy: [acct_group]Generated SQL:
mkt_val / NULLIF(SUM(mkt_val) OVER (PARTITION BY acct_group), 0)

Weighted Average Templates

What it calculates: Market-value-weighted average of an analytic value (e.g., yield, duration) across a fund.Default fields: valueField: analytic_val, weightField: mkt_val, partitionBy: [acct_cd]Generated SQL:
SUM(COALESCE(analytic_val, 0) * COALESCE(mkt_val, 0)) OVER (PARTITION BY acct_cd)
/ NULLIF(SUM(COALESCE(mkt_val, 0)) OVER (PARTITION BY acct_cd), 0)
Example: For ACC001 with positions weighted by market value, the result is the portfolio-weighted average of analytic_val.
What it calculates: Same as above, but partitioned by both account and category (sector).Default fields: valueField: analytic_val, weightField: mkt_val, partitionBy: [acct_cd, sector]Generated SQL:
SUM(COALESCE(analytic_val, 0) * COALESCE(mkt_val, 0)) OVER (PARTITION BY acct_cd, sector)
/ NULLIF(SUM(COALESCE(mkt_val, 0)) OVER (PARTITION BY acct_cd, sector), 0)
What it calculates: Market-value-weighted average of issuer-level metrics (e.g., ESG scores) within a fund.Default fields: valueField: esg_score, weightField: mkt_val, partitionBy: [acct_cd]Prerequisite: The semantic model must include a join to the issuer dimension table with esg_score defined.
What it calculates: ESG or issuer metrics weighted by market value, partitioned by account and sector.Default fields: valueField: esg_score, weightField: mkt_val, partitionBy: [acct_cd, sector]

Percentile Templates

Default fields: valueField: analytic_val, partitionBy: [acct_cd], percentile: 0.5 (median)Generated SQL:
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY analytic_val) OVER (PARTITION BY acct_cd)
Default fields: valueField: analytic_val, partitionBy: [acct_cd, sector], percentile: 0.5

Calculation Object Structure

When creating calculations via the API or the customCalculations array in onboarding, use this structure:
{
  "name": "pct_of_fund",
  "label": "% of Fund",
  "type": "measure",
  "calculationType": "percentage_of_total",
  "valueField": "mkt_val",
  "partitionBy": ["acct_cd"],
  "description": "Position market value as percentage of fund total"
}

Fields

FieldTypeRequiredDescription
namestringYesUnique identifier within the model
labelstringNoDisplay label (defaults to name)
typestringNoAlways "measure" for calculations
calculationTypestringYesOne of: percentage_of_total, weighted_average, percentile, custom
valueFieldstringConditionalThe field to calculate on. Required for all types except custom.
weightFieldstringConditionalThe weighting field. Required for weighted_average.
percentilenumberConditionalValue between 0 and 1. Required for percentile.
partitionBystring[]NoFields to partition (group) by. Produces PARTITION BY in SQL.
sqlstringConditionalRaw SQL expression. Required for custom. Supports ${fieldName} references.
templateIdstringNoApply a pre-built template (auto-populates defaults).
descriptionstringNoHuman-readable description.

Weighted Average Example

{
  "name": "wavg_duration",
  "label": "Weighted Avg Duration",
  "calculationType": "weighted_average",
  "valueField": "duration",
  "weightField": "mkt_val",
  "partitionBy": ["acct_cd"]
}

Custom SQL Example

{
  "name": "spread_to_benchmark",
  "label": "Spread to Benchmark",
  "calculationType": "custom",
  "sql": "${oas} - ${benchmark_oas}"
}
The ${field} syntax resolves against the model’s dimensions, measures, and other calculations.

Using Calculations in SDK Import

Calculations defined on the semantic model are automatically translated into VDM EXPRESSION measures by the BI import adapter. Once in the VDM, you can reference them in SDK import payloads using the as-is aggregation:
{
  "name": "Holdings Dashboard",
  "dataSource": { "dbId": "D2026A00002", "vdmId": "V2026A00101", "connType": "VDM" },
  "charts": [
    {
      "title": "Position % of Fund",
      "type": "column",
      "measures": [
        { "field": "pct_of_fund", "aggregation": "as-is" }
      ],
      "dimensions": ["security_name"]
    },
    {
      "title": "Weighted Avg Analytics",
      "type": "bar",
      "measures": [
        { "field": "wavg_analytics", "aggregation": "as-is" }
      ],
      "dimensions": ["sector"]
    }
  ]
}
The calculation must already exist in the VDM’s measureConfiguration before referencing it in SDK import. Define calculations on the semantic model first (via the Model Editor UI, the calculation API, or the customCalculations array during client onboarding).

How the Pipeline Works

Semantic Model (calculations defined)
    -> BI Import Adapter (translates to EXPRESSION measures)
        -> VDM (SQL baked into querySTMT)
            -> SDK Import (reference by label with "as-is")
                -> Experiment / Facade (renders in charts)

API Endpoints

MethodEndpointDescription
GET/v1/bi/model/calculation/templates/:userIdList all available calculation templates
GET/v1/bi/model/:modelId/calculations/:userIdGet calculations for a model
POST/v1/bi/model/:modelId/calculation/:userIdAdd a calculation to a model
PUT/v1/bi/model/:modelId/calculation/:calcName/:userIdUpdate a calculation
DELETE/v1/bi/model/:modelId/calculation/:calcName/:userIdDelete a calculation
POST/v1/bi/model/:modelId/calculation/preview/:userIdPreview generated SQL without saving

Preview Example

curl -X POST https://<instance>/v1/bi/model/SM2026A00001/calculation/preview/<userToken> \
  -H "Content-Type: application/json" \
  -H "CTN: <csrf-token>" \
  --cookie "LASID=<session>;ATN=<access>;RTN=<refresh>" \
  -d '{
    "calculationType": "weighted_average",
    "valueField": "duration",
    "weightField": "mkt_val",
    "partitionBy": ["acct_cd", "sector"]
  }'
Response:
{
  "modelId": "SM2026A00001",
  "calculation": {
    "calculationType": "weighted_average",
    "valueField": "duration",
    "weightField": "mkt_val",
    "partitionBy": ["acct_cd", "sector"],
    "resolvedSql": "SUM(COALESCE(duration, 0) * COALESCE(mkt_val, 0)) OVER (PARTITION BY acct_cd, sector) / NULLIF(SUM(COALESCE(mkt_val, 0)) OVER (PARTITION BY acct_cd, sector), 0)"
  }
}