跳到正文

Almgren-Chriss 最优执行:交易轨迹的均值-方差框架

卖得快付冲击,卖得慢担风险——Almgren-Chriss (2000) 把这个权衡写成一个可解的均值-方差问题,解出最优轨迹。整条推导、一个算到底的数值例子、以及模型在哪里失效。

第 6 篇 · 共 12 篇 约 12 分钟

假设你必须在未来 4 小时内卖出 100 万股苹果。卖得快,你自己的单子把价格砸下去,冲击成本吃掉你;卖得慢,你抱着大额库存暴露在价格波动里,一条坏新闻就能把你拍在沙滩上。快慢之间存在一条最优轨迹——它长什么样?

这就是 Almgren-Chriss 问题(Almgren and Chriss, 2000)。它是机构执行模型的常用起点,Harris 也给了篇幅(Harris,《Trading and Exchanges》,第 19 章)。基础版本假设线性的暂时和永久冲击,答案落在”立刻全成”和”均匀铺开”之间的一条平滑曲线上——而且整个权衡最终被压缩进一个无量纲数。下面把它推出来。

设定

你有一笔规模 QQ 股的父单要在水平期 TT 内执行。让 xtx_t 为 tt 时刻剩余股数,x0=Qx_0 = Q,xT=0x_T = 0。成交速率是 vt=−(xt−xt−1)v_t = -(x_t - x_{t-1}),每单位时间卖出的股数。

要算成本,先要说清你的交易怎么影响价格。Almgren-Chriss 把冲击拆成两块。第一块进中间价、留下来:

St=S0+(成交的永久冲击)+(基本面随机游走)S_t = S_0 + \text{(成交的永久冲击)} + \text{(基本面随机游走)}

具体地:

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

其中 γ\gamma 是永久冲击系数,τ\tau 是时间步长,ϵt\epsilon_t 是标准正态冲击。你卖得越多,中间价被压得越低,而且不回来。

第二块只在你成交那一刻起作用:实际执行价格比中间价再差一截,

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

其中 η\eta 是暂时冲击系数。这是你为”现在就要流动性”多付的钱,你一停手它就消失。这个永久/暂时的二分是整个模型的地基,后面会看到它直接决定优化的方向。

有了价格,收益就是逐笔成交的加总:

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)

我们关心的是相对无冲击基准少收了多少:

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}

随机项期望为零,取期望后剩下两块干净的东西:

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

第一项是暂时冲击成本——注意它是速率的平方和,同样的量卖得越急,罚得越重。第二项是永久冲击成本——只依赖总规模 QQ,跟你怎么排轨迹无关。这个区别马上就有用。

成本还有第二个维度。SS 里的随机游走意味着你没卖完的库存一直在承担价格风险:

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

其中 xtx_t 是剩余库存。库存维持越久、越大,方差越大。到这里,快慢权衡已经被写成数学了:∑vt2\sum v_t^2 罚快,∑xt2\sum x_t^2 罚慢。

优化

Almgren-Chriss 把两个维度合成一个均值-方差目标:

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

其中 λ\lambda 是风险厌恶参数:λ\lambda 越大越怕方差,λ\lambda 越小越在乎期望成本。代入上面的表达式:

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]

约束 ∑vt=Q\sum v_t = Q(你必须全成交)以及 vt≥0v_t \geq 0。

这里永久冲击项帮了个大忙:γ2Q2\frac{\gamma}{2} Q^2 给定 QQ 就是常数,跟轨迹无关,直接丢掉。换句话说,永久冲击是你决定交易那一刻就注定要付的,轨迹优化根本碰不到它;能优化的只有暂时冲击和风险的平衡。问题简化为:

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

约束 ∑vt=Q\sum v_t = Q。

离散时间解

用库存变量 xtx_t 求解最干净(vt=xt−1−xtv_t = x_{t-1} - x_t,端点 x0=Qx_0 = Q、xT=0x_T = 0 自动吸收了约束)。目标写成:

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

每个内点 xtx_t 只出现在三处:(xt−1−xt)2(x_{t-1}-x_t)^2、(xt−xt+1)2(x_t-x_{t+1})^2 和自己的方差项。对 xtx_t 求偏导并令其为零:

−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

整理一下:

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

左边是离散二阶导。这条差分方程说的是:最优库存曲线的”弯曲程度”处处正比于剩余库存本身——库存越多,越要加速往下卖。这类线性差分方程的解是 e±κte^{\pm\kappa t} 的组合,套上两端边界条件,得到:

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

其中 κ\kappa 由下式确定:

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

对应的每期成交量:

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)

这就是 Almgren-Chriss 的标准离散解。所有参数——风险厌恶 λ\lambda、波动率 σ\sigma、暂时冲击 η\eta——只通过一个组合数 κ\kappa 进入答案。这不是巧合,是下一节的全部内容。

连续时间极限

τ→0\tau \to 0 时公式更干净。库存和速率:

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)}

其中 κ=λσ2/η\kappa = \sqrt{\lambda \sigma^2 / \eta}。边界条件当场可验:x(0)=Q⋅sinh⁡(κT)/sinh⁡(κT)=Qx(0) = Q \cdot \sinh(\kappa T)/\sinh(\kappa T) = Q,x(T)=Q⋅sinh⁡(0)/sinh⁡(κT)=0x(T) = Q \cdot \sinh(0)/\sinh(\kappa T) = 0。库存从 QQ 平滑降到 0,κT>0\kappa T > 0 时曲线是凸的——前端偏置。

当 κT≫1\kappa T \gg 1 时,sinh⁡(κ(T−t))/sinh⁡(κT)≈e−κt\sinh(\kappa(T-t))/\sinh(\kappa T) \approx e^{-\kappa t},轨迹退化成一条纯指数衰减,常用的近似写法是:

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}}

(注意这只是大 κT\kappa T 的近似,不是精确解——精确的 v(0)=Qκcosh⁡(κT)/sinh⁡(κT)v(0) = Q\kappa \cosh(\kappa T)/\sinh(\kappa T)。)两个极限都对得上:κT\kappa T 小时 v(0)≈Q/Tv(0) \approx Q/T,均匀成交;κT\kappa T 大时 v(0)≈Qκv(0) \approx Q\kappa,可以远大于 Q/TQ/T;κT\kappa T 极大(极端风险厌恶)时 v(0)→Qv(0) \to Q——你立刻全成,这是市价单极限。

三种情景

于是整个问题被压缩进一个无量纲数 κT=Tλσ2/η\kappa T = T\sqrt{\lambda \sigma^2 / \eta},它就是快慢之争的裁判。

κT\kappa T 低(风险厌恶低、波动小、暂时冲击贵):v(t)≈Q/Tv(t) \approx Q/T,近乎均匀铺开。你不怕拿库存,就慢慢卖省冲击,成本几乎全是暂时冲击。

κT\kappa T 高(风险厌恶高、波动大、暂时冲击便宜):轨迹强前端偏置,大部分量一开始就出掉。你在主动多付暂时冲击(平方罚则下快就是贵),换来的是库存风险的快速下降——这是花钱买确定性。

κT\kappa T 中间:平滑曲线,介于两者之间。机构执行最常落在这一档。情景之间的边界大致在 κT=2\kappa T = 2 附近。

一个数值算例

把数字代进去走一遍,顺便踩掉一个几乎人人会踩的坑。

你要卖 Q=1,000,000Q = 1{,}000{,}000 股,T=4T = 4 小时 = 14400 秒,τ=60\tau = 60 秒(1 分钟 bar)。日波动 σ=0.02\sigma = 0.02,暂时冲击 η=10−6\eta = 10^{-6}(每股每秒),永久冲击 γ=10−7\gamma = 10^{-7}(每股),风险厌恶 λ=10−6\lambda = 10^{-6}。

坑在单位。如果你把日波动 0.02 直接塞进公式:

κ=λσ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

得到 κT=0.02⋅14400=288\kappa T = 0.02 \cdot 14400 = 288——一个荒谬的强前端偏置,等于说”半分钟内清仓”。错在 TT 以秒计而 σ\sigma 是日的。方差按时间线性缩放:每秒方差是 σ2/23400\sigma^2 / 23400(一个交易日 6.5 小时),所以每秒 σ≈0.02/154≈1.3×10−4\sigma \approx 0.02 / 154 \approx 1.3 \times 10^{-4},每秒方差 1.7×10−81.7 \times 10^{-8}。

用对单位重来:λσ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},除以 η=10−6\eta = 10^{-6} 得 κ2=1.7×10−8\kappa^2 = 1.7 \times 10^{-8},κ≈1.3×10−4\kappa \approx 1.3 \times 10^{-4} 每秒。于是 κT≈1.87\kappa T \approx 1.87——中间情景,轨迹温和前端偏置。同一组参数,单位一错,结论从”从容铺 4 小时”变成”半分钟砸完”。核对 σ\sigma、η\eta、TT 的单位一致,是用这个模型的第一道检查。

代入精确解算两端的速率(sinh⁡(1.87)≈3.17\sinh(1.87) \approx 3.17,cosh⁡(1.87)≈3.32\cosh(1.87) \approx 3.32):

初始速率 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 股/秒。均匀速率是 106/14400≈6910^6 / 14400 \approx 69 股/秒,所以起步大约是均匀的 2 倍。末端速率 v(T)=Qκ/sinh⁡(κT)=130/3.17≈41v(T) = Q\kappa/\sinh(\kappa T) = 130 / 3.17 \approx 41 股/秒,约为均匀的 0.6 倍。轨迹从 136 股/秒平滑降到 41 股/秒。

一个看似不通过的检验:头尾平均 (136+41)/2≈88(136+41)/2 \approx 88 股/秒,乘 14400 秒得 1.27×1061.27 \times 10^6 股,比 QQ 多了近三成?没错,而且这不说明算错了——cosh⁡\cosh 是凸函数,头尾取平均系统性高估了曲线下面积。精确轨迹的积分恰好是 QQ(由构造保证),真正的平均速率就是 69 股/秒。

期望成本

期望成本回到那两块:

Expected cost=η∫0Tv(t)2 dt⏟暂时冲击+γ2Q2⏟永久冲击\text{Expected cost} = \underbrace{\eta \int_0^T v(t)^2 \, dt}_{\text{暂时冲击}} + \underbrace{\frac{\gamma}{2} Q^2}_{\text{永久冲击}}

对算例,暂时冲击项用 v(t)v(t) 的均方根粗估约 80 股/秒:∫v2dt≈802⋅14400=9.2×107\int v^2 dt \approx 80^2 \cdot 14400 = 9.2 \times 10^7,乘以 η=10−6\eta = 10^{-6} 得约 9292 美元。永久冲击项:γ2Q2=0.5⋅10−7⋅1012=50,000\frac{\gamma}{2} Q^2 = 0.5 \cdot 10^{-7} \cdot 10^{12} = 50{,}000 美元。

两项差了三个数量级——这笔单的成本几乎全是永久冲击。对 100 万股、$100 一股的出售(名义 $100M),50,000是5bp,量级合理。但回想前面:永久冲击是轨迹碰不到的。所以这个例子里优化真正在管的,是那50{,}000 是 5 bp,量级合理。但回想前面:永久冲击是轨迹碰不到的。所以这个例子里优化真正在管的,是那 92 的暂时冲击和下面这个方差之间的平衡。

成本方差:σ2∫x(t)2dt\sigma^2 \int x(t)^2 dt。x(t)x(t) 在水平期上平均约 Q/2=5×105Q/2 = 5 \times 10^5 股,∫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},乘每秒方差 1.7×10−81.7 \times 10^{-8} 得方差 6.1×1076.1 \times 10^7(美元平方),标准差 6.1×107≈7800\sqrt{6.1 \times 10^7} \approx 7800 美元。也就是说,这笔执行的成本围绕 50,00050{,}000 的期望有大约 ±7800\pm 7800 的一倍标准差摆动。期望成本对标准差之比 50,000/7,800≈6.450{,}000 / 7{,}800 \approx 6.4——在 λ=10−6\lambda = 10^{-6} 下,这就是均值-方差目标平衡出来的位置。

风险调整前沿

让 λ\lambda 扫过全程,最优轨迹描出一条前沿。λ=0\lambda = 0 是纯成本最小化:把成交铺到尽可能长的水平期,暂时冲击压到最低,方差随它去。λ=∞\lambda = \infty 是纯方差最小化:立刻执行,市价单,冲击照单全收。中间的 λ\lambda 平滑过渡。前沿是凸的:λ\lambda 每增加一点,期望成本上升(多付冲击)换方差下降(更快完成)——跟组合理论里的有效前沿是同一种几何。Harris 第 19 章有图示,Hasbrouck (2007) 给了正式版本。

Python 实现

一个简单的 Almgren-Chriss 仿真器:

import numpy as np

def almgren_chriss_trajectory(Q, T, sigma, eta, lam, n_periods=100):
    """
    计算最优 Almgren-Chriss 轨迹。
    Q: 总成交股数
    T: 水平期(秒)
    sigma: 每秒波动率(小数)
    eta: 暂时冲击系数
    lam: 风险厌恶
    返回:(t, 库存 x(t), 速率 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  # 每期成交速率
    return t, x, v


# 示例:4 小时 100 万股
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"初始速率: {v[0]:.1f} 股/秒")
print(f"末尾速率: {v[-1]:.1f} 股/秒")
print(f"平均速率: {v.mean():.1f} 股/秒(目标: {1e6/14400:.1f})")

合理参数下,初始速率是平均的两倍上下,末尾速率低于平均——就是上面手算的那条前端偏置曲线。注意 sigma 传的是每秒波动率:单位坑在代码里同样存在。

永久与暂时:为什么这个二分是贡献本身

回头看模型的地基。Almgren-Chriss 真正的贡献不是那条 sinh 曲线,而是把冲击拆成两类并说清各自的后果。永久冲击(γ\gamma):价格因你成交而移动并停留,你收手了它也不回来——这是”信息”分量,跟 Kyle 的 lambda 是一回事。暂时冲击(η\eta):价格被你压下去,你一停就弹回来——这是”流动性”分量,要求即时性的瞬态代价。

经验上两者形态很不一样。永久冲击小但持续,流动美股上量级在个位 bp 以下(随流动性和规模变化)。暂时冲击更大但会回复,成交期间可以到几个 bp 至十来个 bp,大部分在几分钟内消失。这些是量级感,不是常数——它们本身就随市况漂。

这个二分直接决定优化方向:如果冲击是纯永久的,怎么排轨迹都一样(它只看总量),你只需要慢慢来避免额外摩擦;如果是纯暂时的,平方罚则说均匀成交最优;两者混合,才有 Almgren-Chriss 这个非平凡的解。Harris 第 13 章在 dealer 语境下讨论了同一个区分,Hasbrouck 的信息份额(第 5 篇)度量的正是永久分量。

顺带纠正一个常见误解:“所有冲击最终都会回复。“不是。经验研究里,metaorder(大额机构成交)的价格冲击大致一半永久、一半暂时:永久的那半反映信息进了价格,暂时的那半是流动性成本。还要注意,Almgren-Chriss 把两者都建成线性,而真实冲击是凹的(平方根律,第 8 篇),所以模型里的 γ\gamma 应理解为平均的每单位成交永久冲击,不是边际。

模型在哪里失效

上面这条线性假设是五个失效点里最大的一个。真实冲击凹,意味着线性模型对大单会高估边际冲击——单子越大,高估越狠。第二,模型假设你没有 alpha,是个纯被动执行者;如果你有私人信息,最优轨迹应该更前端偏置,赶在 alpha 衰减前把仓位拿到手(Almgren 2003 正是加了漂移项的扩展)。第三,σ\sigma、η\eta、γ\gamma 被当成常数,现实里它们全随市况漂移。第四,模型假设你的单永远成交——现实里限价单可能排队排不到(第 1 篇)。第五,没有交叉冲击:大额股票成交会带动相关 ETF、期权、期货,模型对此视而不见。

所以机构的用法是:Almgren-Chriss 当骨架,真正的执行算法在上面为这五条各打补丁。扩展文献差不多就是沿这几条缺口长出来的:Almgren (2003) 加入 alpha 与非线性冲击;Almgren, Thum, Hauptmann, Li (2005) 用真实市场数据估计冲击参数;Huberman and Stanzl (2004) 证明永久冲击必须线性,否则存在价格操纵式的准套利——这给了线性假设一个意外的辩护;Predoiu, Shaikhet, Shreve (2011) 在一般限价簿形状下重解最优执行;Cartea, Jaimungal, Penalva (2015) 在教科书里给了整章的现代处理。对实战派,基础模型加标定就很能打;扩展是理论家和大单 desk 的事。

还有一个实现层面的选择:离散版显式带 τ\tau,连续版是 τ→0\tau \to 0 的极限。连续版公式干净、适合理论;但实操里你的成交间隔就是离散的(每分钟、每 5 分钟),离散版更诚实。实现用离散,直觉用连续。

Arithmion 怎么实现

arithmion.execution.AlmgrenChriss 提供连续和离散轨迹的闭式解、从执行数据标定 γ,η,λ\gamma, \eta, \lambda、均值-方差前沿可视化,以及带交叉冲击矩阵的多资产扩展。这是 Arithmion 执行仿真器的核心;多数机构执行算法内部跑的也是这个的某种变体。

标定里最有后果的一个数是 λ\lambda。它没有”正确值”,只有跟你处境匹配的值:授权是长水平期、能扛波动的,λ\lambda 低;有 alpha 在衰减的,λ\lambda 也应该低——快点成交把 alpha 抓到手;担心市场要跌、想快速降敞口的,λ\lambda 高。desk 的风险预算也会压进来:刚经历回撤的团队通常会调高 λ\lambda,用更贵的执行换更窄的结果分布。实践中 λ\lambda 由 desk 授权设定、定期重标定;Arithmion 的 AdaptiveAlmgrenChriss 会根据波动率和库存水平实时调整它。

把整个模型收在一句话里:永久冲击在你决定交易时已经付掉,剩下的全部艺术是用 κT=Tλσ2/η\kappa T = T\sqrt{\lambda\sigma^2/\eta} 这一个旋钮,在暂时冲击和库存风险之间选你要站的位置。

参考文献

  • Harris, L. Trading and Exchanges: Market Microstructure for Practitioners. Oxford University Press, 2003. 第 13 章(dealers),第 19 章(流动性)。ISBN: 978-0-19-514470-3.
  • Almgren, R., Chriss, N. “Optimal Execution of Portfolio Transactions.” Journal of Risk, 3(2), 2000.(工作论文版,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(精装)/ 978-0-19-539320-0(平装)。