Zack Meacham

Flagship · independent systems

← All work

Building a Research-First, Risk-Gated Trading Harness

2026 · Active build

A solo-built autonomous equities trading system where autonomy is earned, not assumed: every order routes through a fail-closed risk chokepoint no code path can bypass. Phase One is deliberately bounded (US equities, paper-only, sub-$1,000 capital) so the engineering goes into correctness and governance, not breadth.

  • Python
  • Alpaca
  • SQLite
  • Parquet
  • PySide6 / Qt Quick
  • pytest

At a glance

Role
Solo build; owner of architecture, code, tests, and governance
Year
2026
Status
Active build · paper-only, no live capital (enforced in code)
Stack
Python 3.11 · Alpaca · SQLite event store · Parquet · PySide6 / Qt Quick · pytest
Scale
15-module package · ~53K LOC source / ~94K LOC tests · ~990 commits (solo)
Tests
~225 test files · coverage ratcheted at 89% · manual mutation audit
Governance
58 ADRs · a custom Opus risk-invariant-reviewer run on every risk and execution diff
Proof
17-check fail-closed risk layer · exactly-once order drain · 17 governed strategies (config-driven)
Links
GitHub

Why this mattered

Trading software is unusual in that its blast radius can be financial. Most hobby-grade systems collapse vendor logic, strategy, and execution into one tangle. Milodex inverts that: vendors sit behind internal models, the risk layer holds an unconditional veto, and autonomy has to be earned instead of assumed. The genuinely hard problems turned out to be distributed-systems and financial-correctness problems: exactly-once execution, crash recovery, and cross-process serialization over a shared brokerage account.

My role and ownership

Solo. I own the architecture, the code, the tests, the operator surfaces, and the governance. Every consequential decision is captured in a 58-record ADR corpus, and a custom Opus-backed reviewer subagent I built reviews every diff that touches risk, execution, or promotion against named safety invariants.

Core constraints

  • Financial blast radius. Defaults have to be refuse, not execute.
  • Exactly-once execution under failure: an overnight double-launch or a mid-submit crash must never place a duplicate order.
  • Cross-process safety: many strategy runners share one brokerage account and must never act on a stale snapshot.
  • Broker-vendor risk: trading-API behavior is the kind of dependency that shouldn't leak into strategy code.
  • Single-developer operability. The CLI, the tests, and the audit trail have to be the operator's source of truth.

Architecture and key decisions

FIG. 1 MILODEX · SIGNAL PATH
Milodex system signal path The operator CLI drives a strategy research harness. Every order the strategy proposes passes through a risk gate of 17 checks that fails closed and refuses by default. Only approved orders reach the broker abstraction, which routes to Alpaca in paper mode or a simulated broker for backtesting. Market data lands in a Parquet store that feeds the strategy. Live capital stays behind an explicit human-approval gate. order approved market data OPERATOR CLI drives · inspects · replays STRATEGY research harness RISK GATE 17 checks · fails closed DEFAULT: REFUSE BROKER ABSTRACTION one internal model ALPACA paper SIMULATED broker · backtest PARQUET store paper-only · live capital behind a human gate
Strategy proposes; the risk gate disposes, refusing by default. Market data lands in Parquet and feeds research.

Append-only event store as the single source of truth

An append-only SQLite (WAL) event store holds all trade, explanation, kill-switch, strategy-run, and backtest history. Explanation and trade rows write atomically in one transaction, and the schema evolves only through ordered, additive, version-pinned migrations. Event sourcing buys full decision-level auditability: every outcome is reconstructable from the log. Every decision (submit, veto, expired, idempotency-suppressed, dropped) emits a durable explanation record.

  • SQLite
  • Event sourcing
  • Schema migrations

Exactly-once execution drain

A single ExecutionService is the only path to the broker: it assembles context, invokes risk, records the explanation, then submits. An idempotent consume-CAS plus pre-submit outbox makes the drain crash-recoverable: a pending row commits before the broker call, and a single-transaction compare-and-swap flips an intent from queued to consumed only if it is still queued, so an overnight double-launch or a crash-retry can never place a duplicate order.

  • Idempotency
  • Consume-CAS + outbox
  • Crash recovery

Fail-closed risk layer and kill switch

A risk evaluator runs 17 veto checks (kill switch, staleness, daily-loss, fat-finger, exposure, duplicate- and opposite-side-order) with an unconditional veto and no skip flag, sitting above backtest so it cannot be bypassed for convenience. A daily-loss breach trips a manual-reset-only kill switch where auto-resume is structurally impossible. Cross-process advisory locks (PID plus heartbeat liveness, stale auto-reclaim) serialize the snapshot-to-submit path and fail closed on acquire timeout.

  • Fail-closed
  • Veto gate
  • Advisory locks

Promotion pipeline and walk-forward backtest

A backtest, paper, micro-live, live state machine with no stage-skipping, a two-tier statistical gate (a permissive paper-readiness tier and a stricter capital-readiness tier with a 30-trade floor), hash-pinned frozen strategy manifests, and human approval for capital-bearing stages. The walk-forward engine indexes out-of-sample trading days and dispatches on a Timeframe enum between a daily path and an intraday advance-evaluate-drain path with guaranteed T+1 fills, so the same engine runs identically in backtest and live and even replays 24/7 crypto bars. Seventeen governed strategies are defined entirely in YAML.

  • State machine
  • Walk-forward
  • YAML config

Operator surfaces: CLI and Qt desktop GUI

An argparse CLI is the primary, source-of-truth operator surface, with paired human and JSON formatters. Alongside it, a PySide6 / Qt Quick (QML) desktop GUI (~11K LOC of QML across ~45 files) sits over thin command facades and ~34 event-store-backed read models, with a promotion-pipeline kanban and a design-system and theme architecture.

  • argparse
  • PySide6
  • Qt Quick / QML

Execution highlights

  • The single ExecutionService chokepoint means a paper-stage strategy is structurally incapable of submitting live.
  • Cross-process serialization means many runners sharing one Alpaca account never evaluate against a stale snapshot.
  • ~225 test files (~94K LOC) with coverage ratcheted at 89%, including AST-level invariant tests that lock the existence of safety guards, golden regression tests, and a manual mutation audit; 58 ADRs and a custom Opus risk-invariant-reviewer I run on every risk-touching diff against 8 named safety invariants.

Impact / current state

Active build, solo. The correctness core (event store, exactly-once execution drain, 17-check risk layer, promotion gates) and the operator surfaces are settled; Phase One stays deliberately bounded (US equities, paper-only, sub-$1,000 capital) so the work goes into correctness and governance. Strategy research and the null-baseline evidence lane are the next focus.

What this demonstrates

Distributed-systems correctness under financial blast radius (exactly-once execution, crash recovery, cross-process safety), fail-closed risk-first design, and governance built in (an ADR corpus and a custom reviewer agent), delivered solo.