发布 2026-10-14 · 更新 2026-10-25

用因子筛选,而不是用观点

筛选器把一句模糊的想法 ——「便宜、优质、小盘」—— 变成一条可复现的过滤条件。纪律在于把每个因子说精确,以及知道这个筛选不能告诉你什么。


本页目录

思路

「我想要便宜的、优质的、小盘的股票」是一句话。筛选是把同一句话写成机器能跑 —— 而且能重跑的形态。

这个区别很重要,因为筛选可以被检查,一句话不能。


第一步 —— 把形容词变成因子

每个模糊的词背后都藏着一个可测量的定义。工作是选一个,并说出来。

形容词 变成因子 需要说明
「便宜」 低市净率,或低 PE 哪个比率,什么时候测的
「优质」 高 ROE、盈利稳定 哪个指标,多长窗口
「小盘」 市值低于某阈值 阈值,什么币种
「动量」 最近 N 期的收益 N 是多少,是否跳过最近一期

一个没有说明定义的因子不是一个过滤条件 —— 是一个词。


第二步 —— 写成过滤条件

当每个形容词都变成一个有区间的因子,筛选就是几条条件连起来 —— 而且必须同时成立:

intersect([
  TotalMV <= 20000000000,   # 「小盘」—— 总市值,单位:元
  PB < 1.5,                 # 「便宜」—— 市净率
  ROETTM > 15,              # 「优质」—— 净资产收益率,单位:%
])

每一行要说明三件事,不是一件:字段名、单位、比较关系。 ROETTM > 0.15 不是「ROE 大于 15%」,而是「ROE 大于 0.15%」。单位写错的筛选不是一个更弱的筛选,是另一个筛选。

intersect([...]) 只是这个端点表达「全部同时成立」的写法。真正承载含义的东西在括号里面。

这是可检查的。别人能跑一遍、拿到同样的名单,然后对选择提出异议 —— 而不是对含义。

这就是全部好处:分歧从「你是什么意思」变成了「你同意吗」。


第三步 —— 跑它,并复现它

只有当同样的输入给出同样的输出,筛选才是可复用的。这意味着取数本身也必须可复现 —— 参数写明、序列一致。

# 这个端点需要付费档 API Key —— 把你的 key 作为 `key` 参数带上。
# 同一个请求,同一个结果 —— 你能辩护的筛选,基础在这里。
curl -G "https://api.ashareapi.com/v1/screen" \
  --data-urlencode "expr=intersect([TotalMV<=20000000000, PB<1.5, ROETTM>15])" \
  --data-urlencode "key=YOUR_KEY"

如果跑不出同样的结果,这份名单不是一个筛选 —— 是一张已经过去的某一刻的快照。


第四步 —— 知道筛选不能告诉你什么

这一步把有用的筛选和误导人的筛选分开。

筛选不说明 因为
这些股票会涨 筛选是一个过滤器,不是预测
因子会继续有效 因子一旦被广泛知晓就会衰减
名单是完整的 它只包含数据里有的东西
排名是稳定的 输入的微小变化可以重排输出

筛选只回答一个问题:「哪些标的匹配这些写明了的条件?」 其他一切都是你在做的跳跃,不是筛选告诉你的。


第五步 —— 说明来源

一个因子,不会比它背后的数据更好。 对每一个因子,都要知道:

  • 输入来自哪里 —— 以及是否事后被重述过
  • 什么时候已知 —— 时点,不是修正后
  • 是否包含退市标的 —— 否则幸存者问题就被藏起来了

在重述数据 + 今天股票池上做的筛选,不是一个筛选。它是对一个从没存在过的市场的描述。

见时点数据与幸存者偏差。


你现在有了什么

你把一个观点变成了可运行、可复现、可证伪的东西 —— 而且你现在能准确说出它声称什么、不声称什么。

这就是筛选和荐股的区别,而这个区别不小。


下一步

出处