Quick start
Every LX expression starts with a pointer to a metric. Add modifiers in square brackets to target a specific period, scenario, or revision.
@reporter.net_income # Get a metric @reporter.net_income[scenario=budget] # Compare to budget @reporter.net_income[period=M::LTM] # Last twelve months @reporter.net_income[asof=2024-12-31] # The value as it was known on a date
Finding your configuration
Your global object
The word after the @ is your global object — the level your data lives at. Find it on the deliveab tracker, above the list of companies:
"Reporters" → use
@reporter"Companies" → use
@company"Entities" → use
@entity
Your metric names and scenarios
Left sidebar → Reporters → Metrics
Open Metric groups
Browse categories (Balance Sheet, etc.) and scenarios (actuals, budget, etc.)
Use these exact names in your queries
Your specific scenarios and metrics are configured during setup.
Core concepts
Basic structure
@reporter.metric_name[modifiers]
Modifiers
Modifiers add specificity using key–value pairs inside square brackets [ ]. They target a specific dimension of your data. You can combine several, comma-separated.
Period modifiers: set the periodicity of a metric and resample from one grain to another with source::target.
# Syntax: period={source_period}::{target_period} @entity.example-1[period=M::LTM] # Resample monthly data to Last Twelve Months💡 Resampled targets can be any window period type. Prefer fiscal periods over calendar ones when the intent is ambiguous.
Scenario modifiers — select a version of a metric, such as actuals, budget, or an origination case.
@entity.example-1[period=M, scenario=actual]
Everything else you can put in brackets 🆕 — beyond period and scenario, these modifiers shipped over the last few releases:
Modifier | What it does | Values |
| Choose which reported revision of a value to use | see below |
| Turn entity-mapping resolution on or off |
|
| View a window (LTM, YTD…) on a chosen grain, e.g. |
|
| Fill the synthesized rows created when upsampling |
|
| Carry a value across every period |
|
| Return cumulative (running-total) values |
|
| Select a cashflow financial scenario | per namespace |
Smart defaults
When you leave modifiers off, LX fills in sensible defaults:
@reporter.net_income # Same as @reporter.net_income[scenario=actuals, period=M, asof=latest]
As-of revisions 🆕
Every value can be reported more than once. A first estimate, then a restatement. The asof modifier picks which revision you get, so a dashboard can show today's best number or reconstruct what you knew at a point in time.
Pick a revision
@company.revenue[asof=latest] # Most recently reported (this is the default) @company.revenue[asof=earliest] # First reported value @company.revenue[asof=previous] # Second most recent @company.revenue[asof=all] # All revisions, as a list
Compare revisions
@company.revenue[asof=min] # Smallest value across all revisions @company.revenue[asof=max] # Largest value across all revisions @company.revenue[asof=average] # Average across all revisions @company.revenue[asof=delta] # Latest − earliest @company.revenue[asof=percent] # % change, earliest → latest @company.revenue[asof=delta-previous] # Latest − previous revision @company.revenue[asof=percent-previous] # % change, previous → latest
Reconstruct a point in time — add ::YYYY-MM-DD to bound any strategy to a version cutoff. Only revisions reported on or before that date count. A bare date is shorthand for latest as of that date.
@company.revenue[asof=latest::2024-12-31] # Latest revision known by year-end 2024 @company.revenue[asof=2024-12-31] # Shorthand for latest::2024-12-31
When was it reported? — the companion function as_of_date() returns the date a value was reported or recorded.
as_of_date(@company.revenue[asof=latest])
Real-world examples
Go to any Dashboard, Formula, Mapping, or Excel calculation to write LX.
Scenario comparisons
# Compare actual to budget @reporter.net_income - @reporter.net_income[scenario=budget] # Variance with scaling (shows in thousands) scale( @reporter.net_income[period=M::FYTD] - @reporter.net_income[scenario=budget, period=M::FYTD], 1000 )
Growth calculations
# Year-over-year growth (@reporter.net_income[period=M::LTM] / @reporter.net_income-close) - 1 # Or, more directly, on monthly data: prior_period_percent_change(@reporter.net_income, 12)
Asset coverage
(@reporter.accounts_receivable[scenario=actuals, period=M] * .85 + coalesce(@reporter.inventory[scenario=actuals, period=M], 0) * .5) / coalesce(@reporter.total_syndicated_outstanding[], @reporter.total_debt_outstanding[scenario=actuals, period=M])
A complex, real example
"If LTM revenue is beating our 12-month budgeted average, show the growth rate; otherwise show current revenue, all in thousands."
scale( # Display in 1000s if( # If / then logic @reporter.revenue[period=M::LTM] > # Is LTM revenue greater than rolling_average( # the rolling average @reporter.revenue[scenario=budget], 12 # of 12 months of budget? ), prior_period_percent_change( # If yes: show % change @reporter.revenue # from prior period ), coalesce(@reporter.revenue, 0) # If no: show revenue or 0 ), 1000 # Scale to thousands )
💡 if(), not when(). Older docs used when(...) for conditionals — it's no longer part of LX. Use if() for one branch, or case() for several.
Working with dates 🆕
Dates are now first-class LX values. You can read them, do arithmetic on them, and anchor time-series calculations to a real business date — "since close", "prior fiscal year", "trailing 12 months" — instead of a raw count of rows.
Date math
# Date-returning functions current_date() # Today's date at evaluation time (today() is an alias) relative_to_date() # The report or widget's anchor date effective_date(@company.cash) # The date a value was reported # Pull parts out of a date year(date) month(date) quarter(date) fiscal_year(date) fiscal_quarter(date) # Distance between two dates days_between(date1, date2) months_between(date1, date2) years_between(date1, date2)
Literal and relative dates
Write a literal date as YYYY-MM-DD. Relative dates shift by calendar or fiscal periods — -1FY (prior fiscal year), -12CM (trailing 12 calendar months), 0CM (current month). Add ! for the start of the period or @ to keep the day-of-period anchor.
exact(@company.revenue, 2024-12-31) date_shift(@company.close-date, -1FY) # shift a date by a relative date
Duration constructors 🆕
Unlike a fixed reldate like 18CM, these take a computed (even fractional) number and shift a date with + or -.
months(n) days(n) years(n) # Runway: project a cash-out date from computed months of runway effective_date(@company.cash) + months(@company.cash / @company.monthly-burn) # Maturity date from a loan term @company.close-date + years(@company.loan-term-years)
Date-anchored time series
These shift and roll by a date anchor instead of an integer count — reach for them whenever the question is framed around calendar or fiscal dates.
period_shift(@company.revenue[period=m], -1FY) # shift to the prior fiscal year period_shift(@company.revenue, @company.close-date) # shift relative to a date property period_shift_percent_change(@company.revenue[period=m], -1FY) period_rolling_sum(@company.revenue[period=m], -12CM) # trailing 12 calendar months period_rolling_average(@company.revenue[period=m], -3CM) # trailing 3-month average cumulative_sum(@company.revenue, @company.close-date) # accumulate since close
Point-in-time lookups 🆕
Read a single value out of a series, with or without carry-forward semantics.
first(@company.revenue) # earliest value last(@company.revenue) # latest value previous_known(@company.cash-balance, @company.close-date) # carry last known value forward next_known(@company.revenue, 2024-01-01) # first value on or after a date exact(@company.revenue, 2024-12-31) # strict match — null if no value on that date
Cross-entity & fund metrics 🆕
Most formulas stay within one entity. When a question genuinely spans related entities — a portfolio total, a share of total, a fund IRR — these functions reach across the hierarchy.
Cross-entity lookups
# Pull from related entities (auto up/down), optionally aggregating and filtering lookup_related(@security.nav, "sum", @security.type != "warrant") # Aggregate across ALL entities in a namespace lookup_all(@company.loan, "sum") # Share of total @company.loan / lookup_all(@company.loan, "sum")
The aggregation method is a quoted string: "sum", "avg", "min", "max", or "count".
Cashflows & fund metrics
# Net IRR from combined cashflows plus the latest NAV as terminal value xirr( combine(@fund.cashflows.contribution, @fund.cashflows.distribution), latest_nav(@fund.cashflows.nav) ) # Latest NAV, falling back to cost until one exists latest_nav(@fund.cashflows.nav, @fund.cost) # Roll the latest NAV forward with cashflows since that NAV date cashflow_adjusted_nav( latest_nav(@fund.cashflows.nav), combine(@fund.cashflows.contribution, @fund.cashflows.distribution * -1) )
Making numbers look right
Scaling
scale(@reporter.net_income, 1000) # Display in thousands round(@reporter.net_income, 0) # Round to whole numbers
Available formats
Currency ($)
Percent (%)
Decimal places (0–2 typical)
Thousands separator
Handling missing data
Use coalesce only when you need fallback behavior:
# If adjusted EBITDA is missing, use regular EBITDA coalesce( @reporter.adjusted_ebitda, @reporter.ebitda )
Complete syntax reference
Base period types
Code | Meaning |
| Day |
| Month (base period) |
| Calendar Quarter |
| Calendar Year |
| Fiscal Quarter |
| Fiscal Year |
| Last Twelve Months |
| Next Twelve Months |
| Year to Date |
| Fiscal Year to Date |
| Quarter to Date |
| Fiscal Quarter to Date |
Resample with period=M::LTM, period=M::YTD, and so on.
Relative dates (reldates)
Format: [+-]<N><suffix>[!@]. Suffixes: D CW CM CQ CH CY FQ FH FY. Examples: -1FY, -12CM, 0CM, -3CM!. Optional anchors: ! = start of period, @ = keep day-of-period.
💡 Relative dates are usable directly in LX now — in date-aware functions and date arithmetic — not just in the effective-date field.
Operators
+ - * / ^ # add, subtract, multiply, divide, power > >= < <= = != # comparisons
Comments in LX start with #.
Function catalog
This list is generated directly from the LX function specs, so it always matches the shipped grammar. See "Keeping this in sync" at the end.
Conditional
Use when an expression needs branch logic, labels, thresholds, or fallback values.
if(condition, truthy_value, falsey_value): Return one value when a condition is true and another when it is false. Example:if(@company.revenue > 0, "Positive", "Negative")case(condition1, result1, condition2, result2, ..., default): Evaluate condition/result pairs in order and return the first matching result. Example:case(@company.revenue > 1000, "High", @company.revenue > 500, "Medium", "Low")switch(value, match1, result1, match2, result2, ..., default): Match a value against explicit choices and return the corresponding result. Example:switch(@company.status, "active", 1, "inactive", 0, null)
Logic
Use when combining or negating boolean checks.
any(condition1, condition2, ...): Return true when at least one condition is truthy. Example:any(@company.revenue > 0, @company.ebitda > 0)all(condition1, condition2, ...): Return true only when every condition is truthy. Example:all(@company.revenue > 0, @company.ebitda > 0)not(condition): Invert a boolean expression. Example:not(@company.status == "active")contains(value, "search_text"): Check whether a string or list value contains the provided text. Example:contains(@company.tags, "priority")
Math
Use for numeric transforms, rounding, ratios, powers, logs, and basic arithmetic helpers.
max(value1, value2, ...): Return the maximum value across explicit arguments. Example:max(@company.budget_revenue, @company.forecast_revenue)min(value1, value2, ...): Return the minimum value across explicit arguments. Example:min(@company.base_rate, @company.floor_rate)sum(value1, value2, ...): Add explicit expressions together. Example:sum(@company.revenue, @company.other_income)average(value1, value2, ...): Compute the arithmetic mean across explicit arguments. Example:average(@company.gross_margin, @company.net_margin)absolute(value): Return the absolute value of a numeric expression. Example:absolute(@company.variance)scale(value, divisor): Divide a numeric expression by a scale factor for display or comparison. Example:scale(@company.revenue, 1000)round(value, digits?): Round a numeric expression to a number of decimal digits. Example:round(@company.revenue / @company.headcount)
Null Handling
Use when values may be missing and the expression needs defaults or null-aware behavior.
coalesce(value1, value2, ..., fallback): Return the first non-null value from an ordered list of expressions. Example:coalesce(@company.adjusted_ebitda, @company.ebitda, 0)
Text
Use for string formatting, matching, extraction, and text cleanup.
concat(value1, value2, ...): Concatenate values as text without adding separators automatically. Example:concat("Total: ", @company.revenue)
Time Series
Use for rolling windows, lag/lead comparisons, cumulative values, and period-over-period trends.
latest(series): Return the most recent value in a time series. Example:latest(@company.revenue)earliest(series): Return the earliest value in a time series. Example:earliest(@company.revenue)effective_date(series): Return the effective date associated with a non-null series value. Example:effective_date(@company.revenue)as_of_date(series): Return the as-of date associated with a versioned field value. Example:as_of_date(@company.revenue[asof=latest])first(series, date?): Return the earliest value in the series, optionally anchored to a minimum date. Example:first(@company.revenue)last(series, date?): Return the latest value in the series, optionally anchored to a maximum date. Example:last(@company.revenue)previous_known(series, date?): Carry the latest known value forward to the current or explicit date anchor. Example:previous_known(@company.revenue)next_known(series, date?): Return the earliest known value on or after the current or explicit date anchor. Example:next_known(@company.revenue)exact(series, date): Return the value whose effective date exactly matches the provided date. Example:exact(@company.revenue, 2024-12-31)next_period(series, periods_forward): Shift a time series forward by a number of periods. Example:next_period(@company.revenue, 1)prior_period(series, periods_back): Shift a time series backward by a number of periods. Example:prior_period(@company.revenue, 12)prior_period_delta(series, periods_back): Return the difference between the current value and a prior value. Example:prior_period_delta(@company.cash, 1)prior_period_percent_change(series, periods_back): Return the percent change between the current value and a prior value. Example:prior_period_percent_change(@company.revenue, 12)period_shift(series, date_anchor): Shift a series by a date, relative date, or date-valued property instead of a raw period count. Example:period_shift(@company.revenue[period=m], -1FY)cumulative_sum(series, date_anchor): Return a cumulative sum beginning at a date, relative date, or date-valued property. Example:cumulative_sum(@company.revenue, 2021-12-31)period_rolling_sum(series, date_anchor): Return a rolling sum over a date-aware window anchored by a date or relative date. Example:period_rolling_sum(@company.revenue[period=m], -12CM)period_rolling_average(series, date_anchor): Return a rolling average over a date-aware window anchored by a date or relative date. Example:period_rolling_average(@company.revenue[period=m], -3CM)period_shift_percent_change(series, date_anchor): Return the percent change versus a date-aware comparison point. Example:period_shift_percent_change(@company.revenue[period=m], -1FY)quarter_to_date_sum(series, fiscal_month_end?): Return the cumulative sum within each quarter. Example:quarter_to_date_sum(@company.revenue)year_to_date_sum(series, fiscal_month_end?): Return the cumulative sum within each year. Example:year_to_date_sum(@company.revenue)rolling_sum(series, window_size): Return a rolling sum across the most recent N periods. Example:rolling_sum(@company.revenue, 12)rolling_average(series, window_size): Return a rolling average across the most recent N periods. Example:rolling_average(@company.revenue, 3)rolling_min(series, window_size): Return the minimum value seen in the rolling window. Example:rolling_min(@company.revenue, 6)rolling_max(series, window_size): Return the maximum value seen in the rolling window. Example:rolling_max(@company.revenue, 6)rolling_quantile(series, window_size, quantile): Return a rolling quantile across the most recent N periods. Example:rolling_quantile(@company.revenue, 4, 0.5)
Date Math
Use for deriving, shifting, comparing, or formatting dates.
current_date(): Return the wall-clock date at evaluation time. Example:current_date()relative_to_date(): Return the evaluation-relative anchor date for the current context. Example:relative_to_date()today(): Alias forcurrent_date(). Example:today()days_between(date1, date2): Return the number of calendar days from the first date to the second date. Example:days_between(@company.close-date, current_date())months_between(date1, date2): Return the number of months from the first date to the second date. Example:months_between(@company.close-date, relative_to_date())years_between(date1, date2): Return the number of years from the first date to the second date. Example:years_between(@company.close-date, relative_to_date())year(date): Extract the calendar year from a date expression. Example:year(@company.close-date)month(date): Extract the calendar month from a date expression. Example:month(@company.close-date)quarter(date): Extract the calendar quarter from a date expression. Example:quarter(@company.close-date)fiscal_year(date): Extract the fiscal year from a date expression using the cluster fiscal-year settings. Example:fiscal_year(@company.close-date)fiscal_quarter(date): Extract the fiscal quarter from a date expression using the cluster fiscal-year settings. Example:fiscal_quarter(effective_date(@company.revenue))months(count): A month duration computed from any numeric expression, for shifting dates. Example:effective_date(@company.cash) + months(@company.cash / @company.monthly-burn)days(count): A day duration computed from any numeric expression, for shifting dates. Example:@company.close-date + days(@company.grace-period-days)years(count): A year duration computed from any numeric expression, for shifting dates. Example:@company.close-date + years(@company.loan-term-years)
Aggregation
Use when collapsing many values into summary statistics.
aggregate_sum(series): Collapse a series to a single sum per entity or group. Example:aggregate_sum(@company.cashflows.distribution)aggregate_average(series): Collapse a series to a single average per entity or group. Example:aggregate_average(@company.margin)aggregate_max(series): Collapse a series to its maximum value. Example:aggregate_max(@company.revenue)aggregate_min(series): Collapse a series to its minimum value. Example:aggregate_min(@company.cash_balance)aggregate_mode(series): Collapse a series to its most frequent value. Example:aggregate_mode(@company.status)aggregate_median(series): Collapse a series to its median value. Example:aggregate_median(@company.revenue)aggregate_weighted_average(weight, value): Collapse a series to a weighted average using separate weight and value expressions. Example:aggregate_weighted_average(@company.position_weight, @company.return_pct)
Cashflow
Use for cashflow-specific calculations and schedule-oriented values.
combine(series1, series2, ...): Vertically combine multiple cashflow series into one series. Example:combine(@fund.cashflows.contribution, @fund.cashflows.distribution)latest_nav(series, fallback?): Return the latest NAV per entity, ignoring the outer grouping context. Example:latest_nav(@fund.cashflows.nav)xirr(cashflows, terminal_value?): Compute an internal rate of return from cashflow data and an optional terminal value. Example:xirr(combine(@fund.cashflows.contribution, @fund.cashflows.distribution), latest_nav(@fund.cashflows.nav))cashflow_adjusted_nav(base_terminal_nav, adjustment_cashflows): Roll the latest NAV forward with selected cashflows since that NAV date. Example:cashflow_adjusted_nav(latest_nav(@fund.cashflows.nav), combine(@fund.cashflows.contribution, @fund.cashflows.distribution * -1))
Cross-Entity
Use when an expression needs to look across related entities or aggregate across an entity set.
lookup_related(expression, "agg_method"?, filter_expression?): Resolve data from related entities across the hierarchy, optionally aggregating it. Example:lookup_related(@security.nav, "sum")lookup_all(expression, "agg_method"?, filter_expression?): Resolve data across all entities in the referenced namespace, optionally aggregating it. Example:lookup_all(@company.loan, "sum")
Common mistakes to avoid
1. when() is gone — use if() ❌
# ✕ Removed when(@reporter.revenue > 0, true, false) # ✓ Correct if(@reporter.revenue > 0, true, false)
2. Wrong time-period syntax
# ✕ Wrong @reporter.revenue::LTM # ✓ Right @reporter.revenue[period=M::LTM]
3. Missing base period
# ✕ Wrong @reporter.revenue[period=LTM] # ✓ Right @reporter.revenue[period=M::LTM]
4. Unnecessary coalesce
# ✕ Wrong (scenarios don't need fallbacks) coalesce(@reporter.revenue[scenario=budget]) # ✓ Right @reporter.revenue[scenario=budget]
⚠️ Heads-up on CW: CW, CH, and FH are relative-date suffixes, not period= values. There is no period=M::CW — the valid period types are listed in the reference above.
Tracing a number back 🆕
Any calculated value on a dashboard or grid can be traced to the source it came from. Click a cell to open the traceback panel, which routes you to the underlying source documents and shows how the number was assembled.
See the source document behind each figure, including for cashflows.
A "contains carried data" badge appears when a value was carried forward or backward rather than reported for that period.
Provenance is date-aware, so restated values and effective dates line up with the right column.
Need help?
Check your configuration
Homepage → Recently visited (for your global object)
Left sidebar → Metric groups (for metric names)
Check your configured scenarios
Build step by step
Start with a basic metric
Add time periods, then scenarios, then calculations
Break a complex formula apart — most functions are inspectable on their own
Contact support — email support@lumonic.com for metric configuration questions, scenario setup, custom calculations, or additional training.