第29章 实战案例:A股市场深度分析、美股市场深度分析、外汇市场深度分析

讲到这里,咱们已经聊了不少理论。什么限价订单簿啊,什么价格弹性系数啊。但说实话,这些东西不上手跑一遍数据,你永远不知道里面有多少坑。

这一章,我就拿三个市场——A股、美股、外汇——分别跑一遍深度分析。每个市场的微观结构都不一样,处理方式也完全不同。我把自己踩过的坑、总结的经验,全摊开来讲。

29.1 A股市场深度分析:Level-2数据的正确打开方式

A股市场有个特点:盘口数据是快照式的。你拿到的Level-2行情,每3秒推送一次。这跟美股那种逐笔成交流,完全是两码事。

我个人习惯,分析A股深度时,重点看三个指标:

  • 委买委卖总量比:衡量买卖双方的力量对比
  • 价格档位厚度:每个价位上的挂单量分布
  • 大单异动检测:突然出现的巨量挂单

先看一段代码,怎么从Level-2数据里提取这些信息:

import pandas as pd
import numpy as np

def analyze_ashare_depth(df_snapshot):
    """
    分析A股单时刻的盘口深度
    df_snapshot: 包含10档买卖盘口的DataFrame
    """
    # 计算委买委卖总量比
    total_bid = df_snapshot['bid_vol'].sum()
    total_ask = df_snapshot['ask_vol'].sum()
    ratio = total_bid / total_ask if total_ask > 0 else np.inf
    
    # 计算价格档位厚度(前5档)
    bid_thickness = df_snapshot['bid_vol'].iloc[:5].mean()
    ask_thickness = df_snapshot['ask_vol'].iloc[:5].mean()
    
    # 检测大单异动(单笔挂单超过均值的3倍)
    bid_mean = df_snapshot['bid_vol'].mean()
    ask_mean = df_snapshot['ask_vol'].mean()
    large_bid = df_snapshot[df_snapshot['bid_vol'] > 3 * bid_mean]
    large_ask = df_snapshot[df_snapshot['ask_vol'] > 3 * ask_mean]
    
    return {
        'bid_ask_ratio': ratio,
        'bid_thickness': bid_thickness,
        'ask_thickness': ask_thickness,
        'large_bid_count': len(large_bid),
        'large_ask_count': len(large_ask)
    }
注意:A股的Level-2数据,不同券商给的格式可能不一样。我曾经被这个坑过——换了家数据源,字段名全变了。建议先做一轮字段映射,别直接硬编码。

实际项目中,我一般会连续采集30秒的盘口快照,然后计算一个深度衰减率。说白了就是:价格每偏离当前价1%,挂单量会减少多少?这个指标能直接反映市场的流动性深度。

29.2 美股市场深度分析:逐笔流数据的处理艺术

美股市场就完全不一样了。它有逐笔成交流(TAQ数据),每一笔成交、每一次挂单变动,你都能看到。数据量巨大,一天下来几个GB很正常。

我处理美股深度时,核心关注的是订单流不平衡(Order Flow Imbalance)。这个指标能提前捕捉到做市商的意图。

公式其实很简单:

OFI = (主动买成交量 - 主动卖成交量) / 总成交量

但真正的难点在于——你怎么判断一笔成交是主动买还是主动卖?

嗯,这里有个小技巧。看成交价和买卖报价的关系:

  • 成交价 ≥ 卖一价 → 主动买(买方吃掉了卖单)
  • 成交价 ≤ 买一价 → 主动卖(卖方吃掉了买单)
  • 成交价在中间 → 可能是撮合单,忽略

我写过一个处理函数,分享给你:

def classify_trade(trade_price, bid_price, ask_price):
    """
    判断一笔成交是主动买还是主动卖
    """
    if trade_price >= ask_price:
        return 'buy'  # 主动买
    elif trade_price <= bid_price:
        return 'sell' # 主动卖
    else:
        return 'mid'  # 中间价成交,不参与计算
经验之谈:美股盘前盘后的深度分析,跟盘中完全不一样。盘前流动性极差,一个1000股的订单就能把价格打穿好几个档位。我建议你只分析9:30-16:00的常规交易时段,否则数据噪音太大。

另外,美股有个特殊机制叫暗池交易。这些交易不显示在公开订单簿上。所以你看到的深度数据,其实只是冰山一角。我个人习惯在分析时,给深度指标加一个10%-15%的折扣系数,算是给暗池留点余量。

29.3 外汇市场深度分析:分散市场的聚合难题

外汇市场是最特殊的。它没有中央交易所,流动性分散在全球各大银行和ECN平台。你看到的深度数据,其实只是某一个流动性提供商的切片。

我刚开始做外汇深度分析时,犯过一个错误——只拿一家银行的报价数据就做分析。结果模型在回测时表现很好,实盘一跑就崩。为什么?因为那家银行的报价深度,跟整个市场的真实深度差太远了。

正确的做法是:聚合多家流动性提供商的报价。至少3家以上,最好5-7家。

聚合逻辑是这样的:

def aggregate_forex_depth(quotes_list):
    """
    聚合多家银行的报价深度
    quotes_list: 每家银行的报价DataFrame
    """
    # 合并所有买价和卖价
    all_bids = pd.concat([q['bid_price'] for q in quotes_list])
    all_asks = pd.concat([q['ask_price'] for q in quotes_list])
    
    # 按价格聚合挂单量
    agg_bid = all_bids.groupby(all_bids).sum()
    agg_ask = all_asks.groupby(all_asks).sum()
    
    # 计算聚合后的买卖价差
    best_bid = agg_bid.index.max()
    best_ask = agg_ask.index.min()
    spread = best_ask - best_bid
    
    return {
        'agg_bid_depth': agg_bid,
        'agg_ask_depth': agg_ask,
        'spread': spread
    }
核心要点:外汇市场的深度分析,重点不是看绝对挂单量,而是看相对深度——即在不同价格偏移百分比下,挂单量的变化曲线。因为不同货币对的波动率差异很大,绝对数值没有可比性。

还有一个外汇特有的指标——订单簿斜率。它衡量的是:价格每偏离1个pip,挂单量变化多少。斜率越大,说明市场越有弹性,大单不容易造成价格滑点。

我记得有一次做EUR/USD的深度分析,发现某个时段订单簿斜率突然变得很平缓。我当时就觉得不对劲,果然半小时后出了个非农数据,市场瞬间暴跌。嗯,这个指标确实能提前预警。

29.4 三个市场的对比总结

说了这么多,我整理了一张对比表,方便你快速回顾:

维度 A股 美股 外汇
数据频率 3秒快照 逐笔流 实时报价流
核心指标 委买委卖比、档位厚度 订单流不平衡、OFI 聚合深度、订单簿斜率
主要难点 数据格式不统一 数据量大、暗池交易 流动性分散、聚合困难
避坑指南 先做字段映射 避开盘前盘后时段 至少聚合3家以上报价
价格弹性特征 中等弹性,大单影响明显 高弹性,做市商提供缓冲 低弹性,滑点成本高

最后说一句。这三个市场的深度分析,没有哪个是简单的。A股的数据格式乱,美股的数据量大,外汇的数据分散。但只要你掌握了核心逻辑——从订单簿中提取供需关系——换哪个市场都一样。

我个人建议,新手先从A股入手。数据量适中,逻辑清晰。等把Level-2数据玩透了,再挑战美股和外汇。别一上来就搞外汇,那个聚合过程能把人搞疯。

一个小提醒:不管分析哪个市场,一定要做数据清洗。我见过太多人拿脏数据跑分析,结果模型一塌糊涂。尤其是外汇数据,经常出现跳空、重复报价、时间戳错乱等问题。花30%的时间做数据清洗,一点都不夸张。