大单识别逻辑:如何定义大单?

做盘口分析,第一个绕不开的问题就是:到底多大的单子才算大单?

这个问题听起来简单,但我在实际项目中踩过不少坑。刚开始做量化的时候,我天真地以为“单笔超过100手就算大单”。结果呢?茅台和工商银行的100手,那能一样吗?

所以今天咱们就来聊聊,怎么科学地定义大单。

一、大单的本质是什么?

说白了,大单就是显著偏离当前市场正常交易规模的订单

你想想看,一只股票平时每笔成交就几手、十几手,突然蹦出来一笔500手的单子——这肯定不正常。但如果是一只日均成交几千万股的大盘股,500手可能只是毛毛雨。

所以,定义大单不能搞“一刀切”。

我个人习惯从两个维度来考量:

  • 成交量维度:单笔成交的手数
  • 成交金额维度:单笔成交的金额

两个维度各有优劣,咱们一个一个说。

二、基于成交量的阈值设定

成交量阈值,就是设定一个手数门槛。比如“单笔超过200手就算大单”。

这个方法的好处是直观、计算快。但问题也很明显——不同股票的价格差异太大了

举个例子:

股票 股价 200手金额 是否合理?
贵州茅台 1800元 360万元 ✅ 绝对算大单
工商银行 5元 10万元 ❌ 可能只是普通单
某ST股 1.5元 3万元 ❌ 散户都能做到

看到问题了吧?同样的200手,在不同股票上的资金含义天差地别。

那怎么办?

我建议用相对阈值,而不是绝对阈值。

具体做法:

  1. 统计该股票过去N天的平均每笔成交量
  2. 设定一个倍数,比如3倍或5倍
  3. 超过这个倍数的,就算大单

代码实现起来也很简单:

import pandas as pd
import numpy as np

def detect_large_trade_by_volume(trades, multiplier=5, window=20):
    """
    基于成交量的相对大单识别
    
    Parameters:
    - trades: DataFrame, 包含'volume'列
    - multiplier: 倍数阈值
    - window: 统计窗口天数
    
    Returns:
    - 标记为大单的布尔序列
    """
    # 计算滚动平均每笔成交量
    avg_volume = trades['volume'].rolling(window).mean()
    
    # 标记大单
    is_large = trades['volume'] > avg_volume * multiplier
    
    return is_large

嗯,这里要注意:窗口大小的选择很关键。窗口太小,均值不稳定;窗口太大,反应太迟钝。我个人习惯用20个交易日,也就是一个月左右。

三、基于成交金额的阈值设定

成交金额维度,其实更能反映资金的真实意图。

为什么?因为资金看的是钱,不是手数。一个机构要建仓,他关心的是“我要花多少钱”,而不是“我要买多少手”。

我见过不少交易员,只看手数不看金额,结果把几百万的小单当大单,把几十万的机构单当普通单——这坑我踩过。

基于金额的阈值设定,同样建议用相对法:

  • 计算该股票过去N天的平均每笔成交金额
  • 设定倍数阈值(比如3倍)
  • 超过的标记为大单

代码示例:

def detect_large_trade_by_amount(trades, multiplier=3, window=20):
    """
    基于成交金额的相对大单识别
    
    Parameters:
    - trades: DataFrame, 包含'amount'列(单位:元)
    - multiplier: 倍数阈值
    - window: 统计窗口天数
    
    Returns:
    - 标记为大单的布尔序列
    """
    # 计算滚动平均每笔成交金额
    avg_amount = trades['amount'].rolling(window).mean()
    
    # 标记大单
    is_large = trades['amount'] > avg_amount * multiplier
    
    return is_large
我的经验:金额阈值通常比成交量阈值更稳定。因为股价波动会影响手数,但金额直接反映资金量。我一般优先用金额维度,成交量维度作为辅助验证。

四、综合阈值:双维度联合判定

单一维度总会有盲区。比如:

  • 一只低价股,突然出现大量手数但金额不大——可能是散户跟风
  • 一只高价股,手数不多但金额巨大——可能是机构在吸筹

所以,我建议用双维度联合判定

具体逻辑:

  1. 先分别计算成交量和成交金额的相对阈值
  2. 设定一个“大单分数”
  3. 两个维度都超过阈值的,标记为“强信号大单”
  4. 只有一个维度超过的,标记为“弱信号大单”

代码实现:

def detect_large_trade_combined(trades, vol_mult=5, amt_mult=3, window=20):
    """
    双维度联合大单识别
    
    Returns:
    - DataFrame, 包含'is_large_vol', 'is_large_amt', 'large_signal'列
    """
    df = trades.copy()
    
    # 计算滚动均值
    avg_vol = df['volume'].rolling(window).mean()
    avg_amt = df['amount'].rolling(window).mean()
    
    # 单维度标记
    df['is_large_vol'] = df['volume'] > avg_vol * vol_mult
    df['is_large_amt'] = df['amount'] > avg_amt * amt_mult
    
    # 联合判定
    conditions = [
        (df['is_large_vol'] & df['is_large_amt']),  # 双维度都满足
        (df['is_large_vol'] | df['is_large_amt'])   # 至少一个满足
    ]
    choices = ['strong', 'weak']
    
    df['large_signal'] = np.select(conditions, choices, default='none')
    
    return df
核心要点:
  • 成交量阈值:适合识别“量异常”,但受股价影响大
  • 金额阈值:适合识别“资金异常”,更稳定
  • 联合判定:取两者交集,信号更可靠

五、避坑指南

我曾经犯过一个错误:把“大单”和“主力资金”直接划等号。

后来发现,有些大单是对倒单(左手倒右手),有些是拆单后的汇总(比如算法交易),还有些是乌龙指(手滑了)。

所以,识别出大单只是第一步。你还需要结合:

  • 盘口挂单变化:大单成交前后,买卖盘口有没有异常
  • 时间分布:是开盘、盘中还是尾盘出现的
  • 价格影响:大单成交后,价格是突破还是反转

这些内容,后面的章节会详细展开。

重要提醒:阈值参数不是固定的!不同市场(A股、港股、美股)、不同板块(主板、创业板、科创板)、不同市值(大盘、中盘、小盘),阈值都需要调整。我一般会每季度重新校准一次参数。

六、本章知识体系

下面这张图,帮你梳理大单识别的完整逻辑:

大单识别逻辑框架 大单识别 成交量维度 成交金额维度 绝对阈值 相对阈值(推荐) 滚动窗口 绝对金额 相对金额(推荐) ... 双维度联合判定 强信号大单 弱信号大单 非大单

这张图把整个逻辑串起来了。从最底层的单维度识别,到双维度联合判定,再到最终的信号输出——每一步都有讲究。

好了,大单识别的基础逻辑就讲到这里。记住:没有完美的阈值,只有不断优化的方法。多复盘、多测试,找到适合你交易品种的参数,这才是正道。


公众号:蓝海资料掘金营,微信deep3321