A safe, deterministic reference architecture for turning signed strategy events into risk-checked paper orders.
This public engineering sample focuses on the difficult seams in event-driven execution—authentication, strict contracts, replay protection, risk gates, auditability, and infrastructure boundaries. It deliberately contains no proprietary strategy, live broker adapter, credentials, performance claims, or real-market automation.
Safety: Educational software only. The sole symbol is
DEMO; the sole adapter is an in-memory paper broker. This project cannot place a real order and is not financial advice.
- Trust boundaries: HMAC-SHA256 verification happens before JSON parsing.
- Fail-closed contracts: unknown fields, malformed timestamps, and non-finite prices are rejected.
- Exactly-once intent: SQLite atomically claims event IDs and caches completed outcomes.
- Visible risk policy: allow lists, freshness, sizing, stop-distance, and directional checks are isolated and unit tested.
- Port-and-adapter design: execution depends on a small broker protocol; only a deterministic mock exists.
- Honest operational framing: the docs distinguish a reference system from production readiness.
flowchart LR
A["Toy signal generator"] --> B["HMAC-authenticated API"]
B --> C["Strict signal contract"]
C --> D["Idempotency ledger"]
D --> E["Risk policy"]
E --> F["Paper broker"]
F --> G["Paper order journal"]
Read the architecture notes for the tradeoffs and the deliberately unimplemented production concerns.
git clone https://github.com/ChrisTeso/trading-execution-lab.git
cd trading-execution-lab
./scripts/verify.sh
PYTHONPATH=src python3 -m trading_lab.demoThe demo runs a deliberately trivial 3/5 moving-average crossover over six synthetic prices, processes its signal twice, and proves that the replay produces one paper order.
Example result (timestamps abbreviated):
{
"result": {"status": "accepted", "order_id": "paper-demo-001"},
"duplicate": {"status": "accepted", "duplicate": true},
"paper_orders": [{"symbol": "DEMO", "quantity": 1}]
}No package installation or third-party runtime dependency is required. Python 3.11+ is sufficient.
Start the paper-only server:
export TRADING_LAB_SECRET='local-demo-secret-change-me'
PYTHONPATH=src python3 -m trading_lab.api --port 8080In a second terminal, sign the exact JSON bytes and submit them:
python3 - <<'PY'
from datetime import datetime, timezone
import hashlib, hmac, json, urllib.request
secret = b"local-demo-secret-change-me"
payload = {
"event_id": "readme-001",
"strategy": "toy-sma-crossover",
"symbol": "DEMO",
"side": "buy",
"quantity": 1,
"reference_price": 100.0,
"stop_price": 99.0,
"created_at": datetime.now(timezone.utc).isoformat(),
"schema": "execution-signal/v1",
}
body = json.dumps(payload).encode()
signature = "sha256=" + hmac.new(secret, body, hashlib.sha256).hexdigest()
request = urllib.request.Request(
"http://127.0.0.1:8080/v1/signals",
data=body,
headers={"Content-Type": "application/json", "X-Trading-Lab-Signature": signature},
)
print(urllib.request.urlopen(request).read().decode())
PYsrc/trading_lab/
api.py signed HTTP boundary and body limits
models.py strict signal and result contracts
ledger.py atomic SQLite event claims and audit records
risk.py explicit, fail-closed pre-trade policy
broker.py broker protocol and paper-only adapter
engine.py orchestration across those boundaries
strategy.py intentionally trivial synthetic signal source
tests/ unit and local HTTP integration tests
docs/ architecture decisions and production gaps
./scripts/verify.shThe same command runs in GitHub Actions on Python 3.11, 3.12, and 3.13. It executes the test suite, byte-compiles the code, runs the end-to-end demo, and scans the tree for common secret or source-leak patterns.
Execution code becomes dangerous when a demo blurs the boundary between architecture and operational readiness. Keeping the only adapter deterministic makes behavior reproducible and the safety claim inspectable. SECURITY.md lists the controls modeled here and the controls still required for a real system.
MIT © 2026 Chris Teso