2、羊群效应的量化识别

好,咱们直接进入正题。

识别羊群效应,说白了就是找到市场里「跟风」的证据。你想想看,一群人同时买同一个股票,到底是英雄所见略同,还是无脑跟风?量化交易要做的,就是把这种模糊的感觉,变成一串可执行的数字。

我个人习惯把识别方法分成三类:看交易量、看价格、看持仓。这三类各有各的脾气,咱们一个一个来拆。

基于交易量的羊群效应指标:订单失衡率

先讲最简单的——订单失衡率。这个指标我特别喜欢,因为它直接,不绕弯子。

什么叫订单失衡?就是买单和卖单的数量差。正常情况下,买卖双方势均力敌。但如果突然有一边压倒另一边,嗯,羊群可能来了。

核心公式:
订单失衡率 = (买单量 - 卖单量) / (买单量 + 卖单量)

取值范围在 -1 到 1 之间。正值表示买方主导,负值表示卖方主导。绝对值越大,失衡越严重。

我在项目中遇到过这么个事:某只小盘股,平时订单失衡率在 ±0.2 以内晃悠。突然有一天,这个值飙到了 0.85。我当时就觉得不对劲,一查消息,果然有个大V在社交媒体上吹票。后面三天,股价涨了 18%,然后一地鸡毛。

实战技巧:
  • 用 5 分钟或 15 分钟 K 线计算,太短了噪音大
  • 设置阈值:|订单失衡率| > 0.6 视为异常
  • 配合成交量一起看,效果更好
# Python 实现:订单失衡率
import pandas as pd

def order_imbalance_ratio(buy_volume, sell_volume):
    """
    计算订单失衡率
    buy_volume: 买单成交量
    sell_volume: 卖单成交量
    """
    diff = buy_volume - sell_volume
    total = buy_volume + sell_volume
    # 防止除零
    return diff / total if total != 0 else 0

# 示例:5分钟K线数据
data = pd.DataFrame({
    'buy_vol': [1200, 3400, 5600, 2100],
    'sell_vol': [1100, 1500, 1800, 2000]
})

data['OIR'] = data.apply(
    lambda row: order_imbalance_ratio(row['buy_vol'], row['sell_vol']), 
    axis=1
)
print(data)
注意:订单失衡率对高频数据敏感。如果你用的是 tick 级数据,记得先聚合。我曾经吃过这个亏,直接用原始 tick 算,结果全是噪音,根本没法用。

基于价格动量的羊群效应指标:收益率分散度

第二个指标,收益率分散度。这个思路很有意思——它不看方向,看「整齐度」。

你想想,如果整个板块的股票都在朝同一个方向跑,而且步调极其一致,那大概率是羊群在行动。反之,如果大家各走各的,那就是正常市场行为。

计算步骤:
  1. 选取同行业或同板块的 N 只股票
  2. 计算每只股票在 t 时刻的收益率
  3. 计算这些收益率的横截面标准差
  4. 标准差越小,说明大家越「齐步走」,羊群效应越强

说白了,收益率分散度就是看大家是不是在「抄作业」。我习惯用 30 只同板块股票,滚动 20 个交易日计算。分散度降到历史 10% 分位以下时,就要警惕了。

# Python 实现:收益率分散度
import numpy as np

def return_dispersion(returns_matrix):
    """
    returns_matrix: 形状为 (n_stocks, n_periods) 的收益率矩阵
    返回每个时间点的分散度
    """
    # 计算横截面标准差
    cross_sectional_std = np.std(returns_matrix, axis=0)
    return cross_sectional_std

# 示例:5只股票,10个时间点
np.random.seed(42)
returns = np.random.randn(5, 10) * 0.02  # 模拟收益率

dispersion = return_dispersion(returns)
print("各时间点分散度:", dispersion)
避坑指南:我曾经用全市场股票算分散度,结果发现根本没用。为什么?因为不同行业的股票本来就不该同步。一定要限定在同行业或同概念板块内,才有意义。

基于持仓数据的羊群效应指标:LSV模型

最后这个,LSV模型,是学术界的老牌选手。由Lakonishok、Shleifer和Vishny三位大佬在1992年提出,专门用来检测机构投资者的羊群行为。

LSV的核心思想很简单:如果某只股票在一段时间内,买入的机构数量显著多于卖出的机构数量,或者反过来,那就说明机构在抱团。

LSV模型公式:
H(i,t) = |p(i,t) - E[p(i,t)]| - E[|p(i,t) - E[p(i,t)]|]

其中:
  • p(i,t) = 买入股票 i 的机构数 / 交易股票 i 的总机构数
  • E[p(i,t)] = 所有股票 p(i,t) 的期望值
  • 第二项是调整项,用于消除随机性

H(i,t) 大于 0,说明存在羊群效应。值越大,羊群越明显。

说实话,这个模型在实战中有点「重」。你需要完整的机构持仓数据,而且计算量不小。但我个人觉得,它最大的价值在于——当你用前两个指标发现异常后,用 LSV 来交叉验证,准确率会高很多。

# Python 实现:LSV 羊群效应指标
def lsv_herding(buy_counts, sell_counts):
    """
    buy_counts: 各股票买入机构数
    sell_counts: 各股票卖出机构数
    """
    total = buy_counts + sell_counts
    p = buy_counts / total  # 买入比例
    
    # 期望值:所有股票的平均买入比例
    p_avg = np.mean(p)
    
    # 原始偏离度
    raw_deviation = np.abs(p - p_avg)
    
    # 调整项:模拟随机情况下的期望偏离度
    # 这里用简化版,实际需要蒙特卡洛模拟
    adjustment = np.sqrt(p_avg * (1 - p_avg) / total)
    
    H = raw_deviation - adjustment
    return H

# 示例
buy = np.array([12, 8, 15, 3, 20])
sell = np.array([5, 10, 3, 15, 2])

H_values = lsv_herding(buy, sell)
print("LSV指标:", H_values)
重要提醒:LSV模型对数据频率很敏感。我建议用季度数据,因为机构持仓报告通常是季度更新。用月度数据的话,样本量太小,结果不稳定。另外,第二项的调整因子一定要算对,不然容易误判。

三种指标的对比与选择

指标 数据来源 计算复杂度 适用场景 我的评价
订单失衡率 高频交易数据 日内交易、短线 简单粗暴,适合快速筛选
收益率分散度 日线/周线价格 板块轮动、中长线 逻辑清晰,实战好用
LSV模型 机构持仓数据 机构行为分析、季度调仓 学术范,适合做交叉验证

我个人习惯的用法是:先用订单失衡率做快速扫描,发现异常后,用收益率分散度确认板块级别的一致性,最后用 LSV 模型看看机构是不是也在里面掺和。三层过滤下来,误报率能降到很低。

一个小技巧:这三个指标可以合成一个综合评分。比如各占 1/3 权重,超过 0.7 就报警。我在实盘里就是这么干的,效果比单用任何一个都好。
羊群效应量化识别框架 数据源 交易量数据 价格数据 持仓数据 订单失衡率 (买单-卖单)/总单量 收益率分散度 横截面标准差 LSV模型 机构买卖比例偏差 三层过滤综合判断 快速扫描 → 板块确认 → 机构验证 羊群效应识别结果

嗯,以上就是三种核心识别方法。说实话,没有哪个指标是万能的。关键是要理解每个指标的脾气,知道它在什么情况下会失灵。我在实盘里吃过不少亏,慢慢才摸索出这套组合拳。

专注资料整理