01 - 市场微观结构
01 - 市场微观结构
定位:给有10年金融经验的架构师/PM讲清楚"交易所里面到底发生了什么" 目标:理解订单簿运行原理、价格发现机制、做市策略科学、市场冲击模型 前提:你知道什么是股票/期货/交易所,但不需要知道随机微积分
一、核心概念与直觉
1.1 什么是市场微观结构?
市场微观结构研究的是一个根本问题:价格是怎么产生的?
不是宏观的"供需决定价格",而是微观的:
- 谁在买?谁在卖?
- 订单以什么顺序到达?
- 撮合引擎按什么规则配对?
- 做市商怎么设定买卖报价?
- 大单怎么拆分才能不把价格砸崩?
这些问题直接决定了交易系统的架构设计。
1.2 为什么架构师需要理解这些?
| 你要设计的系统 | 需要理解的微观结构概念 |
|---|---|
| 撮合引擎 | 价格优先-时间优先规则、订单类型 |
| 行情系统 | Level 1/2/3 数据、快照 vs 增量 |
| 风控系统 | 市场冲击、异常订单检测 |
| 算法交易 | 最优执行、TWAP/VWAP |
| DeFi AMM | 与传统订单簿的对比 |
1.3 两个关键类比
订单簿就像拍卖场:
- 买方举牌报价(Bid),卖方标价出售(Ask)
- 拍卖师(撮合引擎)按规则配对
- 最高买价和最低卖价之间的差距就是"叫价差"(Spread)
- 但比拍卖场快一百万倍——每秒数百万次
做市商就像二手车商:
- 低价收车(Bid),高价卖车(Ask),赚差价
- 必须控制库存——收了太多某款车卖不掉就亏了
- 要判断来的客户是不是"内行人"——如果对方知道这车有问题/特别值钱,自己就被坑了
- 这就是逆向选择问题
二、订单簿(LOB)深度解析
2.1 限价单 vs 市价单:本质区别
| 维度 | 限价单(Limit Order) | 市价单(Market Order) |
|---|---|---|
| 定义 | "我要以 ¥100 买100股" | "我要买100股,多少钱都行" |
| 角色 | 提供流动性(Maker) | 消耗流动性(Taker) |
| 风险 | 可能永远成交不了 | 一定成交,但价格不确定 |
| 费用 | 通常手续费更低 | 通常手续费更高 |
| 类比 | 在货架上摆商品 | 从货架上拿商品 |
关键洞察:限价单构成了订单簿,市价单消耗订单簿。做市商的工作就是不断往订单簿里放限价单。
2.2 订单簿的5档深度图解
订单簿快照 (某时刻)
卖方(Ask/Offer) 买方(Bid)
────────────── ──────────
价格 数量 价格 数量
────────────── ──────────
102.50 200 ← Ask 5
102.40 150 ← Ask 4
102.30 300 ← Ask 3
102.20 500 ← Ask 2
102.10 100 ← Ask 1 (最优卖价/最低卖价)
─────────────────────────────────────
Spread = 0.10
─────────────────────────────────────
102.00 200 ← Bid 1 (最优买价/最高买价)
101.90 400 ← Bid 2
101.80 350 ← Bid 3
101.70 150 ← Bid 4
101.60 100 ← Bid 5
术语对照:
- Best Bid / Best Ask:最优买价/最优卖价
- Spread:Ask1 - Bid1 = 102.10 - 102.00 = 0.10(越小=流动性越好)
- Mid Price:(Ask1 + Bid1) / 2 = 102.05(中间价,很多模型用这个)
- Depth:每档的数量,反映流动性厚度
2.3 深度图(另一种可视化)
数量(累积)
1500 | ████
1200 | ████████
1000 | █████████████
800 | █████████████████████████████
600 | ██████████████████████████████████
400 | █████████████████████████████████████████
200 | ████████████████████████████████████████████
0 |────────────|──────────|────────────────────
101.60 102.00 102.10 102.50
Bid Ask
↑ Spread ↑
深度图是交易界面上常见的"山丘图",左边是买盘堆积,右边是卖盘堆积。
2.4 价格优先-时间优先撮合规则
这是全球绝大多数交易所采用的撮合规则,也叫 FIFO (First In First Out) 规则:
第一优先级 — 价格:
- 买单:出价越高越优先(你愿意出更多钱,优先成交)
- 卖单:出价越低越优先(你愿意卖更便宜,优先成交)
第二优先级 — 时间:
- 同一价格,先到的订单先成交
示例:撮合引擎收到一笔市价买单(买200股)
卖方订单簿(按价格升序,同价按时间排):
#001 102.10 100股 09:30:01.001 ← 先成交(价最低,时间最早)
#003 102.10 50股 09:30:01.005 ← 然后成交(同价,时间次早)
#002 102.20 200股 09:30:01.003 ← 最后成交50股(下一个价位)
结果:
成交100股@102.10 + 50股@102.10 + 50股@102.20
加权平均价格 = (100×102.10 + 50×102.10 + 50×102.20) / 200 = 102.125
注意:这200股的买单把 Ask1 (102.10) 的流动性全部吃掉了,还穿透到了 Ask2 (102.20)。这就是市场冲击。
2.5 订单簿形态分析
| 形态 | 描述 | 含义 |
|---|---|---|
| 厚单(Thick Book) | 每档数量很大 | 流动性好,大单不容易冲击价格 |
| 薄单(Thin Book) | 每档数量很小 | 流动性差,小单就能大幅移动价格 |
| 冰山单(Iceberg) | 只显示一部分数量,成交后自动补充 | 大户想隐藏真实意图 |
| 隐藏单(Hidden) | 完全不显示在订单簿上 | 更彻底的隐藏,暗池常用 |
| 单边厚/薄 | 买盘厚但卖盘薄 | 可能暗示价格上涨压力 |
架构启示:冰山单和隐藏单意味着你在行情系统里看到的订单簿是不完整的。这对策略设计有重大影响。
三、价格发现理论
3.1 Kyle (1985) Lambda模型
这是金融学最经典的模型之一,回答一个关键问题:知情交易者如何通过交易来传递信息?
场景设定:
- 市场上有三类参与者:
- 知情交易者(Informed Trader):知道资产真实价值
- 噪声交易者(Noise Trader):随机买卖
- 做市商(Market Maker):观察总订单流来设定价格
核心公式:
ΔP = λ · (净订单流)
其中:
ΔP = 价格变化
λ (Lambda) = 市场冲击系数
净订单流 = 买入量 - 卖出量
直觉解读:
- Lambda大 → 市场不流动 → 同样的订单量引起更大的价格变化
- Lambda小 → 市场流动性好 → 大单也不怎么影响价格
- 做市商不知道哪笔订单来自知情交易者,所以对所有订单都收取信息成本
为什么Lambda不是0? 因为做市商知道知情交易者混在噪声交易者里面。如果Lambda=0,知情交易者可以无限量买入/卖出而不影响价格,做市商就会被掏空。
实际应用:
- 估算大宗交易的市场冲击成本
- 衡量市场流动性质量(Lambda越小越好)
- DeFi中AMM的滑点本质上就是Lambda
3.2 Glosten-Milgrom模型:Spread的来源
做市商为什么要收Spread?不是因为贪心,而是因为逆向选择。
核心逻辑:
做市商面对的每一笔交易:
├── 80% 可能来自噪声交易者 → 做市商赚Spread
└── 20% 可能来自知情交易者 → 做市商亏钱
如果知情交易者知道真实价值 = 105:
做市商报 Ask = 103 → 知情交易者买入 → 做市商亏2
做市商报 Bid = 101 → 知情交易者卖出?不会,因为价值更高
所以做市商必须把Spread设大到足以覆盖被知情交易者割的损失。
Spread的三个组成部分:
Spread = 逆向选择成本 + 库存风险成本 + 竞争利润
(1) 逆向选择成本:
被知情交易者割韭菜的预期损失
→ 信息不对称越大,Spread越大
(2) 库存风险成本:
持有头寸的风险(价格可能朝不利方向变动)
→ 波动率越大,Spread越大
(3) 竞争利润:
做市商要赚的正常利润
→ 竞争越激烈,利润越薄
实际观察:
- 蓝筹股(信息透明):Spread很小(1-2个tick)
- 小盘股(信息不透明):Spread很大
- 财报发布前:Spread会变大(信息不对称增加)
- DeFi AMM:没有显式Spread,但有滑点曲线,本质一样
3.3 有效市场假说与现实的差距
**有效市场假说(EMH)**说:价格已经反映了所有可用信息,你无法持续跑赢市场。
现实:
- 价格发现有延迟——这就是高频交易赚钱的窗口
- 不同交易所的价格有微小差异——这就是套利机会
- 大单会临时扭曲价格——这就是最优执行问题
- 市场有微观结构噪声——价格在真实值附近来回跳
对架构师的启示:EMH在毫秒-秒级别不成立,在天-月级别大致成立。你设计的系统需要在哪个时间尺度上工作,决定了你需要考虑多少微观结构效应。
四、做市策略科学
4.1 Avellaneda-Stoikov最优做市模型 (2008)
这是做市策略的"教科书级"模型。核心问题:做市商应该把Bid和Ask报在哪里?
核心思想:
库存偏移 → 报价偏移
库存偏多(持有太多) → 降低Ask(加速卖出) + 提高Bid(减缓买入)
库存偏空(持有太少) → 提高Ask(减缓卖出) + 降低Bid(加速买入)
库存中性 → Bid和Ask对称分布在Mid Price两侧
直觉类比: 水果店老板发现香蕉快过期了(库存太多)→ 降价促销(降低Ask)。 同时不再从批发市场进货(提高Bid,减少买入意愿)。
关键参数:
| 参数 | 含义 | 影响 |
|---|---|---|
| γ (gamma) | 风险厌恶系数 | γ大 → 更害怕库存风险 → Spread更宽 |
| σ (sigma) | 价格波动率 | σ大 → 库存贬值风险高 → Spread更宽 |
| T | 交易结束时间 | 离收盘越近 → 清仓压力越大 → 报价偏移越大 |
| q | 当前库存 | q偏离0越远 → 报价偏移越大 |
最优报价公式(简化版):
保留价格(Reservation Price):
r = s - q·γ·σ²·(T-t)
其中 s = 中间价, q = 库存量
最优Spread:
δ = γ·σ²·(T-t) + (2/γ)·ln(1 + γ/k)
其中 k = 订单到达率参数
最优Bid = r - δ/2
最优Ask = r + δ/2
不需要记住公式,记住直觉:
- 保留价格 = 中间价 - 库存修正量
- 库存为正(多头)→ 保留价格低于中间价 → Bid/Ask整体下移 → 更容易卖出
- 库存为负(空头)→ 保留价格高于中间价 → Bid/Ask整体上移 → 更容易买入
4.2 库存与报价偏移关系图
报价偏移
(相对中间价)
↑
+0.05| ──── Ask报价
| ────
| ────
+0.02| ────
| ────
0.00|─────────────────────────────────── Mid Price
| ────
-0.02| ────
| ────
-0.05| ────
| ──── Bid报价
└──────────────────────────────→ 库存(q)
-5 -3 -1 0 1 3 5
空头 中性 多头
解读:库存越偏向多头,Bid和Ask整体越往下移
→ 以更低价格卖出,加速减仓
4.3 做市商的盈利模型
做市商P&L = Spread收入 - 逆向选择成本 - 库存风险成本
(1) Spread收入:
每笔成交赚取 Bid-Ask 差价的一半
日收入 ≈ (Spread/2) × 成交笔数 × 2
(2) 逆向选择成本:
被知情交易者方向性交易割的钱
越是信息不对称的市场,这个成本越高
(3) 库存风险成本:
持有头寸期间价格不利变动的损失
波动率越大,这个成本越高
关键公式:
预期利润 > 0 的条件:
Spread/2 > P(informed) × E[|V - Ask|]
即:半个Spread必须覆盖被知情交易者割的期望损失
4.4 做市策略的主要风险
| 风险 | 描述 | 应对 |
|---|---|---|
| 库存风险 | 积累太多单边头寸,价格反向时巨亏 | 库存限制、对冲、报价偏移 |
| 逆向选择 | 持续被知情交易者割韭菜 | 检测有毒订单流、调宽Spread |
| 闪崩(Flash Crash) | 价格瞬间暴跌,库存瞬间贬值 | 熔断机制、紧急撤单逻辑 |
| 技术故障 | 系统延迟导致报价过时 | 冗余系统、自动撤单保护 |
| 竞争 | 其他做市商报价更优,自己成交不了 | 更快的系统、更优的参数 |
五、市场冲击模型
5.1 临时冲击 vs 永久冲击
价格
↑
| ╱╲
| ╱ ╲ 临时冲击(恢复)
| ╱ ╲────────────── 永久冲击(不恢复)
| ╱
|─────╱
|
└──────────────────────→ 时间
↑ ↑
开始交易 交易结束
总冲击 = 临时冲击 + 永久冲击
临时冲击:你的大单暂时推高/压低了价格,交易完成后会回弹
永久冲击:你的交易传递了信息(或消耗了流动性),价格永久改变
类比:
- 临时冲击 = 你去菜市场一次买50斤白菜,老板临时涨价,但你走后价格恢复
- 永久冲击 = 因为你买了50斤,其他商贩觉得白菜要涨价,集体提价
5.2 Almgren-Chriss最优执行模型
核心问题:你要卖100万股,该一次性卖完还是分批卖?
核心权衡:
执行速度快 执行速度慢
↓ ↓
市场冲击大 市场冲击小
(一次倒100万股,价格崩盘) (慢慢卖,每次冲击小)
↓ ↓
但没有时间风险 但有时间风险
(快速完成,不怕价格继续跌) (卖到一半价格暴跌)
最优执行 = 在"冲击成本"和"时间风险"之间找平衡
5.3 常用执行算法
| 算法 | 原理 | 适用场景 |
|---|---|---|
| TWAP | 按时间均匀分批 | 流动性均匀的市场 |
| VWAP | 按历史成交量分布分批 | 追求接近市场加权均价 |
| IS | 最小化实施缺口(Implementation Shortfall) | 对价格敏感的交易 |
| 冰山单 | 只显示一部分数量 | 不想暴露交易意图 |
| POV | 按成交量占比参与(如占5%) | 不想影响市场价格 |
TWAP示例:
目标:2小时内卖出100万股
TWAP方案:
09:30 卖出 125,000 股
09:45 卖出 125,000 股
10:00 卖出 125,000 股
...每15分钟一批,共8批...
11:15 卖出 125,000 股
优点:简单,执行风险分散
缺点:不考虑市场实际流动性分布
(可能09:30-10:00流动性好,应该多卖)
VWAP改进:
历史成交量分布:
09:30-10:00 占全天 25% → 卖出 250,000 股
10:00-10:30 占全天 15% → 卖出 150,000 股
10:30-11:00 占全天 10% → 卖出 100,000 股
...按实际流动性分配...
优点:跟着市场节奏走,冲击更小
缺点:依赖历史分布的准确性
5.4 Square-Root Law(平方根法则)
这是一个经验规律,被市场参与者广泛使用:
市场冲击 ∝ σ · √(Q / V)
其中:
σ = 日波动率
Q = 你要交易的股数
V = 日均成交量
示例:
日波动率 = 2%
你要卖 100万股
日均成交量 = 500万股
冲击 ≈ 2% × √(100/500) = 2% × 0.447 ≈ 0.89%
即:你的交易预期会让价格下跌约0.89%
关键特征:冲击与成交量的平方根成正比,不是线性的。这意味着:
- 交易量翻倍 → 冲击只增加41%(而不是100%)
- 这给了分批执行优化的空间
六、工程落地要点
6.1 订单簿数据的三个层次
| 层次 | 内容 | 数据量 | 用途 |
|---|---|---|---|
| Level 1 | 最优买卖价+成交价 | 小 | 行情展示、简单策略 |
| Level 2 | 多档买卖盘 (5-10档) | 中 | 深度分析、算法交易 |
| Level 3 | 每笔订单详情 | 极大 | 做市策略、微观结构研究 |
数据存储设计考量:
Level 1: 简单KV存储或内存缓存
Key: Symbol
Value: {bid, ask, last, volume, timestamp}
Level 2: 内存中的有序结构
BidBook: 红黑树/跳表 (价格降序)
AskBook: 红黑树/跳表 (价格升序)
每个价格节点: {price, total_qty, order_count}
Level 3: 内存 + 持久化
每笔订单: {order_id, side, price, qty, timestamp, type}
需要支持快速插入/删除/修改
日数据量可达数十GB
6.2 撮合引擎架构
┌─────────────┐
订单输入 ───→ │ 网关层 │ 验证、限流、协议解析
└──────┬──────┘
↓
┌─────────────┐
│ 预处理层 │ 风控检查、账户验证
└──────┬──────┘
↓
┌─────────────┐
│ 撮合引擎 │ ← 核心:单线程、确定性
└──────┬──────┘
↓
┌──────────┼──────────┐
↓ ↓ ↓
┌──────────┐ ┌────────┐ ┌────────┐
│ 成交回报 │ │行情推送│ │清算结算│
└──────────┘ └────────┘ └────────┘
与支付网关的有趣对比:
| 维度 | 支付网关 | 撮合引擎 |
|---|---|---|
| 核心操作 | 扣A账户加B账户 | 匹配买卖双方 |
| 一致性 | 强一致性(ACID) | 确定性(同输入同输出) |
| 延迟目标 | <500ms | <10μs |
| 吞吐 | 1万TPS | 100万订单/秒 |
| 并发模型 | 多线程+锁/队列 | 单线程(避免锁) |
| 状态 | 数据库 | 纯内存 |
关键设计原则:
- 撮合引擎通常是单线程的——避免锁争用带来的延迟抖动
- 每个交易品种一个撮合线程(品种间天然隔离)
- 先写WAL日志再撮合——崩溃恢复用
6.3 行情系统的延迟要求
数据流向:
交易所撮合 → 行情快照/增量 → 网关压缩 → 网络传输 → 客户端解码 → 展示
HFT要求:端到端 < 1ms
普通机构:端到端 < 10ms
散户App:端到端 < 1秒
关键技术选择:
推送方式:UDP组播(最快) → WebSocket(适中) → HTTP轮询(最慢)
更新方式:增量更新(带宽小) vs 全量快照(简单但浪费)
压缩方式:自定义二进制(最快) vs Protobuf(适中) vs JSON(最慢)
七、常见误区
误区1:"价格是由供需决定的"
更准确的说法:价格是由边际订单决定的。
一个股票可能有100万个持有者,但此刻价格只由订单簿上最优买卖价的那几笔小订单决定。一笔10手的市价卖单就能把价格砸下去,哪怕大多数持有者都不打算卖。
这就是为什么低流动性资产的价格波动特别大——边际订单的影响力太大了。
误区2:"做市商总是赚钱的"
做市商可以在以下情况下亏大钱:
- 逆向选择严重:大量知情交易者冲进来,做市商来不及调价
- 闪崩:市场突然单方向暴跌,做市商积累的库存瞬间贬值
- 波动率突增:突发事件导致波动率飙升,Spread来不及调整
- 2015年8月24日美股闪崩,多家做市商单日亏损数千万美元
误区3:"高频交易 = 赌博"
高频交易是高度科学化的工程活动:
- 基于数学模型(随机过程、最优控制)
- 基于统计检验(策略需要通过严格的统计显著性测试)
- 基于工程优化(纳秒级延迟优化)
- 有严格的风控系统(持仓限制、亏损限制、熔断机制)
赌博是"正EV不确定"的游戏,HFT是"找到确定的正EV并高频执行"的工程。
八、DeFi对比:AMM vs 订单簿
作为Web3方向的补充,简单对比:
| 维度 | 传统订单簿 | AMM (如Uniswap) |
|---|---|---|
| 做市方式 | 专业做市商挂单 | 算法自动定价(x·y=k) |
| 价格发现 | 订单匹配产生 | 由曲线公式决定 |
| 流动性提供 | 需要专业能力 | 任何人都能提供LP |
| Spread | 动态,做市商决定 | 由曲线斜率决定 |
| 资本效率 | 高(可以集中在某价位) | 低(均匀分布)→V3改善 |
| 延迟 | 微秒级 | 区块时间(12秒) |
| 逆向选择 | 做市商承担 | LP承担(无常损失) |
| 透明度 | 部分(隐藏单/暗池) | 完全透明(链上) |
关键洞察:AMM本质上把"做市"这件需要高度专业化的工作民主化了,代价是资本效率更低、LP面临无常损失。
九、延伸阅读
必读书籍
- 《Trading and Exchanges》 — Larry Harris
- 市场微观结构的"圣经",覆盖最全面
- 适合非量化背景读者,讲解清晰
- 《Market Microstructure Theory》 — Maureen O'Hara
- 更偏学术,适合想深入理论的读者
经典论文
- Kyle (1985) — "Continuous Auctions and Insider Trading"
- Lambda模型的原始论文
- Glosten & Milgrom (1985) — "Bid, Ask and Transaction Prices..."
- Spread与逆向选择的理论基础
- Avellaneda & Stoikov (2008) — "High-frequency trading in a limit order book"
- 最优做市模型
在线资源
- MIT 15.450 Analytics of Finance (OCW课程)
- Stanford MSFE 课程材料
- QuantStart.com 的市场微观结构系列
十、本章小结
| 概念 | 一句话总结 |
|---|---|
| 订单簿 | 买卖双方挂单的有序列表,价格优先-时间优先 |
| Spread | 最优买价和卖价的差距 = 逆向选择+库存+利润 |
| Lambda | 订单流对价格的冲击系数,反映流动性质量 |
| 做市策略 | 库存偏移→报价偏移,赚Spread减逆向选择成本 |
| 最优执行 | 速度 vs 冲击的权衡,TWAP/VWAP/IS |
| 冲击法则 | 冲击 ∝ √(交易量/日均量),不是线性的 |
对架构师的核心启示:
- 撮合引擎要单线程+纯内存,和你设计支付系统的思路完全不同
- 行情系统分Level 1/2/3,决定了存储和带宽需求
- 做市策略不是拍脑袋定价,而是有严格数学基础的最优控制问题
- DeFi的AMM是传统做市的简化+民主化版本,理解传统做市才能真正理解AMM的取舍