跳到正文

研究指南

股票回测与实验

参数太多怎么搜:在相同回测预算下比较网格和随机搜索

股票回测预算有限时,先比较两种搜索路线真正执行了什么,再看各自最高分。网格可以系统覆盖少数轴值,随机抽样则可能到达不同组合,也可能把预算花在重复点上。如果一条路线失败后悄悄补跑,另一条没有补跑,就不能称为相同预算比较。

本文在同一个十六点合法参数域中,生成两组各六次尝试的队列。虚构评分函数只用于演示搜索位置与任务勾稽,不是历史股票表现。一次只研究一个市场和币种。搜索编排属于外部扩展方法,CoTrading是否支持仍为规划或待核实。

在选择采样器之前冻结实验

先固定策略源码、数据、执行引擎、观察区间、费用与评价函数。合法参数域只解析一次,再交给两条路线。不能因为两个生成器接口不同,就让其中一个使用更容易的计分期间、更大的股票池或不同最低交易数门槛。否则最后差异不能归因于采样方法。

样例快周期为二、三、四、五,慢周期为六、八、十、十二,每个快周期都小于每个慢周期,因此十六个组合全部合法。这有意排除了合法性过滤造成的干扰。真实参数域若存在非法组合,应先采用相同约束处理,并单独保存拒绝数量与原因,不能把拒绝算成引擎失败。

scikit-learn参数搜索文档区分完整网格与随机候选评价。本文用Python标准库自行构建两个小采样器,没有运行该库模型或行情引擎。这里的网格是有意设计的六点粗网格,并没有穷举十六点全集,报告名称应当准确反映这一范围。

规定一个预算单位买到什么

本文一个预算单位表示一次实际尝试,完成、失败或重复都消耗一次。两条路线各有六次尝试。失败不会免费补跑;重复点也实际重新评价,所以占用一次预算。这样容易勾稽,也能直接看见重复抽样的代价。

也可以规定六个独立完成配置,或者相同墙钟时间,但那是另外的问题。只数完成任务可能隐藏昂贵的失败,时间预算又受到硬件和调度影响。应在看结果前声明政策,同时报告尝试与完成数量,不能把两种不同政策包装成相同预算。报告如果使用运行时间,还应明确是否包含排队、数据读取和结果整理。

生产任务需要重试时,区分基础设施重试与新候选评价,并事先规定重试是否占预算及其上限。不能一条路线碰到故障就无限补机会。候选编号之下另设尝试编号,防止同一点多次执行被统计成多个独立搜索位置。已经启动但没有最终结果的任务,也不能默认为成功完成。

明确列出两条队列

粗网格采用快周期二和五,交叉慢周期六、八和十二,共六个不同参数对。它覆盖快轴两端与三个慢轴值,但从未访问快周期三、四以及慢周期十。这些空白是设计选择,不是运行故障,图上应该与失败位置区分。

随机路线使用Random(17).choices(legal, k=6),在相同十六点合法域上均匀有放回抽样。实际队列依次为(4,6)、(5,6)、(5,12)、(3,6)、(5,6)、(4,12),其中(5,6)出现两次。必须保存实际队列;只有种子还不够,因为合法域顺序和采样实现变化后,种子相同也未必重现原队列。

legal = list(product([2, 3, 4, 5], [6, 8, 10, 12]))
grid = list(product([2, 5], [6, 8, 12]))
random_queue = Random(17).choices(legal, k=6)

小型有限域上,无放回抽样可能更符合独立探索目标,但它是另一个采样器。不能看到不满意的重复点后切换方法,仍声称在报告原来的实验。还要说明概率是对合法配置均匀,还是先独立抽各轴、再拒绝非法组合;两者在有约束的域上可能产生不同分布。

使用同一个评价函数

合成评分为10 - 2*abs(fast-3) - abs(slow-10)/2,并在(5,12)注入确定性运行失败。两组队列都包含这个点,所以各有一次失败。失败分数保持缺失,不能填零;零分可能是合法的已评价结果,混用会污染排名和均值。

每次尝试单独保留参数、状态、输出和错误原因。本文从请求坐标计算覆盖,同时另数成功完成情况。正式报告要并列展示尝试覆盖和已成功测量覆盖。只被失败任务到达的区域,并没有产生绩效证据;不能因为任务曾经派发,就把该区域涂成已验证。

这个评价函数很便宜而且确定,因此样例比较的是位置和记账,并没有研究昂贵引擎下的计算效率。真实比较还需要实际耗时、资源政策和失败原因,才能说明相同尝试数量是否接近相同计算支出。评分函数也只负责示意,不能把它的峰值位置解释为某种真实股票规律。

勾稽实际覆盖结果

实际网格结果为六次尝试、六个不同参数对、零次重复、一次失败,覆盖两个快轴值和三个慢轴值。随机路线为六次尝试、五个不同参数对、一次重复、一次失败,覆盖三个快轴值和两个慢轴值。两者都完成五次尝试,但随机路线重复了一个成功点,因此独立完成观测更少。

路线尝试数不同请求参数对重复尝试失败尝试
粗网格6601
随机,种子176511

只看轴值数量也不够。三个快轴值配两个慢轴值,与两个快轴值配三个慢轴值,并不构成相同的联合覆盖。保留完整参数对清单,或标出未访问与失败的坐标图。不能把未访问位置平滑成已测分数,也不能因为邻近点分数不错,就推断缺口已经得到验证。

交付时可给每条尝试保存路线名、序号和配置摘要,再按配置分组查看重复。随机队列第二次访问五/六时,尝试编号不同、配置摘要相同,这正是应有的记录。失败的五/十二也保留自己的错误产物引用。最终汇总既能从尝试行重建六次支出,也能从配置分组重建五个独立位置,检查者不必依赖作者口头解释。若只保存一个以参数为键的字典,重复写入会覆盖第一次访问,反而无法证明实际消耗过六次预算。

用重复队列检验另一种失败机制

反例把同一个合法点放进队列六次。虽然有六次尝试,但只有一个独立配置、五次重复。所有执行都可能成功,称其为六点覆盖仍然错误。样例独立断言这一计数,不把它与注入的引擎失败混为一谈。

重复并非总是无意义。若目的是测量随机执行差异,它们可以是有意复制实验,但不应被当作额外参数发现。探索预算与复制预算应分别记录,每次复制也需要独立的随机状态政策。本文评价确定,重复一个已经完成的点不会带来新的位置证据。

真实派发前,还应检验队列意外缩短或出现域外配置的情况。预算数量不符或采样器输出非法点时,比较应立即停止。先修复生成问题,不能通过删除不方便的结果让最后表格看起来对称。排队等待或未知结果,也不能被随意归并到失败或完成中。

解释结论并规定更新条件

Bergstra与Bengio论文的原始摘要页讨论神经网络超参数随机搜索。它提示考虑参数相关性和覆盖,但不证明股票策略使用随机搜索就能赚得更多。这里实际查阅的是摘要页,不冒称已经复现其全文实验。

本例应报告队列、数量、缺口与共同评价器。若展示最高分,标为探索结果,并保留其他尝试。一个种子的最大值不能证明算法长期优越。之后扩展多个种子会增加实验数量,也必须事先计入预算,不能只在偏好结果出现后,把追加搜索称为免费的稳健性验证。

验收要求两组尝试数均为六,全部参数属于冻结域,失败与重复可以勾稽,队列能够重放。域顺序、数据、代码、目标或重试政策变化时,建立新的上下文。候选选择和真正未见区间的验收仍是后续任务,不由一次采样比较直接代替。

下载完整示例。使用Python 3.12或更新版本,运行python R606.py;仅使用标准库和合成输入,断言检查队列记账,不验证市场收益。

常见问题

随机搜索一定不能重复吗?

不是。独立位置探索与随机复制有不同目标,应分别规定和记录预算。

同样尝试次数就是同样计算成本吗?

未必。耗时、重试和资源可能不同,本例固定的是尝试次数。

相关阅读