Deterministic. Auditable. Global.
Designed for explainable processing in regulated environments.
FinLang is a domain-specific language (DSL) and vectorised CLI engine for financial transaction processing.
It replaces opaque machine-learning categorization with transparent, deterministic rules β delivering explainability, auditability, and global compatibility.
Built for audit-friendly logic and deterministic processing.
A deterministic alternative where explainability and reproducibility matter.
FinLang is a deterministic rules engine for financial transaction categorisation.
It is especially useful as a challenge layer alongside ML categorisers: the --reconcile workflow compares FinLang's rule-attributed output against an external classification, row by row.
Same input + same rules = reproducible output, with rule-attributed audit trails.
The v0.7.9 FastAPI wrapper makes the same engine reachable over a self-hosted HTTP surface for service/integration workflows.
Three surfaces. One engine:
- CLI for batch processing
- Python workflows via subprocess-isolated CLI execution
- Self-hosted HTTP wrapper via
finlang-api
FinLang rules are human-readable, Git-friendly, and designed for precision.
The engine processes rules top-to-bottom; the last matching rule sets the category, while flags accumulate.
# Example: Basic categorization and flagging
rule "GROCERIES: Tesco" {
match:
- counterparty ~ "*TESCO*"
set:
- category = "Groceries"
- flags += "Supermarket"
}
# Example: Numeric range and exact match
rule "TRAVEL: High Value Flight" {
match:
- counterparty == "BRITISH AIRWAYS"
- amount in -5000.00 .. -500.00
set:
- category = "Travel"
- flags += "HighValue"
}
| Feature | Description |
|---|---|
| Deterministic DSL | Human-readable .fin rules language β explainable logic, Git-friendly. |
| Vectorised Engine | Vectorised core (Pandas + NumPy + PyArrow) β ~217K rows/sec FastIO validated throughput on the integrity harness (20M Γ 6 cols). |
| Dual Backend | Standard (Engine: c) or FastIO (Engine: pyarrow) with automatic fallback. |
| Growth Loop | Automated Discover β Suggest β Categorize workflow β 97.8% average coverage gain across 5 validation runs (source). |
| Global I18n Support | US/UK/EU/Commonwealth formats, Β£ β¬ $ Β₯ βΉ stripping, localized decimals/dates/delimiters. |
| Audit Trail System | Every decision logged (before/after state diffs); stateless for reproducibility. |
| Exclude Marker | Boolean exclude column β rule-driven, auditable, supports blacklist/whitelist exception patterns. |
| CR/DR Semantics | Case-insensitive CR/DR (with or without space), accounting negatives (123.45), trailing minus 123.45-. v0.7.7 fixes a latent bug on no-space CR/DR formats. |
| Amount Synthesis | Auto-computes amount = abs(credit) β abs(debit) across 9 edge cases. |
| Strict Parsing | Locale-aware normalization with configurable thresholds (--strict-parse). |
| Flag Integrity | Append-only (flags +=) with deterministic deduplication. |
| Integrity Verification | Built-in --verify and --verify-full β SHA-256 fingerprinting of immutable fields with optional artifact output; --verify-html (v0.8.3) can render a self-contained plain-English report. See docs/verify.md. |
| ML Reconciliation (v0.7.8) | --reconcile produces a row-by-row mismatch report against an external (typically ML) categorisation, with rule attribution and audit reason. Optional self-contained HTML report via --reconcile-html; the ML side's date convention is inferred from the data (or stated via --reconcile-date-format, v0.8.3) and recorded in the report. See docs/reconciliation.md. |
| FastAPI Wrapper (v0.7.9) | pip install finlang[api] adds a self-hosted HTTP surface (finlang-api) over the same CLI engine β seven endpoints incl. /process, /reconcile, /impact, /discover, /suggest. Subprocess-dispatched (no second engine surface). 29 standalone integration tests + CLI/API parity contract test. See docs/api.md. |
Requirements: Python 3.10β3.14
From PyPI (Recommended):
pip install finlangWith Fast I/O (PyArrow):
pip install "finlang[fastio]"(Enables --fastio for accelerated CSV I/O.)
With HTTP API wrapper:
pip install "finlang[api]"
finlang-api # binds 127.0.0.1:8000 β interactive docs at /docs(Thin FastAPI wrapper over the CLI for HTTP-based integration and demos. See docs/api.md.)
From Source (Development):
git clone https://github.com/FinLang-Ltd/finlang.git
cd finlang
pip install -e .[fastio]1οΈβ£ Initial Categorization
finlang --input transactions.csv --output baseline.csv \
--rules my_rules.fin --include-pack retail,transport2οΈβ£ Discover Gaps
finlang-discover --input baseline.csv \
--candidates candidates.csv --all-candidates all_candidates.csv \
--min-count 53οΈβ£ Suggest Rules (Exact Mode Recommended)
finlang-suggest --input candidates.csv --output suggested_rules.fin \
--rules my_rules.fin --emit-match exact4οΈβ£ Merge and Re-run
cat my_rules.fin suggested_rules.fin > merged.fin
finlang --input transactions.csv --output improved.csv \
--rules merged.fin --include-pack retail,transportβ
Expected Result: 5β10% coverage improvement; zero duplicates in exact mode.
Measured with --audit-mode none (max throughput) on Intel i7-12700T, 48GB RAM, Windows 11, Python 3.13.7, PyArrow 21.0.
| Dataset | Test | Time (s) | Rows/sec | Notes |
|---|---|---|---|---|
| 100K (UK Synthetic) | Growth Loop | 2.54 | 39,370 β | Baseline (121 rules) |
| 100K (after Growth Loop) | Growth Loop | 4.96 | 20,161 β | +6.3Γ rules β β 2Γ slower (764 rules) |
| 5M Γ 50 cols | Benchmark Harness | 179.27 | 27,900 β | Enterprise validation, 3-run average |
| 20M Γ 6 cols | Integrity Test (FastIO) | ~90 | 217,068 β | Engine throughput, full SHA-256 verified |
v0.7.7 improvement: Hot-path bug fix in
_to_numberremoved an unnecessary\bword boundary that was both producing wrong results on no-space CR/DR formats AND costing measurable runtime. The fix delivered +30-50% throughput on the integrity harness vs v0.7.6, taking standard mode to ~180K rows/sec and FastIO to ~217K rows/sec.Cumulative v0.6.4 β v0.7.7: -14% runtime, +16% throughput on the enterprise harness (5M Γ 50).
Audit Overhead: Enabling
--audit-mode lite/fullreduces throughput by β38% due to diff calculation; provides full decision provenance.Note: These figures are validated benchmark results from controlled tests. Actual performance varies depending on dataset, ruleset, and audit mode.
Seedocs/benchmarks.mdfor full details.
SHA-256 fingerprint verification benchmarked on large datasets:
| Rows | Engine (Standard) | Engine (FastIO) | Result |
|---|---|---|---|
| 5M | 178,903 rows/s | 198,448 rows/s | β All fingerprints match |
| 10M | 178,511 rows/s | 214,136 rows/s | β All fingerprints match |
| 20M | 181,566 rows/s | 217,068 rows/s | β All fingerprints match |
What this benchmark validated: Every row's immutable fields (
date,amount,counterparty) were verified via SHA-256 hash before and after engine processing. Zero cross-row contamination detected. Zero data corruption detected. 60M rows verified field-by-field across three runs, zero mismatches.Note: As of v0.7.7, SHA-256 integrity verification is available as a CLI feature via
--verify(fast fingerprint) and--verify-full(fingerprint + field comparison). Use--verify-output-dirto save audit artifacts (JSON report + proof CSV). Seedocs/cli_reference.mdfor details.
| Region | Example Number | Date Order | CLI Flags |
|---|---|---|---|
| πΊπΈ US / π¨π¦ Canada | 1,234.56 | MM/DD | (defaults) |
| π¬π§ UK / π¦πΊ Commonwealth | 1,234.56 | DD/MM | --dayfirst |
| πͺπΊ Continental Europe | 1.234,56 | DD/MM | --decimal "," --thousands "." --dayfirst |
| π¨π Switzerland | 1'234.56 | DD/MM | --thousands "'" --dayfirst |
Auto-Detection and Normalization: BOM-safe UTF-8 encodings, , ; | \t delimiters, and automatic currency symbol stripping.
Discover β Suggest β Categorize β Repeat
FinLang's Growth Loop accelerates rule creation through data-driven discovery.
- Discover uncategorized counterparties
- Suggest new rules in seconds (1:1 mapping in exact mode)
- Merge + Re-run for incremental coverage gains
- Validated Result: 97.8% average coverage gain across 5 runs (source)
π See: docs/growth_loop_best_practices.md
β οΈ --emit-match fuzzy(default) filters corporate stopwords (LTD, LLC, PLC, INC, GROUP, COMPANY, CO, SAS, GMBH, CORP) and deduplicates patterns within a batch (v0.7.7). Edge cases with very short counterparty names may still produce broad patterns. β Use--emit-match exactfor production workflows.β οΈ Hyphenated/apostrophe names may affect fuzzy matching (< 1% impact).β οΈ No support for non-Gregorian calendars or non-Western numerals.
docs/release_notes/v0_7_9.mdβ FastAPI wrapper (finlang-api), three surfaces / one enginedocs/release_notes/v0_7_8.mddocs/release_notes/v0_7_7.mddocs/release_notes/v0_7_6.mddocs/reconciliation.mdβ--reconcileML validation layer (v0.7.8)docs/verify.mdβ--verifyintegrity verificationdocs/api.mdβ FastAPI wrapper (pip install finlang[api],finlang-api)docs/api_reference.mdβ full API endpoint referencedocs/runtime_contract.mddocs/cli_reference.mddocs/rulepacks.mddocs/benchmarks.mddocs/growth_loop_best_practices.mddocs/amount_synthesis.mddocs/i18n_examples.mddocs/stateless_processing.md
Command-line help:
finlang --help
finlang-discover --help
finlang-suggest --helpfinlang --input bank.csv --output categorized.csv \
--rules examples/rules.demo.fin \
--include-pack retail,transport,subs \
--fastio --audit audit_log.json --audit-mode liteFinLang is open source under the GNU Affero General Public License (AGPL-3.0).
Commercial licenses and enterprise support are available via FinLang Ltd.
π§ info@finlang.io
π https://finlang.io
Contributions are welcome! Before submitting a PR, please review and accept our Contributor Licence Agreement (CLA).
| Component | Version | Validation |
|---|---|---|
| Core Engine | v0.8.3 | Hardening: FINLANG_AUDIT_MAX/audit_max validation; categorisation output unchanged |
| CLI Suite | v0.8.3 | 204 tests across 10 gates (daily); 7-gate full pre-release suite |
| FastAPI Wrapper | v0.8.3 | 29 standalone integration tests + CLI/API parity contract test |
| Discover/Suggest | v0.8.2 | 97.8% average coverage gain across 5 validation runs |
| Integrity Test | v0.8.2 | 20M rows verified field-by-field, ~227K rows/sec FastIO on the integrity harness (re-validated 20 Jul 2026) |
| Verify | v0.8.3 | --verify / --verify-full / --verify-html (SHA-256 fingerprint + field comparison + readable report), vectorised β ~570s β ~15s on the 500K full-mode benchmark |
| Reconcile | v0.8.3 | --reconcile / --reconcile-html / --reconcile-date-format (row-by-row mismatch + audit reason; ML date convention inferred and recorded) |
| Cleanroom | v0.8.3 | 5-gate disposable-venv PyPI validation (incl. API surface) |
| CI | v0.8.3 | GitHub Actions matrix: Python 3.10 / 3.11 / 3.12 / 3.13 / 3.14 |
| Docs | v0.8.3 | Coverage across CLI, rule language, API, reconcile, verify, i18n, growth loop |
| Python Support | 3.10β3.14 | Tested across all five versions via CI matrix |