利弗莫尔的交易思想里,“最小阻力方向”是一种很有生命力的市场描述。今天再看,它很像一种未经数学化的动力学直觉:价格之所以向某个方向运动,是因为那个方向存在持续的交易压力,而市场恰好又更容易被沿着这个方向推动。

现代量化金融换了一套语言。我们讨论订单流、流动性、条件方差和随机过程,很少把这些东西与一百年前投机者所谓的“阻力”联系起来。但如果认真翻译这句话,它会导向一个很现代的问题:为什么收益方向很难预测,而波动率却具有明显的可预测性?

力学提供了一种组织问题的方式:先找运动变量,再问推动它的压力,以及系统对压力的响应。

1. 价格是坐标,订单是压力

拉格朗日力学里的广义坐标,用来描述系统的独立自由度。如果只研究一只资产的价格运动,最简单的起点可以只有一个坐标。盈利、估值、成交量和情绪都会变化,但它们不是资产在市场中的“位置”;市场不断重新确定的核心变量仍然是价格。

设价格为 SS,取对数价格:

q=log⁡Sq = \log S

小幅变化时:

dq≈dSS\mathrm{d}q \approx \frac{\mathrm{d}S}{S}

也就是收益率。因此 qq 可以被看作价格运动的一维坐标,而订单簿、融资条件和参与者约束,决定这个坐标如何运动。

如果完全沿用经典力学,我们也许会写下 md2qdt2=Fm\frac{\mathrm{d}^{2}q}{\mathrm{d}t^{2}}=F。但价格没有明显的机械惯性:如果所有方向性的交易需求突然消失,并没有什么物理理由要求一只刚刚上涨的股票继续上涨。

现实中的动量,更可能来自订单生成机制的持续性。机构需要数天完成建仓,趋势算法会把过去的价格变化转化成新订单,风险约束也会把一次冲击延续成后续交易。因此,在许多交易尺度上,价格可以被类比为一个过阻尼系统,从更简单的关系开始:

dqdt≈MJ\frac{\mathrm{d}q}{\mathrm{d}t} \approx M J

这里的 JJ 表示方向性的订单压力。它不是全市场“买入减卖出”——每一笔成交当然都有买卖双方——而是哪一侧正在主动索取流动性。主动买单不断吃掉卖盘时,J>0J>0;主动卖单不断打掉买盘时,J<0J<0。若希望描述完整的订单簿变化,还必须把限价单的新增和撤销纳入压力的定义。

MM 则表示市场易动度(market mobility),即单位订单压力能造成多大的价格响应。如果借用“阻力”的语言,1/M1/M 就是一个很直观的对应物。同样大小的订单,在不同的订单簿上,会走出完全不同的距离。

这种短时线性响应有实证依据。Cont、Kukanov 与 Stoikov 的订单簿事件研究将新增、撤单与成交事件合并为订单流不平衡,发现它与短时价格变化存在近似线性关系,响应斜率随市场深度增加而下降。

2. 一笔500股订单究竟推动了什么

LOBSTER 官方公开样本可以给这个抽象关系一个直观形状。下面是 NASDAQ AAPL 在2012年6月21日样本中首个订单簿快照的前五档。原始价格以万分之一美元存储,表中已按官方格式说明还原为美元。

买量(股)买价(美元)盘口卖价(美元)卖量(股)
卖五586.9550
卖四586.89300
卖三586.10200
卖二585.98200
卖一585.94200
585.33中间价 585.635585.94
18585.33买一
150585.30买二
5585.10买三
89585.01买四
5584.97买五

价格从上向下降低;买盘在左下、卖盘在右上,中间参考位置单独居中。

这里不存在一笔正在等待成交的“585.635美元订单”。中间价只是最佳买价与最佳卖价之间的参考位置;真实交易必须碰到盘口的一侧。

先把盘口固定在这个快照上。一笔500股市价买单,会从卖一开始向上吃单:

200@585.94  ⟶  200@585.98  ⟶  100@586.10200@585.94 \;\longrightarrow\; 200@585.98 \;\longrightarrow\; 100@586.10

平均成交价为:

PVWAP=∑i=13vipi∑i=13vi=585.988P_{\mathrm{VWAP}} = \frac{\sum_{i=1}^{3} v_i p_i}{\sum_{i=1}^{3} v_i} = 585.988

其中 viv_i 为各档实际成交数量,pip_i 为相应成交价格;价格单位为美元,数量单位为股。这里三档成交数量分别为200、200和100股。

成交后,卖一变成586.10美元,剩余100股;如果买一保持585.33美元,中间价便从585.635变成585.715美元。平均成交价、最后成交价和中间价的变化,是三个不同的量。

订单不是抽象地把“当前价格”改变了一点,而是在实际订单簿里消耗掉一层又一层流动性。若卖一有数千股,它可能在第一档就全部成交;如果附近只有几十股,它就会迅速穿过多个价位。

这就是 MM 最直观的含义:订单压力相同,盘口越薄,价格越容易被推得更远。 真实市场里的 MM 还受到隐藏流动性、撤单、做市商风险预算以及潜在买卖意愿的影响。

3. 波动率可以从哪里来

传统随机价格模型常写成:

dqt=μt dt+σt dWt\mathrm{d}q_t = \mu_t\,\mathrm{d}t + \sigma_t\,\mathrm{d}W_t

其中 σt\sigma_t 是波动率。这种表达很有用,却把波动率直接放进了模型。反过来从市场响应出发,我们可以问:价格的不确定性是怎样被订单与流动性共同产生的?

为了把市场响应写成可计算的关系,在从时刻 tt 开始、长度为 Δ\Delta 的窗口里,定义对数收益:

r(t,Δ)=qt+Δ−qtr(t,\Delta)=q_{t+\Delta}-q_t

用 J(t,Δ)J(t,\Delta) 表示同一窗口累计的方向性订单压力,M(t,Δ)M(t,\Delta) 表示市场对它的响应系数。局部线性关系为:

r(t,Δ)≈M(t,Δ)J(t,Δ)r(t,\Delta)\approx M(t,\Delta)J(t,\Delta)

接下来固定这个窗口,并把响应系数 MM 视为根据当前信息已经给定的量。为使推导更清楚,暂时省略 (t,Δ)(t,\Delta),写成 r≈MJr\approx MJ。

1. 把订单压力分成预期与创新

时刻 tt 的信息集记为 Ft\mathcal F_t。条件期望

Et[J]≡E[J∣Ft]\mathbb E_t[J]\equiv\mathbb E[J\mid\mathcal F_t]

表示根据当前信息,对未来订单压力作出的概率加权平均判断。实际订单压力与这个判断之间的差,定义为订单流创新:

εJ=J−Et[J]\varepsilon_J=J-\mathbb E_t[J]

因此,订单压力可以写成:

J=Et[J]+εJJ=\mathbb E_t[J]+\varepsilon_J

这里的“创新”不是指订单一定很特殊,而是指它尚未包含在当前的预期中。按照这个定义,它的条件均值为零:

Et[εJ]=Et ⁣[J−Et[J]]=Et[J]−Et[J]=0.\begin{aligned} \mathbb E_t[\varepsilon_J] &=\mathbb E_t\!\left[J-\mathbb E_t[J]\right]\\ &=\mathbb E_t[J]-\mathbb E_t[J]\\ &=0. \end{aligned}

第二行成立,是因为在给定当前信息后,Et[J]\mathbb E_t[J] 已经是一个确定的数;再对它取条件期望,仍然得到它本身。

2. 得到收益的条件均值

将订单压力的分解代入价格响应关系:

r≈MEt[J]+MεJr\approx M\mathbb E_t[J]+M\varepsilon_J

对两边取条件期望。由于 MM 在这里被视为给定的响应系数,可以移到条件期望之外:

Et[r]≈MEt[J]+MEt[εJ]=MEt[J].\begin{aligned} \mathbb E_t[r] &\approx M\mathbb E_t[J]+M\mathbb E_t[\varepsilon_J]\\ &=M\mathbb E_t[J]. \end{aligned}

所以,预期订单压力经过市场响应系数的放大,给出了预期收益。实际收益减去这个条件均值,剩下的是:

r−Et[r]≈MEt[J]+MεJ−MEt[J]=MεJ.\begin{aligned} r-\mathbb E_t[r] &\approx M\mathbb E_t[J]+M\varepsilon_J-M\mathbb E_t[J]\\ &=M\varepsilon_J. \end{aligned}

收益围绕预期的偏离,来自订单压力围绕预期的偏离,并由 MM 放大。

3. 从收益偏离得到条件方差

条件方差衡量的正是“偏离条件均值的平方有多大”。按照定义:

Var⁡(r∣Ft)=Et ⁣[(r−Et[r])2]\operatorname{Var}(r\mid\mathcal F_t) =\mathbb E_t\!\left[(r-\mathbb E_t[r])^2\right]

把刚才得到的 r−Et[r]≈MεJr-\mathbb E_t[r]\approx M\varepsilon_J 代进去:

Var⁡(r∣Ft)≈Et ⁣[(MεJ)2]=Et ⁣[M2εJ2]=M2Et[εJ2].\begin{aligned} \operatorname{Var}(r\mid\mathcal F_t) &\approx\mathbb E_t\!\left[(M\varepsilon_J)^2\right]\\ &=\mathbb E_t\!\left[M^2\varepsilon_J^2\right]\\ &=M^2\mathbb E_t[\varepsilon_J^2]. \end{aligned}

这里出现 M2M^2,是因为方差计算的是平方偏离:如果同样的订单创新使收益偏离放大两倍,平方偏离就会放大四倍。

而订单流创新的条件均值为零,所以它的条件二阶矩就是条件方差。它也等于原始订单压力的条件方差:

Et[εJ2]=Et ⁣[(J−Et[J])2]=Var⁡(J∣Ft).\begin{aligned} \mathbb E_t[\varepsilon_J^2] &=\mathbb E_t\!\left[(J-\mathbb E_t[J])^2\right]\\ &=\operatorname{Var}(J\mid\mathcal F_t). \end{aligned}

定义订单压力的条件方差为:

νJ(t,Δ)≡Var⁡ ⁣(J(t,Δ)∣Ft)\nu_J(t,\Delta) \equiv\operatorname{Var}\!\left(J(t,\Delta)\mid\mathcal F_t\right)

恢复完整的窗口记号,便得到:

Var⁡ ⁣(r(t,Δ)∣Ft)≈M(t,Δ)2νJ(t,Δ)\operatorname{Var}\!\left(r(t,\Delta)\mid\mathcal F_t\right) \approx M(t,\Delta)^2\nu_J(t,\Delta)

未来订单压力越不确定,收益越不确定;市场越容易被订单推动,同样的订单不确定性就会产生越大的收益方差。 这两个作用在公式里相乘。

4. 从窗口方差到波动率

上式得到的是整个 Δ\Delta 窗口的收益方差。如果用 σt2\sigma_t^2 表示这个窗口内的平均单位时间方差率,则:

σt2≡Var⁡(r(t,Δ)∣Ft)Δ≈M(t,Δ)2νJ(t,Δ)Δ\sigma_t^2\equiv\frac{\operatorname{Var}(r(t,\Delta)\mid\mathcal F_t)}{\Delta} \approx\frac{M(t,\Delta)^2\nu_J(t,\Delta)}{\Delta}

波动率是方差率的平方根,因此相应地有:

σt≈∣M(t,Δ)∣νJ(t,Δ)Δ\sigma_t\approx |M(t,\Delta)|\sqrt{\frac{\nu_J(t,\Delta)}{\Delta}}

时间单位要保持一致:Δ\Delta 若以年计,得到的就是年化口径;若以交易日计,得到的就是每交易日的口径。这里从窗口方差换算得到的是该窗口的平均方差率。

整个推导的关键,是在当前信息下把 MM 当作给定的响应系数:它才能从条件期望中提出。如果还要描述窗口内 MM 的随机变化,就需要进一步计算 MJMJ 的条件方差。

这个式子提供了一种机制解释:价格的不确定性,可以由“未来订单会有多不确定”与“市场会把这些订单放大多少”共同产生。

深度下降、做市商撤单或风险容量收缩,会使 MM 增大;财报、指数调整、机构换仓或去杠杆,则可能提高订单流创新的条件方差。极端行情有时恰好是两者同时发生:订单压力增加,吸收订单的能力却下降。

4. 为什么市场状态会留下记忆

如果未来窗口里的 MM 和 νJ\nu_J 具有持续性,那么未来方差水平就会依赖今天已经观察到的状态。沿用上述近似:

Et ⁣[σt+h2]≈Et ⁣[M(t+h,Δ)2 νJ(t+h,Δ)Δ]\mathbb{E}_t\!\left[\sigma_{t+h}^2\right] \approx \mathbb{E}_t\!\left[\frac{M(t+h,\Delta)^2\,\nu_J(t+h,\Delta)}{\Delta}\right]

订单簿深度、融资环境和做市商风险容量,不会每一刻都重新随机生成。一笔机构大单也不会在午夜突然消失;趋势交易、财报后的重新配置和去杠杆,同样具有持续时间。

于是,市场今天处于“容易被推动”的状态,本身就可能包含关于明天波动率的信息。需要预测的不是一个孤立的 σ\sigma,而是产生价格响应与订单不确定性的状态。

市场状态也会逐渐恢复。机构完成换仓、事件带来的分歧逐渐消化,订单流创新的强度下降;做市商重新补充报价、风险容量恢复,市场吸收订单的能力改善。前者使 νJ\nu_J 减小,后者使 MM 减小,都会推动条件波动率收敛。如果去杠杆继续、流动性仍然紧张,高波动则会持续,甚至加剧。

因此,延续性与收敛并不矛盾:状态调整需要时间,所以高波动之后往往仍然偏高;冲击逐渐消退,波动幅度又会从极端水平回落。

5. 从SPY价格数据看波动状态

使用 QSTrader 公开代码库的 SPY 历史价格文件,可以做一个简单的描述性实验。样本覆盖2000年1月3日至2016年1月4日,共4,026条日度记录,计算使用复权收盘价(Adj Close)。

首先按日期升序排列,计算每日对数收益:

rt=log⁡ ⁣(PtadjPt−1adj)r_t = \log\!\left(\frac{P_t^{\mathrm{adj}}}{P_{t-1}^{\mathrm{adj}}}\right)

对每一个有足够历史和未来记录的日期,计算截至当天的20个日收益的样本标准差,乘以 252\sqrt{252} 得到年化实现波动率;再计算随后20个日收益的同口径波动率。两段窗口在同一观测内部互不重叠。

然后按当前20日波动率,把3,986个有效观测从低到高排成十个近似等大的组,观察各组未来20日波动率的平均值。

100%查看原图
当前与未来20日平均年化波动率的关系:高波动仍偏高,极端状态平均向内收拢

图1:每个点代表一个波动率分组,横轴是该组当前20日的平均年化波动率,纵轴是随后20日的平均年化波动率。灰色等值线表示“未来与当前一样高”:线上方表示平均抬升,线下方表示平均回落。每组398或399个观测,分组阈值使用全样本。

这张图同时展示两件事。第一,高波动组的未来波动率仍然明显高于低波动组:两端分别约为34.6%与10.6%,说明状态具有延续性。第二,极端状态在组平均意义上有所收拢:最高组从当前的41.3%降至未来的34.6%,最低组则从7.1%升至10.6%。总体上延续的是高低差异,不一定是原来的极端幅度。

当前波动率组当前20日均值未来20日均值
1(最低)7.1%10.6%
28.9%11.3%
310.2%12.8%
411.8%12.4%
513.6%13.9%
615.4%14.8%
717.4%16.9%
820.7%20.4%
925.5%23.9%
10(最高)41.3%34.6%

当前与随后20日波动率的相关系数约为0.727。即使只是这样简单的分组,未来波动水平也已经呈现出清楚的差异:今天所处的波动状态,包含了关于未来波动的信息。

6. 方向与强度,是两个不同的问题

我们通常把这种现象称为波动聚集,再用 GARCH、HAR 或其他时间序列模型去捕捉它。这些模型将历史波动与未来波动联系起来;订单流的视角则解释了这种记忆可能来自哪里:产生波动率的市场状态本身有记忆。

方向性的订单压力取决于带符号的条件均值 Et[J]\mathbb{E}_t[J]。不同参与者的需求可能相互抵消,而且一旦方向性信息被预期并反映到价格中,继续预测收益就更困难。

订单流的强度却更接近二阶矩 Et[J2]\mathbb{E}_t[J^2]。符号相反,并不会像在均值里那样相互抵消。不过二阶矩也不等于条件方差,两者满足:

Var⁡t(J)=Et[J2]−(Et[J])2\operatorname{Var}_t(J) = \mathbb{E}_t[J^2] - \bigl(\mathbb{E}_t[J]\bigr)^2

大量相反方向订单,可以使窗口末端的净压力很小,同时留下剧烈的窗口内价格运动。方向被抵消,交易活动的强度却仍然存在。

我们可能不知道明天究竟涨还是跌,却仍有机会判断明天是不是容易出现大幅运动的市场。这就是条件均值与条件方差的区别。

于是,“价格沿最小阻力方向运动”的投机直觉,经过价格坐标、订单压力和市场响应的翻译,可以引出一个现代量化命题:

价格方向通常更难预测,而具有持续性的市场状态,可以使条件波动率具有可预测性。

连接它们的,仍然是那个简单的问题:同样的订单,在今天这个市场里,究竟能够把价格推多远?

数据与方法

公式采用固定时间窗口内、MM 给定的局部线性响应模型;未来 MM 的随机变化及其与订单流的相关性,属于进一步建模的内容。微分写法用于表达平滑后的价格响应,计算使用离散窗口。

SPY图使用全样本分组,相邻窗口存在重叠,展示的是历史统计关系。极端组的平均收拢也包含估计噪声与筛选效应;区分这些效应与市场恢复机制,需要结合订单流和流动性数据。正式预测评估应按时间划分训练与测试样本。