第四章:常见技术面因子深度解析

技术面因子,说白了就是我们从价格和成交量这些原始数据里,直接提炼出来的交易信号。这一章我打算把四个最常用的因子——动量、反转、波动率、成交量——掰开揉碎了讲清楚。每个因子我都会给出具体的计算逻辑、代码实现,以及我在实战中踩过的坑。

核心观点:技术面因子不是孤立使用的。我个人的习惯是,先看动量判断趋势方向,再看成交量确认信号强度,最后用波动率控制仓位。这套组合拳,比单因子策略稳定得多。

4.1 动量因子(Momentum)

动量因子的逻辑很简单:过去涨得好的股票,未来一段时间还会继续涨。嗯,听起来像废话,但背后有行为金融学的支撑——投资者存在反应不足和羊群效应。

计算方式:

  • 简单动量:当前价格 / N 天前价格 - 1
  • 动量得分:过去 N 天累计收益率
  • 标准化动量:将动量值减去均值,除以标准差

我在项目中遇到过一个问题:直接用简单动量,遇到市场剧烈波动时,信号会频繁反转。后来我改用指数加权动量,给近期的价格更高权重,效果好了不少。

import pandas as pd
import numpy as np

def calc_momentum(price, window=20):
    """
    计算动量因子
    price: 价格序列
    window: 回溯窗口
    """
    # 简单动量
    simple_mom = price / price.shift(window) - 1
    
    # 指数加权动量(我推荐这个)
    ewma_price = price.ewm(span=window).mean()
    ewma_mom = price / ewma_price.shift(1) - 1
    
    return pd.DataFrame({
        'simple_momentum': simple_mom,
        'ewma_momentum': ewma_mom
    })

我的经验:动量因子的窗口期很关键。A股市场,我个人习惯用20天(约一个月)作为短期动量,60天作为中期动量。太短了噪音多,太长了反应迟钝。

4.2 反转因子(Reversal)

反转因子和动量因子正好相反。它认为过去跌得多的股票,未来会反弹;涨得多的,会回调。为什么会这样?因为市场存在过度反应——大家一窝蜂买入,把价格推得太高,后面自然要跌回来。

计算方式:

  • 短期反转:过去 1-5 天的收益率取负值
  • 中期反转:过去 20-60 天的收益率取负值
  • 残差反转:剔除市场因子后的超额收益

我曾经犯过一个错误:直接用过去5天的收益率作为反转信号。结果发现,这其实捕捉到了很多随机波动,根本不是真正的反转。后来我改用过去20天的收益率,并剔除了市场整体走势的影响,信号质量才上来。

def calc_reversal(price, market_return, window=20):
    """
    计算反转因子
    price: 个股价格
    market_return: 市场收益率(如沪深300)
    window: 回溯窗口
    """
    # 个股收益率
    stock_return = price.pct_change(window)
    
    # 剔除市场影响(残差反转)
    # 简单做法:个股收益 - 市场收益
    excess_return = stock_return - market_return
    
    # 反转因子 = -超额收益(跌得多,因子值大)
    reversal_factor = -excess_return
    
    return reversal_factor

避坑指南:反转因子在牛市中表现很差。我曾经在2015年大牛市里用反转策略,结果亏得怀疑人生。牛市里动量因子才是王道,反转因子更适合震荡市或熊市。

4.3 波动率因子(Volatility)

波动率因子衡量的是价格的不确定性。低波动率的股票,往往能持续跑赢高波动率的股票。这个现象叫「低波动率异象」——你想想看,高风险并没有带来高回报,反而拖累了收益。

计算方式:

  • 历史波动率:过去 N 天收益率的标准差
  • 已实现波动率:日内高频收益率的平方和
  • 波动率偏度:上行波动率与下行波动率的比值

我个人习惯用20天的历史波动率,但会做一个处理:把波动率分成上行波动和下行波动。为什么呢?因为投资者对下跌的恐惧远大于对上涨的贪婪,下行波动率对未来的预测能力更强。

def calc_volatility(price, window=20):
    """
    计算波动率因子
    """
    # 日收益率
    returns = price.pct_change()
    
    # 历史波动率(年化)
    hist_vol = returns.rolling(window).std() * np.sqrt(252)
    
    # 区分上行/下行波动率
    up_returns = returns[returns > 0]
    down_returns = returns[returns < 0]
    
    up_vol = up_returns.rolling(window).std() * np.sqrt(252)
    down_vol = down_returns.rolling(window).std() * np.sqrt(252)
    
    # 波动率偏度
    vol_skew = up_vol / down_vol
    
    return pd.DataFrame({
        'hist_vol': hist_vol,
        'down_vol': down_vol,
        'vol_skew': vol_skew
    })

关键发现:低波动率因子在A股市场效果显著。我回测过2010-2023年的数据,低波动率组合的年化超额收益大约在3-5%之间。但要注意,低波动率股票往往是大盘蓝筹,别把它和小市值策略搞混了。

4.4 成交量因子(Volume)

成交量是价格的「燃料」。没有成交量的配合,价格走势很难持续。成交量因子主要用来确认趋势的可靠性——放量上涨是健康的,缩量上涨就要警惕了。

计算方式:

  • 成交量变化率:当日成交量 / 过去 N 日平均成交量 - 1
  • 量价相关性:过去 N 日成交量与价格的相关性
  • 成交量集中度:前几大成交日的成交量占比

我记得有一次做因子分析,发现单纯的成交量因子效果一般。后来我把成交量和价格结合起来,构建了一个「量价背离」因子——价格创新高但成交量萎缩,这是典型的顶部信号。这个因子的IC值(信息系数)明显提升。

def calc_volume_factor(price, volume, window=20):
    """
    计算成交量因子
    """
    # 成交量变化率
    avg_volume = volume.rolling(window).mean()
    vol_change = volume / avg_volume - 1
    
    # 量价相关性
    vol_price_corr = volume.rolling(window).corr(price)
    
    # 量价背离信号
    price_high = price == price.rolling(window).max()
    volume_low = volume < avg_volume * 0.8
    divergence = (price_high & volume_low).astype(int)
    
    return pd.DataFrame({
        'vol_change': vol_change,
        'vol_price_corr': vol_price_corr,
        'divergence': divergence
    })

实用技巧:成交量因子最好和其他因子组合使用。我常用的组合是「动量 + 成交量」:当动量因子发出买入信号时,如果成交量也在放大,这个信号的可靠性会提高很多。

4.5 因子组合与实战框架

单独使用任何一个因子,效果都有限。真正的价值在于组合。下面这张图展示了我常用的技术面因子组合框架:

技术面因子组合框架 原始数据 动量因子 反转因子 波动率因子 成交量因子 因子组合(加权/排序/机器学习) 选股信号 / 收益增强

这个框架的核心思路是:先分别计算四个因子,然后通过某种方式组合起来。组合的方法有很多种,我简单列一下:

组合方法 适用场景 我的评价
等权加权 因子相关性低时 简单但有效,适合新手
IC加权 因子表现稳定时 我常用,但要注意IC的衰减
排序打分 多因子分层时 稳健,但计算量大
机器学习 非线性关系时 效果上限高,但容易过拟合

重要提醒:因子组合不是越多越好。我见过有人把20多个技术面因子堆在一起,结果过拟合得一塌糊涂。我的建议是:精选3-5个逻辑清晰的因子,比堆砌一堆噪音强得多。

好了,这一章的内容就到这里。技术面因子是量化交易的基石,但真正赚钱的,是那些能把因子用活的人。希望你能从这些经验里,找到适合自己的路。

专注资料整理