← 返回目录
p5.4动手⏱ 约 16 分钟

参数优化与参数平原:找平原,不找尖峰

样本内最优参数年化 8.61%,样本外 -2.12%——衰减 10.73 个百分点;而它在样本内参数网格上本就是一根孤针,不是一片高地

🔎 最后验证 2026-07📚 来源:15×15 参数网格 × 3 次(全样本/样本内/样本外)于 2026-07-31 在 ECS 实测,输出见 code/outputs/🧰 qlab.engine(本课自研)、matplotlib 3.11.1、Python 3.12.13
为什么学这个

双均线 (fast, slow) 拉一张 15×15 的网格,218 组有效参数,全跑一遍。

全样本最优点:fast=2, slow=50,年化 4.21%。而全网格中位数只有 1.33%,买入持有 1.66%。

看起来找到宝了。但把样本切成前后两半再来一次:

样本内(2010-01 ~ 2018-04)最优  fast=6, slow=30   年化  8.61%
                    它在样本外                    年化 -2.12%
                              衰减 -10.73 个百分点

而这件事本来在样本内就有迹象:把那个点放回参数网格上看,它四周并没有连成一片高地——

它不是一片高地,它是一根针。

这一节讲怎么在选参的当下就把针和高地区分开。

💡 打个比方

你要在一片山区盖房子。

有两块地:一块是孤峰顶,海拔最高;一块是高原,海拔略低但四周都一样高。

测量总有误差。如果你的海拔仪偏差 50 米,孤峰顶那块地可能根本不存在——而高原上偏 50 米,你还在高原上。

参数不是"选一个点",是"选一片区域"。

一、参数曲面:读法不是"哪里最红"

全样本年化(行=fast,列=slow,单位 %,· 表示 fast ≥ slow 无效):

     20    30    40    50    60    70    80    90   100   110   120
2   0.87  1.50  2.80  4.21  2.47  2.70  2.91  2.27  1.39  2.49  2.64
4  -0.51  1.40  2.27  3.44  2.21  2.38  3.19  2.16  2.14  2.22  2.59
6  -0.51  3.24  3.01  2.42  3.76  1.35  2.87  0.81  1.84  2.06  1.33
8  -0.20  1.51  1.25  2.34  1.92  0.78  1.11  0.85  1.74  2.12  0.83
10  0.28  1.80  3.02  1.47  1.45  1.07  0.96  1.03  1.20  1.35  0.90
...
20   ·    0.66  0.86 -0.67 -0.48 -0.37  0.85  2.09  1.81  2.41  1.30

这张表的正确读法不是"哪一格最红",是"红色成不成片"。

二、尖峰与平原的定量判据

定义平原分:

平原分 = 含自身的 3×3 邻域均值 − 邻域标准差

一个孤立尖峰的邻域均值低、标准差大,会被这个分数双重惩罚

实测对比(全样本):

参数该点年化邻域均值(5 个,不含自身)邻域标准差点比邻域高
单点最优fast=2, slow=504.21%2.64%0.50 pp+1.58 pp
平原最优fast=2, slow=702.70%2.63%0.41 pp+0.07 pp

单点最优比邻居高 1.58 个百分点,平原最优只高 0.07 个百分点。

前者的意思是:只要参数选偏一格,你就掉下去 1.58 个百分点。而现实里你一定会选偏——因为选参用的是历史,兑现用的是未来。

⚠️ 避坑

报告"最优参数"= 报告 218 次比较的最大值。

这张网格跑了 218 组有效参数,你挑出年化最高的那一组来报告。

这就是 p3.4 的多重检验,和 p5.1 那 16 种读法是同一件事——只不过这次的比较次数从 16 变成了 218。

比较次数越多,"最大值"里噪声的占比越高。所以:

网格越密,单点最优越不可信。 加密网格不会让你找到更真的信号,只会让你找到更极端的噪声。

三、样本外检验:衰减 10.73 个百分点

把 4023 个交易日切成前后各半:

样本内 2010-01 ~ 2018-04样本外 2018-04 ~ 2026-07
单点最优 fast=6, slow=308.61%-2.12%
平原最优 fast=6, slow=504.26%0.36%
全网格中位数-0.03%
买入持有2.39%

三件事同时成立,缺一不可地读:

  1. 单点最优衰减 -10.73 个百分点——样本内 8.61%,样本外 -2.12%
  2. 平原最优在样本外更好(0.36% vs -2.12%,高 2.48 pp),平原这个启发式是有效的
  3. 但两者都跑输买入持有(2.39%)

所以"找平原不找尖峰"的正确表述是:它让你少输,不保证你能赢。

一个能少亏 2.48 个百分点的方法值得用;但如果因此以为"用了平原法就能跑赢",那是把风险控制误当成了收益来源。

还有一个数,比上面三条都更说明问题

样本外表现最好的参数是 fast=2, slow=50(样本外 4.47%)。而它在样本内只排第 25 名(218 组里)。

样本内排第 1 的 6/30,样本外是 -2.12%;样本外排第 1 的 2/50,样本内只排第 25。

两张排行榜几乎没有关系。

三张曲面图:形状比数值更早暴露问题

code/outputs/surface.png 把三张曲面并排画出来:

面板看什么
① 样本内年化像雪花点——高值零散分布,没有成片区域
② 平原分(样本内)噪声被邻域平滑掉,浮出两条连续的绿色带
③ 样本外年化同样是雪花点,而且高值区和 ① 不重叠

面板 ① 和 ③ 放在一起看,就是本节全部结论的图形版:在噪声主导的曲面上,"最高点在哪"这个问题本身没有稳定答案。

🔧 动手做:尖峰点和平原点,谁扛得住样本外?(6 分钟)

python param_plateau.py,看【三】样本外检验。样本内它给你两个"好"参数:尖峰 6/30 和平原 6/50。

你会看到(实测):样本内尖峰 6/30 年化 8.61%、样本外 -2.12%(崩了,衰减 10.73pp);平原 6/50 样本内 4.26%、样本外 0.36%(活着)。

想明白:样本内更高的那个点(8.61% vs 4.26%),样本外反而崩得更惨。网格给你的"最优点",大概率是噪声的最大值——判据不是"这个点多高",是"它周围也高吗"。找平原,别追尖峰。

四、网格结果有多脆:随机搜索三次

同样的搜索预算(每次随机抽 30 组参数,取其中最好的):

第 1 次随机 30 组:最好 fast=2,  slow=60,年化 2.47%
第 2 次随机 30 组:最好 fast=4,  slow=80,年化 3.19%
第 3 次随机 30 组:最好 fast=6,  slow=30,年化 3.24%

同一份数据、同样的预算,三次选出的参数完全不同。

这说明这张曲面上"最优点"的位置,由噪声决定的成分很大

顺带回答一个常见问题:"用贝叶斯优化会不会更好?"

贝叶斯优化解决的是"用更少的次数找到最高点"。而本节的问题是最高点本身不可信——搜索效率提高,只会让你更快地找到一根更尖的针。优化算法不解决过拟合。

五、选参的实操顺序

步骤做什么为什么
1先定网格范围并写进规格书事后扩网格 = 增加比较次数(p5.1/p3.4)
2跑全网格,先看曲面形状成片的高地 vs 孤立的针
3平原分排序,不用单点年化排序邻域惩罚孤峰
4报告时同时给出网格中位数与比较次数让读者能自己打折
5参数定下后冻结,拿去做滚动前推(p5.5)一次样本外检验不够
❓ 测验
你把参数网格从 15×15 加密到 50×50,最优点的年化从 4.21% 提高到 5.8%。这说明什么?
✏️ 填空
平原分 = 含自身的 3×3 邻域均值 减去 邻域 ___ ;孤立尖峰会被这个分数双重惩罚。

📌 免责:本课为技术教学,标的为沪深300 指数,所有回测为历史模拟,参数网格为演示口径,不构成投资建议。

✅ 小结

三件事:

  1. 参数曲面的读法不是"哪里最红",是"红色成不成片"。平原分 = 含自身 3×3 邻域均值 − 邻域标准差;实测单点最优比邻域高 +1.58 pp(尖峰),平原最优只高 +0.07 pp(高地)
  2. 样本内最优点样本外衰减 -10.73 个百分点(8.61% → -2.12%);平原点样本外 0.36%,比尖峰高 2.48 pp——平原启发式有效,但两者都跑输买入持有 2.39%。它让你少输,不保证你能赢
  3. 报告最优参数 = 报告 218 次比较的最大值(p3.4)。网格越密,单点最优越不可信;优化算法不解决过拟合——贝叶斯优化只会让你更快找到一根更尖的针

实操顺序:先定网格并写进规格书 → 看曲面形状 → 用平原分排序 → 报告时给出网格中位数与比较次数 → 参数冻结后交给滚动前推。

下一节把"一次样本外检验"升级成流水线:训练 3 年 → 选参 → 冻结 → 测试 1 年 → 前移,共 12 折。结果会很不好看:每年重新优化参数,还不如一开始定死 5/20 不动。

下一节 → 滚动前推验证:每年重新选参,还不如一开始不动
🔎 来源与核验· 5 条,点开核对
本节每个关键论断都对应一个可追溯的来源 —— 这是本课程"靠谱、不过时"的底线。
「全样本 15×15 网格(sh.000300,4023 个交易日,218 组有效参数):最优点 fast=2/slow=50 年化 4.21%,全网格中位数 1.33%,买入持有 1.66%」
📚 本节 code/param_plateau.py,2026-07-31 于 ECS 实测,输出见 code/outputs/stdout.txt✓ 已核验 2026-07
「邻域对比:单点最优(2/50)该点 4.21%、邻域(5 个不含自身)均值 2.64%、标准差 0.50pp,高出 1.58pp;平原最优(2/70)该点 2.70%、邻域均值 2.63%、标准差 0.41pp,高出 0.07pp」
📚 同上实测✓ 已核验 2026-07
「前后各半切分:样本内最优 fast=6/slow=30 年化 8.61% → 样本外 -2.12%(衰减 10.73pp);平原最优 fast=6/slow=50 样本内 4.26% → 样本外 0.36%;样本外全网格中位数 -0.03%,买入持有 2.39%」
📚 同上实测✓ 已核验 2026-07
「随机搜索三次(每次 30 组)选出的参数分别为 (2,60)/(4,80)/(6,30),年化 2.47%/3.19%/3.24%」
📚 同上实测(随机种子 20260731)✓ 已核验 2026-07
「样本外表现最好的参数 fast=2/slow=50 样本外年化 4.47%,而它在样本内 218 组中仅排第 25 名(样本内 4.66%)」
📚 本节 code/plot_surface.py,2026-07-31 于 ECS 实测,输出见 code/outputs/plot_stdout.txt;三张曲面图见 code/outputs/surface.png✓ 已核验 2026-07
网格范围 fast 2~30(步长 2)、slow 20~160(步长 10),固定标的为沪深300 指数;结论为该样本内的实测,不外推。
智图软件的赞赏码
都看到这了,打个赏呗!
接下来 · p5.5
滚动前推验证:每年重新优化,不如一开始不动
继续读下一节 →