本文深入探讨了做市商在交易中面临的挑战,核心在于理解市场微观结构,包括中间价的变动、成交的条件性、深度及其行为模式,以及如何通过控制报价、量化风险来应对不利的市场变动。文章强调了成交后的价格走向(markout)的重要性,以及如何利用它来评估交易的毒性进而优化做市策略。
你懂那种感觉。你对多空双方都报价。点差是一个 tick。成交的频率足以让你觉得有成效。
然后市场悄悄地纠正了你。
一个卖单击中了你的买单。然后又一个。然后是一阵急促的交易。你现在是多头,但看起来仍然不错:买单队列很厚,并且盘口看起来“有支撑”。
然后买单消失了。
不是作为一种比喻。而是作为一种机制。最佳买单消失了,中间价下跌了一个 tick,然后又一个,你整洁的“点差捕获”被按市价计算的库存损失碾压。
那天你明白了点差真正为你支付的是什么。
点差不是礼物。它是站在比赛前沿的补偿。
我们将从第一性原理出发,逐步了解这场比赛的展开:什么移动了中间价,为什么成交是有条件的,为什么深度是一种行为,以及为什么 markout 是测谎仪。
在时间 $t$,最佳买价是 $B_t$,最佳卖价是 $A_t$。点差是 $s_t = A_t - B_t$。中间价是 $M_t = (A_t + B_t)/2$。在最佳买价的挂单队列是 $Q_t^b$,在最佳卖价的挂单队列是 $Q_t^a$。你的库存是 $q_t$(正数表示多头,负数表示空头)。
稍后会出现一个词:markout。它是指在你成交后中间价的变化。通过在交易后的固定时间间隔采样中间价来衡量它:100 毫秒、500 毫秒、2 秒、10 秒,具体取决于交易场所和延迟情况。
在盘口顶部,你有两个桶:
flowchart TB
subgraph OrderBook["盘口顶部(最佳报价)"]
direction TB
A["卖价(卖单队列)<br>[ 最佳卖价的规模:Qᵃₜ ]<br>价格:Aₜ"]
line["点差 sₜ = Aₜ − Bₜ "]
B["买价(买单队列)<br>[ 最佳买价的规模:Qᵇₜ ]<br>价格:Bₜ"]
end
MB["市场买单<br>消耗卖单队列"] --> A
MS["市场卖单<br>消耗买单队列"] --> B
关键见解:只有当最佳报价消失或改善时,中间价才会移动。在流动性好的市场中,消失的队列占主导地位。
快速检查: 要使中间价发生变化,必须发生什么?
答案: $A_t$ 发生变化或 $B_t$ 发生变化。
这通常以两种常见方式发生。最佳水平被移除(交易穿透或取消),显示下一个水平。或者有人在点差内提升报价,成为新的最佳买价或卖价。
当点差很小且市场繁忙时,“最佳水平消失”是主要事件。这就是比赛:哪一方的最佳报价更有可能下一个消失?
急促的交易击中了你的买价,你不断成交。诱人的故事是“太好了,我正在廉价买入”。
快速检查: 为什么做市商会成交?
答案: 因为有人选择穿过点差并与该报价进行交易。“我现在成交了”这一条件改变了接下来会发生什么的分布。
这就是 选择 这个词发挥作用的地方。选择是指:市场倾向于在你不利的时刻接受你的流动性。这不需要阴谋。这是一个关于有条件事件的统计事实。
市场不需要知道你的名字来选择你。它只需要在你提供错误时刻的最佳价格时找到你。
深度是可见的部分:$Q_t^b$ 和 $Q_t^a$。压力是电影:每个桶的消耗速度(扣除补充)。
队列缩小是因为交易者消耗它,以及做市商取消它。它增长是因为做市商添加它。关键的不对称是速度:消耗(激进的交易者加上取消)可以立即扩大;补充通常较慢且更加谨慎,尤其是在你希望它表现出色的时刻。
一个有用的心理模型是“漏水的桶”。泄漏可能会突然加倍。在同一时刻,水龙头很少加倍。
快速检查: 如果“被吃掉”和“被撤回”都会减少规模,为什么要区分它们?
答案: 因为“被撤回”通常是市场机制信号。消耗可能是常规的。取消潮是人群离开剧院。
如果你要计算这篇文章中的任何内容,请计算这种直觉:单位深度的压力。当消耗率相对于 $Q_t$ 增长时,即使快照看起来很好,报价也会变得脆弱。
在急促的交易之前:一个 tick 的点差,买盘看起来很厚,卖盘看起来正常。
在急促的交易期间,你同时注意到三件事:卖单消耗买单,其他做市商取消买单,以及补充滞后。显示的深度是一张照片。这张照片现在已经过时了。
快速检查: 如果每个人都开始取消,“厚的买单队列”意味着什么?
答案: “厚的”从来不是属性,真正的属性是:在攻击下有多少深度能够存活。
这就是点差捕获直觉失效的地方。它将盘口视为一个稳定的缓冲区。盘口是一系列可以在几毫秒内逆转的决策。
这是保持做市诚实的恒等式。
将时间范围 $\tau$ 内的中间价变化定义为:
$$ \Delta M(\tau) := M_{t+\tau} - M_t. $$
如果你以买价 $B_t = M_t - s_t/2$ 买入,并在之后按中间价进行标记,你的按中间价计算的盈亏是:
$$ \Pi{\text{buy}}(\tau) = M{t+\tau} - B_t = \Delta M(\tau) + \frac{s_t}{2}. $$
如果你以卖价 $A_t = M_t + s_t/2$ 卖出:
$$ \Pi_{\text{sell}}(\tau) = At - M{t+\tau} = \frac{s_t}{2} - \Delta M(\tau). $$
这里省略了费用和回扣。将它们作为每次成交的常数加回去。
用简单的英语阅读这些等式:
第二个术语才是整个游戏的关键。如果成交之后伴随着不利的中间价移动,那么半个点差是风险工资,而不是优势。
快速检查: 那么为什么做市商即使在捕获点差时也会赔钱? 答案: 因为 $\mathbb{E}[\Delta M(\tau)\mid \text{fill}]$ 通常不为零。成交后的条件漂移会吞噬半个点差。
这是做市版本的 赢家的诅咒。在拍卖中,“获胜”可能意味着你相对于真实价值支付了过高的价格。在流动性提供中,“赢得交易”可能意味着你是在中间价对你不利移动之前可用的最佳价格。
markout 曲线只是针对 $\tau$ 绘制的 $\mathbb{E}[\Pi(\tau)]$。
“有毒”曲线在成交后立即下降并保持负值,你被支付为知情流动的退出流动性。
graph LR
A[在 t=0 成交] --> B{在 τ=100 毫秒的 Markout:-0.4 个 ticks}
A --> C{在 τ=1 秒的 Markout:-0.7 个 ticks}
B & C --> D[(系统性损失)]
注意:健康的曲线会下降但会恢复,你是在均值回复机制中吸收噪音而获得报酬。
更健康的曲线可以下降(你被击中了)然后恢复(你在嘈杂的、均值回复的微观机制中提供流动性而获得了报酬)。
你不需要图片看起来很漂亮。你需要它真实。
此 markout 恒等式也解释了接下来会发生什么:一旦你了解到成交可能是有害的,首要任务就是控制你接受 哪些 成交。
在急促的交易中,你正在买价上成交。如果你的状态说“下跌风险很高”,那么买价成交是危险的。
控制动作都表达了相同的想法:要求更多的补偿或减少风险敞口。扩大买价;缩小规模;暂时撤回它。保持卖价的竞争力,这样如果你已经做多,就可以卸载库存。
快速检查: 微观 alpha 主要是预测吗?
答案: 预测很重要,因为它决定了你何时应该交易以及何时应该停止交易。优势通过控制来实现:你在哪里报价,报价的宽度以及你显示的数量。
即使你以最佳买价报价,你也不是以某种神奇的方式“处于”买价。你只是在排队。
两个交易者可以报出相同的价格,并获得完全不同的结果,因为他们的队列位置不同。你的成交概率取决于必须交易多少交易量才能触及你,在你之前有多少取消,以及最佳报价是否在你被击中之前移开。
快速检查: 为什么跟踪 $Q_t^b$ 不够?
答案: $Q_t^b$ 是总队列长度。你的风险取决于你在该队列中的位置。任何严肃的做市商模型至少需要一个在交易场所的优先级规则下的队列位置代理。
这是微观回测失败的最直接原因之一:他们假设以最佳价格成交,而没有对队列进行建模。
现在你做多了。即使突发事件结束,库存也不会消失。
许多解释悄悄地在这里作弊,将成交视为独立的。在实时交易中,成交通过库存耦合。库存是将报价转化为反馈的状态变量。
当你做多时,你应该更渴望出售,更不愿意购买。当你做空时,则相反。当波动率上升时,持有库存变得更加昂贵,因此你更积极地倾斜。
快速检查: 为什么波动率显示为 $\sigma^2$,而不是 $\sigma$?
答案: 因为风险惩罚类似于方差。持有库存会使你面临价格方差,并且方差随时间的推移而与 $\sigma^2$ 成正比。
你检测到状态变化并发送取消。取消需要时间。
微观策略中的一个常见故障模式不是“模型是错误的”。该模型及时做出了反应,但订单没有。
延迟不仅仅会降低你的优势。它改变了你有效交易的体制。具有最高不利选择风险的时刻是交易者最快且其他做市商取消最厉害的时刻。这些正是延迟取消仍然会被命中的时刻。
在链上,“延迟”一词包含的不仅仅是网络延迟。时间是离散的(区块)。“快速”通常意味着“包含得早”或“排序有利”,而不是“低 ping”。这引入了一种“最后观察”动态:区块构建者(或排序器)在同一内存池批次中看到你的取消和交易者订单。他们可以选择在你的取消生效之前执行你过时的报价,从而有效地抢先你自己的风险管理。
这给我们带来了中午的转变:即使你能快速反应,盘口本身也可能并非看起来的那样。
一天中的晚些时候,会出现相反的现象。卖单队列看起来很薄,买家消耗它,但它似乎永远不会消失。规模一遍又一遍地在同一水平上补充。
这就是冰山悖论:可见的深度通常是接触时消失的流动性的尖端,或者是神奇地补充的隐藏供应的阴影。重要的不是快照,而是深度在受到攻击时的表现。
有时深度比看起来的要大(隐藏的流动性,快速的补充,及时的流动性)。有时它比看起来的要小(欺骗、消失的流动性)。有些交易所具有正式的冰山订单类型。许多没有。更广泛的观点仍然成立:
有效的深度是潜在的。你从攻击下的行为中学习它。
快速检查: 如果显示的深度不可靠,你应该测量什么?
答案: 响应,而不是姿势:消耗后的补充率、接触前取消率以及顶部附近的订单生命周期分布。
这就是为什么幼稚的不平衡特征在玩具回测中看起来很棒并在实时环境中降级的原因。盘口是对抗性的。
如果你按事件时间观看,交易会成群结队地到达。买盘通常会触发更多买盘(通过动量或流动性耗尽),就像卖盘级联成卖盘一样。这种自我激励是波动率聚集的原因。
订单流不平衡 (OFI) 衡量当前的净压力:买盘消耗速度是否快于卖盘(反之亦然),通常根据定义包含取消和添加。
OFI 告诉你压力现在正在做什么。它本身并不能解释为什么压力会持续存在。
Hawkes 过程是模拟持久性的一种方法:过去的事件会提高未来事件的短期强度,并且该影响会随着时间的推移而衰减。
快速检查: “分支比率”用简单的语言来说是什么?
答案: 由一个父事件触发的子事件的平均数量。如果它大于 1,则该过程是超临界的:它倾向于级联。在稳定的状态下,它保持在 1 以下,但在压力期间它可以接近 1,这就是为什么风暴感觉像风暴的原因。
你不需要成为 Hawkes 专家就可以使用该经验教训。如果流量是自我激励的,那么压力往往会持续一段时间。恢复不是立即的。
微观策略回测失败的最常见原因是它测试了错误的世界。
如果回测假设你可以在中间价交易,随时以最佳价格成交,并立即取消,它测试的就是一个故事。
最强大的回测模拟队列优先级、部分成交、取消/替换延迟、费用和成交后的 markout。简化形式的近似也可以工作,但它们需要根据实际成交和实际 markout 进行校准和验证。
快速检查: 中间价可以交易吗?
答案: 在 CLOB 中,通常不行。中间价是 markout 的一个方便参考,但你不能假设你可以在那里执行,尤其是在点差大或盘口有缺口的情况下。中间价是一种测量工具,而不是成交价格。
DeFi 细微差别:AMM 可以让你在平静的条件下交易“接近”预言机,但你要付出滑点和 MEV 风险的代价。在 CLOB 风格的场所中,中间价仍然是一个幽灵。你围绕它进行交易。
快速检查: 如果你可以从微观回测中保留一个诊断,它会是什么?
答案: 以成交为条件的 Markout。如果成交有系统性的负 markout,那么该策略主要是一种捐赠机制。
大多数微观结构信号都在尝试估计以下一些底层对象:
| 概念 | 它在队列竞赛中意味着什么 | 常见的信号系列 | 它估计什么 |
|---|---|---|---|
| 几何 | 顶部有多少深度 | OBI(订单簿不平衡)、顶层不平衡、深度比率 | 相对队列大小 |
| 压力 | 每一侧的消耗速度与补充速度相比如何 | OFI、签名流量、取消/添加增量 | 净消耗压力 |
| 脆弱性 | 深度在压力下是保持还是消失 | 取消比率 📊,mempool 拉取率 ⛓️ | 影响放大 |
| 持久性 | 压力是否会继续存在 | Hawkes / 自我激励特征 | 未来流量强度 |
| 毒性 | 成交是否意味着成交后不良漂移 | markout 曲线 📊,MEV 调整后的收益 ⛓️ | 不利选择 |
| 控制 | 你如何在库存和风险下做出反应 | 倾斜、扩大、规模控制 | 报价策略 |
<small>图标:⛓️ = DeFi/链上信号(mempool 动态、MEV、区块排序);📊 = CLOB 原生信号(队列优先级、有效时间)。大多数概念都适用于两种实现方式,只是有所不同。</small>
如果你只保留一种心理行动:信号估计几何形状、压力和脆弱性。你的工作是将这些估计转化为控制决策。
点差从未变得免费。你总是在为站在比赛前沿而获得报酬。
经验的变化是,你不再将盘口视为图片,而是将其视为过程。深度是在攻击下幸存下来的东西。流量具有记忆。成交是有条件的。微观 alpha 是一种控制规则。
一个实用的结局,如果你构建:
不要从编写策略开始。从编写记录器开始。记录盘口顶部更新、你的成交以及 1 秒、5 秒和 10 秒后的中间价。绘制 markout。如果你无法衡量毒性,你就无法交易点差。
## 生存记录器的伪代码
log_fill(timestamp, price, side, inventory)
for τ in [0.1, 0.5, 1, 2, 5, 10]: # 秒
markout[τ] = current_mid - fill_price
plot(markout.mean(axis=0), label="成交后的平均 markout")
如果曲线向下倾斜,你不是在做市,而是在向交易者捐款。
在较短的时间窗口 $[t, t+\Delta]$ 修复。测量顶部(或附近)的交易量。在买单处:
将净消耗压力定义为速率:
$$ d^b(t) := \frac{1}{\Delta}\Big(V^{b}{\text{trade}} + V^{b}{\text{cancel}} - V^{b}_{\text{add}}\Big). $$
在卖单处:
$$ d^a(t) := \frac{1}{\Delta}\Big(V^{a}{\text{trade}} + V^{a}{\text{cancel}} - V^{a}_{\text{add}}\Big), $$
其中 $V^{a}_{\text{trade}}$ 是以卖价执行的市场买单。
将正数部分定义为 $(x)_+ := \max(x,0)$。由耗尽或拉动驱动的报价更改的简单危害代理是:
$$ h\uparrow \propto \frac{(d^a(t))+}{Qt^a}, \qquad h\downarrow \propto \frac{(d^b(t))_+}{Q_t^b}. $$
如果你将耗尽时间建模为具有危害 $h\uparrow$ 和 $h\downarrow$ 的独立指数时钟,则:
$$ p\uparrow(t) \approx \mathbb{P}(T\uparrow<T\downarrow) = \frac{h\uparrow}{h\uparrow + h\downarrow}. $$
这给我们:
$$ p\uparrow(t)\approx \frac{\frac{(d^a)+}{Q^a}}{\frac{(d^a)+}{Q^a}+\frac{(d^b)+}{Q^b}}. $$
将其视为一阶函数形式:单位深度的压力。指数假设是一种建模便利,而不是关于自然的声明。
在一个玩具模型中,下一个移动是一个刻度向上或向下:
$$ \Delta M \in {+1,-1},\qquad \mathbb{P}(\Delta M=+1)=p_\uparrow, $$
所以:
$$ \mathbb{E}[\Delta M] = (+1)p\uparrow + (-1)(1-p\uparrow)=2p_\uparrow-1. $$
使用 $B_t = M_t - s_t/2$ 和 $A_t = M_t + s_t/2$:
$$ \Pi_{\text{buy}}(\tau)=\Delta M(\tau)+\frac{st}{2}, \qquad \Pi{\text{sell}}(\tau)=\frac{s_t}{2}-\Delta M(\tau). $$
不利选择声明是:
$$ \mathbb{E}\big[\Delta M(\tau)\mid \text{fill}\big]\neq 0. $$
在时间范围 $\Delta$ 内携带库存 $q$。如果 $\sigma^2$ 是每单位时间的中点移动方差,则:
$$ \mathrm{Var}(\Delta M)\approx \sigma^2\Delta \quad\Rightarrow\quad \mathrm{Var}(q,\Delta M)\approx q^2\sigma^2\Delta. $$
在此模型中,方差与 $\Delta$ 呈线性关系。这就是为什么即使你的报价逻辑保持不变,更长的反应时间和更慢的取消也会使库存成本更高。
二次风险罚款会导致如下目标:
$$ \max \ \mathbb{E}[\text{edge}] - \frac{\gamma}{2}q^2\sigma^2\Delta, $$
这会推动最佳报价在 $|q|$、$\sigma^2$ 或 $\Delta$ 增长时变得更加保守。
因为中点是平均值:
$$ M_t=\frac{A_t+B_t}{2} \quad\Rightarrow\quad A_t-M_t=\frac{s_t}{2}, \qquad M_t-B_t=\frac{s_t}{2}. $$
半点差只是从中点到任一顶部报价的距离。
- 原文链接: github.com/thogiti/thogi...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!