10、价格动量策略:动量因子计算、动量反转信号

动量策略,说白了就是「追涨杀跌」的量化版本。我刚开始做高频交易那会儿,觉得这玩意儿太简单了——涨了就买,跌了就卖,谁不会啊?结果实盘跑了一个月,亏得我怀疑人生。后来才明白,动量因子的计算和反转信号的识别,里面的门道深着呢。

10.1 动量因子的核心逻辑

动量因子的本质,是衡量价格变化的「加速度」。你想想看,一辆车如果加速很快,说明发动机动力足;价格也是一样,短时间内涨得猛,说明买方力量强。

我个人习惯把动量因子分成两类:

  • 绝对动量:直接看价格涨了多少。比如过去N根K线,收盘价涨了5%。
  • 相对动量:看价格相对于某个基准的强弱。比如个股涨了3%,但大盘涨了5%,那相对动量其实是负的。

高频场景下,我一般用绝对动量多一些。为什么?因为高频交易追求的是「快」,相对动量计算起来要额外处理基准数据,延迟受不了。

核心公式:
动量因子 = (当前价格 - N期前价格) / N期前价格
或者更简单的:动量因子 = 当前价格 / N期前价格 - 1

10.2 动量因子的计算方法

计算动量因子,最常用的就是滚动窗口。我给你们看一段代码,这是我在实盘里用过的版本:

import pandas as pd
import numpy as np

def calculate_momentum(price_series, window=20):
    """
    计算动量因子
    :param price_series: 价格序列,pandas Series
    :param window: 回看窗口,默认20个周期
    :return: 动量因子序列
    """
    # 计算收益率
    returns = price_series.pct_change(window)
    
    # 处理缺失值
    momentum = returns.fillna(0)
    
    return momentum

# 示例用法
prices = pd.Series([100, 102, 101, 105, 108, 107, 110])
momentum_20 = calculate_momentum(prices, window=3)
print(momentum_20)

这段代码看着简单,但我曾经踩过一个坑。你们猜是什么?

嗯,是前向偏差。我在一个项目里,用未来数据计算了动量因子,结果回测曲线漂亮得不像话,实盘直接崩了。后来排查才发现,我用的pct_change默认是向后看,但我代码里写错了参数,变成了向前看。所以啊,一定要确认你的窗口方向是对的

10.3 动量反转信号

动量策略有个致命问题:物极必反。涨得太猛了,迟早要回调;跌得太狠了,也会反弹。这就是动量反转信号。

我一般用两个指标来判断反转:

  1. 动量衰减率:如果连续N个周期的动量值在下降,说明上涨动力不足,可能反转。
  2. 极值阈值:设定一个阈值,比如动量因子超过±5%,就认为进入了「过热」或「过冷」状态。
我的经验: 高频数据里,动量反转信号的有效性比低频数据强得多。因为高频交易者更容易「过度反应」,一个消息出来,3秒钟内价格可能冲过头,然后1秒钟内又跌回来。这就是你的机会。

10.4 动量策略的实战框架

下面这张图是我自己总结的动量策略框架,你们可以照着搭:

动量策略实战框架 高频价格数据 动量因子计算(窗口N) 动量持续 → 顺势交易 动量反转 → 逆势交易 生成交易信号

这个框架的核心就是:先判断动量方向,再判断动量是否要反转。如果动量持续,就顺势做;如果动量要反转,就逆势做。

10.5 动量反转信号的识别算法

我给你们看一个我实际用过的反转信号识别代码:

def detect_momentum_reversal(momentum_series, lookback=5, threshold=0.03):
    """
    检测动量反转信号
    :param momentum_series: 动量因子序列
    :param lookback: 回看周期
    :param threshold: 反转阈值
    :return: 反转信号(1=正反转,-1=负反转,0=无信号)
    """
    signals = np.zeros(len(momentum_series))
    
    for i in range(lookback, len(momentum_series)):
        # 取最近lookback个周期的动量
        recent_momentum = momentum_series[i-lookback:i]
        
        # 计算动量衰减
        momentum_slope = np.polyfit(range(lookback), recent_momentum, 1)[0]
        
        # 判断反转条件
        if momentum_slope < -threshold and recent_momentum[-1] > 0:
            # 正动量在衰减 → 可能向下反转
            signals[i] = -1
        elif momentum_slope > threshold and recent_momentum[-1] < 0:
            # 负动量在衰减 → 可能向上反转
            signals[i] = 1
    
    return signals
注意: 这个算法有个前提——动量序列要足够平滑。高频数据噪声大,我建议先做一次平滑处理,比如用EMA或者中值滤波。不然的话,你会被假信号淹死。

10.6 动量策略的常见陷阱

做动量策略这些年,我踩过的坑可以写本书了。挑几个重点说说:

  • 窗口选择:窗口太短,信号太多,手续费吃掉利润;窗口太长,反应太慢,吃不到肉。我个人习惯用5-20个周期,具体看品种的波动特性。
  • 滑点影响:高频交易里,滑点可能是你最大的敌人。动量策略在价格快速变动时进场,滑点尤其大。我一般会在信号出现后,等一个「确认K线」再进场。
  • 过拟合:这个我最有发言权。我曾经为了追求回测曲线好看,调了十几个参数,结果实盘一塌糊涂。后来学乖了,参数越少越好,逻辑越简单越好

10.7 实战中的参数调优

下面这个表格是我在实盘中常用的参数范围,你们可以参考:

参数名称 推荐范围 说明
动量窗口 5 - 20 个周期 周期越短,信号越灵敏,但噪声也越大
反转阈值 0.02 - 0.05 阈值越低,反转信号越多,但准确率下降
衰减斜率阈值 0.001 - 0.005 用于判断动量是否在衰减
确认K线数 1 - 3 根 等待确认后再进场,减少假信号

调参这件事,说白了就是「试错」。我建议你们先用历史数据跑一遍,看看参数对收益曲线的影响。别一上来就想着找到「最优参数」,先找到一个「不亏钱」的参数组合,再慢慢优化

一个小技巧: 我习惯把动量策略和波动率策略结合起来用。波动率低的时候,动量策略效果好;波动率高的时候,反转策略效果好。两者互补,能提高整体稳定性。

好了,关于动量策略的核心内容就这些。记住一句话:动量是趋势的朋友,反转是趋势的敌人。你能识别出什么时候是朋友、什么时候是敌人,就能在市场上活得更久。

无相订单流研究社 微信Lucian808555