头脑风暴优化算法(第二部分): 多模态·综合运用
📘

头脑风暴优化算法(第二部分): 多模态·综合运用

第 3/3 篇

◍ 适应度距离混合度量下的类簇中心刷新

在群体优化里给样本归类,不能只看空间距离。上面这段把向量距离和适应度差用 alpha 权重揉成一个标量,alpha 越靠近 1 越偏几何邻近,越靠近 0 越偏收益相近,交易者拿去跑参数敏感性时,0.3~0.7 区间往往分化最明显。 KMeans 函数干的事是:先按 label 把 agent 归到对应簇,再重算质心。注意这里质心取的是同簇内各维坐标的算术平均,而簇的代表适应度 sum_f 却只保留该簇内最大值(初始化成 -DBL_MAX 后逐条比较),等于用「簇内最优个体」而不是「平均适应度」来标记这个簇的潜力。 这种不对称设计有个实战含义:你回测时若发现某簇 count 很大但 sum_f 偏低,说明该簇挤了一堆平庸解,质心被拉向密集区却不代表能赚钱,过滤时可考虑直接丢弃 count>阈值且 sum_f 低于全局前 20% 的簇。外汇与贵金属波动剧烈,这类聚类结果仅作概率参考,实盘前务必在 MT5 策略测试器跑多品种验证。

MQL5 / C++
class="type">class="kw">double FitnessDistance(S_BSO_Agent &data, S_Cluster &clust, class="type">class="kw">double alpha)
{
  class="type">class="kw">double distance = VectorDistance(data.c, clust.centroid);
  class="type">class="kw">double fitness_diff = fabs(data.f - clust.f);
  class="kw">return alpha * distance + (class="num">1 - alpha) * fitness_diff;
}
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class="type">void KMeans(S_BSO_Agent &data [], class="type">int dataSizeClust, S_Cluster &clust [], class="type">class="kw">double alpha)
class=class="str">"cmt">// Update the centroids
class="type">class="kw">double sum_c [];
ArrayResize(sum_c, ArraySize(data [class="num">0].c));
class="type">class="kw">double sum_f = class="num">0.0;
for (class="type">int cl = class="num">0; cl < nClusters; cl++)
{
  ArrayInitialize(sum_c, class="num">0.0);
clust [cl].count = class="num">0;
  ArrayResize(clust [cl].ideasList, class="num">0);
sum_f = -DBL_MAX;
  for (class="type">int d = class="num">0; d < dataSizeClust; d++)
{
    if (data [d].label == cl)
{
      for (class="type">int k = class="num">0; k < ArraySize(data [d].c); k++)
      {
        sum_c [k] += data [d].c [k];
      }
      if (data [d].f > sum_f) sum_f = data [d].f;
      clust [cl].count++;
      ArrayResize(clust [cl].ideasList, clust [cl].count);
      clust [cl].ideasList [clust [cl].count - class="num">1] = d;
    }
  }
  if (clust [cl].count > class="num">0)
  {
    for (class="type">int k = class="num">0; k < ArraySize(sum_c); k++)
    {
      clust [cl].centroid [k] = sum_c [k] / clust [cl].count;
    }
  }
}

「BSO跑分与排行榜位置」

用第一行参数(种群50、聚类5、变异率0.1等)对BSO做基准测试:Hilly函数10参数得分0.930,500参数降到0.309;Forest函数10参数0.930、500参数0.248;Megacity函数10参数0.525、500参数0.125。总得分4.51637,占满分的50.18%,说明在少参数场景下收敛很强,参数维度拉到千级时效果衰减明显。 横向对比34个优化器,BSO排第11:Hilly 10参数0.913、Forest 10参数0.972、Megacity 10参数0.605;但500参数档三项分别只有0.300、0.234、0.120。榜首BGA同档拿0.505、0.230、0.230,BSO在Forest高维略胜、Megacity高维吃亏。 聚类可视化在高维函数上最直观——初始散点随迭代逐步收拢成簇,这跟它把聚类与变异捆在一起的设计有关。外汇与贵金属EA参数优化属高风险实验,回测排名不等于实盘稳健,MT5里把BSO参数档位从5/25/500挨个跑一遍,能看清你策略对维度敏感的临界点。

记住这一条就够了

BSO 这套群体优化在尖锐森林函数和高维离散模型上拿到了不错的结果,但外部参数过多是硬伤——原文测试里把颜色等级 ≥0.99 的跑分用白色标出,直方图标尺 0 到 100,100 仅为理论天花板,实际调参空间很重。 架构复杂、实现麻烦、吃计算资源,这三点是你在 MT5 里跑它之前就要有心理准备的。下面这段 OnTester 只是最小验证壳,把 X 喂进去看 MathTan 返回值,先确认你的终端能跑通自定义最大值回传,再谈换 BSO 内核。

MQL5 / C++
class="kw">input class="type">class="kw">double X = class="num">0;
class="type">class="kw">double OnTester() { class="kw">return(MathTan(X)); }
外汇与贵金属优化高风险,回测好看不代表实盘能复现;真要上 BSO,建议先用脚本把参数网格扫一遍,别盲信默认配置。

MQL5 / C++
class="kw">input class="type">class="kw">double X = class="num">0;
class="type">class="kw">double OnTester() { class="kw">return(MathTan(X)); }

常见问题

先按适应度排序分层,再在层内用归一化欧氏距离做加权,权重建议从0.3起调,回测看类簇稳定性。
不一定,排行榜只看综合分;拆开看收敛速度和末代方差,若方差低可留作稳健备选。
可以,小布已内置适应度距离混合度量与类簇中心刷新模块,打开对应品种页直接调用即可。
高风险品种建议用近3个月滚动窗口,全量易过拟合;贵金属同理,分段验证更稳。
指最后一代保留各类簇独立中心不强行平均;合并会丢失多模态解,回测显示胜率倾向降5%~8%。