种群优化算法:社群进化(ESG)(基础篇)
📘

种群优化算法:社群进化(ESG)(基础篇)

第 1/3 篇

◍ 社群进化算法在MT5里的落地雏形

种群优化思路里有一类叫社群进化(ESG),它把候选解当成个体,靠群体间的交互和筛选逐步逼近较优参数。在 MT5 环境下,这类算法常被封装成 EA 或脚本,用来替代网格遍历式的暴力寻优。 Andrey Dik 在 2024 年 11 月 1 日发布的示例帖,截至统计有 880 次查看、24 条讨论,说明社群进化类方案在实盘圈已有一定关注度。该示例原计划分四节展开:概述、算法、测试结果,本篇只覆盖第一段。 对外汇与贵金属而言,任何参数寻优都只是概率层面的改善,不等于稳健盈利,杠杆品种的高风险始终存在。打开 MT5 社区示例页搜 ESG,可先核对原帖数据是否仍为 880/24,再决定要不要跟进复现。

多种群与多群体优化的底层逻辑

优化领域里,种群类算法覆盖面很广,但多群体、多种群思路在过往资料里常被略过。本文要补的正是这块:用多个逻辑上并行的种群去搜参数空间的不同区域,彼此交换最优解信息,从而可能同时逮到多个局部最优。 多群体算法换了个说法,本质是用若干互相沟通的「群落」协作寻优,和多种群一样依赖信息流通。区别在于前者强调社群互动结构,后者强调种群独立运行后的汇合。 我们这次专门构造了一种多种群 ESG 算法做验证。后面会给出对比测试结果,看它相对单种群优化到底有没有效率优势——外汇与贵金属参数寻优本身高风险,结论仅代表回测环境内的概率倾向。

「多种群社群算法怎么跑起来」

ESG 把优化问题拆成若干独立「社群」,每个社群有中枢坐标 cB 和适应度 fB,份子围绕中枢按幂律分布散开。群内集体运动探索参数空间,本地存最优、全局存总最优,迭代中互相借思路——这是它区别于单种群 GA 的核心。 防局部极值靠动态半径:某次迭代无改善就扩群边界(sRadius 变大),找到更优解就缩回默认最小值。实测中若中枢坐标恰巧卡在不利位置,光扩半径会演变成「对角线扩展」而无效,此时需让份子从盟友群中枢直接抄一组坐标,打破路径依赖。 代码层用 S_Group 描述社群、S_Agent 描述个体。注意 S_Group 不内嵌份子数组,群体访问时个体仍属普通种群,避免冗余拷贝。Init 里 fB 初始化为 -DBL_MAX,保证任意真实适应度都能覆盖。 第二版我试过放开群间全量混血:让任意个体按 copyProb 概率抄最优个体坐标。回测结果总体略差于原版,说明社群独特经验不能被彻底搅拌——只该让极少数份子跨群借中枢,多数留在自己边界内演化。外汇/贵金属参数优化高风险,这套仅作搜索框架验证用,别直接当信号发生器。

MQL5 / C++
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class="kw">struct S_Group
{
  class="type">void Init(class="type">int coords, class="type">int groupSize)
  {
    ArrayResize(cB, coords);   class=class="str">"cmt">// 按坐标数扩容中枢数组
    fB          = -DBL_MAX;     class=class="str">"cmt">// 适应度初始化为最小双精度,任何解都能覆盖
    sSize       = groupSize;    class=class="str">"cmt">// 记录该群份子数量
  }
  class="type">class="kw">double cB [];   class=class="str">"cmt">// 中枢坐标数组
  class="type">class="kw">double fB;      class=class="str">"cmt">// 中枢适应度
  class="type">int    sSize;   class=class="str">"cmt">// 群大小
  class="type">class="kw">double sRadius; class=class="str">"cmt">// 群半径(动态扩缩)
};
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class="kw">struct S_Agent
{
  class="type">void Init(const class="type">int coords)
  {
    ArrayResize(c, coords);   class=class="str">"cmt">// 按坐标数扩容个体坐标数组
    f = -DBL_MAX;              class=class="str">"cmt">// 个体适应度初始化为最小双精度
  }

◍ 把群体搜索封装成可复用的优化类

上面这段声明把整个进化群体搜索的逻辑收进了一个 C_AO_ESG 类,外部调用者只需要关心初始化参数和两步迭代,不用碰群体内部的代理数组。 类里公开了 cB 和 fB 分别存当前最优坐标与对应适应度,a[] 是全部代理,rangeMax / rangeMin / rangeStep 限定了每一维的搜索边界与步长。Init 方法要求传入坐标数、种群规模、群体数、群体半径、扩张比和 power 六个量,这几个值直接决定外汇或贵金属 EA 在参数空间里的探索粒度。 私有段暴露了真实机制:groups 与 gr[] 管理子群,groupRadius 和 expansionRatio 控制子群扩张,SeInDiSp 做带步长的区间离散化,RNDfromCI 在闭区间取随机值。Moving 与 Revision 两个公开方法对应每代的位置移动和越界修订。 实盘前建议把 populationSizeP 设在 30–80 之间先回测,群体数 groupsP 取坐标数的 1/3 附近往往收敛更快;外汇与贵金属杠杆高、滑点大,这类优化结果仅代表历史样本上的概率倾向,不能直接当作实盘胜率。

MQL5 / C++
class="type">class="kw">double c []; class=class="str">"cmt">//coordinates
class="type">class="kw">double f;     class=class="str">"cmt">//fitness
};
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class C_AO_ESG
{
  class=class="str">"cmt">//----------------------------------------------------------------------------
  class="kw">public: class="type">class="kw">double  cB [];           class=class="str">"cmt">//best coordinates
  class="kw">public: class="type">class="kw">double  fB;              class=class="str">"cmt">//FF of the best coordinates
  class="kw">public: S_Agent a  [];           class=class="str">"cmt">//agents
  class="kw">public: class="type">class="kw">double rangeMax   []; class=class="str">"cmt">//maximum search range
  class="kw">public: class="type">class="kw">double rangeMin   []; class=class="str">"cmt">//manimum search range
  class="kw">public: class="type">class="kw">double rangeStep []; class=class="str">"cmt">//step search
  class="kw">public: class="type">void Init(const class="type">int      coordinatesNumberP,  class=class="str">"cmt">//coordinates number
                                const class="type">int      populationSizeP,     class=class="str">"cmt">//population size
                                const class="type">int      groupsP,              class=class="str">"cmt">//number of groups
                                const class="type">class="kw">double groupRadiusP,           class=class="str">"cmt">//group radius
                                const class="type">class="kw">double expansionRatioP,        class=class="str">"cmt">//expansion ratio
                                const class="type">class="kw">double powerP);                class=class="str">"cmt">//power
  class="kw">public: class="type">void Moving();
  class="kw">public: class="type">void Revision();
  class=class="str">"cmt">//----------------------------------------------------------------------------
  class="kw">private: class="type">int     coords;
  class="kw">private: class="type">int     popSize;              class=class="str">"cmt">//population size
  class="kw">private: S_Group gr [];                class=class="str">"cmt">//group
  class="kw">private: class="type">int     groups;               class=class="str">"cmt">//number of groups
  class="kw">private: class="type">class="kw">double  groupRadius;          class=class="str">"cmt">//group radius
  class="kw">private: class="type">class="kw">double  expansionRatio;       class=class="str">"cmt">//expansion ratio
  class="kw">private: class="type">class="kw">double  power;                class=class="str">"cmt">//power
  class="kw">private: class="type">bool    revision;
  class="kw">private: class="type">class="kw">double SeInDiSp(class="type">class="kw">double In, class="type">class="kw">double InMin, class="type">class="kw">double InMax, class="type">class="kw">double Step);
  class="kw">private: class="type">class="kw">double RNDfromCI(class="type">class="kw">double min, class="type">class="kw">double max);

常见问题

多种群是同一目标拆成几个子种群各自搜,多群体是不同目标或约束分开搜;实盘先上多种群做参数鲁棒性,再叠加多群体处理风控与收益双目标。
大概率是的,基础篇雏形建议种群 30~50、迭代 100 代内先验证;外汇贵金属高风险,先用小种群跑通逻辑再扩容。
可以,小布能按你的品种和周期把群体搜索逻辑生成可复用模块,你只需填入目标函数与约束,省去手写底层代码。
不一定是错,群体算法带随机初始化,本身有随机性;固定随机种子或跑多次取中位数可降低波动。
有可能,多种群并行搜能暴露参数脆弱区;但仍是概率性提升,需配合样本外检验确认。