Engineering principles for building financial systems

Engineering financial and accounting systems turns out to be less about clever math and more about handling messy real‑world constraints: multiple timelines for a single transaction, inconsistent identifiers, time zones and daylight savings, leap seconds, and ever‑changing regulations. Contributors debate whether to represent money and time with integers, decimal types, or richer domain objects, emphasizing consistent rounding rules, clear precision per asset or currency, and strict separation between commercial events and their accounting entries. Many argue that robust relational databases, strong typing, extensive tests, and carefully designed UIs are as critical as performance, while batch vs. streaming architectures, materiality thresholds, and edge cases like FX devaluations or leap seconds can make or break auditability and trust.

Money representation & rounding

  • Strong focus on avoiding binary floating point for money.
  • Two camps:
    • Use integers as fixed-point units (cents, micros, “1/10,000 of a cent”, crypto-style 128–256-bit ints). Rounding only at system boundaries / UI.
    • Use decimal types (BigDecimal, Decimal) where available; these handle precision and rounding modes natively and map better to domain concepts.
  • Several warn that JavaScript’s Number type is unsafe for regulatory-grade money logic; BigInt or backend-only decimal/int logic is preferred.
  • Some argue arbitrary precision rationals/decimals are fast enough for “normal” accounting, but too slow for high-volume trading.
  • Rounding rules themselves should be explicit, testable domain objects, often country / product specific, with regulators sometimes imposing precision rules.

Time, time zones, and leap seconds

  • Debate over “just use integer timestamps”:
    • Works for past events and controlled offsets (e.g., “48 hours from now”).
    • Fails for future calendar-dependent events (cutoffs, tax year ends, holidays, DST moves, leap seconds, changing time-zone law).
  • Suggested patterns: store UTC plus original timezone (or full zone, not just offset), and sometimes distinguish “observed timestamp” from “future scheduled time”.
  • Leap seconds: most financial systems ignore them, but some markets and regulators have explicitly prepared for leap-second events.

Accounting system semantics: accuracy, consistency, completeness

  • Several argue “consistency” is as important as accuracy.
  • Real systems accept late and out-of-order events; multiple time dimensions (trade requested, filled, booked, settled, etc.) and multiple layered ledgers are standard.
  • Systems must represent temporarily “wrong” or inconsistent states to reconcile later.
  • Materiality is seen as a reporting/audit concept, not a system-design justification; internal records should be exact, even if reports aggregate.

Currency conversion & FX

  • Strong view that systems should not convert currencies “for convenience”; amounts are legally in specific currencies.
  • Conversion should occur only at defined business events (e.g., invoice issue, funds transfer), with explicit FX rates and gains/losses lines.
  • Internal dashboards may use approximate FX averages, but that’s BI, not core accounting.

Identifiers and events

  • Transactions often have many external IDs (per counterparty/system) and multiple timestamps.
  • Recommended: model IDs as one-to-many relations with metadata (issuer, type, validity window) rather than assuming a single canonical ID.

Databases, ACID, and architecture

  • Many advocate using relational databases with decimal types, ACID guarantees, and SQL-based reporting for bookkeeping-scale systems.
  • Others warn that treating an ACID DB as the sole “source of truth” can clash with ledger/event-based accounting, where compensating actions, not rollbacks, are correct.
  • Distinction emphasized between fast trading models vs slower, robust bookkeeping stores.

Batch vs streaming

  • Disagreement with “batch is just a special case of streaming”.
  • Always-on streaming and periodic batch runs have different reliability, performance, and migration constraints, especially when large historical datasets and external APIs are involved.

UI/UX for accounting software

  • Multiple accountants/users complain that mainstream accounting UIs are far worse than paper or spreadsheets.
  • Users frequently export to spreadsheets despite custom UIs.
  • Desire for interfaces that surface double-entry structure more transparently and match real workflows.

Testing and auditability

  • Heavy testing is considered crucial, but tests themselves become audit artifacts.
  • Refactors may require a “write-then-solve” approach to keep tests and historical expectations explainable to auditors.