
1. 做量化多因子选股之前先把这几件事想明白聊到量化多因子选股很多人第一反应是“写个模型、跑个回测、躺赚”。我见过不少朋友上来就抓一堆因子丢进模型里结果回测曲线漂亮得像艺术品实盘一跑就变脸。问题往往不在模型本身而在整个体系缺了关键环节。多因子选股的本质是用一套可验证的规则把“好股票”从几千只标的中筛出来。这里的“好”不是拍脑袋觉得好而是有数据支撑、有逻辑依据、能重复检验的。它解决的问题是投资决策的纪律性和可复制性——你不再依赖某一天的盘感或某条消息而是靠一套流程化的框架持续输出决策。一个完整的量化多因子选股系统至少包含五个环节数据清洗与因子计算、因子有效性检验、因子合成与权重分配、组合构建与风险控制、回测验证与实盘衔接。这五块缺了任何一环系统都会瘸腿。比如因子没做好标准化就去合成权重就会被量纲大的因子绑架再比如回测里用了未来函数所有好看的数字都是假的。这篇文章适合三类人一是刚入门、想系统了解多因子框架的朋友二是已经在用简单策略、但不知道怎么深度优化的开发者三是想把策略工程化落地、又不希望踩太多坑的从业者。我会把整个开发链路拆开讲重点放在实操细节和那些文档里不会写的坑上。2. 因子体系设计先搭骨架再填血肉2.1 因子从哪里来三类因子的底层逻辑多因子模型里因子就是一个个“选股维度”。每个因子回答一个问题这家公司便宜吗赚钱能力强吗近期市场情绪如何最常用的因子池可以分成三大类。第一类是估值类因子。包括市盈率的倒数EP、市净率的倒数BP、市销率的倒数SP、股息率等。这类因子的逻辑很简单同等条件下买得越便宜安全边际越高。但要注意估值因子在不同行业之间的可比性差。比如银行业的PB普遍低于科技行业直接用原始BP跨行业对比会出问题所以后面必须要做行业中性化这一点我会在第三节详细说。第二类是质量类因子。代表有ROE、ROA、毛利率、净利率、经营现金流占比、资产负债率等。质量因子的核心逻辑是“好公司才有好回报”。这里有个实操细节计算ROE时有人直接拿当期净利润除以当期净资产但净利润是流量概念、净资产是存量概念更严谨的做法是用期初加期末净资产的平均值做分母或者用期初净资产做分母不同口径算出来排名会有差异选定之后就不要随意更换。第三类是量价类因子包括动量和反转类。动量因子用过去N日的收益率来衡量趋势惯性常用的有20日动量、60日动量、250日动量。反转因子恰好相反认为短期涨太多的标的容易回调。有趣的是A股市场里短周期反转效应往往比动量更明显而长周期动量在部分行业又存在这个结论在不同市场、不同时间段是会漂移的所以不能拿来主义必须自己检验。2.2 数据基础设施的搭建方案因子计算的基础是干净的数据。很多人忽略这一步直接用第三方接口拉数据就跑因子遇到停牌日、复权价错误、财报延迟发布等问题全都浑然不觉结果因子值本身都是错的。我的建议是本地维护一套三层的数据库结构。第一层是原始行情表记录每日的开高低收、成交量、成交额、换手率价格必须用后复权口径。后复权能真实反映持有收益前复权数据在回看历史时容易失真。第二层是财务快照表注意不是简单的财报数据而是“每个交易日能拿到的最近财报数据”的日频快照这是防止前视偏差的关键。第三层是因子宽表每一行是一个日期加一只标的每一列是一个因子值这张表是整个系统的数据枢纽。存储引擎方面行情数据用ClickHouse或者DuckDB这类列式存储很合适查询性能远好于MySQL。如果数据量不大直接Pandas加Parquet文件也能胜任。关键不是工具多高级而是数据的口径要统一、更新流程要自动化。提示财务报表数据一定要做“发布日对齐”。某公司年报可能在3月31日披露但披露的利润却是去年全年的。如果你在1月2日就用了这笔财务数据那你就是偷看了未来。这个坑在回测里极其隐蔽且破坏力极大。2.3 因子值计算一个完整的实战样例纸上谈兵没有意义我直接给一个可落地的因子计算流程以“质量因子ROE_TTM”为例。ROE_TTM的分子是最近四个季度的滚动净利润分母是最近四个季度滚动净资产的期初期末均值。计算步骤分成四步。第一步清洗行情数据。剔除停牌超过10个交易日的标的、剔除上市不足60个交易日的新股这一步是为了避免次新股的价格异常波动干扰因子。停牌期间没有成交价格填零或插值都会污染因子分布直接标记为缺失值更稳妥。第二步对齐财务数据。假设今天是2025年第30个交易日在财务快照表中找到每个标的当前可得的最新财报期。比如某公司2024年报已发布就用年报数据若年报未发布但有2024三季报则用三季报加2023年报减去2023三季报的方式滚动拼接出TTM净利润。这里要写一个简单的SQL或DataFrame逻辑保证每个标的在每个日期都取到自己“当时能看到”的最新的四期季报。第三步计算因子值。净利润TTM除以平均净资产得到ROE_TTM序列。对计算结果做基础过滤剔除净资产小于零的样本这些样本的ROE没有实际经济含义。第四步因子截面标准化。这一步其实是独立环节通常会在全市场截面维度做而不是单只标的维度做。截面标准化的意义是让同一因子在不同日期之间数值可比后面单独讲。3. 因子处理与检验不检验的因子都是鬼话3.1 三个必须做的预处理去极值、中性化、标准化因子原始值直接拿来用结果大概率会炸。原因很简单个别极端值会把整个截面的分布拉偏行业属性会带来系统性的同质化影响量纲不同则让多因子合成时无法公平比较。所以每个因子在进入合成环节之前都要经过标准三步。去极值的方法有很多最常用的是MAD法和百分位法。MAD法实操如下先算因子值的中位数M再算每个值到中位数的绝对偏差取这些绝对偏差的中位数得到MAD然后把超过M加3倍MAD和低于M减3倍MAD之外的值截断。我做了这么多年因子经验值是3倍MAD比5倍更保守适合离群值较多的因子比如单日涨幅类因子。百分位法则直接把上下1%和99%分位以外的值钳制到边界值简单粗暴但有时会破坏分布形状。标准化我推荐用z-score也就是减去截面均值再除以截面标准差。但在A股里有一个特殊性小市值股票数量众多如果直接在全市场截面做z-score小市值群体会主导均值和方差导致标准化失真。我的做法是分成两步先做市值中性化再做标准化效果会稳很多。市值中性化的具体操作是对市值取对数以对数市值为自变量、原始因子值为因变量做截面回归取残差作为中性化后的因子值。行业中性化则用虚拟变量加入回归方程或者按行业分组后在各组内部做标准化再加回总体均值。实际工程中大家习惯把行业和市值同时放进一个回归模型来处理即“市值加行业中性化”。这步处理完因子里受系统性风格影响的部分就被剥离了剩下的才是真正的alpha信息。3.2 因子有效性检验IC分析的完整计算逻辑一个因子有没有用必须用量化指标说话。最核心的指标就是IC信息系数。IC的计算方法是在每一个截面日期T计算该期因子值与下一期收益率的相关系数。如果是全体样本的皮尔逊相关系数称为IC如果是按照截面排序后计算的斯皮尔曼秩相关系数称为Rank IC。Rank IC对极端值的容忍度更高实践中我会两个都看。举例来说假设2025年4月1日这个截面有300只股票每只有对应的PB倒数因子值和未来20个交易日的收益率。把这两组数据求相关系数就得到一个截面上的IC值。对历史上每一个截面都做这个计算能得到一条IC序列。然后统计这条IC序列的特征。平均IC的绝对值超过0.03算初步可用超过0.05算优秀。ICIR也就是IC均值除以IC标准差代表因子预测的稳定性一般超过0.3可以重点跟踪。再算一下IC的t统计量t值的绝对值大于2说明IC显著不为零不是随机噪声。注意IC是截面相关时间序列上不能混在一起算。很多初学者把所有日期、所有股票的因子值和收益率堆在一起求相关系数算出来的“IC”实际上是池化相关没法反映因子选股能力的时序稳定性。3.3 分层回测检验因子是否真的单调有效IC能告诉我们因子与未来收益的相关性但一个优秀的选股因子还应该有单调性。所谓单调性就是按因子值从高到低分成10组第1组到第10组的平均收益应该呈现逐步递减或递增的规律。实操步骤是这样的在每个调仓日把截面上所有股票按因子值排序平均分成10层每层作为一个等权组合持有到下一个调仓日计算每层的组合收益。把所有调仓周期的收益汇总得到每层的历史平均收益和累计净值曲线。判断标准有两个。第一看多空组合收益也就是第1层收益减去第10层收益这个值越高说明因子区分度越大。第二看分层单调性中间层是否大致递变如果第1层最高、第2层突然变低、第3层又变高说明因子关系不稳定用起来风险很大。我当时检验一个“换手率因子”时就遇到这种情况分层收益前几层确实单调但到了最高换手率那组收益反而反弹。原因是最热门的股票里掺杂了题材炒作股它们短期涨幅惊人但持续不了多久。后来我把收益评估周期从5天拉长到20天这个反转特征才暴露出来。所以做分层检验时一定要多看几个持有周期避免被短期噪声误导。4. 因子合成与组合构建从单因子到完整策略4.1 多因子怎么合成打分法、回归法与机器学习当手上有了一批经过检验的因子下一步是把它们合成为一个综合评分。最简单的合成方式是打分法。把每个因子在截面上做标准化处理后按设定的权重加权求和得到综合因子值然后排序选前N只。权重的设定可以是等权也可以按ICIR加权即ICIR高的因子给更高权重。打分法的优势是透明、可控、对过拟合不敏感是生产环境中最主流的方案。回归法略有不同它是用历史数据做因子收益的回归学习出每个因子对收益贡献的大小再动态调整因子权重。常见的实现是把因子值作为自变量、未来收益作为因变量做线性回归或岭回归得到每个因子的系数作为权重。回归法的优势是权重能自适应变化但容易过拟合尤其在因子数量多、样本量少的时候。机器学习方法则更进一步随机森林、XGBoost、LightGBM都可以用来做因子非线性组合。模型能自动捕捉因子之间的交互效应比如“低估值且高ROE”组合起来的效果可能远超两个因子单独作用之和。但我必须提醒一句机器学习在回测里很容易做出极高的收益但实盘失效也快核心原因是非线性模型对小样本噪声过度敏感。如果你还在入门阶段先把打分法做扎实比炫技重要得多。4.2 组合构建的参数选择与交易成本考量因子合成之后组合构建环节有四个关键参数要定。第一个是持仓数量。A股全市场几千只标的持仓数通常选30到100只。持仓太少单票波动对组合影响太大持仓太多因子带来的超额收益会被摊薄。我的经验值是50只左右兼顾分散度和集中度。第二个是调仓频率。常见的有周频、双周频和月频。调仓越频繁因子信号的时效性越强但交易成本也越高。因子IC有半衰期动量类因子衰减快适合偏高频调仓估值类因子衰减慢月频调仓完全足够。把调仓频率和因子的IC半衰期匹配起来是组合设计的核心学问。第三个是权重分配。等权配置最简单实际效果往往不错。市值加权则让组合偏向大票波动更小但超额收益也小。我倾向于“等权加约束”的做法即初始等权但限制单一行业的暴露不超过30%。第四个是交易成本。A股的成本包括佣金、印花税和冲击成本。双边佣金按万2.5算印花税卖出时收千0.5冲击成本保守估计双边千1到千2调仓一次的总成本可能在千1到千3之间。如果一个策略周频调仓每期换手率80%一年的交易成本累积下来会吃掉相当可观的一部分毛收益。回测时不在成本模型里扣掉这些出来的收益曲线都是骗自己的。下面给一个我常用的月度调仓组合参数表供参考参数项参考设定设定理由持仓数量50只兼顾分散度与集中度调仓频率月末最后一个交易日月频与基本面因子衰减周期匹配权重方式等权加行业上限30%简单透明控制行业误配交易成本双边千2包含佣金、印花税、冲击成本停牌处理无法成交顺延至复牌日避免回测中虚假成交4.3 风险控制别让风格暴露毁掉你的alpha很多多因子策略跑着跑着就变味了本质是风格敞口失控。最常见的失控是市值敞口。A股历史上小市值风格长期占优很多模型不加约束时选出来的股票会越来越小回测收益高得吓人但一旦风格切换回撤也吓人。检验方法很简单把组合里每只股票的市值取对数求平均再减去全市场对数市值的平均值看这个敞口是否长期为正且在放大。行业暴露同样要监控。比如你的质量因子天然偏好消费和医药行业组合里这两个行业的权重远高于基准那么收益里有多少来自行业Beta、多少来自因子Alpha就说不清了。控制办法就是在组合优化时加入行业中性约束或者直接采用之前中性化处理后的因子信号。我习惯在每次调仓后自动生成一份组合风险报告包括市值敞口、行业权重分布、前十大持仓占比、组合相对基准的跟踪误差。不要等回撤发生了再去查原因组合报告每隔一段时间看一眼比什么风控指标都管用。5. 回测系统开发数字好看之前先把逻辑做对5.1 回测引擎的核心架构与数据流设计一个合格的A股日频回测引擎至少包含四层数据层、信号层、撮合层和绩效层。数据层负责提供行情、财务、因子等全部数据重点保证“时点正确”。信号层在每一个调仓日根据当时的因子值生成目标持仓。撮合层是最容易出错的地方它要根据调仓信号生成实际成交记录必须处理涨跌停无法成交、停牌顺延、一字板买不进等特殊情况。绩效层负责计算组合每日净值、收益率、回撤、夏普比率、换手率等指标。数据流的顺序必须严格执行T日收盘后获取当日完整行情计算因子值生成T1日的目标持仓信号T1日按信号成交。这样安排是为了规避未来函数。很多新手在T日生成信号却用T日开盘价成交等于提前知道了当天信息去做决策这在现实中是不可能做到的。撮合逻辑上我推荐用“目标持仓对比法”比较当前持仓和目标持仓差额为正的部分是买入列表差额为负的部分是卖出列表。成交价用T1日的收盘价或开盘价模拟我个人倾向于用收盘价加冲击成本因为大单在真实市场中很难按盘中均价一次性成交。5.2 回测中常见的几个致命错误前视偏差是回测里最危险的问题。除了财报数据要按发布日对齐还有两个隐蔽场景要小心。第一个是“当日行情用当日信号”比如用收盘后才知道的因子值、却在当日开盘就买入了。第二个是“未来数据回填”比如某些数据服务商对历史财务数据做了重述修正你拿到的是修正后的数值但当时市场看到的是修正前的旧值。幸存者偏差同样普遍。如果直接用当前处于交易状态的股票列表做历史回测那些因为亏损退市的股票就被自动剔除了这会显著高估策略收益。正确做法是使用历史某一日期的当时股票池包含后来退市的标的。这要求数据库里保存“每只股票在每个历史日期的上市状态和停牌状态”工程量不大但很多人忽略。还有一个回测陷阱是换手率幻觉。有些策略回测中每天换仓30%如果按收盘价成交资金规模大一点就根本无法按收盘价全部成交。解决思路是给成交价施加一个与成交量相关的惩罚项或者直接限制单日成交量占总成交量的比例上限。我一般设为2%到5%超过就按比例削减成交数量。5.3 常见问题速查表现象可能原因排查方向回测收益极高但实盘剧烈偏差前视偏差或幸存者偏差检查财务数据对齐逻辑与股票池是否含退市股分层回测中单调性突然失效因子逻辑在不同市场环境下漂移分年度滚动检验因子IC观察稳定性调仓日计算出的权重和实际成交不一致涨跌停、停牌导致部分股票无法成交在撮合层增加不可成交标记并顺延处理因子选出的股票全是小市值缺少市值中性化或市值权重约束检查中性化回归是否包含对数市值变量策略换手率过高因子噪声大或调仓阈值太低增加调仓缓冲带信号变化超过阈值才调仓样本外表现远差于样本内过拟合减少因子数量改用更简单的合成方式5.4 样本内外划分与过拟合防范回测参数调多了人人都能调出漂亮曲线。防止自欺欺人的办法是把数据集严格切成样本内和样本外。我的做法是用前70%的时间段做因子筛选和权重设定用后30%的时间段做验证并且验证期内禁止再回看调参。进阶一点的做法是做滚动前进分析。比如每12个月重新训练一次因子权重只预测接下来3个月的组合表现然后窗口向前滚动。这样能模拟“持续再优化”的真实生产状态也能看出策略在不同市场风格下的稳健性。另外因子数量要克制。因子数量超过20个时过拟合风险会快速上升。学界有个经验法则样本量N和因子数K的比例至少要达到一定量级才不容易过拟合但实操中大家普遍反映把因子控制在5到10个高质量因子的策略长期表现往往优于堆了50个因子的复杂模型。少即是多在量化选股里是一条真金白银换来的经验。我自己早期做策略的时候就吃过这样的亏把十几个相关性很高的动量类因子全放进模型回测收益确实好看但实盘一跑因子拥挤交易发生时同步回撤组合直接吃了大面。后来我用因子相关性矩阵一看好几个因子之间的相关系数超过0.9本质就是同一个逻辑换了个壳。做因子入库前的相关性筛查非常有必要相关系数高于0.7的因子要合并或者剔除这一步能让组合的冗余暴露大幅下降。6. 生产落地与持续迭代的几点体会多因子选股系统开发到这里已经不是“能不能跑”的问题而是“能不能持续稳定地跑”的问题。结合我自己实战里的体会最后分享几个关键认知。第一数据管线永远比策略模型更需要投入。很多团队把精力放在调参和模型优化上但数据延迟、数据缺失、财务字段对齐错误才是实盘中最常出问题的环节。我建议数据管线要有独立监控每天核对行情完整性、财务更新状态和因子覆盖率任何一个指标异常就自动告警。这个习惯帮我避免过好几次因子值大面积为空的灾难。第二实盘和回测之间永远有差距这是正常的关键是要能解释差距。我实盘跑策略时每季度都会做一次“归因分析”把组合收益拆成市场收益、行业收益、因子收益和残差几部分看看到底是哪一块和回测预期不一致。如果残差一直在扩大说明模型里的某个假设可能失效了。第三多因子策略不是静态产品它需要持续迭代。市场的风格在变因子的有效性也在变。我的做法是每个月跟踪一次所有因子的IC和ICIR变化每季度做一次因子库的全面复审淘汰失效因子、引入新因子。把因子的生命周期管理起来策略才能适应市场。最后想说量化多因子选股这个方向门槛不在策略思想而在工程落地的细致程度。把数据处理环节做扎实、把检验环节做严谨、把回测逻辑做正确你的策略就已经跑赢了绝大多数粗糙的系统。踩过的坑越多最后沉淀下来的一定是更稳健的框架这也是这笔投入最大的回报。