4. 尾段成交量配合分析:回落段量能与前段量能对比

为什么要把“回落量”和“前段量”放在一起看

尾段回落本身只说明价格在走弱,但走弱的性质取决于成交量。同样是回落 1.5%,如果回落区间每分钟成交 8 万手、而前一时段每分钟只有 3 万手,这是放量回落,说明抛压真实释放、承接被击穿;反之若回落区间每分钟只有 1.2 万手,则是缩量回落,更可能是获利盘零星兑现或流动性自然衰减,未必代表趋势反转。因此本例的核心指标是量能比:

量能比 R = 回落区间成交量 ÷ 前一时段成交量,其中两个区间必须等长,否则比值会被时间长度污染。工程上更稳妥的做法是先各自折算成“每分钟均量”再相除,即 R = (V_回落 / T_回落) ÷ (V_前段 / T_前段)。

区间定义与计算口径

沿用分时数据,把回落起点时刻记为 t_start(尾段最高价出现的那一分钟),回落低点时刻记为 t_low。回落区间取 [t_start, t_low],前段区间取紧邻其前的等长时间窗 [t_start − T, t_start),T = t_low − t_start。这样两段首尾相接、长度一致,量能比才有可比性。

下面用一段教学示例分时数据(1 分钟一根,成交量单位:万手)演示完整计算。数据为构造的示例,用于说明算法,不代表任何真实标的。

# 示例分时数据:时间, 价格, 成交量(万手)
bars = [
    ("14:30", 10.00, 2.1), ("14:31", 10.02, 2.4), ("14:32", 10.05, 3.0),
    ("14:33", 10.08, 3.6), ("14:34", 10.12, 4.2), ("14:35", 10.15, 5.1),  # 尾段最高
    ("14:36", 10.11, 6.8), ("14:37", 10.05, 7.5), ("14:38", 9.98, 8.2),
    ("14:39", 9.94, 6.1), ("14:40", 9.92, 4.0),                            # 回落低点
]

def volume_ratio(bars, start_idx, low_idx):
    """start_idx: 回落起点(最高价)下标; low_idx: 回落低点下标"""
    T = low_idx - start_idx                      # 回落区间长度(分钟)
    if T <= 0 or start_idx - T < 0:
        return None                              # 前段窗口不足,无法比较
    fall_vol = sum(v for _, _, v in bars[start_idx:low_idx + 1])
    prev_vol = sum(v for _, _, v in bars[start_idx - T:start_idx])
    fall_avg = fall_vol / (T + 1)                # 含起点与低点共 T+1 根
    prev_avg = prev_vol / T
    return {
        "T": T,
        "fall_vol": round(fall_vol, 2),
        "prev_vol": round(prev_vol, 2),
        "fall_avg": round(fall_avg, 3),
        "prev_avg": round(prev_avg, 3),
        "R": round(fall_avg / prev_avg, 2),
    }

print(volume_ratio(bars, start_idx=5, low_idx=10))
# {'T': 5, 'fall_vol': 32.6, 'prev_vol': 16.3,
#  'fall_avg': 5.433, 'prev_avg': 3.26, 'R': 1.67}

结果解读:回落区间 5 分钟共成交 32.6 万手,前段 5 分钟共 16.3 万手,折算均量后量能比 R ≈ 1.67。回落段每分钟成交是前段的 1.67 倍,属于放量回落。注意这里刻意用均量相除而非总量相除——本例两段长度恰好相等,两种算法结果一致;但一旦低点落在非整分钟或数据有缺失,总量相除就会失真,均量口径更稳健。

量能比的分档与形态判定

量能比是连续值,落地时需要分档。分档阈值应结合标的自身流动性设定,下面给出一个可直接套用的默认分档,并说明其含义:

量能比 R形态判定市场含义后续观察重点
R ≥ 1.5显著放量回落抛压集中释放,承接被有效击穿次日是否低开、能否快速收复回落起点
1.0 ≤ R < 1.5温和放量回落有增量卖压,但尚未形成恐慌回落低点是否被再次测试
0.7 ≤ R < 1.0平量回落量价基本同步,属正常波动结合回落幅度判断是否只是噪声
R < 0.7缩量回落无增量抛压,多为获利兑现或流动性衰减是否在尾盘最后几分钟出现回抽

需要强调:量能比必须与回落幅度联合判读。缩量回落若幅度很小(如 0.5% 以内),通常可视为噪声;缩量回落若幅度很大,则要警惕“无量阴跌”式的流动性缺失,这类形态往往比放量回落更难在次日修复。

计算前务必确认回落起点是“尾段最高价所在分钟”而非“全天最高价”。若全天最高价出现在早盘,用它做起点会把大段无关区间计入前段,量能比失去意义。本例只处理尾段(通常指 14:30 之后)形成的回落。
尾段回落量能比:等长区间对比 前段 [t_start−T, t_start) 与回落段 [t_start, t_low] 长度相同,折算均量后相除 14:30 14:35 14:40 14:45 14:50 14:55 前段区间 14:30–14:35 T = 5 分钟 总量 16.3 万手 均量 3.26 万/分 回落区间 14:35–14:40 T = 5 分钟 总量 32.6 万手 均量 5.43 万/分 t_start 最高价 10.15 t_low 低点 9.92 等长 等长 量能比计算 R = 回落均量 ÷ 前段均量 = 5.43 ÷ 3.26 ≈ 1.67 R = 1.67 ≥ 1.5 判定:显著放量回落 分档参考: R<0.7 缩量 0.7–1.0 平量 1.0–1.5 温和放量 R≥1.5 显著放量

批量计算与形态统计

单日单标的的量能比只是一个数,真正有用的是把它批量算出来并统计形态分布,才能知道“放量回落”和“缩量回落”在样本中各自占多少、后续表现是否有差异。下面把上面的函数扩展成可批量处理的版本,并输出形态计数:

def classify(R):
    if R is None:
        return "无法计算"
    if R >= 1.5:
        return "显著放量回落"
    if R >= 1.0:
        return "温和放量回落"
    if R >= 0.7:
        return "平量回落"
    return "缩量回落"

def batch_ratio(records):
    """records: [(code, bars, start_idx, low_idx), ...]"""
    out = []
    for code, bars, s, l in records:
        r = volume_ratio(bars, s, l)
        R = r["R"] if r else None
        out.append({"code": code, "R": R, "形态": classify(R)})
    return out

# 统计形态分布
from collections import Counter
res = batch_ratio(records)
dist = Counter(x["形态"] for x in res)
total = len(res)
for k, v in dist.most_common():
    print(f"{k}: {v} 例, 占比 {v/total:.1%}")

批量结果落地时建议同时保留 R 的原始值和形态标签,因为阈值附近的样本(如 R = 1.48 与 1.52)形态标签不同但实际差异很小,直接按标签做统计会放大边界噪声。稳妥做法是统计时同时报告 R 的中位数与四分位,形态标签只作为辅助描述。

结果校验与常见偏差

  • 区间长度校验:先断言 T_回落 == T_前段,且前段窗口不越界(start_idx − T ≥ 0)。若尾段回落起点太早、前段窗口不足,应返回“无法计算”而不是硬算。
  • 端点归属:回落区间含起点与低点共 T+1 根,前段为 T 根,均量分母必须分别用 T+1 和 T,否则会系统性高估 R。
  • 停牌与缺失:若区间内存在停牌分钟,成交量会异常偏低,需先剔除或标记,不能直接参与比值。
  • 与幅度联合:R 高但回落幅度极小,说明是高位放量换手而非破位;R 低但幅度大,则警惕无量阴跌。两者必须成对输出。
验证方法:用同一段数据分别按“总量相除”和“均量相除”计算,当两段长度严格相等时结果应完全一致;若不一致,说明区间长度或端点归属写错了,这是最快的自检手段。