制定规则

上次说到《人在系统》,那说干就干,自顶向下快速搭出完整的量化模型。

我尝试用日线量价数据做周频选股:每周给股票打分,再按排名决定持仓。想知道这套方法到底表现如何,还得把交易过程补全。信号什么时候产生,下一次开盘能不能成交,卖不出去怎么办,分红以后账户里的钱和股份该怎么算,这些都会影响最后的结果。

第一轮先选定 100 只股票,用一个固定的梯度提升模型 HGB,每季度重新训练,每周评分。同时,用按过去 60 日涨幅排序的动量策略作对照。两个模拟账户各从 5 万元开始,目标持有约 5 只股票。

开始实现前,我先把股票池、模型参数和交易规则写进规格,固定下来,免得看见结果以后,又顺手改掉不理想的地方。这一轮主要想确认,整套流程能不能跑完,每一步是否都有记录可查。

从模型评分到实际持仓

目前,数据检查、特征与标签、季度训练、每周评分、模拟下单和账户核算已经接了起来,最后会生成一份本地报告。整套流程可以用一条命令重新运行,也能查到某笔订单为什么成交、为什么失败。

模型本身没有做得很复杂。这一轮完成了 7 次季度训练,生成了八千多条周评分。训练时,只能使用已经走完持有周期的样本,不能把尚未发生的收益提前当成答案。

到了模拟交易这一步,要处理的细节就多了。买入数量必须在下单前确定,不能等看到第二天的开盘价,再反推该买多少。换仓时,如果旧股票还没卖掉,就不能拿预期的卖出收入去买新股票。遇到停牌或价格限制,订单可能失败,账本也得继续保留实际持仓。

把这些规则落实到账本里,才能查清模型的排名是怎样一步步变成账户收益的。模型选中了某只股票,账户可能没钱买;准备换仓,旧股可能没卖掉;这周没有合适的交易,现金就继续留在账户里。

核查历史数据

做这套流程时,数据问题让我反复停下来检查。一份历史行情,并不能告诉我某只股票在当时是否停牌、有没有风险警示,也不代表分红送转的记录和处理就是完整的。

同一个事件,还要分清公告发布时间、规则生效时间和数据采集时间。今天能查到的信息,放回过去,未必是当时已经知道的。

有一次,HGB 账户跑到 2026 年 6 月就停住了。持仓里的瑞玛精密发生了转增股份,但现有资料没有说清计税依据。缺了这个字段,我没法确认后续账本是否算得对,只能先停下来补查。

后来,我从公司财报里找到了足以支持历史账本重建的证据,才把账户重新从头跑到期末。不过,那份财报是在事件之后发布的。它能帮助我还原这段历史,却不能证明当时已经掌握这些信息。最终补上了 10 项同类缺口,还有 1 项仍然未知。剩下这一项没有影响本次实际持仓,但我还是把它留在了缺口清单里。

这让我开始更仔细地核对每条信息在什么时候可用。训练代码不使用未来标签,只解决了一部分问题。历史数据是否经过事后修订,某条状态是否取自今天的名册,也都会影响回测。因此,目前的结果仍属于历史重建,还不能证明所有输入在当时都能取得。

滑点收益分析

检查交易成本时,我还遇到了一个有意思的现象:调高滑点以后,收益没有一直下降,有些场景反而赚得更多。起初我以为算错了,查到具体订单才发现,成本变化会让某些买单超过保护价,或者让账户现金不足,后续持仓也就跟着变了。

不同滑点下,实际模拟出来的交易过程已经不同,不能简单地挑收益最高的一档作为新参数。我保留了原来的设置,用这些场景检查执行规则会怎样影响结果。

这轮历史回放的结果

两个账户都从 2025 年 1 月 2 日完整回放到了 2026 年 9 月 30 日,覆盖 424 个交易日。下面的累计收益和回撤来自每日账本,收益已经计入本次设定的交易费用与滑点。

固定 100 股的周频策略历史模拟:HGB 与 60 日动量的累计收益及回撤

指标HGB60 日动量
区间收益+51.34%-17.74%
最大回撤-25.17%-46.43%
期末净资产75,669.53 元41,132.46 元

HGB 在这段历史里表现更好,但过程并不平稳。2025 年第三季度赚了 34.38%,2026 年第三季度又亏了 14.46%。只看期末收益,很容易忽略中间经历过的下跌。

我也检查了哪些股票贡献了收益,以及持仓是否会越来越集中。建仓时,单只股票的目标权重约为 20%;之后如果一直保留原来的股数,股价变化就会让权重偏离这个比例。动量账户里,单只股票的权重曾经超过一半,单看总收益是看不出这一点的。

这些结果只能说明,固定的 100 只股票按这套规则,在这段历史重建中表现如何。股票池本身有选择偏差,这段历史也已经被多次查看,部分账本缺口又是靠后来发布的资料补上的。日线成交同样依赖模拟约定,不能据此推断实盘也会得到相同结果。还需要继续验证

持续运行测试

历史回放完成后,我开始补上持续模拟需要的功能。账户要记住上次算到了哪里,程序中断后能接着算,重复执行时也不能多记一笔成交或分红。

目前已经做了账本持久化和恢复验证。我用真实的 100 股数据回放了一段历史,中间多次重启、重复运行,再与一次性跑完的账本对账。已经验证的部分结果一致,持续自动运行还需要完成验收。

扩大股票池所需的数据也在准备。沪深 300 和中证 500 的历史成分记录已经补齐了一段覆盖范围,全量候选证券的身份资料也已完成关联。但停牌、风险状态和权益字段仍有缺口,

和 Codex 一起做这件事,我明显感觉到代码写得很快。但账户里每项记录的含义、证据是否够用、遇到未知数据要不要停,都得在具体问题里逐一说清楚对齐。

对整个交易系统理解还很皮毛,开始深耕。