跳到正文

研究指南

股票回测与实验

回测最优参数旁边都亏损怎么办:按参数平台选择候选

某个股票策略参数回测得分极高,旁边参数却明显变差,首先应该查看完整搜索地图。只拿最高格子,会掩盖它属于连续可接受区域、孤立尖峰,还是尚未跑完的邻域。本文把参数平台定义为按预先规则连接起来的一组已完成、达标的参数点。平台描述的是这次搜索结构,不是未来稳定性的保证。

本文从冻结的二维结果矩阵出发,交付区域成员账和一个代表配置。全部分数均为虚构的无量纲演示值,不是股票收益。平台计算属于外部研究方法,不代表CoTrading已有相应能力,也不涉及重新训练。把既有净值切成几窗,不能称为完成逐窗重新选参的walk-forward流程。

取得真正运行过的结果矩阵

先固定同一策略、同一市场和币种,以及共同数据快照、引擎、计分期间和执行假设。每个格子保留配置、运行编号、完成状态、成本后评分,以及实际规则需要的风险和交易数量字段。按参数值连接结果,不靠表格行号对齐。重复结果要明确选择哪个版本;把冲突运行直接平均,可能掩盖可复现性问题。

不达标的已观测点和没有完成的点都要留下。负分是已经观察到的证据,缺失是信息空白,二者统一填零会丢失关键区别。结构上不合法的组合也需单列,因为不允许执行的位置不能作为两个平台之间的未知桥梁。

scikit-learn参数搜索文档把参数域、候选评价和评分函数列为搜索的不同组成部分。下文的平台规则是本文原创的搜索后选择方法,不是该库提供的稳健性保证。股票研究还必须尊重时间顺序和执行契约,直接照搬分类器的通用验证例子,不能证明交易实验设计正确。

先确定达标门槛和邻接方式

演示规则为:已观测分数至少五分才算达标;只连接在一个参数轴上相差一个网格位置的点;斜角接触不算相连;连通区域至少包含四个达标点才可保留。这些都是示意性的研究选择,应在查看最终留出期之前固定,不是金融行业统一标准,也不是适合所有策略的阈值。

还要说明坐标含义。本文一步表示参数数组中的相邻位置,不要求数值差固定。如果周期数组是二、三、三十,把相邻数组位置直接连接,可能把经济含义差别很大的设置放在一起。应事先采用有理由的网格,或者规定最大参数距离,不能看到偏好的高峰后再调整邻接定义来连接它。

实际研究可能同时要求收益、回撤和最低交易数量达标,那么每个格子都要逐项执行门槛,并保留失败原因。一片连续区域仍可能共享弱点,例如全部利润都来自相同的少数事件。因此,区域形状只是选择依据之一,不能单独证明策略可以投入真实资金。

完整主例:四格平台与二十五分尖峰

快周期为二、三、四、五,慢周期为十、十二、十四、十六。完整输入如下,缺失位置明确保留:

快周期/慢周期10121416
267-21
378-12
4-3-2缺失1
510225

计划格子共十六个,已观测十五个,缺失一个。五个分数达到门槛,其中四个构成左上角方块,另一个是快周期五、慢周期十六的二十五分。按四邻接计算,连通分量大小分别为四和一,因此只有前者满足至少四点的要求。

最高分被作为孤立峰拒绝,并不说明二十五分一定算错,也不证明它未来一定更差。这里执行的是事先声明的区域偏好,并明确放弃本次观察到的最大值。报告仍要保留这个尖峰,让检查者看见被舍弃的候选和具体理由,不能把它从图上删除。

用队列遍历,不补造格子

先把已经观测且达标的坐标放入集合,再用队列逐个访问其邻居。Python的deque文档说明了这里使用的标准库容器。队列只访问记录中真实存在的达标点,不会插值,也不会把失败任务补成结果。

from collections import deque

good = {(i, j) for i, row in enumerate(scores)
        for j, value in enumerate(row)
        if value is not None and value >= 5}
while good:
    first = min(good)
    good.remove(first)
    queue = deque([first])
    region = [first]
    while queue:
        i, j = queue.popleft()
        for p in [(i-1, j), (i+1, j), (i, j-1), (i, j+1)]:
            if p in good:
                good.remove(p)
                queue.append(p)
                region.append(p)

完整样例会反复执行外层遍历,直到每个达标点都且只属于一个分量。验收时,所有分量的点数之和必须等于达标点总数。图表可以用连续色带辅助阅读,但选择必须基于实际记录的格子。图中加上状态和坐标,避免平滑渐变被误解成网格之间已经存在测量证据。

用确定规则选择代表配置

在合格区域内,计算每个成员到全部成员的曼哈顿网格距离之和,选择距离和最小的点,即网格medoid。若距离相同,先选观测得分较高者,仍相同再按坐标顺序决定。这是一条可以复现的规则,而且最终选择真实运行过的成员,不会像算术中心那样落在两个参数值之间。

主例方块中四个成员的距离和相同,因此使用评分打破平局,得到快周期三、慢周期十二、得分八。区域成员为二/十、二/十二、三/十、三/十二,分数分别为六、七、七、八。选择记录要保存这四次运行的引用,让检查者可以打开原始结果,不只看平台截图。

如果存在多个合格区域,要使用提前规定的区域排序,例如先比较大小,再比较区域最低分。没有事先约定时,应该报告歧义,在开封留出期前确定新的探索性政策。不能根据未见期间的表现选平台,再把相同期间写成独立验证;那样留出信息已经参与选择。

不同机制反例:缺失格制造假桥梁

另一个输入是单行[6, None, 7]。两个端点都达到门槛,但中间没有结果,遍历只能得到两个单点分量。若此反例要求区域至少两个点,则没有合格区域。把中间位置填成均值,会凭空制造三格平台,把两次观测伪装成连续证据。

如果冻结的开发计划允许补跑,就把中间点列为明确的待办研究任务。补跑成功且达标,可能连接端点;结果不达标或执行失败,则可能继续隔开。证据变化后建立新版地图,同时保留之前的缺失状态,不能为了图形好看覆盖历史失败记录。

在仓库运行python docs/growth/research/round-5/examples/R607.py。实际输出为cells=16 observed=15 missing=1 acceptable=5、component_sizes=[4, 1]和selected_fast=3 selected_slow=12 score=8。断言同时确认二十五分尖峰被拒绝,以及缺失桥反例的missing_bridge_sizes=[1, 1]。这只检验合成评分上的区域算法,不验证评分本身来自正确回测。

验收候选并保存全部搜索历史

最终交付应包含原始矩阵、状态图、门槛、邻接定义、区域成员、平局规则和代表参数。逐项确认成员都能追到同一上下文中的完成运行,缺失从未被变成数值结果。保留被拒绝点及探索过程中调整过的门槛,不能只展示最终满意的一张图。

在独立留出测试之前冻结候选和选择记录。修正运行、改变费用、扩大网格或修订数据快照时重新计算,并标注为新分析。相邻表现接近不能消除共同数据错误、多次搜索择优偏差或行情环境依赖。参数平台方法的实际价值,是让选点理由可以重算,边界可以检查,而不是增加一句未经验证的“参数稳健”结论。

把几何证据和经济证据分开交付

区域成员账应列出每个点的坐标、运行引用、分数、达标原因以及已经观测的边界邻居。主例中被选区域四格都已观测,其他位置的缺口仍明确标为未知。若真实规则要求最低交易数量,每个成员都要保留该数量,样本不足的高分不能因为颜色好看就进入区域。还应核对多个成员是否实际依赖同一个特殊事件;如果删除该事件后的结果尚未运行,就把它列为未解决的经济问题,不要猜一个稳定性结论。检查地图周边时,也要说明哪里是预定参数域的边界,哪里是失败格,哪里是低分格。位于域边界的平台可能需要另行研究更宽范围,但这不授权在当前报告里补画范围外得分,更不应在看到结果后更改四邻接规则。修订规则应作为新探索记录保留。

下载完整示例。使用Python 3.12或更新版本,在下载目录运行python R607.py;仅使用标准库与合成输入。

常见问题

最大连通区域总是最好的吗?

不是。区域大小只是选定的标准,网格间距和门槛缺少理由时,这个标准也可能不适用。

能选择没有跑过的中心值吗?

本文规则不允许。medoid从已观测成员中选择;插值得到的新中心需要独立运行,并形成新的记录。

相关阅读