2. 市场微观结构

各位,咱们今天聊点实在的。高频交易这行当,说白了就是跟市场微观结构打交道。你如果不懂订单簿,不懂盘口,那就像开车不看仪表盘——迟早要出事。

我个人习惯,每次开始一个新策略之前,第一件事就是先把目标品种的微观结构摸透。为什么?因为价格波动只是表象,真正的博弈全藏在订单簿里。

限价订单簿(LOB)——市场的“记账本”

限价订单簿,英文叫 Limit Order Book,简称 LOB。你可以把它想象成一个巨大的记账本,上面记录着所有交易者挂出来的买卖意愿。

每一笔限价订单,都包含三个要素:方向(买还是卖)、价格、数量。系统把这些订单按价格排序,买盘从高到低,卖盘从低到高,就形成了我们看到的订单簿。

核心要点:订单簿不是静态的。它每时每刻都在变化——有人挂单,有人撤单,有人成交。高频交易的核心,就是捕捉这些变化中的规律。

我在项目中遇到过一件事,印象很深。有一次我们跑一个套利策略,回测数据漂亮得不行,结果一上实盘就亏钱。查了半天,发现是订单簿的更新延迟问题。回测用的是 tick 级数据,但实盘里订单簿的 snapshot 和增量更新之间有微小的时差,就是这点时差,让我们的策略一直在吃哑巴亏。

买卖盘口——最直观的博弈前线

盘口,就是订单簿最顶层的几档数据。买一、卖一、买二、卖二……这些数字,是市场最直接的博弈信号。

举个例子,你看一个股票的盘口:

档位 买价 买量 卖价 卖量
1 100.01 500 100.02 300
2 100.00 1200 100.03 800
3 99.99 2000 100.04 1500

看到没?买一和卖一之间的差价,就是 spread。这个 spread 越小,说明市场流动性越好。买一挂了 500 手,卖一只有 300 手——这说明什么?说明卖方有点犹豫,或者买方在试探。

你想想看,如果卖一突然从 300 手变成 3000 手,价格还没变,那大概率是有人在压盘。这时候你冲进去买,可能就被套住了。

我的经验:别只看买一卖一。我习惯把前五档的挂单量加起来看。如果买盘前五档总量远大于卖盘前五档,但价格就是不涨,那多半是有人在下面托单,实际意图可能是出货。

市场深度——你能吃下多少“货”

市场深度,衡量的是你在某个价格水平上能成交多少量。深度越大,大单对价格的冲击就越小。

怎么算?很简单。比如你想买 10000 股,从卖一往下吃:

  • 卖一 100.02 有 300 股,吃掉
  • 卖二 100.03 有 800 股,吃掉
  • 卖三 100.04 有 1500 股,吃掉
  • ……一直吃到凑够 10000 股为止

最后成交的加权平均价,就是你的实际买入成本。这个成本跟当前卖一价的差距,就是 市场冲击成本。

我曾经犯过一个错误。当时做一个统计套利策略,觉得某个价差偏离了 3 个标准差,机会难得,直接一把梭进去。结果因为市场深度不够,我的单子把价格推回去了,等于是自己把套利空间给填平了。嗯,从那以后,我所有策略都加了深度检查。

订单簿的三种状态

做高频交易,你得学会“读”订单簿的状态。我一般把它分成三种:

  1. 均衡状态:买卖盘口力量相当,spread 稳定,订单簿呈“金字塔”形状——离最优价越远,挂单量越大。
  2. 失衡状态:某一侧明显厚实,另一侧单薄。比如买盘堆积如山,卖盘稀稀拉拉。这时候价格大概率要往上走。
  3. 稀疏状态:订单簿很“空”,几档之间差距大,spread 宽。这种情况通常出现在流动性差的品种或非交易活跃时段,进去容易,出来难。

注意:订单簿的状态是动态变化的。均衡可能瞬间变成失衡,因为一个大单撤单或进场。高频策略必须能实时感知这种变化,而不是每隔几秒刷新一次。

知识体系总览

下面这张图,是我自己整理的市场微观结构知识框架。你看一眼,心里就有数了。

市场微观结构知识体系 限价订单簿 (LOB) 买卖盘口 市场深度 订单簿状态 买卖盘口关键指标 • 买一/卖一价格与数量 • Spread(买卖价差) • 前五档挂单分布 市场深度计算 • 各档位累计挂单量 • 市场冲击成本估算 • 深度斜率分析 订单簿状态分类 • 均衡状态 • 失衡状态 • 稀疏状态 三者共同构成市场微观结构分析基础

用 Python 看一眼订单簿

光说不练假把式。咱们用 Python 拉一下真实的订单簿数据看看。这里以币安的 BTC/USDT 为例:

import requests
import json

# 获取币安 BTC/USDT 订单簿
url = "https://api.binance.com/api/v3/depth"
params = {"symbol": "BTCUSDT", "limit": 10}

resp = requests.get(url, params=params)
data = resp.json()

print("买盘(Bids):")
for bid in data["bids"][:5]:
    print(f"  价格: {bid[0]}, 数量: {bid[1]}")

print("\n卖盘(Asks):")
for ask in data["asks"][:5]:
    print(f"  价格: {ask[0]}, 数量: {ask[1]}")

# 计算买卖盘口总量
total_bid_vol = sum(float(b[1]) for b in data["bids"])
total_ask_vol = sum(float(a[1]) for a in data["asks"])
print(f"\n买盘总量: {total_bid_vol:.4f}")
print(f"卖盘总量: {total_ask_vol:.4f}")
print(f"买卖比: {total_bid_vol/total_ask_vol:.4f}")

这段代码很简单,但很实用。你跑一下就能看到当前市场的盘口情况。我一般会在策略启动前先跑一遍这个,看看市场深度够不够,spread 大不大。

小技巧:别只看一次 snapshot。我习惯连续拉 10 次,每次间隔 100 毫秒,观察订单簿的变化速度。如果变化剧烈,说明有人在搞事情,这时候策略参数要调得更保守一些。

避坑指南

最后,分享几个我踩过的坑:

  • 别迷信盘口数据:有些大资金会挂假单,挂上去又撤掉,就是为了误导你。我见过最夸张的,有人在买一挂了 5000 个比特币,然后一秒内全撤了。
  • 注意数据源延迟:交易所的 REST API 通常有几百毫秒的延迟。做高频交易,必须用 WebSocket 的增量数据流。
  • 深度不是万能的:有些品种深度看起来很厚,但都是散户的单子,一有风吹草动全撤了。真正的深度,要看那些长期不动的“冰山订单”。

嗯,今天就先聊到这儿。市场微观结构这东西,越挖越深。你先把订单簿、盘口、深度这三个概念吃透,后面讲订单流、成交量分布的时候,你才能跟得上。