3、单因子构建:基于价格、成交量、财务数据的经典因子构建

好了,咱们进入正题。单因子构建,说白了就是给股票打分。你想想看,我们做量化投资,总不能闭着眼睛瞎买吧?总得有个依据。这个依据,就是因子。

我个人习惯把因子分成三大类:价格类、成交量类、财务类。每一类里又有几个经典门派。今天我就把这些压箱底的东西掏出来,跟你好好聊聊。

核心观点:单因子是策略的砖瓦。砖瓦不结实,楼盖得再高也得塌。所以,因子构建这一步,值得你花80%的精力。

3.1 价格类因子:动量与反转

价格类因子,是最直观的。股票涨了,能不能继续涨?跌了,会不会反弹?这就是动量和反转要回答的问题。

3.1.1 动量因子

动量因子,也叫趋势因子。它的逻辑很简单:过去涨得好的股票,未来一段时间还会涨。我在项目中遇到过不少质疑这个逻辑的人,但说实话,A股市场里,动量效应在短期(比如1-3个月)还是挺明显的。

构建方式:

  • 时间窗口:我一般用20个交易日(约1个月)和60个交易日(约1个季度)。
  • 计算公式:动量 = 当前收盘价 / N天前的收盘价 - 1
  • 注意事项:记得剔除新股和停牌股,不然数据会失真。
# 动量因子计算示例
import pandas as pd
import numpy as np

def calc_momentum(close, window=20):
    """
    计算动量因子
    close: 收盘价序列
    window: 时间窗口
    """
    momentum = close / close.shift(window) - 1
    return momentum

# 使用示例
df['momentum_20'] = calc_momentum(df['close'], 20)
df['momentum_60'] = calc_momentum(df['close'], 60)

我的小技巧:动量因子不要只用单一窗口。我习惯把20日和60日动量做个等权合成,效果往往比单个窗口更稳定。

3.1.2 反转因子

反转因子,是动量因子的对立面。它认为:涨多了会跌,跌多了会涨。说白了就是均值回归的思想。

我曾经犯过一个错误:直接用过去5日的涨跌幅做反转因子。结果发现,在牛市中这个因子亏得裤衩都不剩。后来我学乖了,反转因子更适合用在短期(1-5天)和超长期(1年以上)。

构建方式:

  • 短期反转:用过去5日的累计收益率,取负值。
  • 长期反转:用过去250日的累计收益率,取负值。
  • 关键点:反转因子需要做市值中性化处理,否则小市值股票会干扰结果。
# 反转因子计算示例
def calc_reversal(close, window=5):
    """
    计算反转因子
    """
    ret = close / close.shift(window) - 1
    reversal = -ret  # 取负值,收益率越高,因子值越低
    return reversal

df['reversal_5'] = calc_reversal(df['close'], 5)

避坑指南:我曾经用反转因子做日频调仓,结果手续费把收益全吃掉了。反转因子更适合周频或月频调仓,切记!

3.2 成交量类因子:波动率

成交量类因子,反映的是市场情绪和活跃度。波动率是其中最经典的一个。

3.2.1 波动率因子

波动率因子,衡量的是股票价格的不确定性。低波动率的股票,往往有更好的风险调整后收益。这个现象在学术界叫「低波动异象」。

我记得第一次看到这个因子时,觉得不可思议:高风险不是应该带来高收益吗?但数据告诉我,在A股市场,低波动组合确实跑赢了高波动组合。嗯,市场有时候就是这么不讲道理。

构建方式:

  • 历史波动率:用过去20日收益率的标准差。
  • 已实现波动率:用日内5分钟收益率的平方和开根号。
  • 我推荐:用已实现波动率,它对市场变化的反应更快。
# 波动率因子计算示例
def calc_volatility(close, window=20):
    """
    计算历史波动率
    """
    log_ret = np.log(close / close.shift(1))
    volatility = log_ret.rolling(window).std() * np.sqrt(252)  # 年化
    return volatility

df['volatility_20'] = calc_volatility(df['close'], 20)

注意:波动率因子需要做行业中性化处理。不同行业的波动率水平差异很大,比如科技股天生就比银行股波动大。

3.3 财务类因子:价值与质量

财务类因子,是基本面分析的量化体现。价值因子和质量因子,是我最常用的两个。

3.3.1 价值因子

价值因子的核心思想是:买便宜的股票。但「便宜」怎么定义?不是看股价绝对值,而是看估值指标。

我个人习惯用以下几个指标:

  • 市盈率(PE):市值 / 净利润。越低越便宜。
  • 市净率(PB):市值 / 净资产。适合银行、地产等重资产行业。
  • 股息率:每股分红 / 股价。越高越有安全边际。

构建方式:

# 价值因子计算示例
def calc_value_factors(df):
    """
    计算价值因子
    df需要包含: market_cap, net_profit, book_value, dividend, close
    """
    df['pe'] = df['market_cap'] / df['net_profit']
    df['pb'] = df['market_cap'] / df['book_value']
    df['dividend_yield'] = df['dividend'] / df['close']
    
    # 合成价值因子:等权合成
    df['pe_rank'] = df['pe'].rank(pct=True)
    df['pb_rank'] = df['pb'].rank(pct=True)
    df['dy_rank'] = df['dividend_yield'].rank(pct=True)
    
    df['value_factor'] = (df['pe_rank'] + df['pb_rank'] + df['dy_rank']) / 3
    return df

避坑指南:我曾经直接用原始PE值做因子,结果发现亏损公司的PE是负数,排名全乱了。一定要先做极值处理,把PE限制在[-100, 100]之间。

3.3.2 质量因子

质量因子,衡量的是公司的盈利能力、成长性和财务健康度。说白了,就是找好公司。

我常用的质量指标:

  • ROE(净资产收益率):净利润 / 净资产。巴菲特最看重的指标。
  • 毛利率:毛利 / 营收。反映公司的定价权。
  • 资产负债率:总负债 / 总资产。越低越安全。
  • 营收增长率:同比营收增速。反映成长性。

构建方式:

# 质量因子计算示例
def calc_quality_factors(df):
    """
    计算质量因子
    """
    df['roe'] = df['net_profit'] / df['equity']
    df['gross_margin'] = df['gross_profit'] / df['revenue']
    df['debt_ratio'] = df['total_liab'] / df['total_assets']
    df['revenue_growth'] = df['revenue'] / df['revenue'].shift(4) - 1
    
    # 注意:资产负债率是反向指标
    df['debt_ratio_inv'] = 1 - df['debt_ratio']
    
    # 合成质量因子
    df['roe_rank'] = df['roe'].rank(pct=True)
    df['gm_rank'] = df['gross_margin'].rank(pct=True)
    df['dr_rank'] = df['debt_ratio_inv'].rank(pct=True)
    df['rg_rank'] = df['revenue_growth'].rank(pct=True)
    
    df['quality_factor'] = (df['roe_rank'] + df['gm_rank'] + 
                            df['dr_rank'] + df['rg_rank']) / 4
    return df

重要提醒:财务数据有滞后性。一季报通常在4月底才出完,你如果用3月底的数据做因子,用的其实是去年的年报。一定要做「时点对齐」,避免未来函数。

3.4 本章知识体系

下面这张图,是我梳理的本章知识结构。你可以把它当作一个速查表。

单因子构建知识体系 价格类因子 成交量类因子 财务类因子 动量因子 反转因子 波动率因子 价值因子 质量因子 关键参数与注意事项 时间窗口选择 | 极值处理 | 中性化处理 | 时点对齐 | 调仓频率 核心原则:因子构建要逻辑自洽,回测要稳健 避免数据挖掘,注重经济含义

这张图把三大类因子和它们的子因子都列出来了。你写代码的时候,可以对照着看,不容易漏掉关键步骤。

最后说一句:因子构建不是一锤子买卖。我建议你每构建一个因子,都做一遍IC分析(信息系数),看看这个因子到底有没有预测能力。别等到策略亏钱了才回头检查因子。


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