Week 10 — Phase 3: Live Trading

Live
Execution

QT Pillar 4 — Execution · Program Capstone

Run the strategy in the market: trade the impact-vs-risk frontier optimally, and react in real time to macro releases and the order flow.

What this week covers

Weeks 6–9 built the machine: W6 set the weights, W7 read the exposures, W8 stress-tested the regime, W9 priced a single fill. This week runs it live, and live trading is two problems at once: how fast to trade (optimal execution) and how to react while you trade (live information — macro and microstructure).

By Friday you should be able to:

Reading: Almgren & Chriss (2000), Optimal Execution of Portfolio Transactions; Kissell, The Science of Algorithmic Trading (2013); Cartea, Jaimungal & Penalva, Algorithmic and High-Frequency Trading (2015); Easley, López de Prado & O'Hara (2012) on VPIN and flow toxicity.

Optimal execution: the impact–risk trade-off

W9 named the efficient frontier; here is the model behind it (Almgren–Chriss 2000). You must liquidate \( X \) shares over a horizon \( [0,T] \), choosing a trajectory \( x(t) \) — shares still held at time \( t \), with \( x(0)=X \) and \( x(T)=0 \). The trade rate is \( v(t) = -\dot{x}(t) \). Two costs pull in opposite directions:

With permanent-impact coefficient \( \gamma \) and temporary coefficient \( \eta \), the expected shortfall and its variance are:

\[ \mathbb{E}[C] = \tfrac{1}{2}\gamma X^2 + \eta \int_0^T v(t)^2\,dt, \qquad \mathbb{V}[C] = \sigma^2 \int_0^T x(t)^2\,dt \]

The trader minimizes a mean–variance objective, where \( \lambda \ge 0 \) is risk aversion (urgency):

\[ \min_{x(t)} \; \mathbb{E}[C] + \lambda\,\mathbb{V}[C] \]

For linear impact this has a closed-form optimal trajectory — inventory decays as a hyperbolic sine:

\[ x(t) = X\,\frac{\sinh\!\big(\kappa (T-t)\big)}{\sinh(\kappa T)}, \qquad \kappa = \sqrt{\lambda \sigma^2 / \eta} \]

\( \kappa \) is the urgency. At \( \lambda = 0 \) (risk-neutral) \( \kappa \to 0 \) and the trajectory is a straight line — that is TWAP. As \( \lambda \to \infty \), \( \kappa \) is large and the schedule front-loads — dump fast to kill risk. Every schedule in between is a convex curve. This is the math under W9's rule that the schedule follows the signal's decay.

The efficient frontier of execution

Each \( \lambda \) gives a trajectory, and each trajectory has an (expected cost, timing risk) pair. Sweep \( \lambda \) and you trace the efficient frontier: the minimum expected cost achievable at each level of risk. You cannot trade below it; every real execution sits somewhere on it.

The two ends are the strategies W9 already named. Patient / TWAP (low \( \lambda \)) sits bottom-right: low expected cost, high timing risk — you take your time and accept that the price may drift. Urgent (high \( \lambda \)) sits top-left: high cost, low risk — you pay impact to be done. Picking a point on this curve is the execution decision.

Setting the urgency

\( \lambda \) is not a constant you set once — it is a dial you turn per order. Three inputs move it:

Alpha decay

How fast does the edge disappear? A signal gone by tomorrow is urgent — waiting forfeits it, so accept impact now (high \( \lambda \)). A slow structural rebalance has no decay; minimize footprint (low \( \lambda \)).

Volatility

Timing risk scales with \( \sigma \). In a high-vol regime (or into the events below) the unexecuted position is more dangerous per minute, which pushes \( \kappa \) up — trade faster.

Size vs ADV

Bigger relative size means more impact (the square-root law, W9), arguing to stretch the schedule — but only as far as the alpha survives. Capacity and urgency are solved together.

The synthesis

Fast alpha + small size + high vol → trade now. Slow rebalance + large size + calm tape → work it patiently. \( \lambda \) encodes that judgment as one number the algo can act on.

Reacting to live macro information

Scheduled releases are known in time, unknown in content — the worst combination for a resting order. Seconds before FOMC or CPI, market makers pull quotes: the book thins, the spread gaps, and the first print moves the price discontinuously. And the market trades the surprise (actual − consensus), not the level — a strong number is bad for bonds only if it beats what was already priced.

EventTime (ET)Why it moves the tape
FOMC decision2:00pm (8×/yr)Policy rate + statement + presser; the largest scheduled vol event.
CPI8:30amInflation surprise; the single biggest cross-asset mover of 2022–23.
Nonfarm payrolls8:30am, 1st FriGrowth + wage surprise; whipsaws rates and equities.
PCE8:30amThe Fed's preferred inflation gauge.
ECB / BOJvariesRate differentials drive FX — recall the JPY carry unwind in W8.
Treasury auctions1:00pmSupply shocks the curve; weak demand tails move yields fast.

Execution rules follow directly:

Reacting to live microstructure information

Between events, the order flow itself is information. Three real-time signals drive the per-child-order decision:

The reaction, for a passive order: benign flow and a tight spread → rest and earn the spread; adverse imbalance or rising VPIN → step aside or cross before you are picked off. A minimal reactive rule:

def book_imbalance(bid_sz, ask_sz):
    """Order-book imbalance in [-1, +1]; >0 = buy pressure."""
    return (bid_sz - ask_sz) / (bid_sz + ask_sz)

def child_order(imb, spread_bps, vpin, vpin_max=0.6):
    """Place the next passive-buy child order, reacting to live flow."""
    if vpin > vpin_max:
        return "cross"   # flow is toxic — take liquidity before being picked off
    if imb > 0.3 and spread_bps < 3:
        return "cross"   # strong bid pressure, tight spread — price likely ticks up
    if imb < -0.3:
        return "wait"    # sellers stacked — let the price come to you
    return "post"        # benign — rest at the bid, earn the spread

The live execution loop

A live algorithm layers all three together. Every child-order decision is a baseline plus two overlays:

  1. Baseline schedule. The Almgren–Chriss trajectory from your chosen \( \lambda \) sets the target trade rate — the answer to "how fast on average."
  2. Macro overlay. If a scheduled print falls inside the window, blackout that interval and reroute the remaining quantity around it.
  3. Micro overlay. Modulate the rate and order type by live imbalance, VPIN, and spread — post when conditions are benign, cross or wait when they are not.

Then send the child order, take the fill, update remaining inventory, and repeat until done.

The whole week in one line

The baseline answers how fast on average?; the overlays answer exactly when, and with what order, right now? Optimal execution is the baseline — live trading is the overlays.

Risk controls on a live desk

Automation makes mistakes at machine speed, so live execution is wrapped in guardrails that sit outside the strategy:

Why this is not optional — Knight Capital, Aug 1 2012

A botched deployment left dead code live on one server. In ~45 minutes it sent millions of unintended orders and lost ~$460M, ending a firm that had been a top US market maker. The strategy wasn't wrong — the controls were missing. Guardrails are the price of automating execution.

Common mistakes

Four ways live execution goes wrong

  • Trading through a scheduled print. Working an order into the liquidity vacuum before FOMC or CPI pays a gapped spread on thin depth. Route the schedule around the calendar — it is a known input, not a surprise.
  • Setting urgency by habit. One \( \lambda \) for every order over-trades slow rebalances and under-trades fast alpha. Urgency is per-order: it follows decay, volatility, and size.
  • Posting into toxic flow. Resting passively while VPIN climbs or imbalance turns against you means getting adversely selected — filled exactly when the price is about to move through you. Passive is not free.
  • Automating without a kill switch. No throttle, no auto-halt, no manual stop. A bug then trades at machine speed until someone notices. Knight is the tuition; pay it once, in reading.
← Week 9: Basic Market Microstructure QT Program Complete ↑