适应性社会行为优化(ASBO):两阶段演变(基础篇)
📘

适应性社会行为优化(ASBO):两阶段演变(基础篇)

第 1/3 篇

ASBO 的两阶段演变思路

适应性社会行为优化(ASBO)把群体寻优拆成两个阶段:先靠个体在邻域里试探出局部较优位置,再用社会层的信息交换把整群拉向全局更优区。这种两阶段结构比单阶段随机搜索更不容易陷在窄幅震荡的局部极小值里。 在 MT5 里跑这套逻辑,重点不是参数有多少,而是第二阶段的社会权重怎么衰减。权重掉太快,群体会过早收敛、错过延展行情;掉太慢,回测耗时翻倍且容易在噪声里打转。 作者 Andrey Dik 在 2025 年 2 月 17 日发布的示例显示,该文目录已包含概述、算法实现与测试结果三块,说明工程化落地是可行的,读者可直接开 MT5 对照验证。

「从 Schwefel 到 ASBO 的模型进阶」

上一阶段我们跑过 Schwefel 示例,里面用到了正态分布、自适应变异率,以及按适应度值挑最近邻的函数。这一步不再停留于示例,而是把数学模型拆成两个阶段来搭,最终成型为 ASBO(适应性社会行为优化)。 在已熟悉的测试函数上做全套验证,才能判断这套社会行为模型在群体寻优里的真实效率。外汇与贵金属市场高阶参数寻优属高风险操作,回测结论仅代表历史样本倾向,不等于实盘必然复现。 本篇给出的群体行为新用法和对应结果,目的只有一个:让你能在 MT5 里照着复现,亲自看集体行为原理怎么落地到复杂问题求解。

◍ 两阶段ASBO的多种群落地与代理结构

ABSO 算法把搜索拆成两段:第一段用 M 个规模 PZ 的种群各自独立跑 P' 轮 ASBO,第二段把各群最优的 PZ 个解合并再跑一轮局部精搜。原文给的伪代码里,位置更新靠公式 ΔX(i+1)=Cg*R1*(Gb-xi)+Cs*R2*(Sb-xi)+Cn*R3*(Nc-xi),三个自适应参数 Cg/Cs/Cn 初始随机落在 [-1.0, 1.0]。 实际写 MT5 代码时,多种群怎么摆是个坑。若把 50 个体的群硬拆成 5 个 10 人小群,第二阶段凑不出 PZ=50 的新群,只能原样拷回,等于白做。更顺手的做法是建 5 个各 50 人的群,第一阶段每群跑 20 轮(共 100 轮),第二阶段用剩余 100 轮把 250 个代理排序取前 50 重塑种群——总轮次 200,逻辑和原算法对齐,又能塞进统一种群模板。 S_ASBO_Agent 结构只存必要状态:c 与 cBest 坐标数组、f 与 fBest 适应度、Cg/Cs/Cn 三个比率,以及工具对象 u。Init 时 fBest 置为 -DBL_MAX,Cg/Cs/Cn 随机化,c 在 rangeMin~rangeMax 内随机填,再拷给 cBest。 C_AO_ASBO 类扛住全流程:Moving 负责每轮 epochNow+1,第一阶段到 epochsForPop 就切下一群,跑满 numPop 群就进第二阶段并合并排序取优;Revision 扫一遍代理找 f 最大者更新 fB 与 cB,再按阶段写回 fBest/cBest 并排序;AdaptiveMutation 用 N(0,1) 正态扰动调 Cg/Cs/Cn,公式 σ'(j)=σ(j)*exp(τ'*N(0,1)+τ*Nj(0,1))。作者标注 2) 版(带 Cg/Cs/Cn 自适应)在三者里实测效果最好,外汇/贵金属参数寻优属高风险实验,开 MT5 把这段结构挂上 EA 回测才能验真伪。

MQL5 / C++
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class="kw">struct S_ASBO_Agent
{
    class="type">class="kw">double c    [];   class=class="str">"cmt">//coordinates
    class="type">class="kw">double cBest [];   class=class="str">"cmt">//best coordinates
    class="type">class="kw">double f;          class=class="str">"cmt">//fitness

ASBO 优化器的种群与参数骨架

自适应社会行为优化(ASBO)在 MT5 里以多种群结构跑搜索,默认把种群数设成 5、每群 50 个个体、每群迭代 10 代,这三个数直接写在构造函数里,属于可调的硬参数。 单个智能体结构体里先声明了 fBest 存当前最优适应度,Cg / Cs / Cn 三个自适应系数由随机数初始化,Init 里用 ArrayResize 给坐标数组 c 和 cBest 分配空间,并把 fBest 压到 -DBL_MAX 保证任何真实回测值都能覆盖它。 外层 C_AO_ASBO 类通过 params 数组把 popSize、numPop、epochsForPop 暴露给优化框架,SetParams 负责把 double 类型的参数值转回 int 落地;想改规模直接在构造函数或参数面板动那三个数即可,外汇与贵金属品种参数空间波动大,过小的种群可能漏掉有效解。 下面是原文给出的结构定义片段,注意 agent 数组用动态 resize 而非定长,方便不同维度问题复用同一套代码。

MQL5 / C++
  class="type">class="kw">double fBest;       class=class="str">"cmt">//best fitness
  class="type">class="kw">double Cg, Cs, Cn; class=class="str">"cmt">//adaptive parameters
  C_AO_Utilities u;
  class="type">void Init(class="type">int coords, class="type">class="kw">double &rangeMin [], class="type">class="kw">double &rangeMax [])
  {
    ArrayResize(c,     coords);
    ArrayResize(cBest, coords);
    fBest = -DBL_MAX;
    Cg = u.RNDprobab();
    Cs = u.RNDprobab();
    Cn = u.RNDprobab();
    for (class="type">int i = class="num">0; i < coords; i++)
    {
      c     [i] = u.RNDfromCI(rangeMin [i], rangeMax [i]);
      cBest [i] = c [i];
    }
  }
};
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class="kw">struct S_ASBO_Population
{
  S_ASBO_Agent agent [];
};
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class C_AO_ASBO : class="kw">public C_AO
{
  class="kw">public: class=class="str">"cmt">//--------------------------------------------------------------------
  ~C_AO_ASBO() { }
  C_AO_ASBO()
  {
    ao_name = "ASBO";
    ao_desc = "Adaptive Social Behavior Optimization";
    ao_link = "[MQL5官方文档]
    popSize       = class="num">50;   class=class="str">"cmt">//population size
    numPop        = class="num">5;     class=class="str">"cmt">//number of populations
    epochsForPop  = class="num">10;   class=class="str">"cmt">//number of epochs for each population
    ArrayResize(params, class="num">3);
    params [class="num">0].name = "popSize";       params [class="num">0].val = popSize;
    params [class="num">1].name = "numPop";        params [class="num">1].val = numPop;
    params [class="num">2].name = "epochsForPop"; params [class="num">2].val = epochsForPop;
  }
  class="type">void SetParams()
  {
    popSize       = (class="type">int)params [class="num">0].val;
    numPop        = (class="type">int)params [class="num">1].val;
    epochsForPop = (class="type">int)params [class="num">2].val;
  }
  class="type">bool Init(class="kw">const class="type">class="kw">double &rangeMinP  [], class=class="str">"cmt">//minimum search range
             class="kw">const class="type">class="kw">double &rangeMaxP  [], class=class="str">"cmt">//maximum search range
             class="kw">const class="type">class="kw">double &rangeStepP [], class=class="str">"cmt">//step search
             class="kw">const class="type">int     epochsP = class="num">0);  class=class="str">"cmt">//number of epochs
  class="type">void Moving();
  class="type">void Revision();
  class=class="str">"cmt">//----------------------------------------------------------------------------
  class="type">int numPop;       class=class="str">"cmt">//number of populations
  class="type">int epochsForPop; class=class="str">"cmt">//number of epochs for each population

常见问题

若历史波动结构稳定、参数敏感低,单阶段够用;若行情分段明显、止损阈值常失效,优先两阶段,先粗筛再精修。
把目标函数从数学误差换成交易回测指标(如最大回撤、胜率),代理个体存参数组而非坐标点,其余演变逻辑可复用。
小布可内置代理结构自动分批跑基础种群与精炼种群,你只需给品种与风险上限,它回传较稳的参数区间。
基础阶段 30~50 个代理较稳,精炼阶段降到 10~20;样本外切 20% 数据验证,规模再大边际收益骤减。
大概率用了内嵌样本调参,把演变轮次和品种波动率解耦,并加代理年龄淘汰机制可缓解过拟合。