22. 市场冲击模型:Almgren-Chriss模型,大单拆单算法
做量化交易的朋友,尤其是做高频或者程序化套利的,一定都遇到过这个灵魂拷问:「我的大单子怎么一进去,价格就跑了?」
嗯,这就是市场冲击。说白了,你下单本身就在改变市场。你买,价格涨;你卖,价格跌。对于小资金可能无所谓,但做基差套利,尤其是跨期、跨品种套利,仓位一重,冲击成本直接吃掉你大部分利润。
我个人习惯,在实盘前一定会用Almgren-Chriss模型跑一遍冲击成本预估。今天我们就来拆解这个经典模型,以及它背后的拆单算法。
22.1 市场冲击的两种成分
先理清概念。市场冲击不是铁板一块,它分两块:
- 永久冲击(Permanent Impact):你买完,价格回不去了。这反映了市场吸收了你的订单,信息被消化了。
- 临时冲击(Temporary Impact):你买的时候价格被推高,但过一会儿流动性恢复,价格又回落。这部分是「过路费」。
Almgren-Chriss模型的核心,就是把这两部分分开建模。为什么?因为永久冲击你躲不掉,但临时冲击可以通过拆单来优化。
核心公式(简化版):
价格变化 = 永久冲击项 + 临时冲击项
ΔS(t) = γ * v(t) + η * σ * sign(v(t))
其中:γ是永久冲击系数,v(t)是交易速率,η是临时冲击系数,σ是波动率。
我在项目中遇到过最典型的案例:某次做螺纹钢跨期套利,一次性挂了200手买单,结果盘口瞬间被打穿三个tick,成交均价直接比预期高了0.5%。后来用Almgren-Chriss模型一算,发现临时冲击占了总成本的70%。
22.2 大单拆单:从「一锤子买卖」到「细水长流」
既然大单直接砸会引发冲击,那我们就把它拆成小单,分批进场。这就是拆单算法的基本思想。
Almgren-Chriss模型给出了一个最优拆单路径:在「快速完成」和「减少冲击」之间找平衡。
你想想看,如果你拆得太碎,时间拉长,价格波动的风险就大了。如果你一把梭,冲击成本又高。所以这是个典型的优化问题。
我的经验: 对于日内套利策略,我一般把拆单时间窗口设在5-15分钟。太短了冲击降不下来,太长了基差可能已经变了。
22.3 Almgren-Chriss模型的数学框架
这里我尽量不堆公式,但核心逻辑你得懂。
模型假设你要在时间T内完成总数量Q的订单。你选择一条交易速率曲线v(t),使得总成本最小化:
总成本 = 永久冲击成本 + 临时冲击成本 + 风险成本
其中风险成本来自你持仓期间的价格波动。模型解出来,最优策略是:前期交易速率快,后期逐渐减慢。为什么?因为前期你仓位轻,波动风险小,可以多交易;后期仓位重,要减少暴露。
嗯,这里要注意:这个结论的前提是价格服从随机游走。如果你的品种有趋势性,那策略就要调整了。
22.4 代码实现:一个简单的拆单模拟器
光说不练假把式。我写了一个简化版的Almgren-Chriss拆单模拟,帮你直观感受一下。
import numpy as np
import matplotlib.pyplot as plt
class AlmgrenChriss:
def __init__(self, Q, T, sigma, gamma, eta):
self.Q = Q # 总订单量
self.T = T # 总时间
self.sigma = sigma # 波动率
self.gamma = gamma # 永久冲击系数
self.eta = eta # 临时冲击系数
def optimal_trajectory(self, N=100):
"""计算最优交易路径"""
dt = self.T / N
t = np.linspace(0, self.T, N)
# 最优解:交易速率随时间递减
# 这里用简化版:线性递减
v = np.linspace(2*self.Q/self.T, 0, N)
# 累计成交量
x = np.cumsum(v * dt)
# 价格冲击
perm_impact = self.gamma * v
temp_impact = self.eta * self.sigma * np.sign(v)
total_impact = perm_impact + temp_impact
return t, x, v, total_impact
# 使用示例
model = AlmgrenChriss(Q=1000, T=600, sigma=0.02, gamma=0.001, eta=0.005)
t, x, v, impact = model.optimal_trajectory()
print(f"最终成交量: {x[-1]:.0f}")
print(f"最大冲击成本: {np.max(impact):.4f}")
避坑指南: 我曾经在实盘里直接用这个模型,结果发现冲击系数γ和η根本不准。后来才意识到,不同品种、不同时间段的流动性差异巨大。建议你至少用一周的历史数据来校准参数,别直接用默认值。
22.5 知识体系图:Almgren-Chriss模型全流程
下面这张图帮你理清整个逻辑链条:
22.6 实战中的几个关键点
模型讲完了,说几个实战中容易踩的坑:
- 参数校准是灵魂:γ和η不是固定的。我习惯每天开盘前用前5分钟的数据重新算一遍。
- 别忘了滑点:Almgren-Chriss模型假设你能按计算价格成交,但实际还有买卖价差。建议在冲击成本上加一个buffer。
- 拆单粒度要合适:拆得太细,交易次数太多,手续费和延迟成本反而上升。我一般控制在每单不超过总订单量的5%。
- 市场状态要识别:如果盘口深度突然变薄,或者波动率飙升,模型参数要立刻切换。我曾经在数据发布前没调整参数,结果冲击成本翻了三倍。
一个小技巧: 对于基差套利,你可以把两个腿的冲击成本分开算。比如做多近月、做空远月,近月流动性好,冲击系数小;远月流动性差,冲击系数大。这样拆单时,远月可以拆得更碎一些。
22.7 总结
Almgren-Chriss模型不是银弹,但它给了我们一个系统性的框架去思考大单执行问题。说白了,它把「怎么下单」这件事从艺术变成了科学。
我个人建议,刚开始做套利的朋友,先别急着上复杂模型。用这个简化版跑一段时间,积累一些冲击成本的历史数据,慢慢你就能找到自己品种的「手感」了。
嗯,今天就到这里。记住:冲击成本是套利者的隐形杀手,别让它悄悄吃掉你的利润。
公众号:蓝海资料掘金营,微信deep3321