珊瑚礁优化算法(CRO)(基础篇)
📘

珊瑚礁优化算法(CRO)(基础篇)

第 1/3 篇

「珊瑚礁优化在 MT5 里的落地起点」

珊瑚礁优化算法(CRO)把种群搜索类比成珊瑚虫在礁区的繁殖与杂交,用「水播 / 碎播」两种扩张模拟全局与局部探索。相比网格或遗传的单一交叉,它靠礁体占用率动态压竞争,适合多峰参数面。 在 MT5 中它不走内置遗传优化器,而是以 EA 形式外接:把待优参数写进输入组,每代把种群状态通过全局变量回写终端。作者 Andrey Dik 于 2026-04-17 发布的实现帖获 440 次查看、0 条跟评,说明该思路在中文圈还偏冷门。 想验证可行性,直接开 MT5 加载其 EA,把历史品种切到 XAUUSD 的 H1,跑 200 代看参数收敛带宽度;外汇与贵金属杠杆高,回测顺滑不等于实盘稳健,结论仅作概率参考。

用珊瑚礁博弈改写优化搜索

  • 年 S. Salcedo-Sanz 等人提出的珊瑚礁优化(CRO)算法,把珊瑚繁殖、空间竞争和弱势死亡搬进了数学搜索框架。它模拟群体产卵、体内受精、无性繁殖三类机制,让解在有限「礁石空间」里互相挤占,弱解消亡、强解留存,从而在不规则搜索空间里找到近优解。

标准 CRO 靠自然平衡维持全局探索与局部开发,但收敛节奏偏慢。我们改出一版 CROm:在最优解邻域用逆幂律分布生成新解,淘汰机制不再均匀随机,而是长尾式偏向高潜力区。这样探索能力不丢,锁定的搜索区域更准,收敛速度可能更快。 在经典基准函数上跑过广泛测试,CROm 对多模态目标和复杂空间结构的问题提升尤其明显,对比原版 CRO 与若干现代元启发式都有概率优势。外汇与贵金属参数寻优属高风险场景,这类算法只降低盲搜成本,不保证实盘收益。

◍ 把珊瑚礁竞争写成 MT5 优化类

CRO 把优化解看成礁石上的珊瑚,礁石是 N×M 二维网格,每个格子空或被占。初始占用率 ρ₀∈(0,1),实际放珊瑚数是 ⌊ρ₀×N×M⌋,且受 popSize 限制;图例里给过一组可调值:ρ₀=0.6、群体产卵 Fb=0.9、无性 Fa=0.1、淘汰 Fd=0.1 且 Pd=0.05、幼虫尝试 k=3。 在 MT5 里落地时,作者建了 C_AO_CRO 类继承 C_AO。关键参数直接暴露成字段:reefRows/reefCols 定网格,rho0 定起始密度,Fb/Fa/Fd/Pd/attemptsNum 控繁殖与淘汰。SetParams() 吃 params 数组,能在跑的过程中热改参数,不用重编译。 Init() 先调基类 StandardInit,再算 totalReefSize、initialPopSize,清 occupied[] 和 reefIndices[],交 InitReef() 随机占格并离散化坐标(u.SeInDiSp 按 rangeStep 控步长)。Moving() 不直接算适应度,只扫 occupied 里有效 idx 并置 revision=true,保证每轮只触发一次评估;Revision() 才找更优解、生 larvae、跑 BroadcastSpawning/Brooding/LarvaSettling/AsexualReproduction/Depredation。 LarvaSettling 是核心:幼虫最多 attemptsNum 次随机选格,空格就占、被占且 f(幼虫)>f(原主) 就替换,全失败返回 -1。BroadcastSpawning 按 Fb 选占格珊瑚两两平均坐标加微扰;Brooding 对剩余 1-Fb 做变异;AsexualReproduction 按 Fa 克隆最优点;Depredation 以 Pd 概率删最差 Fd 比例。外汇/贵金属参数优化用这套,过拟合风险高,建议拿历史段先回测再上实盘。

MQL5 / C++
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class C_AO_CRO : class="kw">public C_AO
{

「珊瑚礁优化算法的初始化参数怎么配」

在 MT5 里用珊瑚礁优化(CRO)做指标或 EA 的底层寻优时,构造函数里先把种群结构和繁殖销毁比例钉死,是后续跑通的前提。下面这段就是该类默认初始化的核心:种群规模 50,礁盘按 20×20 排布,初始占用率 rho0 设 0.2,意味着开局只有约 80 个珊瑚位被占。 广播产卵比例 Fb=0.99、无性繁殖 Fa=0.01,说明算法几乎靠交叉扩散找解,自我复制极少;淘汰率 Fd=0.8 配销毁概率 Pd=0.9,代表每轮大概率清掉八成旧珊瑚,搜索抖动很猛。 SetParams 负责把外部参数数组回写进成员变量,注意 rho0 到 Pd 都是 double,popSize/reefRows/reefCols 则强转 int。你在 MQ5 里改这些数前,先想清楚:外汇和贵金属杠杆高、滑点乱,这种高淘汰率优化在实盘可能过拟合,调参后务必用历史数据验证。

MQL5 / C++
 class="kw">public:
  class=class="str">"cmt">//--------------------------------------------------------------------
  ~C_AO_CRO() { }
  C_AO_CRO()
  {
    ao_name = "CRO";
    ao_desc = "Coral Reef Optimization";
    ao_link = "[MQL5官方文档]
    
    popSize      = class="num">50;       class=class="str">"cmt">// population size
    reefRows     = class="num">20;       class=class="str">"cmt">// reef height
    reefCols     = class="num">20;       class=class="str">"cmt">// reef width
    rho0         = class="num">0.2;      class=class="str">"cmt">// initial reef occupancy
    Fb           = class="num">0.99;     class=class="str">"cmt">// fraction of corals for broadcast spawning
    Fa           = class="num">0.01;     class=class="str">"cmt">// fraction of corals for asexual reproduction
    Fd           = class="num">0.8;      class=class="str">"cmt">// fraction of corals to remove
    Pd           = class="num">0.9;      class=class="str">"cmt">// probability of destruction
    attemptsNum = class="num">20;        class=class="str">"cmt">// number of attempts for larvae to settle
    ArrayResize(params, class="num">9);
    params [class="num">0].name = "popSize";     params [class="num">0].val = popSize;
    params [class="num">1].name = "reefRows";    params [class="num">1].val = reefRows;
    params [class="num">2].name = "reefCols";    params [class="num">2].val = reefCols;
    params [class="num">3].name = "rho0";        params [class="num">3].val = rho0;
    params [class="num">4].name = "Fb";          params [class="num">4].val = Fb;
    params [class="num">5].name = "Fa";          params [class="num">5].val = Fa;
    params [class="num">6].name = "Fd";          params [class="num">6].val = Fd;
    params [class="num">7].name = "Pd";          params [class="num">7].val = Pd;
    params [class="num">8].name = "attemptsNum"; params [class="num">8].val = attemptsNum;
  }
  class="type">void SetParams()
  {
    popSize      = (class="type">int)params [class="num">0].val;
    reefRows     = (class="type">int)params [class="num">1].val;
    reefCols     = (class="type">int)params [class="num">2].val;
    rho0         = params      [class="num">3].val;
    Fb           = params      [class="num">4].val;
    Fa           = params      [class="num">5].val;
    Fd           = params      [class="num">6].val;

珊瑚礁优化器的类成员与私有结构

这段声明把珊瑚礁优化(CRO)算法的核心状态都压进了一个类里。reefRows 与 reefCols 决定礁盘网格的高宽,totalReefSize 即两者乘积,是私有成员里实际参与寻址的总容量。 公开的 rho0、Fb、Fa、Fd、Pd、attemptsNum 分别对应初始占用率、有性广播比例、无性繁殖比例、清除比例、破坏概率和幼虫定居尝试次数;其中 Pd 与 attemptsNum 由外部参数数组下标 7 和 8 注入,说明调参入口固定在 params[7]、params[8]。 Init 方法接收 rangeMinP、rangeMaxP、rangeStepP 和 epochsP,明确了搜索区间与步长走构造函数式注入,而不是硬编码。 私有侧用 occupied[] 标记网格占用,reefIndices[] 做占用单元到 agent 数组的映射,避免了每次遍历全网格。辅助方法如 LarvaSettling、BroadcastSpawning、Brooding、AsexualReproduction、Depredation 把一代繁殖—破坏循环拆得很细,在 MT5 里照这个类骨架改 Fb/Fd 比值,可能直接改变收敛速度与全局逃逸能力。外汇与贵金属品种上跑这类元启发式优化,仍属高风险,参数过拟合概率不低。

MQL5 / C++
Pd                  = params      [class="num">7].val;
attemptsNum = (class="type">int)params [class="num">8].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">// search step
           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                reefRows;     class=class="str">"cmt">// reef height
class="type">int                reefCols;     class=class="str">"cmt">// reef width
class="type">class="kw">double             rho0;         class=class="str">"cmt">// initial reef occupancy
class="type">class="kw">double             Fb;           class=class="str">"cmt">// fraction of corals for broadcast spawning
class="type">class="kw">double             Fa;           class=class="str">"cmt">// fraction of corals for asexual reproduction
class="type">class="kw">double             Fd;           class=class="str">"cmt">// fraction of corals to remove
class="type">class="kw">double             Pd;           class=class="str">"cmt">// probability of destruction
class="type">int                attemptsNum;  class=class="str">"cmt">// number of attempts for larvae to settle
class="kw">private: class=class="str">"cmt">//-------------------------------------------------------------------
class="type">int                totalReefSize; class=class="str">"cmt">// total reef size
class="type">bool  occupied     [];   class=class="str">"cmt">// flags of reef cell occupancy
class="type">int                reefIndices []; class=class="str">"cmt">// agent indices in a[] corresponding to occupied cells
class=class="str">"cmt">// Auxiliary methods
class="type">void   InitReef();
class="type">int    LarvaSettling(S_AO_Agent &larva);
class="type">void   BroadcastSpawning(S_AO_Agent &larvae [], class="type">int &larvaCount);
class="type">void   Brooding(S_AO_Agent &larvae [], class="type">int &larvaCount);
class="type">void   AsexualReproduction();
class="type">void   Depredation();
class="type">int    GetReefCoordIndex(class="type">int row, class="type">int col);
class="type">void   SortAgentsByFitness(class="type">int &indices [], class="type">int &count);
};

常见问题

它用珊瑚虫播种+竞争淘汰模拟种群演化,能在非凸空间跳过无效区,减少无效回测次数,适合多峰目标函数。
先设礁石规模50~100、幼虫数等于礁石数、适应度阈值0.8,再按品种波动调侵蚀率,贵金属品种建议保守些。
小布盯盘的AIGC可自动调用优化类跑候选参数并标注高概率区,你只需导入品种页看诊断,不必手写竞争逻辑。
常漏存幼虫源礁索引与占领标记位,导致回收阶段错配,建议用结构体打包坐标、适应度、状态三字段。
必须切到样本外数据重跑一遍并观察回撤,外汇贵金属高风险,样本内优不等于实盘倾向盈利。