> ## Documentation Index
> Fetch the complete documentation index at: https://finance.qwedai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# QWED Finance: deterministic verification for financial AI

> QWED Finance uses deterministic verification, SymPy, and Z3 to prevent hallucinations in financial AI, agent workflows, and transaction calculations.

**Deterministic verification for financial AI (v3.0.1).**

> When an LLM told a customer his Chase card had "\$12,889" in rewards, QWED-Finance would have caught the hallucination before it caused a lawsuit.

QWED Finance is a guardrail library that prevents financial hallucinations in LLMs. It combines LLM translation with deterministic solvers (SymPy, Z3, mpmath) and standard financial algorithms.

**New in v3.0.1: security fixes.**

* ISO 20022 business rules read amounts and currencies from the parsed XML tree, not from raw text ([GHSA-mrrj-6m2q-jch9](https://github.com/QWED-AI/qwed-finance/security/advisories/GHSA-mrrj-6m2q-jch9))
* Sanctions screening folds diacritics and look-alike letters and compares separator-free names, so `E.V.I.L. CORP` or `ÉVIL CORP` no longer clears an `EVIL CORP` entry ([GHSA-mv2c-jwm9-pfrq](https://github.com/QWED-AI/qwed-finance/security/advisories/GHSA-mv2c-jwm9-pfrq))
* `QueryGuard` rejects MySQL `/*! ... */` and MariaDB `/*M! ... */` executable comments ([GHSA-q8r4-6gpp-5fx2](https://github.com/QWED-AI/qwed-finance/security/advisories/GHSA-q8r4-6gpp-5fx2))

**v3.0.0 highlights:** keyed HMAC receipt signatures (`get_signature(key)`), ISO amount and currency limits in receipts and UCP, a fail-closed batch for AML, sanctions, amounts, and message validation, and a breaking change to the npm bridge (stdin JSON with runtime validation). See the [changelog](https://github.com/QWED-AI/qwed-finance/blob/main/CHANGELOG.md) for details.

## Why QWED Finance?

LLMs struggle with basic math and strict logic. In finance, close enough is not good enough.

* **Problem:** LLM says "IRR is 12%" (when it's actually 11.8%)
* **Solution:** QWED calculates the *exact* IRR symbolically and either validates or corrects the LLM.

## Key features

* **11 specialized guards:** Compliance, Calendar, Derivatives, Messages, Query, Cross, Bond, FX, Risk, ISO, Trading.
* **GitHub Action:** CI/CD verifier with optional SARIF output for security dashboards.
* **Audit trails:** Verification receipts for cross-guard and integration flows. Receipts are unsigned by default: call `get_signature(key)` and store the returned HMAC-SHA256 signature separately to get a tamper-evident record.
* **Deterministic verification:** When deterministic engines apply, results are exact rather than probabilistic.

## The 4 pillars of banking verification

| Pillar | Guard | Engine | Use case |
| - | - | - | - |
| **Calculation** | Finance + Calendar + Derivatives + Bond + FX + Risk | SymPy, `Decimal`, mpmath | NPV, IRR, day counts, options pricing, YTM, VaR |
| **Regulation** | Compliance | Z3 | KYC/AML, OFAC sanctions |
| **Interoperability** | Message | XML Schema | ISO 20022, SWIFT MT |
| **Data safety** | Query | SQLGlot | SQL injection prevention |

## Quick example

```python theme={null}
from qwed_finance import ComplianceGuard

guard = ComplianceGuard()

# Verify AML flagging decision
result = guard.verify_aml_flag(
    amount=15000,        # Over $10k threshold
    country_code="US",
    llm_flagged=True     # LLM flagged it
)

print(result.compliant)  # True ✅
print(result.proof)      # "Z3: LLM decision matches regulatory requirement"
```

## Architecture

### High-level flow

```mermaid theme={null}
flowchart TB
    subgraph Agent["🤖 Banking Agent"]
        LLM["LLM (GPT-4, Claude)"]
    end
    
    subgraph QWED["🛡️ QWED-Finance v3.0.1"]
        direction TB
        subgraph Guards["Verification Guards"]
            CG["Compliance Guard<br/>(Z3 Logic)"]
            CAL["Calendar Guard<br/>(Decimal day counts)"]
            DG["Derivatives Guard<br/>(Black-Scholes)"]
            MG["Message Guard<br/>(XML Schema)"]
            QG["Query Guard<br/>(SQLGlot AST)"]
        end
        XG["Cross-Guard<br/>(Multi-layer)"]
        Receipt["📋 Verification Receipt<br/>SHA-256 + Timestamp"]
    end
    
    subgraph Output["✅ Verified Output"]
        Bank["Banking System"]
        SWIFT["SWIFT Network"]
        DB["Database"]
    end
    
    LLM -->|"Tool Call"| Guards
    Guards --> XG
    XG --> Receipt
    Receipt -->|"Approved"| Output
    Receipt -->|"Rejected"| LLM
```

### Guard selection flow

```mermaid theme={null}
flowchart LR
    Input["LLM Output"] --> Detect{"Detect Type"}
    
    Detect -->|"$$ Amount"| CG["Compliance Guard"]
    Detect -->|"Date/Time"| CAL["Calendar Guard"]
    Detect -->|"Option Price"| DG["Derivatives Guard"]
    Detect -->|"XML/SWIFT"| MG["Message Guard"]
    Detect -->|"SQL Query"| QG["Query Guard"]
    
    CG --> Result["Verified ✓ / Rejected ✗"]
    CAL --> Result
    DG --> Result
    MG --> Result
    QG --> Result
```

### Verification engine stack

```mermaid theme={null}
graph TB
    subgraph "QWED-Finance"
        subgraph "Layer 1: Guards"
            G1["Compliance"] 
            G2["Calendar"]
            G3["Derivatives"]
            G4["Message"]
            G5["Query"]
        end
        
        subgraph "Layer 2: Engines"
            E1["🔬 Z3 SMT Solver"]
            E2["📐 Decimal Day-Count Arithmetic"]
            E3["📊 Black-Scholes Calculus"]
            E4["📄 XML Schema Validation"]
            E5["🗃️ SQLGlot AST Parser"]
        end
        
        subgraph "Layer 3: Audit"
            A1["Verification Receipt<br/>(CrossGuard, UCP, Open Responses)"]
            A2["Audit Log"]
        end
    end
    
    G1 --> E1
    G2 --> E2
    G3 --> E3
    G4 --> E4
    G5 --> E5
    
    E1 --> A1
    E2 --> A1
    E3 --> A1
    E4 --> A1
    E5 --> A1
    A1 --> A2
```

### Payment verification sequence

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Agent as Banking Agent
    participant QWED as QWED-Finance
    participant Bank as Bank API
    
    User->>Agent: "Transfer $15,000 to John"
    Agent->>QWED: verify_payment_token()
    
    Note over QWED: Check 1: Amount limits
    Note over QWED: Check 2: AML threshold ($10k)
    Note over QWED: Check 3: KYC status
    Note over QWED: Check 4: Sanctions screening
    
    alt All checks pass
        QWED-->>Agent: ✅ Approved + Receipt
        Agent->>Bank: Execute transfer
        Bank-->>User: Transfer complete
    else AML flag required
        QWED-->>Agent: ⚠️ Pending Review
        Agent-->>User: "Flagged for compliance review"
    else Sanctions hit
        QWED-->>Agent: ❌ Blocked
        Agent-->>User: "Transaction blocked"
    end
```

## Why not just trust the LLM?

LLMs are **probabilistic**. They can:

* Hallucinate numbers ($12,889 instead of $2.88)
* Miss compliance thresholds (CTR at \$10,000.01)
* Generate malformed XML (rejected by SWIFT)
* Create dangerous SQL (DROP TABLE)

QWED-Finance uses **deterministic** verification:

| LLM output | QWED verification | Engine |
| - | - | - |
| "NPV is \$180.42" | SymPy recalculates | Math |
| "Transaction is compliant" | Z3 checks threshold | Logic |
| "Payment XML is valid" | Schema validation | Structure |
| "SELECT \* FROM users" | AST analysis | SQL |

## Regulatory alignment

QWED-Finance aligns with:

* **RBI FREE-AI Framework** (India 2025)
* **BSA/FinCEN** (AML/CTR thresholds)
* **OFAC** (Sanctions screening)
* **ISO 20022** (Payment messaging)

> "Accuracy alone is not sufficient - transparency, auditability, and defensible decision logic are required." — India AI Governance Guidelines

## FinanceVerifier: fail-closed inputs

`FinanceVerifier` rejects ambiguous or unknown inputs instead of silently falling back to a default. In finance, a wrong answer with no error signal is worse than a loud failure.

### `verify_compound_interest` — accepted compounding frequencies

<Warning>
  **Since N-04 fix:** `verify_compound_interest()` raises `ValueError` for unknown compounding frequencies. Previously, unknown values (for example `"weekly"` or `"continuous"`) silently defaulted to **annual** compounding, producing wrong results with no indication of failure.
</Warning>

Accepted values for the `compounding` argument:

| Value | Periods per year |
| - | - |
| `annual` | 1 |
| `semi-annual` | 2 |
| `quarterly` | 4 |
| `monthly` | 12 |
| `daily` | 365 |

```python theme={null}
from qwed_finance import FinanceVerifier

verifier = FinanceVerifier()

# ✅ Valid frequency
result = verifier.verify_compound_interest(
    principal=10000,
    rate=0.05,
    periods=10,
    compounding="monthly",
    llm_output="$16,470.09",
)

# ❌ Unknown frequency — fail-closed
verifier.verify_compound_interest(
    principal=10000,
    rate=0.05,
    periods=10,
    compounding="weekly",  # not supported
    llm_output="$16,470.09",
)
# raises ValueError:
#   Unknown compounding frequency: 'weekly'.
#   Accepted values: annual, daily, monthly, quarterly, semi-annual
```

If you need a frequency outside this list, compute the equivalent rate yourself and pass one of the supported values, or use a guard that explicitly models continuous compounding.

## Next steps

* [The 11 guards](/finance/guards) - Deep dive into each verification guard
* [Compliance and auditing](/finance/compliance) - Receipts and regulatory proof
* [QWED UCP: transaction verification for AI commerce](https://docs.qwedai.com/ucp/overview) - Connect finance verification to commerce transactions
* [QWED Open Responses: verified tool calls for AI agents](https://docs.qwedai.com/open-responses/overview) - Verify finance-related agent actions before execution


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.