因子挖掘基础:因子定义、分类与有效性检验

各位同学,欢迎来到因子挖掘的核心章节。

说实话,做可转债量化这几年,我最大的感触就是——因子是模型的灵魂。模型再花哨,因子不行,一切都是白搭。今天我们就来聊聊因子挖掘的基础,把地基打牢。

一、因子到底是什么?

先问大家一个问题:你凭什么觉得一只可转债会涨?

是因为它价格低?还是因为正股在涨?或者因为市场情绪好?

这些「凭什么」,其实就是因子。

因子的定义:因子是能够解释或预测资产收益的某种特征或变量。在可转债领域,因子就是那些能帮助我们判断转债未来表现的量化指标。

我个人习惯把因子比作「选品的尺子」。你手里尺子越多、越准,挑出来的转债就越可能跑赢市场。

举个例子:

  • 转股溢价率:衡量转债相对正股是贵了还是便宜了
  • 到期收益率:持有到期的年化回报
  • 余额规模:转债的流通市值大小

这些都是因子。每个因子都在告诉你一些信息,但单独看都不够全面。

二、因子分类:四大门派

做因子研究这么多年,我习惯把因子分成四类。这四类基本覆盖了可转债定价的方方面面。

1. 估值类因子

这类因子回答的是「贵不贵」的问题。

  • 转股溢价率:越低越好,说明转债跟正股跟得紧
  • 纯债溢价率:衡量债底保护程度
  • 隐含波动率:反映市场对正股波动的预期
  • YTM(到期收益率):债性投资者的核心指标

避坑指南:我曾经在2021年用纯低溢价率策略赚了不少,但2022年市场风格切换,低溢价率因子突然失效。后来我才意识到——估值因子需要结合市场环境来看,不能死板套用。

2. 动量类因子

这类因子回答的是「趋势如何」的问题。

  • 价格动量:过去N日涨幅,比如20日动量
  • 成交量变化:放量还是缩量
  • 正股动量:正股的趋势强度
  • 换手率:交易活跃度

你想想看,一只转债如果连续放量上涨,说明资金在关注。但动量因子有个毛病——容易追高。我一般会搭配估值因子一起用。

3. 情绪类因子

这类因子回答的是「市场怎么看」的问题。

  • 资金流向:大单净流入/流出
  • 融券余额变化:做空力量的强弱
  • 舆情热度:新闻、论坛讨论量
  • 波动率偏度:市场对尾部风险的定价

情绪因子很有意思。我记得有一次,某只转债正股出了利空,但转债价格反而涨了。后来发现是游资在炒作。情绪因子能捕捉到这种「非理性」的机会。

4. 基本面类因子

这类因子回答的是「公司怎么样」的问题。

  • 正股PE/PB:正股的估值水平
  • ROE:盈利能力
  • 营收增速:成长性
  • 负债率:财务风险
  • 下修概率:公司是否有动力下修转股价

注意:基本面因子在可转债上的应用和股票不太一样。转债更看重「下修博弈」和「强赎预期」,这些是股票没有的独特逻辑。

三、因子有效性检验框架

好了,因子定义清楚了,分类也明白了。但问题来了——你怎么知道这个因子真的有用?

说白了,不能拍脑袋说「我觉得这个因子好」,得用数据说话。

我搭建了一套因子检验框架,分为五个步骤:

  1. 数据清洗:去极值、填充缺失值、中性化处理
  2. 分组回测:按因子值分成5组或10组,看各组收益
  3. IC分析:计算因子值与未来收益的相关系数
  4. 多空组合:做多因子值高的、做空因子值低的,看收益
  5. 稳健性检验:换时间段、换样本、换参数,看结果是否稳定

下面这张图是我常用的因子检验流程:

因子有效性检验流程图 数据清洗 去极值·填充·中性化 分组回测 5组/10组收益对比 IC分析 Rank IC / 截面IC 多空组合 多空收益·夏普比 稳健性检验 不同时段·不同参数 不通过则返回调整因子 核心指标:IC均值 > 0.03 | ICIR > 0.5 | 多空夏普 > 1.0 示例:转股溢价率因子检验结果 分组收益:G1(低溢价) 2.3% | G2 1.8% | G3 1.2% | G4 0.5% | G5(高溢价) -0.8% Rank IC:-0.052(显著负相关) | 多空收益:3.1% | 结论:有效

四、实战:用Python快速检验一个因子

光说不练假把式。我给大家看一段核心代码,这是检验转股溢价率因子的标准流程:

import pandas as pd
import numpy as np
from scipy import stats

def factor_test(df, factor_col='premium_rate', ret_col='next_ret', n_groups=5):
    """
    因子有效性检验核心函数
    df: 包含因子值和未来收益的DataFrame
    """
    # 1. 去极值(MAD方法)
    median = df[factor_col].median()
    mad = np.abs(df[factor_col] - median).median()
    df['factor_clipped'] = df[factor_col].clip(
        median - 3 * mad, median + 3 * mad
    )
    
    # 2. 分组
    df['group'] = pd.qcut(df['factor_clipped'], n_groups, labels=False)
    
    # 3. 计算各组收益
    group_ret = df.groupby('group')[ret_col].mean()
    
    # 4. IC分析
    ic, p_value = stats.spearmanr(df['factor_clipped'], df[ret_col])
    
    # 5. 多空组合收益
    long_short_ret = group_ret.iloc[-1] - group_ret.iloc[0]
    
    return {
        'group_returns': group_ret,
        'rank_ic': ic,
        'p_value': p_value,
        'long_short_ret': long_short_ret
    }

# 使用示例
result = factor_test(data, 'premium_rate', 'next_week_ret')
print(f"Rank IC: {result['rank_ic']:.3f}")
print(f"多空收益: {result['long_short_ret']:.2%}")

经验之谈:我一般会同时看Rank IC和分组收益的单调性。IC高但分组收益不单调,说明因子有非线性关系,需要做变换处理。

五、因子检验的常见陷阱

做了这么多年因子研究,踩过的坑真不少。分享几个最常见的:

  • 幸存者偏差:只看了存续的转债,忽略了已经退市的。结果因子表现虚高。
  • 前视偏差:用到了未来的信息来构造因子。比如用当天的收盘价来预测当天的收益。
  • 过拟合:在历史数据上反复调参数,结果一到实盘就崩。
  • 多重共线性:两个因子高度相关,导致模型不稳定。

我曾经犯过一个低级错误:用全样本数据做因子检验,没做滚动窗口。结果因子IC高达0.08,但实盘时直接变成负的。后来才发现是数据泄露了——因子计算用到了未来信息。

从那以后,我每次做因子检验都会严格区分训练集和测试集,绝不偷看未来数据。

六、小结

因子挖掘是量化投资的核心能力。今天我们把基础打牢了:

  • 因子定义:能预测收益的特征变量
  • 四大分类:估值、动量、情绪、基本面
  • 检验框架:清洗→分组→IC→多空→稳健性

记住一句话:因子没有绝对的好坏,只有适不适合当前的市场环境。多思考因子背后的逻辑,比单纯跑代码重要得多。

好了,今天就到这里。希望大家动手跑一跑上面的代码,用真实数据感受一下因子检验的流程。有什么问题,我们随时交流。

专注资料整理