Open source

The trading and risk platform you can own, audit, and extend.

OpenTRMS runs the full trade lifecycle for FX, money markets, derivatives and fixed income — with an immutable audit trail and an AI control room your operations team can actually trust. Self-hosted. No license metering. No black box.

Open sourceSelf-hostedAudit-ready by designAI-native ops

Built on Java 21 · Spring Boot · PostgreSQL · Spring AI + MCP

Live · Rates desk
EOD T−1 · 17:00 NY
USD swap curve
Projection · today
4.12%
+3.2 bp
4.80%4.35%3.90% 1M2Y10Y30Y
P&L · 30D
+1.42%
Open trades
1,284
+47 today
CurrencyPVDV01
USD +12.4M −18,420
EUR +8.1M −9,205
GBP −2.7M +3,140
JPY +1.9M −2,015
Multi-asset coverage

One ledger for everything your treasury actually trades.

Most "modern" platforms cover a slice and silently push the rest into spreadsheets. OpenTRMS books FX, money markets, fixed income and derivatives against the same event store — so positions, P&L and exposure stay consistent without nightly stitching.

One position model. One P&L. One audit trail. No more end-of-day stitching between siloed systems.

The complete deal lifecycle

Follow one trade from capture to closeout.

A trading platform isn't a feature list — it's the path a deal walks every day. Here is that path on OpenTRMS, told from the seat of the person who actually does the work.

  1. 01

    Captured

    Front office

    A trader books a 5Y USD interest-rate swap with ABC Bank. One screen, one click — or one sentence to the AI desk assistant.

  2. 02

    Validated

    STP engine

    Limits, counterparty, product schema and credit checks run in milliseconds. Eligible trades flow through; exceptions stop and explain themselves.

  3. 03

    Approved

    Middle office

    A scoped approval chain routes the trade to the right desk head. No self-approval, no shortcuts — every signature is recorded as an event.

  4. 04

    Confirmed

    Operations

    Confirmation flows out, the deal is locked, and the position updates on the trader's blotter and the risk desk's exposure view at the same time.

  5. 05

    Settled

    Treasury / settlements

    Netting collapses cashflows by counterparty and currency. Payment messages (MT103/MT202) are generated and dispatched on schedule.

  6. 06

    Accrued & valued

    Finance / risk

    End-of-day rebuilds curves, accrues interest, marks the book to market and posts journals — every step is an event you can replay.

  7. 07

    Closed out

    Back office

    At maturity or termination, rule-driven matching offsets positions and the deal walks cleanly off the book — with the full history intact.

Behind every state change: a typed event, an immutable hash, an authorised user, a correlation id. Reconstructing what happened on any day, for any deal, is a query — not an investigation.

Audit trail as system of record

Your audit trail isn't a report. It's the platform.

Most TRMS vendors bolt audit tables onto a CRUD database and hope. OpenTRMS is event-sourced from the first commit — the history of every deal is the deal. Audit, control and risk teams get the answer they actually want: a single, attributed, replayable timeline.

  • Nothing is overwritten — ever.

    Every state change appends a new event. The history of a deal is the deal. Auditors stop asking "show me the change log" because the change log is all there is.

  • Tampering breaks the chain, visibly.

    Every event is hashed and linked to the previous one. Insert, delete or modify any record and the chain refuses to reconcile — no quiet edits, no "lost" rows.

  • Immutability enforced by the database, not by trust.

    UPDATE and DELETE on the event table are revoked at the PostgreSQL level. Application bugs cannot rewrite history. Neither can a misbehaving DBA.

  • Every action is attributed.

    User, scope, correlation id and timestamp are part of the event. "Who approved this?" is a one-line query, not a forensics project.

  • Replay any day, on demand.

    Rebuild the book as it stood at any point in time. Reconcile to a regulator, run a what-if, or unblock a dispute — without freezing production.

A live hash chain

Event #1 DealCaptured
hash a7f3c91d…e2b10f84
prev 00000000…00000000
SHA-256
Event #2 STPPassed
hash 3d82b47e…f4a96c51
prev a7f3c91d…e2b10f84
SHA-256
Event #3 DealConfirmed
hash 9bc14a2f…d3e70862
prev 3d82b47e…f4a96c51
SHA-256
Event #4 DealValuated
hash e5f0d839…a8c21b73
prev 9bc14a2f…d3e70862
AI-native operations

An operations control room that never sleeps — and never lies about what it did.

The boring half of trade ops — chasing breaks, pulling confirmations, summarising P&L moves — is exactly the work an agent should own. OpenTRMS gives your team agents that act through the same controls a human does, leave the same audit trail, and stop the moment they hit a limit.

  • Agents that go through your controls, not around them.

    Every agent calls the same domain services as the REST API. Same scopes. Same approval chains. An agent cannot do anything a user with its scope couldn't do.

  • Human-in-the-loop where it matters.

    The agent proposes; the human approves. Material actions never auto-execute, and every proposal is recorded as an event — including the one you rejected.

  • Plug into your AI stack, not ours.

    Built-in MCP server: any MCP-compatible client (Claude, internal agents, Copilot-style IDEs) talks to OpenTRMS out of the box. No bespoke connectors, no proprietary protocol.

  • Your data stays where it is.

    Self-hosted. Bring your own model. The agent runtime sits next to your event store — not in a vendor cloud you don't control.

opentrms · ops control room

$ opentrms ops review --book G10-RATES

› Anything I should look at before EOD?

Agent:

3 trades exceed the +/-2σ price band on the desk:

#45215Y USD IRS · ABC Bank · +3.1σ

#45442Y EUR IRS · DEF Sarl · −2.4σ

#456110Y GBP IRS · GHI plc · +2.8σ

Flag for review? [Y/n] Y

3 deals routed to Head of Rates

Events appended · correlation b3f9e1

$

End-of-day you can trust

Closing the day shouldn't be a leap of faith.

EOD is where most TRMS deployments quietly fall apart — partial runs, mystery breaks, finance and risk arguing over whose number is right. OpenTRMS runs EOD as a sequence of attributable events, each one reproducible from the same audit trail your auditors will read.

Curve projection
USD 3M · today vs T−1
+3.2 bp
▲ steepened
1M1Y5Y10Y30Y
today T−1
01

Cut-off

Cut-off lands and the desks stop booking. The system snapshots the book at a single, attributable point in time — no "as of when?" arguments at 7am.

02

Curves & rates

Fixings come in. Discount and projection curves rebuild from the snapshot, not last night's leftovers. Every input is recorded; every output is reproducible.

03

Accruals

Interest accrues on every open position. Finance gets numbers they can tie back to specific trades and specific days — not aggregate fudge.

04

Mark-to-market

The whole portfolio is valued: IRS, FX, bonds, options. Greeks, DV01, PV01 fall out of the same model your trading desk used yesterday.

05

Journals & margin

Posting rules turn valuations into journal entries; margin is calculated against the same numbers. Finance and risk see the same truth.

06

Settlements

Cashflows are netted by counterparty and currency. Payment messages are produced and queued, ready for SWIFT or your bank rails.

07

Sign-off

Every step is an event. Skipped, retried, late? You can see it. The next morning's reg report is pulled from the same trail, not retyped.

One trail from cut-off to sign-off. If something needs to be re-run, it's a replay — not a rebuild.

Read the source. Audit the logic.

A trading platform you can read end to end.

For your CISO, your audit committee, and the architect who has to live with this for a decade: the entire codebase is open source. There is no escrow, no "trust the vendor", no surprise re-licensing. The logic that prices your book is the logic in this repository.

DealStatus.java View on GitHub

Sealed Deal Lifecycle — 11 States, Compiler-Enforced

DealStatus is a sealed interface with one record per state. The compiler enforces exhaustive pattern-matching — no forgotten cases, no stringly-typed strings leaking into business logic.

public sealed interface DealStatus
        permits DealStatus.Draft, DealStatus.PendingReview, DealStatus.Confirmed,
                DealStatus.Settling, DealStatus.Settled, DealStatus.Accounted,
                DealStatus.Matured, DealStatus.Terminated, DealStatus.Rejected,
                DealStatus.Cancelled, DealStatus.ClosedOut {

    String value();

    static DealStatus fromString(String s) {
        return switch (s) {
            case "draft"          -> new Draft();
            case "pending_review" -> new PendingReview();
            case "confirmed"      -> new Confirmed();
            case "settling"       -> new Settling();
            case "settled"        -> new Settled();
            case "accounted"      -> new Accounted();
            case "matured"        -> new Matured();
            case "terminated"     -> new Terminated();
            case "rejected"       -> new Rejected();
            case "cancelled"      -> new Cancelled();
            case "closed_out"     -> new ClosedOut();
            default               -> throw new IllegalArgumentException("Unknown DealStatus: " + s);
        };
    }

    record Draft()        implements DealStatus { public String value() { return "draft"; } }
    record PendingReview() implements DealStatus { public String value() { return "pending_review"; } }
    record Confirmed()    implements DealStatus { public String value() { return "confirmed"; } }
    // ... 8 more states
}
DealAgent.java View on GitHub

AI Deal Agent — Natural Language Trade Capture

A Spring AI ChatClient agent that implements human-in-the-loop deal capture: gather terms, preview before booking, confirm before executing. Pure Java — no Python orchestration.

var(--wb-warning);">@Component
public class DealAgent {

    static final String SYSTEM_PROMPT = """
            You are a deal capture assistant for a Trading and Risk Management System.
            You help traders book financial deals. When capturing a deal, always show a preview first
            and ask for confirmation before executing. Available product types: swap, spot, forward,
            option, repo, deposit. Asset classes: rates, fx, credit, equity, money_market.

            Workflow for deal capture:
            1. Gather all required information from the user.
            2. Call captureDeal to generate a preview and confirmation token.
            3. Show the preview to the user and ask: "Shall I proceed with booking this deal?"
            4. Only call confirmCaptureDeal if the user explicitly confirms.
            """;

    public String chat(String userMessage) {
        return chatClient.prompt()
                .system(SYSTEM_PROMPT)
                .user(userMessage)
                .call()
                .content();
    }
}
HashChainService.java View on GitHub

SHA-256 Hash Chain — Tamper-Evident Event History

Every event in the store is chained to its predecessor via SHA-256. Replaying the chain and comparing hashes reveals any insertion, deletion, or modification — making audit trail falsification cryptographically detectable.

var(--wb-warning);">@Component
public class HashChainService {

    public static final String GENESIS_HASH =
            "0000000000000000000000000000000000000000000000000000000000000000";

    /** Computes SHA-256( previousHash + canonicalJson(payload) ) */
    public String computeHash(String previousHash, Object payload) {
        var canonical = canonicalJson(payload);
        var input = (previousHash + canonical).getBytes(StandardCharsets.UTF_8);
        return sha256Hex(input);
    }

    /** Verifies an entire ordered chain — returns broken position on tampering. */
    public HashVerificationResult verifyChain(List<Event> events) {
        var previousHash = GENESIS_HASH;
        for (int i = 0; i < events.size(); i++) {
            var event = events.get(i);
            var expectedHash = computeHash(previousHash, event.payload());
            if (!expectedHash.equals(event.hash())) {
                return HashVerificationResult.broken(i, event.version(), expectedHash, event.hash());
            }
            previousHash = event.hash();
        }
        return HashVerificationResult.ok(events.size());
    }
}
From repo to first trade

A pilot you can stand up in an afternoon.

No multi-month implementation project, no rooms full of consultants. Clone the repository, bring up the stack with Docker, and book your first trade against a real PostgreSQL ledger.

bash
$ git clone https://github.com/ichagas/OpenTRMS
$ cd opentrms && docker compose up -d
$ mvn -pl trms-api spring-boot:run
Started TrmsApplication in 4.2s
API explorer → http://localhost:8080/docs
First trade booked · audit trail live
API explorer Swagger UI at /docs
Versioned schema Flyway, forward-only
Executable specs Cucumber BDD suite
Self-hosted Open source · your VPC

Ready to replace your multi-million dollar trading system?

Walk us through your book. We'll walk you through how OpenTRMS would run it — on your infrastructure, against your controls, with your team.

Open source · No license metering · Enterprise support available