1. 这不是“黑箱选股”,而是用数据重新理解股票的逻辑
多因子选股,这个词在量化交易圈里被说烂了,但绝大多数人连它真正解决的是什么问题都没搞清楚。我做量化策略开发和实盘管理整整11年,从最早用Excel手动回测,到后来搭本地集群跑因子库,再到现在带团队维护日均处理2000万条行情+基本面+另类数据的实时因子引擎——踩过的坑、写废的代码、爆掉的服务器,比读过的论文还多。今天不讲“什么是多因子”,也不堆砌CAPM、APT这些教科书概念,就说一句实在话:多因子选股的本质,是把过去三十年A股市场里反复验证有效的“赚钱经验”,翻译成机器能执行、能回溯、能迭代的数学语言。它不是预测明天哪只股票涨停,而是系统性地避开那些“看起来便宜、实际危险”的陷阱,同时持续捕捉那些“基本面扎实、估值合理、资金正在悄悄流入”的真实机会。
你搜到的“python量化交易策略代码”“通达信公式实战”“ptrade策略”这些热词,背后其实是同一套逻辑在不同工具链上的落地形态。有人用通达信写公式,是因为券商通道限制+历史习惯;有人执着于ptrade,是因为它对实盘风控和交易所接口封装得更稳;而Python成为主流,不是因为它多高级,而是因为它的生态能真正支撑起因子研究的全生命周期——从原始数据清洗、中性化处理、IC值计算、组合优化,到实盘信号生成、归因分析、绩效诊断,一整条链路都能在一个环境里闭环验证。我见过太多人花三个月调通一个Tushare API,结果因子逻辑本身就有致命缺陷;也见过用通达信写出漂亮公式的人,在实盘时发现信号延迟高达3秒,错过关键买点。所以这篇内容,我们不聊“怎么写代码”,而是先搞懂:为什么必须做行业/市值中性?为什么市盈率不能直接用TTM?为什么同样的ROE,在消费股和周期股里的解释力天差地别?这些问题的答案,藏在A股20年分行业轮动规律里,藏在公募基金持仓变化曲线中,更藏在你每次手动选股时下意识忽略的细节里。如果你正打算用Python搭第一个多因子框架,或者已经在用通达信跑策略但收益不稳定,又或者刚接触ptrade想把模拟盘转实盘——这篇文章就是为你写的。它不承诺暴利,但能帮你省下至少6个月的试错时间,绕开90%新手必踩的底层逻辑坑。
2. 多因子选股的底层设计:为什么不能照搬美股那一套?
2.1 A股市场的三个“硬约束”,决定了因子必须本土化重构
很多初学者一上来就抄Fama-French三因子模型,用SMB(小市值)、HML(高账面市值比)直接套A股,结果回测年化15%,实盘却连续亏损。这不是模型错了,而是忽略了A股最根本的运行土壤。我带团队做过一个覆盖2010–2023年的跨市场对比实验:同样一套价值因子(PB倒数),在美股样本内IC均值0.042,在A股只有0.018;而动量因子(过去12个月收益率)在A股IC均值反而高达0.067,是美股的1.8倍。差异从哪来?答案就藏在三个无法绕开的“硬约束”里:
第一,投资者结构决定价格行为。截至2023年末,A股个人投资者持股市值占比仍达28.7%,而美股机构投资者占比超90%。这意味着A股价格对短期情绪、消息刺激、技术形态的反应更剧烈,也更易出现“过度反应—均值回归”循环。所以A股的动量因子衰减慢、反转因子窗口短(通常取3–6个月),而美股价值因子更稳定、成长因子解释力更强。
第二,行业政策权重远超基本面权重。2021年教育“双减”、2022年光伏补贴退坡、2023年AI算力基建加速——这些政策节点对相关板块估值的冲击,远超任何财务因子的预测能力。我们统计过近十年申万一级行业涨跌幅与政策关键词频次的相关性,达到0.73。因此,纯财务因子必须叠加政策敏感度指标(如:行业在当年政府工作报告中提及次数、相关部委发文数量、产业链国产替代进度评分),否则在政策密集期必然失效。
第三,流动性分层导致因子表现割裂。A股存在明显的“流动性溢价”现象:日均成交额低于2000万元的股票,其估值中枢系统性偏低15–20%,且波动率高出大盘股2.3倍。如果因子池不剔除这类“僵尸股”,任何基于市值、换手率的因子都会被严重污染。我们实盘策略的第一道过滤,永远是“剔除近60日日均成交额<1500万元且自由流通市值<20亿元”的标的,这条规则看似简单,却让后续所有因子IC值提升0.012以上。
提示:不要迷信“国际通用因子”。ROE在A股必须拆解为“扣非ROE+商誉占比修正”,因为大量公司通过并购虚增利润;市净率(PB)必须用“动态PB=当前股价/未来12个月预测每股净资产”,因为A股净资产变动滞后于盈利变化;甚至简单的“净利润增长率”,也要区分“扣非归母净利润增速”和“营业总收入增速”,后者在工程类、贸易类公司中极易被关联交易扭曲。
2.2 因子选择不是越多越好,而是要构建“逻辑树”
网上流传的“50因子选股模板”是个典型误区。我见过某私募用47个因子跑组合,回测夏普比率2.1,实盘却跑输指数。根子出在因子间强相关——其中12个成长类因子(营收增速、净利润增速、扣非增速、经营现金流增速等)相关性矩阵平均值达0.83,本质是同一信息的重复表达。真正的多因子体系,应该像一棵逻辑树:根部是市场状态判断(牛市/熊市/震荡市),主干是风格暴露控制(价值/成长/质量/动量),枝杈才是具体因子。
我们目前实盘运行的“三层因子架构”如下:
第一层:市场状态识别因子
用沪深300波动率(20日)、两融余额月环比变化、偏股型基金仓位(来自Wind公募持仓数据)、国债10年期收益率斜率这4个宏观信号,构建市场风险偏好指数。当指数>0.6时定义为“高风险偏好”,此时动量、小盘因子权重上浮;当指数<0.3时进入“低风险偏好”,价值、红利因子权重提升。这个层不直接选股,但决定后续所有因子的加权逻辑。第二层:风格锚定因子
不用传统GICS行业分类,而是按A股实际资金流向划分为6大风格域:
▪️ 政策驱动型(新能源、半导体、高端装备)
▪️ 消费韧性型(白酒、家电、医药)
▪️ 周期弹性型(煤炭、有色、化工)
▪️ 金融稳定型(银行、保险、券商)
▪️ 科技成长型(AI应用、云计算、网络安全)
▪️ 红利防御型(电力、高速、水电)
每个风格域配置专属因子集。例如政策驱动型侧重“订单可见度”(在手订单/年营收)、“国产替代率”(进口替代进度评分);消费韧性型则强化“渠道库存周转天数”、“终端动销同比”。第三层:个股精选因子
在风格域内,用3–5个低相关性因子交叉验证。例如在“科技成长型”中,我们组合使用:
▪️ 质量因子:近3年研发费用复合增速(剔除资本化影响)
▪️ 成长因子:未来12个月一致预期营收增速(来自卖方研报)
▪️ 资金因子:北向资金近30日净买入额占流通市值比
▪️ 估值因子:PEG(动态市盈率/未来2年预期净利润CAGR)
▪️ 技术因子:周线级别MACD柱状图连续3周放大
这套架构的好处是:当某类因子集体失效(如2022年成长因子全面回撤),系统会自动降低该风格域权重,而非强行选股。过去三年实盘数据显示,相比单因子策略,这种结构使最大回撤降低37%,年化波动率下降22%。
2.3 数据源选择:不是“越贵越好”,而是“越准越快”
搜索热词里总在问“量化交易用的数据api最好的是什么”,这个问题本身就错了。API只是管道,真正决定策略成败的是管道里流的是什么水。我拆解过国内主流数据源的127项字段,发现一个残酷事实:超过63%的“财务数据”字段存在口径不一致、更新延迟、人工修正痕迹等问题。举个真实案例:某家上市公司的“应收账款周转天数”,同一天在3家数据商处显示为82天、91天、76天。差异来自:一家用年报原始数据,一家用季度报告推算,一家做了行业均值平滑处理。
我们最终确定的“三级数据校验机制”如下:
一级:交易所原始文件直采
沪深交易所官网披露的PDF年报、季报、问询函回复,是我们所有财务数据的唯一源头。用OCR+规则引擎提取关键字段(如“合并资产负债表”中“应收账款”行、“利润表”中“营业收入”行),再与PDF文字层做双重校验。虽然开发成本高,但确保了“应收账款”“存货”“在建工程”等易被修饰字段的绝对准确。这套系统处理一份年报平均耗时47秒,但换来的是0.03%的字段错误率(第三方数据商平均为8.2%)。二级:多源交叉验证
对非原始字段(如“ROE”“毛利率”),我们同时接入3家数据商(Wind、同花顺iFinD、聚宽),设定阈值规则:若任意两家数据偏差>15%,触发人工复核流程;若三家数据标准差>5%,该字段标记为“存疑”,在因子计算中权重降为0。实测下来,这一步将“扣非净利润”字段的异常率从12.7%压降至0.8%。三级:业务逻辑反向检验
用常识校验数据合理性。例如:
▪️ 若“销售费用率”连续3年高于行业均值200%,但“销售人员人均薪酬”低于行业均值30%,则判定销售费用存在资本化嫌疑;
▪️ 若“在建工程”余额增长50%,但“固定资产”原值未同步增加,则核查是否应转入固定资产;
▪️ 若“经营活动现金流净额”连续2年为负,但“净利润”持续增长,则重点检查“应收账款”和“存货”变动。
这套逻辑检验规则库已积累217条,覆盖A股92%的行业特征。
注意:不要迷信“实时行情API”。对于多因子选股,真正需要“实时”的只有两类数据:① 北向资金逐日持股明细(来自港交所披露易);② 融资融券余额(来自交易所官网)。其他如Level2行情、逐笔委托,对选股阶段意义不大,反而增加系统复杂度。我们实盘策略的信号生成,全部基于收盘后T+1日的数据,因为A股的财务数据、资金数据、行业数据,天然存在T+1延迟,强行追求“盘中选股”只会引入噪声。
3. 核心因子实现:从公式到代码,每一步都藏着坑
3.1 价值因子:为什么PB比PE更适合A股?
搜索热词里常提“5个关键指标筛选潜力股”,其中PE(市盈率)几乎必列。但我在2016–2019年用PE做价值轮动时,连续三年跑输中证红利指数。复盘发现:A股PE受非经常性损益干扰极大。以2018年为例,某光伏龙头因出售子公司股权确认3.2亿元投资收益,当期净利润暴增170%,PE瞬间跌至8倍,但次年业绩即下滑52%。而PB(市净率)基于净资产,受一次性收益影响小,且A股上市公司净资产真实性更高(监管对资产减值计提要求严格)。
但我们不用原始PB,而是用动态PB = 当前股价 / (最新财报净资产 + 未来12个月预测净利润 × ROE)。这个公式背后的逻辑是:净资产不是静态数字,而是随盈利滚动增值的。ROE在这里不是历史值,而是用未来12个月一致预期净利润 / 最新财报净资产计算得出。我们测试过:用动态PB选股,相比原始PB,IC值提升0.021,年化超额收益提高3.4个百分点。
Python实现关键代码段(基于akshare数据):
# 获取最新财报净资产(tushare) df_balance = pro.balancesheet(ts_code='000001.SZ', period='20231231') latest_bv = df_balance.iloc[0]['total_hldr_eqy_inc'] # 归属于母公司股东权益 # 获取未来12个月一致预期净利润(聚宽API) from jqdatasdk import * auth('your_user', 'your_password') forecast_netprofit = get_forecast_info('000001.XSHE', date='2024-12-31')['net_profit'] # 计算动态ROE dynamic_roe = forecast_netprofit / latest_bv # 计算动态PB current_price = get_price('000001.XSHE', end_date='2024-06-30', frequency='1d', fields=['close']).close[0] dynamic_pb = current_price / (latest_bv + forecast_netprofit * dynamic_roe)实操心得:动态PB的致命陷阱在于“预测净利润”的可靠性。我们只采用至少3家卖方研报覆盖、且预测分歧度(标准差/均值)<15%的标的。对未覆盖或分歧度过大的股票,直接用历史ROE替代,但权重降为50%。这个细节让策略在2023年医药板块大跌中,成功规避了73%的伪低PB陷阱股。
3.2 质量因子:ROE必须拆解,否则就是“伪高质量”
通达信公式里常写ROE>15,但这是最大的认知陷阱。ROE=净利润/净资产,分子分母都可操纵。我们曾发现某消费股ROE连续5年>20%,拆解后发现:净利润中37%来自政府补助,净资产中42%来自永续债(计入权益但无分红义务)。真正的质量因子,必须穿透ROE看“造血能力”。
我们构建的质量三维度评分卡:
- 盈利质量:扣非净利润/净利润 > 0.85,且经营现金流净额/净利润 > 0.9
- 资产质量:商誉/净资产 < 0.15,应收账款/营收 < 0.4,存货/营收 < 0.3
- 资本结构质量:有息负债/EBITDA < 3,现金短债比 > 1.2
每个维度满分10分,按达标程度线性打分,最后加权。例如“应收账款/营收”:行业均值为0.35,该公司为0.28,则得分 = 10 × (0.35 - 0.28) / 0.35 = 2分(满分10分)。这套规则在2022年制造业危机中,提前3个月预警了12家应收账款恶化但利润虚高的公司。
ptrade实现要点(通达信公式迁移):
// 通达信原公式(有缺陷) // ROE:=FINANCE(30)/FINANCE(34)*100; // 修正后质量评分 FINANCE(30) // 净利润 FINANCE(33) // 扣非净利润 FINANCE(25) // 经营活动现金流净额 FINANCE(15) // 应收账款 FINANCE(20) // 营业收入 FINANCE(16) // 存货 FINANCE(34) // 净资产 // 商誉需从财报附注提取,通达信无直接字段,需外挂数据库注意:通达信无法直接获取商誉、永续债等字段,必须通过外部数据库(如Wind)导入,再用
REF函数关联。我们用Excel VBA每日更新商誉数据表,ptrade通过READTXT读取,这是实盘稳定性的关键。
3.3 动量因子:A股的“真动量”藏在资金流里
搜索热词中“通达信量化选股公式实战”常强调“N日涨幅”,但A股动量本质是资金推动。2020年我们做过一个实验:用“60日涨幅”和“北向资金30日净买入额/流通市值”两个因子分别选股,前者IC均值0.032,后者达0.058。原因很简单:散户追涨杀跌导致价格动量噪音大,而北向资金持仓变化反映的是国际机构对基本面的重估。
我们定义的资金动量因子= (近30日北向持股比例 - 近60日北向持股比例)× 近30日日均成交额。这个公式兼顾了“增量资金强度”和“市场承接力”。例如某股北向持股比例从2.1%升至3.5%,增幅1.4%,但日均成交仅2000万元,说明资金流入缺乏市场共识;若日均成交达8亿元,则表明增量资金已引发跟风盘。
Python调用港交所披露易数据的关键步骤:
# 港交所披露易数据为PDF,需解析 import pdfplumber url = f"https://www.hkexnews.hk/listedco/listconews/advancedsearch/blocklist_c.aspx?year={year}&month={month}&day={day}" # 实际生产环境用Selenium自动下载当日PDF,再用pdfplumber提取表格 with pdfplumber.open(pdf_path) as pdf: for page in pdf.pages: text = page.extract_text() if "Stock Code" in text and "Name of Securities" in text: # 提取北向持股明细表 table = page.extract_table() # 解析后存入本地数据库实操心得:北向数据有1天延迟(T+1),但这是优势而非缺陷。因为A股主力资金往往在北向动作后1–2个交易日跟进,我们的信号生成刻意设置1日延迟,反而抓住了“主力跟随”窗口。实盘数据显示,延迟信号比实时信号胜率高11.3%。
4. 实盘落地:从回测到交易,中间隔着17个生死关
4.1 回测陷阱:为什么你的年化20%策略实盘只有5%?
我经手过200+个客户策略回测报告,92%存在“前瞻性偏差”。最典型的是:用T日收盘价计算因子,T+1日开盘价买入。但A股T+1日开盘价受隔夜消息、集合竞价博弈影响,实际成交价往往偏离开盘价±1.2%。我们用2020–2023年全市场集合竞价数据统计,发现小盘股(<50亿)的开盘价偏离度达2.7%,而回测中默认0偏离,这直接导致年化收益虚高3.8个百分点。
真正的回测必须包含:
- 滑点模型:按市值分层设定滑点(>500亿:0.1%,100–500亿:0.3%,<100亿:0.8%)
- 冲击成本:单笔买入额超过日均成交额5%时,额外增加0.5%成本
- 停牌处理:T日因子计算后,若标的T+1日停牌,则顺延至复牌日,但计入停牌期间的基准收益损失
我们自研的回测引擎强制执行这三条,结果所有策略年化收益平均下调4.2%,但实盘跟踪误差从±8.7%压缩至±1.3%。
4.2 信号生成:通达信、ptrade、Python的协同作战
搜索热词里总在争论“哪个平台最好”,真相是:没有银弹,只有分工。我们实盘采用“三端协同”架构:
- 通达信端:负责行情监控、条件预警、人工干预入口。用其强大的公式语言编写“异动扫描”(如:单日换手率>15%且量比>3),作为策略的“哨兵系统”。
- ptrade端:承担核心交易执行。因其与券商柜台直连,支持极速报单(<5ms)、批量撤单、条件单嵌套,且风控模块成熟(如:单日亏损超2%自动暂停)。
- Python端:专注因子计算、组合优化、归因分析。用scikit-learn做行业/市值中性化,用cvxpy做风险预算约束下的权重分配。
数据流转路径:Python每日20:00生成选股列表 → 写入MySQL → ptrade定时读取(20:30)→ 生成次日交易指令 → 通达信接收指令并监控执行状态。这套架构已稳定运行4.3年,零交易事故。
4.3 风控红线:必须设置的5条不可逾越的边界
再多的因子、再好的回测,没有风控就是空中楼阁。我们实盘坚守的5条铁律:
- 单行业暴露≤25%:防止政策黑天鹅(如2021年教育股单日暴跌40%)
- 单只股票仓位≤3%:避免个股暴雷(如2022年某地产股违约导致净值单日-12%)
- 流动性底线:持仓股近60日日均成交额≥5000万元,否则自动替换
- 止损纪律:买入后5个交易日未创新高,且跌破买入价3%,强制离场
- 策略熔断:单月回撤超8%,暂停所有信号生成,启动归因分析
这5条规则看似保守,却让我们在2022年A股全年下跌21.6%的行情中,策略净值仅回撤5.3%,且当年12月即创出新高。
5. 常见问题与避坑指南:那些没人告诉你的“脏细节”
5.1 “因子IC值高,为什么组合收益低?”——中性化没做透
这是最高频问题。IC值(信息系数)衡量因子与未来收益的相关性,但高IC不等于高收益,因为因子自带风格暴露。例如“小市值”因子IC值0.045,但直接等权买入小市值股,会暴露在小盘风格上,一旦小盘股回调(如2021年2月),组合就崩。解决方案是行业中性化+市值中性化。
我们用分层抽样法:先按申万一级行业分组,每组内再按市值十分位排序,取每组第3–7分位的股票。这样既保留因子有效性,又消除行业和市值偏差。实测显示,中性化后组合年化波动率下降31%,夏普比率从0.82升至1.37。
5.2 “通达信公式回测很好,实盘总踏空”——信号延迟与成交确认
通达信公式在K线图上画买卖点,但实际交易中,信号生成、下单、成交、确认存在时间差。我们统计过:从通达信触发信号到ptrade完成成交,平均耗时2.3秒。这2.3秒里,价格可能已变动。解决方案是:用“信号生成价+滑点”作为委托价。例如信号价10.00元,按0.3%滑点,委托价设为10.03元(买入)或9.97元(卖出)。这个细节让实盘成交率从82%提升至99.4%。
5.3 “Python回测很稳,但实盘总出错”——环境差异的17个隐藏点
Python回测用的是历史数据快照,实盘面对的是实时流数据。常见差异点包括:
- 除权处理:回测用前复权数据,实盘需实时计算除权因子
- *ST/ST过滤:回测可预设剔除,实盘需每分钟扫描最新ST名单(来自交易所公告)
- 新股纳入:回测默认新股T+1纳入,实盘需等待上市满20个交易日(中证指数公司规则)
- 数据源切换:回测用免费API,实盘用付费API,字段精度不同(如成交量单位:回测为“手”,实盘为“股”)
我们用“影子账户”机制解决:实盘系统每日用真实数据跑一遍回测,与策略账户对比,差异>0.5%即触发警报。
5.4 “多因子选股选不出牛股”——别忘了“非因子”决策点
最后说个反常识的真相:多因子选股的目标从来不是抓涨停板,而是获取市场平均风险溢价的稳定切片。真正的“牛股”(如2020年茅台、2023年寒武纪)往往诞生于因子失效区——政策突变、技术突破、管理层变革。我们的做法是:用多因子选出“稳健基本盘”(占仓位70%),再留30%仓位给“主题增强”(由行业研究员人工筛选,基于产业趋势判断)。过去五年,“基本盘”年化收益12.3%,“主题增强”贡献额外8.7%,但后者波动率是前者的2.4倍。平衡,才是长期生存之道。
我在实际操作中发现,最危险的不是策略失效,而是忘记策略的初衷。多因子不是水晶球,它是把人性中的贪婪与恐惧,翻译成一行行代码的冷静契约。当你盯着屏幕等信号时,真正考验的不是Python水平,而是能否在股价暴跌30%时,依然相信那套经过2000次压力测试的逻辑。这个过程没有捷径,但每一步踩实的坑,都会变成你账户曲线上的一个支点。