1. 从零开始理解多因子选股:为什么基本面量化值得花时间
很多人第一次听到“多因子选股”这个词,脑子里浮现的是一堆数学公式和密密麻麻的财务表格,觉得这是机构里拿着高薪的量化研究员才玩得转的东西。但实际情况是,只要你懂一点Python基础,能看懂资产负债表和利润表的大致结构,就已经具备了搭建一套基础多因子选股系统的前提条件。我自己最开始接触这个方向的时候,也是从“什么是因子”“为什么要做基本面量化”这些最基础的问题一步步摸索过来的,踩过不少坑,也走过一些弯路,今天就把这些前期知识储备的东西系统性地梳理一遍。
所谓多因子选股,本质上就是用多个维度的指标来给股票打分排序,然后选出综合得分最高的那一批。这里的“因子”就是指标,比如市盈率、净资产收益率、营收增速、资产负债率等等。单看一个指标选股很容易翻车,比如你只看低市盈率,可能会选出一堆夕阳行业的股票;只看高ROE,又可能买在景气度顶点。多因子的逻辑就是“不把鸡蛋放在一个篮子里”,从估值、盈利、成长、质量等多个角度综合评估,降低单一指标失效带来的风险。
那为什么用Python来做这件事?因为Python在数据处理方面有天然优势。pandas处理表格数据、numpy做数值计算、matplotlib做可视化,再加上各种财经数据接口,整个流程可以高度自动化。你不需要手动去Excel里一个一个拉数据、算指标,写一次代码,以后每期更新数据就能自动跑出结果。这对于需要定期调仓的选股策略来说,效率提升是数量级的。
这篇文章适合谁看?如果你是刚接触量化投资的新手,想从基本面角度入手但不知道从哪里开始,那这篇内容就是为你准备的。如果你已经有一些编程基础,但对财务指标和因子构建的逻辑还不清楚,也可以从这里补齐短板。我会尽量用生活化的例子来解释专业概念,让没有金融背景的读者也能跟上节奏。
注意:本文涉及的所有数据接口、代码示例均为通用方案演示,不构成任何投资建议。实际使用时请自行评估数据源的可靠性和策略的适用性。
2. 核心概念拆解:因子、基本面与选股逻辑
2.1 什么是因子?用买菜的逻辑来理解
因子这个词听起来很学术,但其实逻辑特别简单。你去菜市场买菜,会看几个维度:价格便不便宜、新不新鲜、是不是当季的、摊主口碑好不好。这几个维度就是你的“选菜因子”。股票也一样,你需要一些可量化的维度来判断一家公司值不值得买。
在量化选股里,因子通常分为几大类:
- 估值因子:市盈率(PE)、市净率(PB)、市销率(PS)、股息率等。核心逻辑是“便宜的东西上涨空间大”。
- 盈利因子:净资产收益率(ROE)、总资产收益率(ROA)、毛利率、净利率等。核心逻辑是“赚钱能力强的公司更值得投资”。
- 成长因子:营收增长率、净利润增长率、经营现金流增长率等。核心逻辑是“增长快的公司未来价值更高”。
- 质量因子:资产负债率、流动比率、应收账款周转率等。核心逻辑是“财务健康的公司抗风险能力强”。
- 动量因子:过去一段时间的收益率、换手率等。虽然严格来说动量属于技术面,但在多因子框架里经常和基本面因子混合使用。
每个因子就像一把尺子,从某个特定角度去衡量股票的好坏。但任何一把尺子都有局限性,所以需要多把尺子一起量。
2.2 基本面选股和技术面选股的本质区别
技术面选股看的是价格和成交量的历史规律,比如均线金叉、MACD背离、成交量放大等等。它的假设是“历史会重演”,价格走势已经反映了所有信息。基本面选股看的是公司的财务数据和经营状况,它的假设是“价格终将回归价值”,好公司迟早会被市场认可。
这两种方法没有绝对的好坏之分,但基本面选股有几个明显的优势:第一,数据更新频率低,财报一个季度才出一次,不需要天天盯盘;第二,逻辑更扎实,你知道自己为什么买这家公司,而不是因为“图形好看”;第三,容量更大,基本面策略通常能容纳更大的资金规模,不容易因为交易拥挤而失效。
当然,基本面选股也有缺点。最大的问题是数据滞后性——你看到的财报可能是三个月前的经营情况,等你买入的时候,市场可能已经提前反应了。另外,财务数据有可能被粉饰,单纯依赖报表数字有踩雷的风险。这些都是在构建因子时需要特别注意的地方。
2.3 多因子模型的基本框架长什么样
一个完整的多因子选股流程,大致可以拆成这么几步:
- 确定股票池:比如全市场剔除ST股、剔除上市不满一年的新股、剔除流动性太差的股票。
- 获取财务数据:从数据源拉取每只股票的估值、盈利、成长、质量等指标。
- 数据清洗与预处理:处理缺失值、异常值,做去极值、标准化等操作。
- 因子有效性检验:看每个因子和未来收益的相关性,剔除无效因子。
- 因子合成:把多个因子加权合成为一个综合得分。
- 排序选股:按综合得分从高到低排序,选出前N只股票。
- 回测验证:用历史数据检验策略的表现,看收益、回撤、夏普比率等指标。
- 定期调仓:比如每季度财报发布后重新计算因子并调仓。
这个框架看起来步骤不少,但每一步拆开来看都不复杂。前期知识储备阶段,最重要的是理解每一步在做什么、为什么这么做,而不是急着写代码。
3. 数据准备:财务数据从哪里来、怎么用
3.1 常见的数据获取渠道对比
做基本面量化,数据是基础。没有可靠的数据源,后面的一切都是空中楼阁。目前常见的获取渠道有这么几类:
| 数据源类型 | 代表方案 | 优点 | 缺点 |
|---|---|---|---|
| 开源财经接口 | 各类公开财经数据接口 | 免费、上手快 | 数据字段有限、稳定性一般 |
| 券商研究平台 | 部分券商提供的量化研究环境 | 数据质量高、字段全 | 需要开户、有使用门槛 |
| 付费数据服务 | 专业金融数据服务商 | 数据全面、更新及时 | 费用较高 |
| 自建爬虫 | 自行抓取公开财报数据 | 灵活可控 | 维护成本高、易失效 |
对于刚入门的个人开发者,我的建议是先从开源接口入手,把整个流程跑通,等策略逻辑验证清楚了再考虑升级数据源。一开始就追求完美数据,很容易陷入“数据准备半年,策略一行没写”的困境。
3.2 财务数据的关键字段说明
拿到数据之后,你需要知道哪些字段是核心的。下面这张表列出了最常用的基本面字段:
| 字段名称 | 含义 | 所属类别 | 使用注意 |
|---|---|---|---|
| PE_TTM | 滚动市盈率 | 估值 | 负值需特殊处理 |
| PB | 市净率 | 估值 | 重资产行业参考性更强 |
| ROE_TTM | 滚动净资产收益率 | 盈利 | 需关注可持续性 |
| gross_margin | 毛利率 | 盈利 | 行业间差异大 |
| revenue_yoy | 营收同比增长率 | 成长 | 需剔除基数效应 |
| profit_yoy | 净利润同比增长率 | 成长 | 波动较大 |
| debt_to_assets | 资产负债率 | 质量 | 金融行业不适用 |
| current_ratio | 流动比率 | 质量 | 低于1需警惕 |
这些字段不是越多越好,关键是理解每个字段背后的经济含义。比如PE_TTM为负说明公司亏损,这时候低PE不代表便宜,反而可能是陷阱。再比如资产负债率,制造业和银行业的合理水平完全不同,不能一刀切。
3.3 数据清洗的四个关键步骤
原始财务数据往往有很多“脏”的地方,直接拿来算因子会出问题。数据清洗通常包括以下几步:
第一步:处理缺失值。有些股票某些字段没有数据,可能是新股、可能是行业特殊性。常见的处理方式是直接剔除该股票,或者用行业中位数填充。我个人的习惯是如果核心字段缺失超过三个,就直接把这只股票从当期股票池里去掉。
第二步:去极值。财务数据里经常出现极端值,比如某家公司卖资产导致净利润暴增几百倍,这种数据会严重干扰因子排序。常用的去极值方法有MAD法(中位数绝对偏差法)和分位数法。MAD法的逻辑是:先算所有数据的中位数,再算每个数据与中位数的偏差,把偏差超过一定倍数的值拉回到边界上。
第三步:标准化。不同因子的量纲完全不同,PE可能是10到100,ROE可能是0到30%,直接加权没有意义。标准化的目的就是让所有因子都变成均值为0、标准差为1的分布,这样才有可比性。最常用的是Z-score标准化。
第四步:中性化。这一步很多人会忽略,但其实很重要。比如你发现小市值股票的ROE普遍偏低,如果不做市值中性化,你的因子可能实际上在赌市值风格,而不是真的在选高质量公司。中性化的做法是用因子值对市值等行业变量做回归,取残差作为新的因子值。
实操心得:数据清洗这一步看起来枯燥,但实际上是整个流程里最影响最终结果的环节。我见过太多人因子逻辑设计得很漂亮,结果因为没处理好极端值,回测收益虚高得离谱,实盘一跑就原形毕露。
4. 因子构建与有效性检验的实操要点
4.1 单因子测试的标准流程
构建好因子之后,不能直接拿来用,必须先检验它是否有效。所谓“有效”,简单说就是这个因子值高的股票,未来收益是不是真的比因子值低的股票好。标准的单因子测试流程是这样的:
- 每期(比如每个季度)根据因子值将股票池分成5组或10组。
- 计算每组在下一期的平均收益。
- 观察最高组和最低组的收益差是否显著。
- 计算IC值(信息系数),即因子值与下期收益的相关系数。
- 看IC的均值、标准差、IC_IR(信息比率)等指标。
如果最高组的收益持续高于最低组,且IC均值在0.03以上、IC_IR大于0.3,那这个因子就算是比较有效的。当然,这只是经验阈值,不同市场、不同时期的标准会有差异。
4.2 因子有效性的三个核心指标
评价一个因子好不好,主要看三个指标:
IC值(Information Coefficient):因子值与未来收益的截面相关系数。IC均值越高,说明因子的预测能力越强。一般来说,IC均值超过0.05就算不错了,超过0.1就是非常强的因子。但要注意,IC高不代表一定能赚钱,还要看稳定性。
IC_IR(IC Information Ratio):IC均值除以IC标准差。这个指标衡量的是因子预测能力的稳定性。IC_IR越高,说明因子在不同时期的表现越一致。通常IC_IR大于0.5就算比较稳定了。
多空收益差:最高分组和最低分组的收益差。这个指标直接反映了因子的选股能力。如果多空收益差常年为正且幅度可观,说明因子确实能区分好坏股票。
4.3 因子相关性分析与合成方法
当你手上有多个因子时,不能简单地把它们加起来,因为因子之间可能存在高度相关性。比如ROE和ROA都是衡量盈利能力的,相关性可能达到0.8以上,同时使用会导致盈利因子被重复计算,权重失衡。
处理方法是先算因子之间的相关系数矩阵,把相关性过高的因子合并或剔除。一般来说,相关系数超过0.7的两个因子,保留IC更高的那个就行。
因子合成最常用的方法是等权加权和IC加权。等权就是每个因子权重一样,简单粗暴但有效。IC加权是根据每个因子的历史IC均值来分配权重,IC高的因子权重更大。我个人更倾向于等权,因为IC加权容易过拟合历史数据,而且因子IC本身波动就大,用历史IC推未来权重未必靠谱。
5. 回测框架搭建与常见陷阱
5.1 回测的基本逻辑和关键参数
回测就是用历史数据模拟策略的表现。听起来简单,但细节特别多。一个基本的回测框架需要明确以下参数:
- 调仓频率:季度调仓还是月度调仓?基本面因子通常用季度调仓,因为财报数据是季度更新的。
- 持仓数量:选前10只、前20只还是前50只?持仓太少波动大,持仓太多超额收益被稀释。
- 交易成本:佣金、印花税、滑点都要考虑。很多人回测收益很高,一算交易成本就亏了。
- 基准指数:用来对比策略表现,比如沪深300或中证500。
5.2 回测中最容易犯的五个错误
第一个错误:未来函数。这是最致命的。比如你在计算因子时用了当天收盘后的数据,但回测时假设当天收盘就能交易,这就用了未来信息。正确的做法是财报发布后的下一个交易日才能使用该数据。
第二个错误:幸存者偏差。如果你只用了当前还在上市的股票做回测,那些已经退市的股票就被自动剔除了,这会高估策略收益。正确的做法是使用包含退市股票的全历史数据。
第三个错误:过度优化。为了让回测曲线好看,不断调整参数,比如把持仓数量从20改成18,把调仓频率从季度改成两个月。这种过度拟合历史数据的策略,实盘表现往往很差。
第四个错误:忽略流动性。小市值股票收益可能很高,但实际交易时可能买不进也卖不出。回测时必须考虑成交额限制,比如只选日均成交额超过一定阈值的股票。
第五个错误:数据对齐错误。财务数据的报告期和实际发布日期是两回事。比如一季报的报告期是3月31日,但实际发布可能在4月底。如果你用报告期来对齐数据,就会引入未来信息。
避坑技巧:回测结果好得离谱的时候,先别高兴,大概率是哪里出错了。正常的年化超额收益在10%到20%之间就算不错了,如果回测显示年化50%以上,几乎可以肯定有bug。
5.3 评价策略表现的四个核心指标
| 指标名称 | 含义 | 参考标准 |
|---|---|---|
| 年化收益率 | 策略每年的平均收益 | 跑赢基准5%以上算合格 |
| 最大回撤 | 从最高点到最低点的最大亏损 | 控制在30%以内比较理想 |
| 夏普比率 | 单位风险的超额收益 | 大于1算不错,大于2算优秀 |
| 胜率 | 盈利调仓次数占总次数的比例 | 基本面策略通常50%到60% |
这四个指标要结合起来看,不能只看收益。一个策略年化收益30%但最大回撤50%,持有体验会非常差,很多人中途就割肉离场了。
6. 常见问题与排查技巧实录
6.1 数据类问题排查
问题一:财务数据缺失严重怎么办?
先排查是数据源的问题还是股票本身的问题。如果是数据源接口不稳定,换一个数据源试试。如果是股票本身某些字段没有,比如银行股没有毛利率数据,那就针对行业做特殊处理,或者直接剔除该行业。
问题二:不同数据源的财务数据对不上怎么办?
这是很常见的情况,不同数据商对同一家公司的净利润统计可能有差异。处理原则是:选定一个数据源后就不要频繁更换,保持一致性。如果发现某个字段明显异常,可以手动核对原始财报。
问题三:财报数据更新不及时怎么办?
有些数据接口的更新有延迟,比如财报发布后一周才更新。这时候可以在代码里加一个判断逻辑:如果最新报告期数据缺失,就沿用上一期数据,但要标记出来,避免误用。
6.2 因子类问题排查
问题一:因子IC值很低甚至为负怎么办?
先检查因子计算逻辑有没有写错,比如增长率算成了绝对值。如果逻辑没问题,可能是这个因子在当前市场环境下失效了。因子失效是正常现象,没有永远有效的因子。可以尝试调整因子定义,比如把ROE换成ROE的同比变化。
问题二:因子之间相关性太高怎么办?
用相关系数矩阵排查,把相关性超过0.7的因子合并。合并方法可以是取平均,也可以做主成分分析提取主成分。但主成分分析的可解释性差,我个人不太推荐在初期使用。
问题三:因子在回测中表现好但实盘不行怎么办?
大概率是过拟合了。检查回测中是否有未来函数、幸存者偏差等问题。另外,实盘和回测的交易成本、滑点差异也要考虑进去。如果回测时没算交易成本,实盘一扣就亏了。
6.3 代码实现类问题排查
问题一:pandas处理大数据量时内存不够怎么办?
可以用分块读取的方式,每次只读一部分数据。另外,把数据类型从float64降为float32也能省不少内存。如果数据量实在太大,考虑用数据库存储,只把需要的数据读进内存。
问题二:循环计算因子太慢怎么办?
尽量用pandas的向量化操作代替for循环。比如计算所有股票的ROE,不要一只一只循环,直接用列运算。如果实在需要循环,可以用apply或者numba加速。
问题三:回测代码跑一次要很久怎么办?
先做性能分析,看时间花在哪里。通常是数据读取和因子计算占大头。可以把中间结果缓存起来,避免重复计算。另外,用多进程并行处理也能显著提速。
实操心得:我刚开始写回测的时候,一个季度调仓的策略跑十年数据要十几分钟,后来发现是每次调仓都重新读取全部数据。改成一次性读取、内存中切片之后,时间缩短到几十秒。这种优化看起来不起眼,但当你需要反复调试参数时,节省的时间非常可观。
7. 从知识储备到实战的过渡建议
前期知识储备做得再充分,最终还是要落到代码上。我的建议是不要等所有知识都学完了再动手,而是边学边做。可以先从一个最简单的单因子策略开始,比如只用低市盈率选股,把数据获取、清洗、排序、回测整个流程跑通。跑通之后再逐步加入更多因子,优化数据清洗逻辑,完善回测框架。
这个过程中你会遇到很多文档里不会写的问题,比如某个数据接口突然不能用了、某只股票的财务数据明显异常、回测结果和预期完全相反。这些问题才是真正让你进步的地方。每解决一个问题,你对整个系统的理解就深一层。
另外,不要闭门造车。多看看别人写的因子逻辑和回测框架,哪怕不直接用,也能给你很多启发。量化投资这个领域,思路比代码重要,而好的思路往往来自于广泛的阅读和交流。
最后说一个我自己的体会:基本面多因子选股不是一夜暴富的工具,它更像是一种系统化的投资思维方式。它强迫你去关注公司的真实经营状况,而不是被市场情绪牵着走。即使你最终不用它来实盘交易,学习这套方法本身也能让你对投资有更理性的认识。