DuckDB Finance Quant SQL Extension

Development Guide

This guide explains how to build, test, document, and extend DuckDB Finance as a standard out-of-tree DuckDB extension.

Repository Shape

Path Purpose
src/scalar.cpp and src/scalar/*.inc Native scalar functions for math, rates, options, cash flows, portfolios, validation, calendars, and compatibility structs.
src/aggregate.cpp and src/aggregate/*.inc Native aggregate state for metrics such as Sortino, EWMA volatility, drawdowns, outliers, IV rank, and IV percentile.
src/macros.cpp and src/macros/*.inc SQL macro registrations and compatibility aliases.
src/table_functions.cpp and src/table_functions/*.inc Table functions and bind-replace SQL generators.
include/finance/finance_extension.hpp Extension registration declarations.
test/sql/gold_dataset.sql Small deterministic fixture tables.
test/sql/gold_tests.sql Assertion-based behavior and edge-case tests.
test/sql/smoke_queries.sql Broad callable-surface smoke coverage.
docs/function_reference.md Public usage reference for registered fin_* functions.

Build Requirements

Build:

make debug DUCKDB_ROOT=/path/to/duckdb

Test Commands

make smoke
make gold
make test
make check

make check runs:

  1. scripts/check_function_docs.py to confirm registered functions are covered in docs/function_reference.md.
  2. scripts/check_docs_site.py to confirm the GitHub Pages navigation and publishing workflow are wired.
  3. scripts/check_function_tests.py to confirm registered functions are covered by the gold behavior tests.
  4. scripts/check_function_perf_tests.py to confirm the profiled gold corpus covers registered functions.
  5. make smoke to load the extension and run broad smoke queries.
  6. make gold to run deterministic fixtures and assertions.

The test targets start DuckDB with unsigned local extensions enabled:

make test DUCKDB_ROOT=/path/to/duckdb

CI Scope

CI always runs the static coverage gates:

make ci-static

Pull requests that touch source, tests, examples, build files, workflow files, or other runtime-sensitive paths also run the DuckDB-backed gate:

make ci-duckdb DUCKDB_ROOT=/path/to/duckdb

Protected-branch, merge-queue, and manual CI runs execute the full path. This keeps documentation-only checks fast without weakening behavior checks for extension changes.

Adding A Function

  1. Choose the smallest native or SQL-macro implementation that fits the behavior.
  2. Register the function under fin_*.
  3. Add behavior tests in test/sql/gold_tests.sql.
  4. Add or update deterministic fixture rows in test/sql/gold_dataset.sql only when a reusable fixture makes the test clearer.
  5. Document the function in docs/function_reference.md.
  6. Run make check.

Prefer native C++ for numerically sensitive models, custom list/struct output, table-function binding, and hot row-wise execution. Prefer SQL macros when DuckDB already exposes the right aggregate or window primitive.

Numerical And Finance Conventions

Documentation Expectations

The public docs should make model assumptions explicit. Every new function should describe:

The function reference is intentionally concise; longer workflows belong in docs/playbooks.md or examples/playbooks.sql.