共计 2330 个字符,预计需要花费 6 分钟才能阅读完成。
一、为什么你的因子模型总在实盘失效?
最近和几个做量化的朋友聊天,发现大家普遍遇到这样的问题:回测时年化收益动辄 30%+ 的因子组合,实盘跑起来连指数都跑不赢。这其实就是典型的过拟合现象——我们的模型在历史数据上表现太好,到了真实市场就原形毕露。
A 股市场的特殊挑战
- 政策市特征明显:比如 2023 年的中特估行情,传统估值因子集体失效
- 波动率显著高于成熟市场:创业板指单日±3% 的波动已成常态
- 市场结构快速变化:注册制实施后小市值因子有效性明显下降

(示意图:样本内完美曲线 vs 样本外的灾难性表现)
二、从零搭建稳健因子库
基础因子代码实现(Python 示例)
# 使用聚宽 API 获取基础数据
import jqdatasdk
jqdatasdk.auth('你的账号', '你的密码')
def get_market_cap(stocks, date):
"""市值因子(对数化处理)"""
q = query(
valuation.code,
valuation.market_cap
).filter(valuation.code.in_(stocks)
)
df = get_fundamentals(q, date=date)
df['log_mcap'] = np.log(df['market_cap'])
return df.set_index('code')['log_mcap']
def momentum_factor(stocks, end_date, lookback=21):
"""20 日动量因子(避免使用未来数据)"""
start_date = end_date - pd.Timedelta(days=lookback+5)
prices = get_price(stocks, start_date, end_date, '1d', ['close'], skip_paused=True)
returns = prices['close'].iloc[-20:].pct_change().mean()
return returns.dropna()
必备的数据预处理
- 极值处理:A 股常有涨跌停导致的异常值
def winsorize(series, sigma=3):
"""3sigma 去极值"""
mean, std = series.mean(), series.std()
return series.clip(mean - sigma*std, mean + sigma*std)
- 标准化:使不同量纲因子可比
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
factors_scaled = scaler.fit_transform(factors_df)
三、过拟合防御实战技巧
正则化实战:LASSO 回归
from sklearn.linear_model import LassoCV
# 5 折交叉验证自动选择 alpha
lasso = LassoCV(cv=5, alphas=np.logspace(-3, 1, 50))
lasso.fit(X_train, y_train)
# 查看因子权重
pd.Series(lasso.coef_, index=X_train.columns)
时间序列交叉验证
from sklearn.model_selection import TimeSeriesSplit
tscv = TimeSeriesSplit(n_splits=5)
for train_idx, test_idx in tscv.split(X):
X_train, X_test = X.iloc[train_idx], X.iloc[test_idx]
y_train, y_test = y.iloc[train_idx], y.iloc[test_idx]
# 训练和评估代码...
四、2024 年 A 股特有陷阱
北向资金因子构建要点
- 使用 持仓变化比例 而非绝对金额
- 注意沪深股通名单的月度调整
- 避免与市值因子高度相关
def north_money_factor(stocks, date):
"""北向资金净流入占比因子"""
q = query(
valuation.code,
valuation.market_cap,
north_money.net_pct_main
).filter(valuation.code.in_(stocks)
)
df = get_fundamentals(q, date=date)
return df.set_index('code')['net_pct_main']
注册制下的特殊处理
- 次新股因子需要特殊处理(上市满 60 天再纳入)
- 涨跌幅限制差异(科创板 / 创业板 20%)
五、验证体系搭建
Walk-Forward 回测框架
- 按季度滚动训练模型
- 使用未来一个季度数据测试
- 累计所有样本外结果
关键评价指标
- IC(信息系数):因子与下期收益的相关系数,>0.03 算有效
- IR(信息比率):IC 均值 /IC 标准差,>1.5 说明稳定性好
def calculate_ic(factor, next_ret):
"""计算 Rank IC"""
return factor.rank(pct=True).corr(next_ret.rank(pct=True))
附:因子研究 Checklist
- [] 所有因子避免使用未来函数
- [] 完成 3sigma 去极值处理
- [] 测试过不同市场环境(牛市 / 熊市 / 震荡市)
- [] 样本外测试周期≥3 年
- [] IC 值在不同时间段保持稳定
- [] 因子间相关性 <0.7
最后分享一个血泪教训:去年我有个动量因子在 2019-2021 年回测表现极好,但实盘后发现它只在流动性宽松期有效。现在我的标准流程是必须单独测试 2015 股灾、2018 贸易战等极端行情下的表现。量化没有圣杯,与诸君共勉!
正文完
