The separation that makes systems survivable
In quant systems, the fastest path to chaos is mixing signal generation, decision policy, and execution into a single opaque service. You get speed early and fragility later. The fix is simple but strict: treat signal, policy, and execution as distinct layers with explicit contracts between them.
This separation doesn’t promise better returns. It promises replay, auditability, and iterability—the things you need before you can trust any output at all.
Signal: generate observations, not decisions
Signals are observations derived from data. They can be raw features, statistical summaries, or model outputs. The key is that they do not decide. A signal service should be able to answer:
- What data was used?
- What version of the feature pipeline generated it?
- What time window does it represent?
If you can’t answer those, you can’t replay the system when something breaks or when you update the pipeline.
Policy: codify rules, risk, and constraints
Policy turns signals into decisions. This is where constraints live: risk limits, exposure caps, position sizing rules, and governance checks. You want policy to be explainable and testable. That means:
- Explicit versioning and change history.
- A ruleset that can be diffed and reviewed.
- A stable decision schema that execution can rely on.
Policy is also where you can enforce “do nothing” decisions. Many systems fail because the policy layer is implicit or optional. If execution can be called without a policy decision, you will ship bugs into the market.
Execution: make the world match the decision
Execution is about state transitions in the real world. It needs to be deterministic and measurable: orders placed, orders canceled, confirmations received, and slippage recorded. The execution layer should never re-interpret policy or re-run signal logic. It should only do the thing it was told to do, then report back.
This is the layer where your operational constraints are tightest. Latency matters. So does idempotency. If you replay the policy decisions from yesterday, execution should produce the same sequence of order intents—even if it chooses not to send them because markets are closed.
Replay: the quiet power move
Replay works when each layer is pure enough to rerun:
- Recompute signals from the same raw data.
- Re-apply a policy version to those signals.
- Re-simulate execution with deterministic inputs.
This turns debugging from guessing into evidence. It also turns system upgrades into controlled experiments: you can measure the effect of a policy change without conflating it with new features or execution code.
What this enables
Separating signal, policy, and execution gets you:
- A traceable audit path for compliance and stakeholders.
- A stable way to evaluate changes before they reach production.
- Fewer “unknown unknowns” when incidents happen.
It’s a system design move, not a trading strategy. But it’s one of the few moves that reliably makes complex systems calmer instead of louder.
Practical start
If you’re building or rebuilding:
- Write a schema for signals, policy decisions, and execution commands.
- Version those schemas and keep them stable.
- Make replay a first-class path, not an emergency hack.
You don’t need more complexity. You need clear seams.