Skip to content
Khaled.dev
1 min read

What Trading Systems Taught Me About Software Correctness

Lessons from building automated trading systems where a bug costs real money — idempotency, reconciliation, and trusting nothing.

In most software, a bug is annoying. In a trading system, a bug spends your money before you finish reading the stack trace. That pressure reshapes how you think about correctness.

Trust nothing, reconcile everything

The exchange is the source of truth, not your local state. After every action I reconcile:

local = position_store.get(symbol)
remote = exchange.fetch_position(symbol)

if local != remote:
    alert(f"drift detected on {symbol}: {local} vs {remote}")
    position_store.set(symbol, remote)  # exchange wins

Drift is not an edge case. It's a when, not an if.

Idempotency or death

Networks fail mid-request. Did the order go through? You don't know. So every order carries a client-generated id, and re-sending it is a no-op:

  • generate clientOrderId before sending
  • the exchange dedupes on it
  • retries become safe

Make the dangerous path loud

The order placement code is the most boring, most reviewed, most logged code in the whole system.

Boring code in the dangerous places. Clever code only where mistakes are cheap.

Crossing over to AI agents

This mindset transfers directly to autonomous agents. An agent taking actions in the world is just a trading system with a fuzzier decision engine — and it needs the same idempotency, reconciliation, and loud failure paths.

Takeaways

  • The external system is the source of truth; reconcile relentlessly.
  • Make every action idempotent.
  • Keep the dangerous code boring and observable.
#trading#correctness#systems#engineering
ShareLinkedInX
Part 2 of 2 in the series

Building AI agents

  1. 1.Building Reliable AI Agents That Don't Fall Over
  2. 2.What Trading Systems Taught Me About Software Correctness

Related reading

Comments

Comments are enabled once giscus is configured.