Skip to content

Almgren-Chriss Optimal Execution: The Mean-Variance Framework for Trading Trajectories

Trade fast and pay impact, or trade slow and carry risk — Almgren-Chriss (2000) turns that trade-off into a solvable mean-variance problem. The full derivation, a numerical example worked to the end, and where the model breaks.

2 of 12 ~15 min

Suppose you have to sell 1,000,000 shares of Apple over the next 4 hours. Sell fast, and your own orders hammer the price — impact cost eats you. Sell slow, and you sit on a large inventory exposed to every tick of volatility — one bad headline and you take a bath. Somewhere between the two extremes there is an optimal trajectory. What does it look like?

This is the Almgren-Chriss problem (Almgren and Chriss, 2000). It’s the workhorse model of institutional execution, and Harris devotes space to it (Harris, Trading and Exchanges, Ch. 19). The basic version assumes linear temporary and permanent impact, and the answer turns out to be a smooth curve between “trade everything immediately” and “spread uniformly” — with the entire trade-off compressed into one dimensionless number. The derivation follows.

The Setup

You have a parent order of size QQ shares to execute over horizon TT. Let xtx_t be the number of shares remaining at time tt, with x0=Qx_0 = Q and xT=0x_T = 0. The trading rate is vt=−(xt−xt−1)v_t = -(x_t - x_{t-1}), the number of shares sold per unit time.

Before we can price the trajectory, we need to say how your trading moves the price. Almgren-Chriss split the impact in two. The first piece goes into the midprice and stays there:

St=S0+(permanent impact from trades)+(random walk in fundamentals)S_t = S_0 + \text{(permanent impact from trades)} + \text{(random walk in fundamentals)}

Specifically:

St=S0−γ∑s=1tvs+στ⋅ϵtS_t = S_0 - \gamma \sum_{s=1}^{t} v_s + \sigma \sqrt{\tau} \cdot \epsilon_t

where γ\gamma is the permanent impact coefficient, τ\tau is the time step, and ϵt\epsilon_t is a standard normal shock. The more you have sold, the lower the midprice sits — permanently.

The second piece bites only at the moment you trade: your execution price is worse than the mid by

S~t=St−η⋅vt\tilde{S}_t = S_t - \eta \cdot v_t

where η\eta is the temporary impact coefficient — the surcharge for demanding liquidity right now. Stop trading and it vanishes. This permanent/temporary split is the foundation of the whole model; we’ll see shortly that it single-handedly determines the direction of the optimization.

With prices in hand, revenue is just the sum over fills:

revenue=∑t=1Tvt⋅S~t=∑t=1Tvt(St−ηvt)\text{revenue} = \sum_{t=1}^{T} v_t \cdot \tilde{S}_t = \sum_{t=1}^{T} v_t (S_t - \eta v_t)

What we care about is the shortfall relative to a no-impact benchmark:

Cost=∑t=1Tvt(S0−S~t)=∑t=1Tvt(ηvt+γ∑s=1tvs)−σ terms\text{Cost} = \sum_{t=1}^{T} v_t (S_0 - \tilde{S}_t) = \sum_{t=1}^{T} v_t (\eta v_t + \gamma \sum_{s=1}^{t} v_s) - \sigma \text{ terms}

The random terms have zero mean, so in expectation two clean pieces remain:

E[Cost]=η∑tvt2+γ2Q2E[\text{Cost}] = \eta \sum_{t} v_t^2 + \frac{\gamma}{2} Q^2

The first term is the temporary impact cost — note it is a sum of squared rates, so the same quantity traded faster is punished harder. The second is the permanent impact cost — it depends only on total size QQ, not on how you schedule the trades. That difference is about to matter.

Cost has a second dimension. The random walk in SS means every share you haven’t yet sold is carrying price risk:

Var(Cost)=σ2∑t=1Txt2τ\text{Var}(\text{Cost}) = \sigma^2 \sum_{t=1}^{T} x_t^2 \tau

where xtx_t is the remaining inventory. The larger and longer-held the inventory, the bigger the variance. At this point the fast/slow tension is fully written down in math: ∑vt2\sum v_t^2 punishes speed, ∑xt2\sum x_t^2 punishes slowness.

The Optimization

Almgren-Chriss fold the two dimensions into one mean-variance objective:

min⁡vt[E[Cost]+λ⋅Var(Cost)]\min_{v_t} \left[ E[\text{Cost}] + \lambda \cdot \text{Var}(\text{Cost}) \right]

where λ\lambda is the risk-aversion parameter: higher λ\lambda fears variance, lower λ\lambda cares about expected cost. Substituting:

min⁡[η∑tvt2+γ2Q2+λσ2τ∑txt2]\min \left[ \eta \sum_t v_t^2 + \frac{\gamma}{2} Q^2 + \lambda \sigma^2 \tau \sum_t x_t^2 \right]

subject to ∑vt=Q\sum v_t = Q (you must execute everything) and vt≥0v_t \geq 0.

Here the permanent-impact term does us a favor: γ2Q2\frac{\gamma}{2} Q^2 is a constant given QQ, independent of the trajectory, so we drop it. Read that again, because it’s a real insight: permanent impact is paid the moment you decide to trade the size; no scheduling cleverness can touch it. All the optimization can manage is the balance between temporary impact and risk. The problem reduces to:

min⁡[η∑tvt2+λσ2τ∑txt2]\min \left[ \eta \sum_t v_t^2 + \lambda \sigma^2 \tau \sum_t x_t^2 \right]

subject to ∑vt=Q\sum v_t = Q.

The Discrete-Time Solution

The cleanest route is to work in the inventory variables xtx_t (with vt=xt−1−xtv_t = x_{t-1} - x_t; the endpoints x0=Qx_0 = Q, xT=0x_T = 0 absorb the constraint automatically). The objective becomes:

L=η∑t(xt−1−xt)2+λσ2τ∑txt2\mathcal{L} = \eta \sum_t (x_{t-1} - x_t)^2 + \lambda \sigma^2 \tau \sum_t x_t^2

Each interior xtx_t appears in exactly three places: (xt−1−xt)2(x_{t-1}-x_t)^2, (xt−xt+1)2(x_t-x_{t+1})^2, and its own variance term. Differentiate with respect to xtx_t and set to zero:

−2η(xt−1−xt)+2η(xt−xt+1)+2λσ2τxt=0-2\eta (x_{t-1} - x_t) + 2\eta (x_t - x_{t+1}) + 2\lambda \sigma^2 \tau x_t = 0

Rearranged:

xt+1−2xt+xt−1=λσ2τη xtx_{t+1} - 2 x_t + x_{t-1} = \frac{\lambda \sigma^2 \tau}{\eta} \, x_t

The left side is a discrete second derivative. The equation says the optimal inventory curve must bend, everywhere, in proportion to the inventory still held — the more you’re carrying, the harder you should be accelerating out of it. Linear difference equations of this type have solutions built from e±κte^{\pm\kappa t}; imposing the two boundary conditions gives:

xt=Q⋅sinh⁡(κ(T−t))sinh⁡(κT)x_t = Q \cdot \frac{\sinh(\kappa (T - t))}{\sinh(\kappa T)}

where κ\kappa is pinned down by:

cosh⁡(κτ)=1+λσ2τ22η,κ≈λσ2η (for small τ)\cosh(\kappa \tau) = 1 + \frac{\lambda \sigma^2 \tau^2}{2\eta}, \qquad \kappa \approx \sqrt{\frac{\lambda \sigma^2}{\eta}} \ \text{(for small } \tau)

The per-period trade sizes follow:

vt=xt−1−xt=2Qsinh⁡(κτ/2)sinh⁡(κT)⋅cosh⁡ ⁣(κ(T−t+τ2))v_t = x_{t-1} - x_t = \frac{2 Q \sinh(\kappa \tau / 2)}{\sinh(\kappa T)} \cdot \cosh\!\big(\kappa (T - t + \tfrac{\tau}{2})\big)

This is the standard Almgren-Chriss discrete solution. Notice that every parameter — risk aversion λ\lambda, volatility σ\sigma, temporary impact η\eta — enters the answer only through the single combination κ\kappa. That is not a coincidence; it is the entire next section.

The Continuous-Time Limit

As τ→0\tau \to 0 the formulas get cleaner. Inventory and rate:

x(t)=Q⋅sinh⁡(κ(T−t))sinh⁡(κT),v(t)=−x′(t)=Q⋅κcosh⁡(κ(T−t))sinh⁡(κT)x(t) = Q \cdot \frac{\sinh(\kappa (T - t))}{\sinh(\kappa T)}, \qquad v(t) = -x'(t) = Q \cdot \frac{\kappa \cosh(\kappa (T - t))}{\sinh(\kappa T)}

with κ=λσ2/η\kappa = \sqrt{\lambda \sigma^2 / \eta}. Boundary conditions check on sight: x(0)=Q⋅sinh⁡(κT)/sinh⁡(κT)=Qx(0) = Q \cdot \sinh(\kappa T)/\sinh(\kappa T) = Q and x(T)=Q⋅sinh⁡(0)/sinh⁡(κT)=0x(T) = Q \cdot \sinh(0)/\sinh(\kappa T) = 0. Inventory declines smoothly from QQ to 0, and the curve is convex — front-loaded — whenever κT>0\kappa T > 0.

When κT≫1\kappa T \gg 1, sinh⁡(κ(T−t))/sinh⁡(κT)≈e−κt\sinh(\kappa(T-t))/\sinh(\kappa T) \approx e^{-\kappa t} and the trajectory degenerates into pure exponential decay, giving the commonly used approximation:

v(t)≈Q⋅κe−κt1−e−κT,v(0)≈Q⋅κ1−e−κTv(t) \approx Q \cdot \frac{\kappa e^{-\kappa t}}{1 - e^{-\kappa T}}, \qquad v(0) \approx Q \cdot \frac{\kappa}{1 - e^{-\kappa T}}

(An approximation for large κT\kappa T, not the exact solution — exactly, v(0)=Qκcosh⁡(κT)/sinh⁡(κT)v(0) = Q\kappa \cosh(\kappa T)/\sinh(\kappa T).) Both limits behave: for small κT\kappa T, v(0)≈Q/Tv(0) \approx Q/T — uniform trading; for large κT\kappa T, v(0)≈Qκv(0) \approx Q\kappa, which can dwarf Q/TQ/T; and for very large κT\kappa T (extreme risk aversion), v(0)→Qv(0) \to Q — execute everything immediately, the market-order limit.

Three Regimes

So the whole problem compresses into one dimensionless number, κT=Tλσ2/η\kappa T = T\sqrt{\lambda \sigma^2 / \eta}, and it referees the fast/slow dispute.

Low κT\kappa T (low risk aversion, low volatility, expensive temporary impact): v(t)≈Q/Tv(t) \approx Q/T, near-uniform. You’re not afraid to hold inventory, so you sell slowly and save impact; the cost is almost entirely temporary impact.

High κT\kappa T (high risk aversion, high volatility, cheap temporary impact): strongly front-loaded, most of the volume goes out at the start. You are deliberately overpaying temporary impact — under a squared penalty, speed is expensive — in exchange for collapsing inventory risk quickly. This is buying certainty with cash.

Intermediate κT\kappa T: a smooth curve between the two. Institutional execution lives here most of the time. The boundary between regimes sits roughly around κT=2\kappa T = 2.

A Worked Numerical Example

Let’s push numbers through — and step on a trap almost everyone steps on, deliberately.

You’re selling Q=1,000,000Q = 1{,}000{,}000 shares, T=4T = 4 hours = 14400 seconds, τ=60\tau = 60 seconds (1-minute bars). Daily vol σ=0.02\sigma = 0.02, temporary impact η=10−6\eta = 10^{-6} (per share per second), permanent impact γ=10−7\gamma = 10^{-7} (per share), risk aversion λ=10−6\lambda = 10^{-6}.

The trap is units. Feed the daily vol 0.02 straight into the formula:

κ=λσ2η=10−6⋅4×10−410−6=4×10−4=0.02\kappa = \sqrt{\frac{\lambda \sigma^2}{\eta}} = \sqrt{\frac{10^{-6} \cdot 4 \times 10^{-4}}{10^{-6}}} = \sqrt{4 \times 10^{-4}} = 0.02

and you get κT=0.02⋅14400=288\kappa T = 0.02 \cdot 14400 = 288 — an absurdly extreme front-load, effectively “liquidate in half a minute.” The error: TT is in seconds while σ\sigma is daily. Variance scales linearly in time: per-second variance is σ2/23400\sigma^2 / 23400 (a 6.5-hour trading day), so per-second σ≈0.02/154≈1.3×10−4\sigma \approx 0.02 / 154 \approx 1.3 \times 10^{-4} and per-second variance is 1.7×10−81.7 \times 10^{-8}.

Redo it with consistent units: λσ2=10−6⋅1.7×10−8=1.7×10−14\lambda \sigma^2 = 10^{-6} \cdot 1.7 \times 10^{-8} = 1.7 \times 10^{-14}; divided by η=10−6\eta = 10^{-6}, κ2=1.7×10−8\kappa^2 = 1.7 \times 10^{-8}, so κ≈1.3×10−4\kappa \approx 1.3 \times 10^{-4} per second. Hence κT≈1.87\kappa T \approx 1.87 — the intermediate regime, gently front-loaded. Same parameters, one unit slip, and the conclusion flips from “work it calmly over 4 hours” to “dump it in 30 seconds.” Checking that σ\sigma, η\eta, and TT share consistent units is the first sanity check whenever you use this model.

Plug into the exact solution for the endpoint rates (sinh⁡(1.87)≈3.17\sinh(1.87) \approx 3.17, cosh⁡(1.87)≈3.32\cosh(1.87) \approx 3.32):

Initial rate: v(0)=Qκcosh⁡(κT)/sinh⁡(κT)=130×3.32/3.17≈136v(0) = Q\kappa \cosh(\kappa T)/\sinh(\kappa T) = 130 \times 3.32 / 3.17 \approx 136 shares/sec. The uniform rate would be 106/14400≈6910^6 / 14400 \approx 69 shares/sec, so you start at roughly 2× uniform. End rate: v(T)=Qκ/sinh⁡(κT)=130/3.17≈41v(T) = Q\kappa/\sinh(\kappa T) = 130 / 3.17 \approx 41 shares/sec, about 0.6× uniform. The trajectory glides from 136 down to 41 shares/sec.

Here’s a check that appears to fail: averaging the endpoints, (136+41)/2≈88(136+41)/2 \approx 88 shares/sec, times 14400 seconds gives 1.27×1061.27 \times 10^6 shares — almost 30% more than QQ. That’s correct, and it does not mean the math is wrong: cosh⁡\cosh is convex, so averaging the endpoints systematically overestimates the area under the curve. The exact trajectory integrates to QQ by construction, and the true average rate is exactly 69 shares/sec.

Expected Cost

Expected cost returns to the two pieces:

Expected cost=η∫0Tv(t)2 dt⏟temporary impact+γ2Q2⏟permanent impact\text{Expected cost} = \underbrace{\eta \int_0^T v(t)^2 \, dt}_{\text{temporary impact}} + \underbrace{\frac{\gamma}{2} Q^2}_{\text{permanent impact}}

For our example, estimate the temporary term with an RMS rate of about 80 shares/sec: ∫v2dt≈802⋅14400=9.2×107\int v^2 dt \approx 80^2 \cdot 14400 = 9.2 \times 10^7, times η=10−6\eta = 10^{-6} gives about 9292 dollars. The permanent term: γ2Q2=0.5⋅10−7⋅1012=50,000\frac{\gamma}{2} Q^2 = 0.5 \cdot 10^{-7} \cdot 10^{12} = 50{,}000 dollars.

Three orders of magnitude apart — this order’s cost is almost all permanent impact. On a 1M-share sale of a $100 stock ($100M notional), 50,000is5bps;asensiblemagnitude.Butrecall:permanentimpactisexactlythepartthetrajectorycan′ttouch.Sowhattheoptimizerisactuallymanaginginthisexampleisthebalancebetweenthat50{,}000 is 5 bps; a sensible magnitude. But recall: permanent impact is exactly the part the trajectory can't touch. So what the optimizer is actually managing in this example is the balance between that 92 of temporary impact and the following variance.

Variance of cost: σ2∫x(t)2dt\sigma^2 \int x(t)^2 dt. With x(t)x(t) averaging around Q/2=5×105Q/2 = 5 \times 10^5 shares over the horizon, ∫x2dt≈2.5×1011⋅14400=3.6×1015\int x^2 dt \approx 2.5 \times 10^{11} \cdot 14400 = 3.6 \times 10^{15}; times the per-second variance 1.7×10−81.7 \times 10^{-8}, that’s a variance of 6.1×1076.1 \times 10^7 (dollars squared), i.e. a standard deviation of 6.1×107≈7800\sqrt{6.1 \times 10^7} \approx 7800 dollars. So the execution’s cost swings about ±7800\pm 7800 (one sigma) around its 50,00050{,}000 expectation. The ratio of expected cost to its standard deviation is 50,000/7,800≈6.450{,}000 / 7{,}800 \approx 6.4 — the balance point the mean-variance objective settles at for λ=10−6\lambda = 10^{-6}.

The Risk-Adjusted Frontier

Sweep λ\lambda across its range and the optimal trajectories trace out a frontier. λ=0\lambda = 0 is pure cost minimization: spread the trades over as long a horizon as possible, minimize temporary impact, let the variance fall where it may. λ=∞\lambda = \infty is pure variance minimization: execute immediately, market order, swallow the impact. Intermediate λ\lambda interpolates smoothly. The frontier is convex: each increment of λ\lambda buys a variance reduction (you finish faster) at the price of higher expected cost (you pay more impact) — the same geometry as the efficient frontier in portfolio theory. Harris Ch. 19 has the visual; Hasbrouck (2007) has the formal treatment.

Python Implementation

A simple Almgren-Chriss simulator:

import numpy as np

def almgren_chriss_trajectory(Q, T, sigma, eta, lam, n_periods=100):
    """
    Compute optimal Almgren-Chriss trajectory.
    Q: total shares to execute
    T: horizon (seconds)
    sigma: per-second volatility (decimal)
    eta: temporary impact coefficient
    lam: risk aversion
    Returns: arrays of (t, inventory x(t), rate v(t))
    """
    tau = T / n_periods
    kappa = np.sqrt(lam * sigma**2 / eta)
    t = np.linspace(0, T, n_periods + 1)
    x = Q * np.sinh(kappa * (T - t)) / np.sinh(kappa * T)
    v = -np.diff(x) / tau  # trading rate per period
    return t, x, v


# Example: 1M shares over 4 hours
t, x, v = almgren_chriss_trajectory(
    Q=1_000_000, T=14400, sigma=1.3e-4, eta=1e-6, lam=1e-6, n_periods=240
)
print(f"Initial rate: {v[0]:.1f} shares/sec")
print(f"Final rate:   {v[-1]:.1f} shares/sec")
print(f"Avg rate:     {v.mean():.1f} shares/sec (target: {1e6/14400:.1f})")

For reasonable parameters, the initial rate lands around twice the average and the final rate below it — the same front-loaded curve we computed by hand. Note that sigma takes per-second volatility: the units trap lives in code, too.

Permanent vs Temporary: Why the Split Is the Contribution

Back to the model’s foundation. Almgren-Chriss’s real contribution is not the sinh curve — it’s splitting impact into two types and spelling out what each implies. Permanent impact (γ\gamma): the price moves because of your trade and stays moved; stop trading and it does not come back. This is the “information” component — the same object as Kyle’s lambda. Temporary impact (η\eta): the price is pushed down while you trade and rebounds when you stop. This is the “liquidity” component, the transient cost of demanding immediacy.

Empirically the two look very different. Permanent impact is small but persistent — on liquid US equities, single-digit basis points or below, varying with liquidity and size. Temporary impact is larger but reverts: several to a dozen-odd basis points while you trade, mostly dissipating within minutes. Treat these as orders of magnitude, not constants — they drift with market conditions themselves.

The split directly determines the optimization. If impact were purely permanent, the schedule wouldn’t matter (only total size does) and you’d simply trade slowly to avoid extra friction. If purely temporary, the squared penalty says uniform trading is optimal. Only the mixture makes Almgren-Chriss non-trivial. Harris Ch. 13 discusses the same distinction in the dealer context; Hasbrouck’s information share (article 5) measures precisely the permanent component.

One common misconception, corrected in passing: “all impact eventually reverts.” No. Empirically, the price impact of a metaorder (a large institutional trade) is roughly half permanent, half temporary: the permanent half is information reaching the price, the temporary half is the liquidity toll. Also note that Almgren-Chriss models both as linear while real impact is concave (the square-root law, article 8) — so the model’s γ\gamma should be read as the average permanent impact per unit traded, not the marginal.

Where the Model Breaks

That linearity assumption is the biggest of five failure points. Real impact is concave, so the linear model overestimates the marginal impact of large orders — the larger the order, the worse the overestimate. Second, the model assumes you have no alpha, that you’re a purely passive executor; if you hold private information, the optimal trajectory should be more front-loaded, grabbing the position before the alpha decays (Almgren 2003 is exactly the extension that adds drift). Third, σ\sigma, η\eta, γ\gamma are treated as constants; in reality all three drift with market conditions. Fourth, the model assumes your orders always fill — in reality limit orders can sit in the queue and miss (article 1). Fifth, no cross-impact: a large equity trade moves correlated ETFs, options, and futures, and the model is blind to all of it.

So the institutional recipe is: Almgren-Chriss as the skeleton, with real execution algos patching each of these five gaps. The extension literature grew along exactly these seams: Almgren (2003) adds alpha and nonlinear impact; Almgren, Thum, Hauptmann, and Li (2005) estimate the impact parameters from real market data; Huberman and Stanzl (2004) prove that permanent impact must be linear or price-manipulation quasi-arbitrage appears — an unexpected defense of the linearity assumption; Predoiu, Shaikhet, and Shreve (2011) re-solve optimal execution for general limit-order-book shapes; Cartea, Jaimungal, and Penalva (2015) give the modern textbook-chapter treatment. For practitioners, the base model plus calibration goes a long way; the extensions are for theorists and very-large-order desks.

There’s also an implementation-level choice: the discrete version carries τ\tau explicitly; the continuous version is the τ→0\tau \to 0 limit. Continuous formulas are clean and good for intuition, but your actual trading intervals are discrete (every minute, every 5 minutes), so the discrete version is the more honest one. Implement discrete, think continuous.

How Arithmion Implements This

arithmion.execution.AlmgrenChriss provides closed-form continuous and discrete trajectories, calibration of γ,η,λ\gamma, \eta, \lambda from execution data, mean-variance frontier visualization, and a multi-asset extension with a cross-impact matrix. It’s the workhorse of Arithmion’s execution simulator, and most institutional execution algos run some variant of it internally.

The most consequential number in the calibration is λ\lambda. It has no “correct” value, only a value that matches your situation. A mandate with a long horizon and tolerance for swings argues for low λ\lambda; decaying alpha also argues for low λ\lambda — trade faster and capture it; fear of a downturn and a need to cut exposure argues for high λ\lambda. Desk risk budgets press in too: a team coming off a drawdown will typically raise λ\lambda, paying up in execution cost for a tighter distribution of outcomes. In practice λ\lambda is set by the desk’s mandate and recalibrated periodically; Arithmion’s AdaptiveAlmgrenChriss adjusts it in real time from volatility and inventory levels.

The whole model in one sentence: permanent impact was paid the moment you decided to trade the size; everything else is using the single dial κT=Tλσ2/η\kappa T = T\sqrt{\lambda\sigma^2/\eta} to choose where you stand between temporary impact and inventory risk.

References

  • Harris, L. Trading and Exchanges: Market Microstructure for Practitioners. Oxford University Press, 2003. Ch. 13 (dealers), Ch. 19 (liquidity). ISBN: 978-0-19-514470-3.
  • Almgren, R., Chriss, N. “Optimal Execution of Portfolio Transactions.” Journal of Risk, 3(2), 2000. (Working paper version, 1999.)
  • Almgren, R. “Optimal Execution with Nonlinear Impact Functions and Trading-Enhanced Risk.” Applied Mathematical Finance, 10(1), 2003.
  • Almgren, R., Thum, C., Hauptmann, E., Li, H. “Direct Estimation of Equity Market Impact.” Risk, 2005.
  • Cartea, A., Jaimungal, S., Penalva, J. Algorithmic and High-Frequency Trading. Cambridge University Press, 2015.
  • Hasbrouck, J. Empirical Market Microstructure. Oxford University Press, 2007. ISBN: 978-0-19-518115-9 (hardcover) / 978-0-19-539320-0 (paperback).