DuckDB Finance Quant SQL Extension

Best Practices

DuckDB Finance is most useful when finance assumptions stay visible in SQL. Use these practices for research, CI fixtures, desk sanity checks, and agent-written queries.

Keep Units Explicit

Use decimal units:

Name derived columns with units when they are not obvious:

WITH desk_risk(trade_id, dv01_usd, scenario_pnl_usd, volatility_annualized) AS (
  VALUES ('SPX_ATM_CALL', 125.0, -3400.0, 0.20)
)
SELECT
  trade_id,
  dv01_usd,
  scenario_pnl_usd,
  volatility_annualized
FROM desk_risk;

Normalize Before Aggregating

Portfolio functions and SQL sums do not make incompatible risks compatible. Normalize first, then aggregate:

WITH desk_risk(portfolio_id, quantity, pv_usd, dv01_usd_per_bp) AS (
  VALUES
    ('CORE', 2.0, 10.45, 0.64),
    ('CORE', 1.0, 2500.00, -42.00)
),
normalized AS (
  SELECT
    portfolio_id,
    quantity,
    pv_usd,
    dv01_usd_per_bp
  FROM desk_risk
)
SELECT
  portfolio_id,
  sum(pv_usd * quantity) AS pv_usd,
  sum(dv01_usd_per_bp * quantity) AS dv01_usd_per_bp
FROM normalized
GROUP BY portfolio_id;

Do not add equity delta, FX delta, credit spread sensitivity, and IR DV01 into a single total unless you have mapped them to the same scenario or PnL unit.

Treat Models As Local Models

The extension prices from caller-supplied inputs. It does not calibrate curves, fetch market data, select calendars, or apply desk-specific risk conventions.

Before using outputs in a serious workflow, reconcile:

Prefer Small Reproducible Examples

For docs, tests, and agent-generated answers:

Validate At Boundaries

Use validation helpers before pricing or aggregation:

WITH quotes(open, high, low, close) AS (
  VALUES (100.0, 102.0, 99.0, 101.0)
)
SELECT
  fin_validate_ohlc(open, high, low, close) AS valid_ohlc,
  fin_is_price(close) AS valid_close
FROM quotes;

For schema-sensitive workflows, document the expected input columns and fail early when data is missing or in the wrong unit.

Use Compatibility Helpers Deliberately

Compatibility helpers are useful when porting an existing workflow, but core finance functions are usually clearer for new SQL. Prefer the core function unless the compatibility shape carries useful structure across queries.

See Compatibility for the supported boundary.

Verify Changes

Run local validation before handing off a change:

python3 scripts/check_docs_site.py
python3 scripts/check_function_docs.py
python3 scripts/check_gs_quant_surface.py
make check DUCKDB_ROOT=/path/to/duckdb

When the change only edits prose, the Python docs checks catch navigation, function-reference, and compatibility-manifest drift. When SQL examples change, run those examples against the local extension too.