Skip to main content
Concepts
DraftLast reviewed 2026-06-24

End-of-day

End-of-day in OpenTRMS is not a single batch job with internal steps hidden from view — it's an explicit, ordered sequence of API calls orchestrated by trms-batch, each one independently idempotent. Trigger a run from /api/v1/batch/eod/trigger and track it at /api/v1/batch/eod/status/{date}; under the hood, the orchestrator walks through fixings, curve construction, cashflow evaluation, portfolio valuation, closeout, netting, margin, compliance, journal posting, and (when applicable) period close, finishing with a system audit event marking EOD complete for that date.

Why the order matters

Each step depends on the output of the one before it: curves need the day's fixings; valuation needs curves; closeout needs valuations to compute realized P&L on a match (see Closeout & compression); netting needs to know which settlements survived closeout; journal entries need the day's valuations and closeout P&L to post against (see Accounting); period-close needs every entry posted first. Running these out of order, or in parallel where the pipeline assumes sequence, would mean later steps consuming stale or partial inputs — so the orchestrator runs them as a strict sequence rather than a fan-out.

Reproducibility

Every input EOD consumes — fixings, curves, market data, the deal book at that point in time — is itself recorded in the event store. Re-running EOD for a historical date against the same recorded inputs reproduces the same valuations, the same closeout matches, and the same journal entries, because nothing EOD touches is mutable state that could have silently drifted since the original run. This is what makes it credible to say "rerun yesterday's EOD" as an operational answer to a discrepancy, rather than something to be feared as non-deterministic.

Idempotency and concurrency control

Each of the eleven steps is individually idempotent — re-running POST /portfolio/valuate for a date that already has valuations doesn't double-post them. An advisory lock prevents two EOD runs for overlapping scope from executing concurrently, which matters because the steps are stateful and sequential by design; a second run racing the first would violate the ordering guarantee the whole pipeline depends on. Two supporting scheduled jobs run independently of the EOD pipeline itself: an approval timeout checker every 15 minutes (see Approval chains) and an instruction expiry checker hourly — both keep moving even between EOD runs.

Sign-off

The final visible state of an EOD run is its status, queryable per date, and the system audit event that marks completion. Because every step along the way appended its own events — fixings recorded, curves published, valuations calculated, closeout batches matched, netting sets calculated — sign-off isn't a single opaque "EOD: PASS" flag; it's a chain of evidence a reviewer can walk through step by step. See the operate-eod guide for triggering and monitoring a run in practice.