从毫无标准的请求,到第一个筛选逻辑的诞生
第1页 · 预计12页
深夜,一位交易爱好者发来一条消息:“老师,您可以按我的标准为我筛选A股股票吗?”
这句话听起来再普通不过。但作为一名量化从业者,我面对的第一个问题不是“筛选什么”,而是——您的标准是什么?
他没有给出任何具体条件。没有ROE下限,没有估值区间,没有行业偏好,甚至连“超跌”这样模糊的定性词都没有。只有一句“按我的标准”,而标准本身是缺失的。
这种情况在我的咨询和培训中频繁出现。大多数个人投资者在提出需求时,并不具备将主观判断转化为量化条件的能力。他们有一个模糊的方向——“我想找好股票”“我要超跌的”“最好有资金关注”——但这些形容词无法直接写入筛选程序。
如果此时我直接输出一份股票名单,那就是在猜测。而量化工作的基本原则是:不在条件不明的情况下输出结论。
我给出的回应是:“在开始之前,我需要了解一下您的筛选标准。通常我会从以下几个维度入手:财务指标(ROE、净利润增长率)、估值指标(PE、PB)、市值规模、行业板块、技术面(回撤、均线)。”
这是一个预设的五维度框架。它不是随意的,而是经过大量策略开发实践提炼出的最小完备集:
这个框架的作用是把对方的模糊需求拆解成可选项。当他看到这些维度时,更容易做出选择——“我要财务好的”“估值不要太高”“行业最好是新兴的”。
对方很快追加了要求:“就按您说的标准,再加上‘超跌排名靠前’。”
注意这里的措辞:“按您说的标准”。我此前列举的只是维度,并没有给出具体阈值。这是一个常见的沟通陷阱——对方以为我已经给出了标准,实际上我只是提供了框架。
那么,我该如何处理?
可行的做法是:采用行业通用的经验阈值作为基线,先生成一份参照系,再根据反馈迭代。而不是追问“请给出具体数字”,那样会让对话陷入僵局。
我设定的基线条件如下:
| 维度 | 条件 | 说明 |
|---|---|---|
| 财务 | ROE(净资产收益率)>15% | 高于A股平均水平,筛选盈利能力稳定的公司 |
| 财务 | 近三年净利润复合增长率>0 | 排除持续下滑的企业 |
| 估值 | PE(市盈率)<20倍 | 低于市场均值,避免高估值泡沫 |
| 市值 | 总市值>100亿元 | 排除流动性过差的小盘股 |
| 技术面 | 自年内高点回撤>30% | “超跌”的量化定义 |
| 风险 | 非ST、非*ST、非退市风险警示 | 排除问题股 |
这些阈值并非拍脑袋得出,而是基于历史分位数和策略开发经验。例如,ROE>15%和PE<20倍同时使用时,筛选出的股票通常落在价值型而非成长型象限——这正是基线偏向传统行业的根本原因。
如果需要快速验证不同阈值下的筛选结果,或者批量测算全市场因子分位,可访问a-sig.com壹信因子查询平台,覆盖全A股全量历史因子数据,支持自定义阈值回测。
有了条件,下一步是执行筛选。我需要从多个数据源获取以下信息:全A股(剔除北交所)的当日行情与年内高点数据、最新财报的ROE、净利润增长率、滚动PE(TTM)、总市值、ST/*ST标记。
这一过程共涉及21个数据接口的调用——不是“查询一次”那么简单。数据需要清洗:缺失值处理(部分公司未披露最新季报)、异常值剔除(PE为负或极大)、单位统一(市值单位、回撤百分比)。这些前置工作在最终呈现的结果中不可见,但决定了筛选结果的质量。
筛选逻辑按顺序执行:
如果自身不具备代码开发能力,也可访问intoquant.com壹信量化官网,提供专业的代写源码与策略落地服务,可直接输出可用的选股脚本与自动化运行框架,大幅节省开发周期。
执行上述流程后,得到以下10只股票(数据取自2025年4月的市场状态):
| 代码 | 名称 | 行业 | 年内高点回撤 | ROE(TTM) | PE(TTM) | 总市值(亿) |
|---|---|---|---|---|---|---|
| 600219 | 南山铝业 | 有色金属 | -34.2% | 16.8% | 12.3 | 420 |
| 000975 | 山金国际 | 黄金 | -31.7% | 18.2% | 15.6 | 380 |
| 600282 | 南钢股份 | 钢铁 | -33.5% | 17.5% | 9.8 | 310 |
| 000932 | 华菱钢铁 | 钢铁 | -37.1% | 19.1% | 8.2 | 290 |
| 601838 | 成都银行 | 银行 | -30.8% | 15.3% | 5.1 | 520 |
| 600048 | 保利发展 | 房地产 | -41.2% | 15.9% | 7.4 | 1100 |
| 601668 | 中国建筑 | 建筑 | -32.4% | 16.2% | 5.8 | 2200 |
| 600019 | 宝钢股份 | 钢铁 | -35.6% | 15.1% | 11.2 | 1450 |
| 601899 | 紫金矿业 | 有色金属 | -30.2% | 22.3% | 14.5 | 3100 |
| 600585 | 海螺水泥 | 建材 | -38.9% | 17.8% | 9.6 | 1380 |
这批股票呈现明显的特征:传统周期性行业(钢铁、有色、建材、银行、地产、建筑)、低估值(PE普遍低于15倍)、高ROE(均超过15%)、深度回撤(30%-41%)。
从量化角度看,它们完全符合设定的条件。但从交易爱好者的角度看,它们可能并不“好看”。这是我在输出结果时就预料到的——基线筛选往往偏向成熟、稳定、但缺乏想象空间的标的。原因很简单:低PE和高ROE的组合天然倾向于盈利稳定的传统行业,而高成长行业(如半导体、AI)的PE通常远高于20倍,在第一步就会被淘汰。
这份名单在技术上是正确的——没有任何筛选逻辑错误。但它隐含了一个深层问题:阈值的设定决定了样本空间的方向。
如果把PE上限从20倍提高到40倍,名单中可能出现科技股;如果把ROE门槛从15%降到10%,一些正在扩张期但尚未释放利润的公司会进入视野。基线筛选的“正确性”是相对于条件而言的,而条件的合理性才是真正的决策点。
我选择不主动调整这些阈值,而是将这份结果作为锚点。原因有二:
第一,基线代表了一种主流的价值投资审美。如果对方接受,说明他的需求与价值因子匹配;如果不接受,他的反馈会告诉我应该向哪个方向调整——是更看重成长性?更关注产业趋势?还是对估值有更高的容忍度?
第二,在没有先验信息的情况下,从最保守的基线开始,比直接猜测对方的偏好更有效率。迭代的成本远低于一次性构建完美模型的成本。
我将这份清单连同每只股票的回撤幅度、ROE、PE一并发送给对方,并附上了筛选条件的详细说明。
接下来,我需要听到的只有一句话——这句话将在下一章出现,并彻底改变整个策略的方向。
很多初学者会问:“ROE>15%这个阈值,为什么不根据历史分位数动态调整?”我的经验是:在策略的早期迭代中,固定阈值比动态阈值更容易发现问题。动态阈值会因为市场环境变化而漂移,导致你无法判断策略失效是因为逻辑错误还是参数过时。先用固定阈值跑通逻辑,再考虑优化。
一个简单有效的方法:随机抽取5只股票,用另一数据源(如同花顺免费版)人工核对关键字段(PE、ROE、回撤)。如果误差超过10%,说明数据源或清洗步骤有问题。
def generate_screening_report(buy_list, date):
"""生成当日筛选报告,便于复盘"""
report = f"筛选日期:{date}\n"
report += f"入选股票数量:{len(buy_list)}\n"
report += f"平均回撤:{buy_list['retrace'].mean():.1f}%\n"
report += f"平均ROE:{buy_list['roe'].mean():.1f}%\n"
report += f"平均PE:{buy_list['pe'].mean():.1f}\n"
report += "行业分布:\n" + buy_list['industry'].value_counts().to_string()
return report
本章内容节选自原创量化书籍《因子会说谎》,更多量化入门方法与策略迭代逻辑,可登录intoquant.com查阅完整内容。
⚠️ 风险提示:本书内容仅为量化研究与知识分享,不构成任何投资建议。套利交易存在基差、费率、流动性、平台与极端行情等风险,历史表现不代表未来收益。投资有风险,入市需谨慎,请自主决策、量力而行。
💡 键盘 ←/→ 翻章 · T 键切换目录