Research release · September 4, 2026

Introducing FinIR

FinIR is a finance-aware intermediate representation and execution runtime for turning AI-interpreted financial instructions into deterministic, typed, and auditable computation. It does this without relying on generated Python, SQL, or spreadsheets as the execution layer.

By Lethabo Scofield and Alisha Fatima

Before-and-after comparison of a financial spreadsheet model showing updated assumptions, profit and loss figures, key metrics, and net profit trend
A financial model before and after updated assumptions flow through its dependent calculations and metrics.

A reliable place for financial computation

AI systems are good at interpreting financial instructions, but interpretation is not the same as reliable execution. When an AI generates Python, SQL, or spreadsheet formulas for every task, the execution logic can change between runs, financial types are difficult to enforce, and the origin of each result becomes harder to audit.

FinIR addresses this problem by placing a deterministic computational layer between the AI and the final result. The AI expresses financial intent, while FinIR validates the types, records the dependencies, compiles the computation, and recalculates only the values affected by a change.

A computational boundary for AI

FinIR separates probabilistic interpretation from deterministic financial execution.

FinIR workflow from AI financial intent through typed graph dependency analysis, incremental execution, hardware dispatch, and financial results
FinIR turns financial intent into a typed dependency graph, recomputes only affected nodes, dispatches execution to available hardware, and returns auditable financial results.

How FinIR works

You describe a financial model once. FinIR turns it into a graph of typed calculations and runs that graph directly, so there is no generated Python, SQL, or spreadsheet in between.

Three-step diagram: define the model as inputs and formulas, build a typed financial graph, then recompute only the nodes affected by a change
Define the model, build the graph, recompute only what changed. When COGS changes, only Gross Profit, Gross Margin, and EBITDA run again.

Finance-aware type semantics

In a spreadsheet, every cell is just a number. FinIR gives every value a financial type, so the engine knows what a cell means before it computes it. Valid formulas keep their meaning; formulas that mix incompatible meanings are stopped with an error instead of producing a wrong number.

  1. RevenueFormulainputTypemoney[ZAR]ResultR 1,200,000
  2. COGSFormulainputTypemoney[ZAR]ResultR 720,000
  3. Gross ProfitFormulaRevenue − COGSTypemoney[ZAR]ResultR 480,000
  4. Gross MarginFormulaGross Profit ÷ RevenueTyperatioResult40.0%
  5. Receivable daysFormulainputTypedaysResult45 days
  6. Revenue + daysFormulaRevenue + Receivable daysTypemoney + daysResult#TYPE_ERRORYou cannot add money to days.
  7. USD + ZARFormulaUS Revenue + RevenueTypeUSD + ZARResult#CURRENCYCurrencies must match.
The first five rows compute normally and keep their financial type. The last two would quietly produce a number in a spreadsheet; FinIR stops them before evaluation.

FinIR ships with money, percentage, ratio, days, quantity, rate, series, scenario, scalar, and boolean types. Money arithmetic requires matching currencies, and adding money to days fails loudly rather than returning a plausible-looking figure.

Compiler and evaluate flow

Before any number is produced, FinIR compiles the model. It first validates the module, checking that every referenced name exists and that the graph has no cycles. It then type-checks each expression using the finance-aware rules above, so a currency mismatch or a money-plus-days formula is caught here, once, rather than at the point of use. Only a model that passes both stages can be evaluated.

Evaluation is target-driven. When you ask for EBITDA, the engine plans the minimal set of nodes that EBITDA depends on, orders them so each dependency is computed before the node that needs it, and hands the arithmetic to a backend. It returns the requested values together with runtime statistics, such as how many nodes were computed and how many were reused from cache, so every result is accompanied by an account of the work done to produce it.

The compiler also defines a set of optional analysis and transformation passes for ahead-of-time compilation: constant folding, common-subexpression elimination, dead-node elimination, dependency pruning, scenario-vectorization analysis, fusion analysis, and cache planning. Running finir compile shows each pass and its effect on the graph. Interactive models keep validation and type checking on every change but retain queryable, human-readable node names so results can always be traced back to the model as written.

Incremental runtime

The runtime maintains a value store and validity set. Changing an input invalidates its downstream cone using precomputed dependents. Evaluation walks needed nodes in dependency order: valid nodes are reused by lookup; invalid nodes are recomputed and marked valid.

Diagram: a 4% change to COGS flows through the dependency graph so Gross Profit, Gross Margin, and EBITDA are recomputed while unrelated nodes such as model config and other metrics are reused
When COGS changes by 4%, only its downstream nodes (Gross Profit, Gross Margin, EBITDA) run again; everything else is served from the value store.

The repository also exposes transient what-if evaluation, state snapshots, and cache-hit metrics.

Evidence and reproducibility

Experiment 001 asks whether dependency-aware caching reduces the cost of iterative financial reasoning. Its 1,000-turn synthetic workload uses a 6-node model and compares a warm FinIR cache with a same-engine baseline whose cache is cleared each turn.

Baseline, full recompute
Time
0.0355s
Recomputes
6,000
Cache hit
0%
FinIR incremental
Time
0.0223s
Recomputes
3,600
Cache hit
40.0%
Log-scale line chart comparing median execution time for full recomputation and FinIR incremental execution across synthetic graphs from 98 to 100,000 nodes
Synthetic dependency-graph benchmark for FinIR v0.1.0. Incremental execution remains below full recomputation across the measured graph sizes; results are benchmark-specific and should not be read as a general production speedup claim.

Observed in this run: 1.59×. This is a synthetic workload, with cheap arithmetic and Python traversal overhead, run in a single CPU process using the same engine and no-cache baseline. It is not a general production speedup claim. Reproduce with python research/reproduce_experiment_001.py in the public repository.

How the execution models compare

The table below compares typical out-of-the-box execution models, not measured runtime speed. Products and custom implementations vary; external tools were not included in Experiment 001.

FinIR

Finance-aware types
Built in
Incremental recomputation
Built in
Dependency graph
Built in
AI execution boundary
Designed for it

Spreadsheets

Finance-aware types
Limited
Incremental recomputation
Common, implementation-dependent
Dependency graph
Implicit cell graph
AI execution boundary
Not by default

Generated Python / SQL

Finance-aware types
Custom code required
Incremental recomputation
Custom code required
Dependency graph
Not by default
AI execution boundary
Generated code executes directly

Generic DAG tools

Finance-aware types
Custom domain layer required
Incremental recomputation
Tool-dependent
Dependency graph
Built in
AI execution boundary
Custom integration required

Limitations and boundaries

FinIR is a compiler target and runtime for financial computation. It is not a dashboard, ERP, trading platform, quant library, or generic DAG engine. This release makes no novelty, first, or breakthrough claim.

Experiment 001 is one synthetic graph and one CPU, with no engine-level parallelism. Experiment 002 does not verify a GPU crossover; its GPU_MIN_ELEMENTS = 250_000 threshold is a heuristic placeholder. The repository describes a CPU-first reference/vectorized backend and an optional CuPy GPU backend; this page does not claim shipping CPU, SIMD, or GPU acceleration beyond that status.

Install and get started

The public package is FinIR 0.1.0, released August 31, 2026. Install the CPU-first package with:

PythonPython 3.10+Terminal
pip install finir
python -c "import finir; print(finir.__version__)"
finir --help
finir doctor

The repository also documents optional gpu and viz extras and editable development installation. The canonical company model and exact .finir syntax are available in the repository’s examples/company_model/model.finir.

References and resources

Primary materials for inspecting the release, reproducing the reported experiment, and working with the public package.

Each link opens the original source in a new tab.