按行业选股:在同行里筛出相对符合条件的公司
行业相对选股,是先在每个明确同行组里计算比较阈值,再对股票执行同一种相对规则,不是给全市场套一个市盈率门槛后改称行业调整。结果应附组定义、有效观测数量、阈值和逐股状态,让研究者可以还原公司为什么进入候选名单,以及哪些组根本没有达到计算条件。
本文使用虚构正市盈率和合成行业标签,实际计算组内中位数并执行低于或等于阈值的规则。它不证明相对低市盈率能预测收益,也不代表CoTrading已有行业筛选入口。A股、港股和美股分别需要确认分类版本与数据可比性,不能只换市场名称就共用同一张结果。
同时冻结分类与测量口径
先固定有日期的股票池、一个分类系统及其层级。某公司用大行业、另一家用细分子行业,得到的比较组不一致。给每股保存分类标识、版本和分配日期;没有分类的股票继续保留,不要为了容易计算就塞进一个大型组。分类来自供应商还是研究者自定义,也要明确区分。
SEC的SIC列表是EDGAR披露所用业务分类的官方示例,不是所有市场的统一映射,也不保证每个代码下公司都经济同质。本例Tech、Utility、Rare是虚构标签,不对应真实SIC代码,更不是建议所有研究任务使用该分类。
分组前先约定指标有效条件。这里市盈率必须有值、为正,并采用同一盈利口径。负市盈率不作为特别便宜的观测;缺市盈率不进入中位数分母,但该股仍计入原股票池并标记缺指标。这样可以分别对账总体覆盖与实际计算样本,而不是把缺值直接从任务里删除。
规定相对规则及最低规模
操作规则是“正市盈率不高于所属行业有效观测中位数者入选”。样例要求至少三条有效观测才提供可用阈值。三只是演示中预先设定的操作门槛,不是统计验证过的可靠性标准。真实组规模要求应依据研究目的、覆盖质量和同业集中度另行说明,不能因为脚本设了一个数字就宣称排名可信。
中位数包含被筛股票自身。若改为剔除自身后比较,每股可能需要不同阈值,是另一种方法,应单独实现。等于中位数是否入选也要事先声明;本例包含等号。不能看到结果太少,临时改成含等号却继续沿用旧规则编号。
| 行业 | 有效正市盈率 | 有效数 | 阈值 | 处理 |
|---|---|---|---|---|
| Tech | 10、20、30 | 3 | 20 | 计算 |
| Utility | 4、6、8 | 3 | 6 | 计算 |
| Rare | 2、4 | 2 | 不可用 | 暂不执行相对选择 |
Tech另有T4缺市盈率,所以总成员四只、有效分母三只。M1市盈率12但缺行业。两条记录都应有去向,不能因为无法参与阈值就从输入数量里消失。表中有效分母与入选数量含义不同,报告时要分别命名。
先计算完整组阈值,再筛每只股票
第一遍按组收集有效数值,只有达到门槛的组才进入阈值映射;第二遍回到每条原始股票记录判定。两遍操作避免前面股票只对部分同业比较,也避免接口行序改变就产生不同中位数。正式数据较大时仍应保持相同语义,即使底层用其他数据工具实现。
groups = defaultdict(list)
for symbol, industry, pe in records:
if industry is not None and pe is not None and D(pe) > 0:
groups[industry].append(D(pe))
thresholds = {group: median(values)
for group, values in groups.items()
if len(values) >= minimum}
Python统计模块参考说明中位数计算,偶数组采用中间两数平均。应记录这一约定;改用其他分位数算法、插值方式或缺值政策,即使原始数据相同也可能改变边界成员。真实数据还应先隔离非有限数,不能让异常数参与排序。
下载完整示例。使用Python 3.12+和标准库,全部为合成数据,运行python R520.py。作者源文件在docs/growth/research/round-5/examples/R520.py。
实际输出选中Tech的T1、T2及Utility的U1、U2;T3与U3未通过各自相对阈值。R1、R2为小组规模不足,M1缺行业,T4缺指标。断言检查阈值20与6、有效数3、3、2,并把输入倒序后重算,验证结果不依赖行序。通过样例说明当前操作可执行,不替代行业分类质量审阅。
解释相对通过时不跨行业下结论
T2市盈率20仍通过,因为恰好位于Tech中位数;U3市盈率8却不通过,因为高于Utility中位数6。这不能推导T2在经济上比U3便宜。筛选回答的是在指定同行中处于什么位置,不回答各行业应得到多高估值,也没有把行业差异转换成可交易预测。
每条结果保留实际市盈率、组阈值和有效分母。只给“行业价值通过”标签会隐藏比较对象。研究者后来改变分类层级时,重算阈值并重新打开旧通过状态,不能换了行业名称还保留原来的入选理由。组成员变化同样属于阈值依赖变化,应能追到具体分组输入。
行业相对也不会自动消除组内会计差异。财年、非经常项目、盈利正规化和业务模式仍需核对。分类提供组织观测的方法,不是保证每个成员都完美可比。特别是集团型公司,单一标签可能覆盖多种业务,应按研究任务决定是否进一步拆分,而不是由脚本默认认为同业关系已经充分。
小样本组与分类缺失分别处理
Rare两条市盈率其实可以算出中位数3,但本例故意不发布阈值,因为未达到预设有效规模。自动选R1虽然算术简单,却违反操作约定。保留两只为组规模待审,不把它们写成已经证明可靠的低估值排名。这是本题不同机制反例:不是某个股票数值缺失,而是比较总体不足。
M1则是有数值却没有比较组。为了凑分母把它归到Tech,会无依据地改变阈值与其他股票状态。应从适当来源确认分类、保存分配修订,再重跑受影响组。不要把分类空白当作“其他”并与不相关公司一起排名,除非“其他”组本身经过明确定义并接受相应边界。
T4需要补的是指定市盈率。值到来后Tech分母和中位数可能都变化,所以重跑整组,而不只评估T4自身。其他行业输入未变时可保留原结果。局部补数引起组内整体重算,是本题的重要数值依赖,不能套用“补一行只改一行”的独立阈值假设。
交付可检查的分组计算包
保存原股票池、分类快照、有效观测表、阈值表、逐股状态和被排除观测原因。十条输入应对到账:四条通过、两条相对失败、两条小组不足、一条无分类、一条缺指标。有效观测分母另行核对,不与最终通过数混算。交接时清楚说明哪些数据是合成、哪些来源已真实取得。
让审阅者从保留观测重建Tech和Utility中位数,再检查一个被挡住的组确实没有偷偷生成阈值。成功路径与停止路径都通过,才算验收。新可比数据、分类重分配、来源更正或最低规模主动修改后重新打开筛选,先比较组输入,再解释成员变化。
最终产物是一张有分母边界、能复跑的行业内研究清单。它不能冒充全市场估值顺序,也不是因子收益验证。明确组内规则的计算与限制,后续公司研究才能知道入选基于哪些同行观测,以及哪些比较还需要补充依据。
解释阈值前先审覆盖
每个行业同时发布总分配股票数与有效指标数。一个组达到最低门槛,却有很多其他成员取不到数据,中位数仍可能只反映有覆盖的选择性子集。阈值描述观察到的合格样本,不自动代表完整行业估值基准。覆盖表要与阈值放在一起,不能只在报告末尾留一句数据可能不全。
分类修订时同时定位旧组与新组。一只股票迁移,可能让两边阈值和全部依赖决定改变,即使它自身市盈率没有更新。保留分类迁移记录,避免把这类成员重组描述成行业盈利或价格普遍变化。若组低于门槛,要撤销旧阈值有效状态,而不是继续展示上次计算值冒充当前。
让审阅者从有效原值重算阈值,同时核对恰等于边界的入选者和一条被排除观测。这样分母政策、中位数计算与最终比较连接在同一检查里。算术干净不能验证同行组选择合理,因此另留研究问题,确认分类层级是否适合当前公司比较;必要时调整范围并新建方法版本。
发布后的更新同样应先检查组输入是否完整。若只取得部分新财报,旧新期间混合可能改变相对位置,却不代表真实可比关系改善。先隔离期间冲突,再计算阈值,能够防止一张看似精确的排名表掩盖观测基础已经变化。
常见问题
至少三只就说明行业排名可靠了吗?
没有。三只是样例操作门槛,统计或经济可靠性需要单独论证。
补一个指标只重跑该股可以吗?
若它改变组阈值就不可以,应重算所有依赖该组阈值的股票。