Quant Python: Architecting Autonomous Trading Systems

Quant Python: Architecting Autonomous Trading Systems

Day 29 — The Base Order: Side, Qty, and Type

Python Quant's avatar
Python Quant
Apr 04, 2026
∙ Paid

Every trading system begins with a single abstraction: the order. Get this layer wrong and every component built on top of it inherits the flaw. This lesson builds it right, from scratch.


Table of Contents

  1. The Dictionary Trap

  2. Three Failure Modes

  3. The AutoQuant-Alpha Architecture

  4. Implementation Deep Dive

  5. Prerequisites & Project Setup

  6. Build, Run & Demo

  7. Test Suite

  8. Verify with Alpaca

  9. Production Metrics

  10. Homework


1. The Dictionary Trap

Every new quant engineer writes this on day one. It works in a notebook, it passes a smoke test, and it gets merged:

# Looks fine. Ships to production. Causes account ruin.
order = {
    "symbol": "AAPL",
    "side":   "buy",
    "qty":    10.0,
    "type":   "market",
}
submit_order(order)

Then, at 09:31:04 EST on a high-volatility open, the async event loop processes two signals concurrently. A position-sizing coroutine reads order["qty"] while a risk-gate coroutine is mid-write. You now have a torn read on a mutable dict. Your fill comes back for 7 shares on a 10-share order. Your P&L model is off by 3 shares forever, silently.

That is the dictionary order trap. It is not a beginner mistake — it is an architectural one. Everything built on top of it inherits the flaw. We fix it at the foundation.


2. Three Failure Modes

These are not hypothetical edge cases. Each one has taken money out of real accounts.

Crash 01 — Floating-Point Qty Drift

# Simulating accumulated partial fills
qty_filled = 0.0
fills = [0.1] * 10  # ten 0.1-share fills
for f in fills:
    qty_filled += f

print(qty_filled)          # 0.9999999999999999
print(qty_filled == 1.0)   # False

Your position reconciliation now shows -0.0000000000000001 shares. Multiplied across 500 positions and 6.5 trading hours, this is not rounding error — it is a systematic P&L leak that compounds into real dollar discrepancies at month-end.

Crash 02 — String Side Misrouting

SIDE_MAP = {"BUY": 1, "SELL": -1}

order["side"] = "Buy"   # Capital B, lowercase uy — easy to type by hand
multiplier = SIDE_MAP[order["side"]]  # KeyError at market open

StrEnum eliminates this entirely. Side.BUY == "buy" is True. You cannot construct an invalid side value at all — the error happens at the source, not at execution time.

Crash 03 — Mutable State in Async Context

# risk_gate coroutine
async def apply_risk_cap(order: dict, cap: float) -> None:
    if order["qty"] > cap:
        order["qty"] = cap        # mutates shared reference

# sizing coroutine running concurrently
async def apply_kelly(order: dict, fraction: float) -> None:
    order["qty"] = order["qty"] * fraction  # reads mid-mutation

Python’s GIL does not protect you here. asyncio coroutines yield at await points, not at arbitrary dict mutations. Two coroutines operating on the same dict reference will tear each other’s writes. This bug never appears in your unit tests — only under load.


3. The AutoQuant-Alpha Architecture

We build BaseOrder around three constraints. Each one directly eliminates one of the crashes above.

User's avatar

Continue reading this post for free, courtesy of Python Quant.

Or purchase a paid subscription.
© 2026 Python Quant · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture