Tessera RiskA pre-trade risk gateway
A reference architecture that validates every order against size, position, price-band and rate limits before routing, with state rebuildable from an event log. Exercised against an exchange simulator.
- Discipline
- Financial Infrastructure
- Technologies
- Rust · Event sourcing · PostgreSQL · Simulator
- Demonstrates
- Pre-trade risk
- Event-sourced, auditable state
- Deterministic replay
- Fail-safe behavior
The challenge
- 01
The check must sit on every order's critical path without becoming the bottleneck.
- 02
Every decision (accept or reject) must be explainable later, with the exact state at that moment.
- 03
If market data goes stale, price bands become meaningless and the system must react.
Constraints
- Predictable latency
- Complete audit trail
- Fail-safe behavior
Architecture
Components
- Strategy / OMS
- Order origin: strategies or traders.
- Order gateway
- Normalizes protocol and assigns sequence numbers.
- Market data
- Last price and timestamp for price bands.
- Risk engine
- Single writer per account, lock-free; checks ordered by cost.
- Router
- Forwards approved orders to their destination.
- Venue simulator
- Exchange simulator used in tests; not a live connection.
- Event log
- Append-only record of orders, decisions and fills.
- Drop copy
- Execution reports that update positions.
Engineering decisions
D1One writer per account
- Choice
- Accounts are sharded; each shard is processed by a single thread with in-memory state.
- Rejected alternative
- Shared state guarded by locks.
- Why
- Without lock contention, latency stays predictable and processing order is deterministic, which makes replay exact.
D2State derived from events
- Choice
- Positions and consumed limits are rebuilt from the event log.
- Rejected alternative
- Persisting only current state.
- Why
- Audits ask “why was this order accepted at 10:31:07?”. The log answers that; a snapshot can't.
D3Fail closed on stale data
- Choice
- If the reference price is older than the threshold, market orders are rejected.
- Rejected alternative
- Using the last known price indefinitely.
- Why
- A price band computed on stale data approves exactly the orders it should block.
D4Checks ordered by cost
- Choice
- Kill switch and max size first; exposure computations last.
- Rejected alternative
- Arbitrary order.
- Why
- Most rejections come from the cheap rules, so the common path stays fast.
Implementation details
Each rule is a pure function that takes the order and account state and returns approval or a rejection reason. The engine runs rules in sequence and stops at the first failure.
State lives in memory inside the shard. On startup it's rebuilt by replaying the log; in operation, every decision is appended to the log before the gateway is answered.
Tests include deterministic replay: the same log processed twice must produce exactly the same decisions.
pub fn evaluate(order: &Order, acct: &AccountState, mkt: &MarketView, now: Nanos) -> Decision {
// Ordered by cost: cheap, frequent rejections first.
if acct.kill_switch { return Decision::reject(Reason::KillSwitch); }
if order.qty > acct.limits.max_order_qty { return Decision::reject(Reason::MaxOrderQty); }
if !acct.rate.allow(now) { return Decision::reject(Reason::RateLimit); }
let Some(reference) = mkt.last_price_fresh(order.instrument, now, STALE_AFTER) else {
return Decision::reject(Reason::StaleMarketData); // fail closed
};
if !within_band(order.price.unwrap_or(reference), reference, acct.limits.price_band_bps) {
return Decision::reject(Reason::PriceBand);
}
let projected = acct.position(order.instrument) + order.signed_qty();
if projected.abs() > acct.limits.max_position { return Decision::reject(Reason::PositionLimit); }
Decision::Accept
}Outcomes
Not applicable. As an internal demonstration there are no verified production metrics to report, and we don't publish estimates dressed up as results.
Facing a similar problem?
Tell us the context. We discuss architecture before any commercial proposal.
Next studyRelay MeshAn event-driven integration hub