Skip to main content
QWED-Finance uses Neurosymbolic AI - combining neural (LLM) outputs with symbolic (math/logic) verification.

1. Compliance guard (Z3)

Purpose: Verify KYC/AML regulatory decisions using formal boolean logic.

Methods

Since v3.0.0, verify_aml_flag fails closed: country codes must be canonical ISO alpha-2 codes, and malformed, non-finite, or missing amounts are rejected instead of passing.

How Z3 works


2. Calendar guard (day counts)

Purpose: Deterministic day count conventions for interest calculations, computed with exact Decimal arithmetic.

Supported conventions

Other methods: verify_day_count_fraction(), verify_accrued_interest(), verify_business_day(), and get_next_business_day().

3. Derivatives guard (Black-Scholes)

Purpose: Options pricing and margin verification using pure calculus.

Methods

Arbitrary-precision arithmetic

Since the Decimal/mpmath migration: DerivativesGuard uses mpmath (30 decimal places) for all transcendental functions — log, exp, sqrt, and erf — replacing IEEE-754 math.* calls. The standard normal CDF and PDF (_norm_cdf, _norm_pdf) are now exact to 30 dp, and verify_margin_call and verify_put_call_parity compare values in Decimal space.
Breaking change — Greeks are now str, not float. Each Greek is Decimal.quantize()’d and returned as a string to preserve precision across serialization boundaries. Cast explicitly if you need a numeric type:
mpmath is now a runtime dependency. It was already pulled in transitively by sympy, so no extra install step is required.

4. Message guard (XML schema)

Purpose: Validate ISO 20022 and SWIFT messages before transmission.

Supported formats

MessageGuard also provides verify_iban() and verify_bic().

SWIFT MT validation


5. ISOGuard (JSON schema)

Purpose: Enforce ISO 20022 compliance for JSON-based Agentic Banking.

Why JSON vs. XML?

While MessageGuard handles traditional XML SWIFT messages, ISOGuard enables Modern Banking Agents to speak the same standard using lightweight JSON.

6. Query guard (SQLGlot)

Purpose: Prevent SQL injection and unauthorized data access.

Methods

Why AST, not regex?

Queries that SQLGlot cannot parse fail closed with an SQL parse error violation.
Since v3.0.1 (GHSA-q8r4-6gpp-5fx2): queries that contain MySQL /*! ... */ or MariaDB /*M! ... */ executable comments are rejected. MySQL runs the content of these comments, but the parser drops it, so tables and columns inside them could bypass the allow-list and PII checks. This applies to verify_readonly_safety, verify_table_access, verify_column_access, sanitize_query, and CrossGuard.verify_query_with_pii_protection. Ordinary comments and optimizer hints (/*+ ... */) are unaffected.

7. Cross-guard (multi-layer)

Purpose: Combine multiple guards to verify every component.

Methods

CrossGuard is the only guard that issues VerificationReceipt objects directly (in result.receipts). See Compliance and auditing.
Since v3.0.1 (GHSA-mrrj-6m2q-jch9): business rules read IntrBkSttlmAmt values and Ccy attributes from the parsed XML tree (local names, any namespace), not from regex over raw text. Amounts with child nodes, exponents, or grouping separators fail closed as unparseable.Since v3.0.1 (GHSA-mv2c-jwm9-pfrq): sanctions screening folds diacritics and look-alike letters and compares separator-free names, so EV-IL CORP, E.V.I.L. CORP, or ÉVIL CORP no longer clear an EVIL CORP entry. An empty or missing sanctions list fails closed as unscreened.

8. Bond guard (yield analytics)

Purpose: Verify fixed income calculations like Yield to Maturity (YTM) and duration using Newton-Raphson.

Rate format rules

Since v2.1.0: _parse_rate() no longer silently guesses whether an input is a percentage or decimal. The old heuristic (val < 1 → decimal, else percentage) has been removed.
The same explicit-% rule applies to BondGuard._parse_rate() and FinanceVerifier.verify_irr(), so a rate string means the same thing in both.

Exact arithmetic with Decimal

Since the Decimal/mpmath migration: BondGuard runs Newton-Raphson YTM solving and all duration, convexity, and accrued-interest math in Decimal with 50-digit precision (getcontext().prec = 50). Inputs are converted to Decimal at the boundary, eliminating IEEE-754 cancellation in long-dated bond cashflow sums.tolerance_pct is now stored as Decimal. Pass a float or int — the guard converts it via Decimal(str(value)) to avoid float contamination:
verify_ytm, verify_duration, and verify_convexity return computed_value and their details fields as quantized strings (e.g. "5.6617%") instead of raw floats.Other methods: verify_accrued_interest() and verify_dirty_price().

9. FX guard (currency arbitration)

Purpose: Validate cross-currency conversions and detect arbitrage opportunities.
Pass llm_converted as a plain number ("920.00"). A leading currency symbol ($, €, £, ¥) is stripped, but currency codes such as "EUR 920.00" raise decimal.InvalidOperation.

Methods


10. Risk guard (portfolio metrics)

Purpose: Ensure risk metrics like Sharpe Ratio and VaR (Value at Risk) are mathematically consistent.

Exact arithmetic with Decimal

Since the Decimal/mpmath migration: every RiskGuard method computes in Decimal. verify_var and verify_sortino_ratio use Decimal.sqrt() instead of math.sqrt(), and verify_beta accumulates covariance and variance in Decimal to prevent catastrophic cancellation on large return histories.The Z_SCORES lookup table is Decimal-typed:

11. Trading guard (order parameters)

Purpose: Verify order payloads for prediction markets (tick size, price bounds, volume, contract type, side) before they reach an execution API.
Unknown markets fail closed (risk = "UNKNOWN_MARKET"). Prices are exact Decimal values; float prices, non-finite values, and boolean volumes are rejected. Use verify_order_batch() to check a list of orders.
All 11 guards are available via pip install qwed-finance.