跳到正文

研究指南

股票因子研究

美股盈利收益率因子:按申报可得日形成月度股票组合

盈利收益率因子需要保存“何时已经知道”的历史,而不只是“属于哪个报告期”的历史。先用统一利润口径除以当时的股权市值,再限制每个调仓时点只能读取此前可得的事实。交付结果应当能逐月重建财务输入、排序成员和实际现金变化,而不是给每只股票贴上今天看到的估值数字。

下面使用虚构美股公司、申报时间和美元价格,演示披露版本选择与两次自筹资金交易。没有下载SEC真实数据,也不是历史盈利收益率业绩。CoTrading基本面研究功能仍属规划或待核实,因此按独立研究契约说明步骤,不提供未经验证的产品操作路径。

保存事实时同时保存上下文

SEC官方EDGAR接口文档介绍了公司申报和XBRL事实,以及概念、单位和报告期间的区别。采集时保留申报编号、表单、报告区间、单位、数值、申报时间及研究管线真正可用的时间。公司标识还需要映射到相应历史股票,不能只靠今天的交易代码连接全部年份。

排序前先确定分子。若采用滚动年度利润,应由四个互不重叠季度或等价年度区间组成,并明确累计期间的处理。不能把九个月累计利润再与其中已包含的三个季度相加。还要核对概念归属,是公司净利润、归属于普通股股东的利润,还是需要调整优先股等权益后的利润。同名标签也应核对上下文。

分母需要匹配经济范围。公司全部利润若只除以一个股类的不完整市值,可能夸大收益率。保存价格日期、股数日期、所含股类及币种。无法恢复可信历史股权市值时,应将股票标为不可用,不能用今天市值填满过去。为隔离时序问题,本例明确给三家公司各提供虚构市值一百,并不声称已经解决真实资本结构数据。

明确月末选择与可得规则

固定月末决策截止时点,在后续指定交易日开盘执行。只有日期的财务数据,需要采用保守的下一交易日可用规则,或补充准确时间戳;一个申报日期本身不能证明当日收盘前就能读取。本例中的可得日期已经是这一步处理后的输入,不直接等同原始申报日。

每个截止时点,先过滤尚不可得的事实,再选择最新报告期,最后选择该报告期内当时可用的最新修订。旧版本必须保留,否则二月修订后将无法复现一月决策。选择最近下载的数字,会把今天的归档资料变成仿佛过去一直知道的答案。这与数据下载成功是两件不同的事。

本策略事先排除非正利润、缺市值和非正市值。它是为了明确正盈利收益率组合的资格规则,不是对亏损公司的普遍投资结论。亏损、缺利润、分母无效和历史不足应分别标记。正收益率由高到低排序,同分按稳定证券标识决胜,再选择预定名额,不能临时改变筛选口径。

重建一月和二月的选股

虚构A年度利润五,一月二十日可得;B利润八,一月二十二日可得;C利润负四,一月二十五日可得,报告期末都是十二月三十一日。三者给定市值均为一百。一月三十日截止时,A为百分之五,B为百分之八,C被亏损规则排除。教学组合只有一个名额,选择B。

二月十日,B同报告期的修订利润降到二。二月二十七日截止时,B变为百分之二,A仍为百分之五,因此A替换B。另有一条A的利润一百,但属于后续报告期,直到四月二十日才可得。这个极高值不允许进入一月或二月,不能因为它今天已存在于下载结果中就提前使用。

本例固定市值,是为了让变化只来自财务修订。真实月度研究还需按当月允许使用的价格与股数重新计算市值。否则收益率变化可能被错误归因于财报消息,实际却来自价格,或者价格已经变动但分母被遗漏。财务版本表与市场价格表应分别留存,再按截止时点连接。

把替换成员转成现金桥

初始资金一千。在第一次决策之后的指定开盘,以十买入九十股B,支付虚构费用一,剩现金九十九。后续调仓开盘以十一卖出九十股,名义收入九百九十,扣费用一后现金变成一千零八十八。再以十买入一百股A,支付费用一,剩八十七。

最后用给定价格十点五估值A,持仓价值一千零五十,总权益一千一百三十七,已支付费用三。这仍含未平仓股票,不是最终清仓现金。若要求期末全部变现,需要另外指定卖出价格和费用,不能直接把估值视为可立即取得的现金。示例上升价格是人为输入,不构成因子历史收益证据。

真实多股篮子还要固定数量取整、同步现金分配和拒单处理。分数决定谁入选,数量规则决定买多少,两层应分别验收。看到某个修订结果后临时改变名额或仓位,等于更改被研究策略。保留调仓前后持仓,以及实际数量偏离目标的每个原因,才能解释费用和暴露。

执行版本选择与断言

标准库样例位于docs/growth/research/round-5/examples/R562.py。每条财务观察独立存储,原版本不会因修订而被覆盖。核心选择步骤如下:

known = [fact for fact in facts
         if fact['symbol'] == symbol and fact['available'] <= cutoff]
latest = max(known, key=lambda fact: (fact['period'], fact['available']))

完整程序在调用最大值前处理空候选,之后排除亏损、计算收益率并排序。运行python docs/growth/research/round-5/examples/R562.py,断言一月选择B、二月选择A,B分数从百分之八变成百分之二,C不入候选,首次可得日前没有选择,现金八十七、估值权益一千一百三十七。输出保留所用可得日期,便于反查。

用修订回填作为不同机制反例

若把二月的B利润二回填到全部历史,一月就会提前选择A。即使每个除法都正确,这仍是时点错误。相反,如果永久保留原始利润八,二月又忽略当时已经可用的修订。因此不能只保留一个“全局最新版”,也不能永远只读初版,版本选择必须随研究截止时间推进。

数据供应商更新财务后,抽查归档原行,不要假设返回最近日历期间事实的接口已经具备历史可得性。扩展样本前处理重复上下文、修订申报及财政年度变更。验收时,独立读者应能指出每个月每个分数来自哪一版本,再复算成员替换和现金。分子、可得约定、证券映射或市值口径变化后,创建新研究版本,保留旧版,而不是悄悄覆盖过去结果。

下载完整示例,保存为R562.py,使用Python 3.12及以上运行python R562.py。仅使用标准库与合成数据。

为无法确认的财务事实保留队列

不要把下载到的每一条记录立即强塞进排序。单位冲突、期间重叠、修订原因不明的事实,放入独立队列,附原申报编号、报告区间和未解决原因。只有既定政策允许、且年龄没有超过限制时,才可继续使用上一条合格事实;否则该股票暂不可用。这样质量问题成为可见依赖,不会藏在评分函数里,由某个人临时决定。

每次月度构建前复核队列,记录是由原申报澄清、发现概念不符而拒绝,还是仍未解决。原来排除的股票后来恢复,应生成新面板版本和原因,不能无声修改已经归档的一月名单。月度同时比较正利润候选数、亏损排除数和分母缺失数;覆盖突然下降可能来自标识或分类标准问题,不一定代表市场经济状态发生变化。

财务原事实、市值快照、可得选择和账户执行最好分成四个工件。读者可以先确认利润来自哪条披露,再看截止时点允许哪一版、当月分母如何组成,最后才检查数量与现金。若只保存最终收益率,任何一项修订都会失去追查入口。尤其不能把后来的解释写回过去的决策理由;过去实际可见资料与今天更完整的资料应同时保留,才能诚实说明研究限制。

如果某次名单无法找到原申报版本,验收应停在来源缺口,不用最近下载值代替。先补证据,再讨论分数是否吸引人,能够避免把数据恢复问题误写成新的选股发现。

常见问题

为什么排除负利润?

这是本策略预先定义的资格规则。若要研究亏损股票,需要另行明确评分和选择方法。

SEC接口是否足够直接组成完整回测?

还需要历史证券映射、可用时间、匹配价格、市值和成交假设,不能把财务接口等同完整回测数据。

相关阅读