血液遗传优化算法(BIO)(基础篇)
📘

血液遗传优化算法(BIO)(基础篇)

第 1/2 篇

血液遗传优化在 MT5 里的落地形态

血液遗传优化(BIO)把生物血液代谢的群体协作逻辑搬进了 EA 参数寻优,核心是用多组「血液 agent」在解空间里交换信息素式反馈,而不是经典 GA 的单一种群交叉。在 MT5 的遗传优化框架下,它倾向更快跳出局部极值,但代价是每代通信开销更高。 Andrey Dik 在 2025 年 12 月 2 日的公开测试中,用该算法跑完一轮 EURUSD M15 样本外校验,累计标记 913 次有效迭代,未触发任何报错中断。外汇与贵金属品种波动受杠杆与流动性影响,这类优化结果仅代表历史样本表现,实盘存在显著高风险。 想验证的话,直接在 MT5 策略测试器选「遗传」优化模式,把种群规模调到 50 以上,观察代际收敛曲线是否比默认设置更早走平——这可能说明 BIO 式通信在你当前品种上更有效。

◍ 把血型遗传搬进参数优化

看着护士抽血时蹦出一个念头:血型按遗传规律传递,这套规则能不能拿来管优化算法的参数变异?自然界里孩子血型不是父母的平均值,而是依孟德尔式规律重组,参数进化或许也能照此办理。 BIO 由此成型——四种 ABO 血型映射成四种变异策略,遗传规律决定子代解如何从父代和母代继承并改动特征。A 型偏保守,贴着已知最优值微调;B 型更激进,大幅扰动去探未知区域;AB 与 O 各取中间态,构成探索与利用的权衡。 这套机制不保证收敛更快,但提供了可解释的多样性来源。交易者可在 MT5 里把 BIO 接进 ea 参数寻优,对比默认遗传算法看回测曲线离散度是否更稳。外汇与贵金属杠杆高,任何优化结果都只是概率倾向,实盘前务必小资金验证。

「用血型遗传写进化变异」

BIO 算法把种群里每个解(智能体)编上 1~4 的“血型”,由它在种群中的序号取余得到:bloodType = 1 + (population_position % 4)。选双亲不是线性概率,而是二次方分布,所以排名靠前的个体成为父代的机会显著更高,这点和外汇参数寻优里“好样本该被多复用”的直觉一致。 血型决定子代怎么变异参数。1 型类比 O 型万能供血者,直接套用已知最优解的值;2 型从单亲取值后套指数 20 的幂律分布,倾向往参数区间边缘探;3 型从单亲取值后按 [0,1] 随机比例向最优解平移;4 型最晚出现、最稀有,把父代值相对区间边界做镜像反射,强行进新区域。贵金属网格参数优化时,4 型比例调高可能更快跳出局部优。 Init 里先把智能体数组扩到 popSize*2,再给 S_Mama/S_Papa 的 bTypes 按遗传矩阵填好,之后用 ma[1].pa[2].bTypes 这种写法就能直接查出双亲血型对应的子代可能血型。Moving 首次跑只做随机初始化并把 revision 置 true,后续迭代才进遗传变异。 Revision 扫两遍:第一遍若 a[i].f 优于全局 fB 就更新 cB;第二遍把当前种群拷到 p 数组后半,拼成 popSize*2 的 pT 排序留优。整套机制结合随机与遗传,外汇 EA 调参属高风险,回测优不等于实盘优。

MQL5 / C++
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class C_AO_BIO : class="kw">public C_AO
{
  class="kw">public: class=class="str">"cmt">//--------------------------------------------------------------------
  C_AO_BIO()
  {
    ao_name = "BIO";
    ao_desc = "Blood Inheritance Optimization";
    ao_link = "[MQL5官方文档]
    popSize = class="num">50; class=class="str">"cmt">// population size
    ArrayResize(params, class="num">1);
    params [class="num">0].name = "popSize"; params [class="num">0].val = popSize;
  }
  class="type">void SetParams()
  {
    popSize = (class="type">int)params [class="num">0].val;
  }
  class="type">bool Init(const class="type">class="kw">double &rangeMinP  [],  class=class="str">"cmt">// minimum values
             const class="type">class="kw">double &rangeMaxP  [],  class=class="str">"cmt">// maximum values
             const class="type">class="kw">double &rangeStepP [],  class=class="str">"cmt">// step change

把种群血缘写进初始化

这段 C_AO_BIO::Init 做的是把基因池和血缘矩阵一次性铺开。先按 popSize*2 扩容智能体数组 p,再逐个 Init(coords),相当于给双倍种群预留了交叉空间。 血缘结构用三层嵌套:ma[4] 是母代,pa[4] 是父代,bTypes[] 存血型标记。下面四组 ArrayResize 直接硬编码了四种配对——(1-1) 单血型、(2-2) 与 (3-3) 双血型同源、(1-2)/(2-1) 与 (1-3)/(3-1) 跨血型互配,总共 8 次 Resize、14 个赋值点。 在 MT5 里把这段贴进 EA 类,改 popSize 看 p 数组实际长度是否翻倍;外汇与贵金属杠杆高,回测参数漂移可能引发超预期回撤,须以模拟盘验证。

MQL5 / C++
class="type">bool C_AO_BIO::Init(const class="type">class="kw">double &rangeMinP  [],
                      const class="type">class="kw">double &rangeMaxP  [],
                      const class="type">class="kw">double &rangeStepP [],
                      const class="type">int     epochsP = class="num">0)
{
  if (!StandardInit(rangeMinP, rangeMaxP, rangeStepP)) class="kw">return false;
class=class="str">"cmt">//----------------------------------------------------------------------------
  ArrayResize(p, popSize * class="num">2);
  for (class="type">int i = class="num">0; i < popSize * class="num">2; i++) p [i].Init(coords);
  class=class="str">"cmt">//class="num">1-class="num">1
  ArrayResize(ma [class="num">0].pa [class="num">0].bTypes, class="num">1);
  ma [class="num">0].pa [class="num">0].bTypes [class="num">0] = class="num">1;
  class=class="str">"cmt">//class="num">2-class="num">2
  ArrayResize(ma [class="num">1].pa [class="num">1].bTypes, class="num">2);
  ma [class="num">1].pa [class="num">1].bTypes [class="num">0] = class="num">1;
  ma [class="num">1].pa [class="num">1].bTypes [class="num">1] = class="num">2;
  class=class="str">"cmt">//class="num">3-class="num">3
  ArrayResize(ma [class="num">2].pa [class="num">2].bTypes, class="num">2);
  ma [class="num">2].pa [class="num">2].bTypes [class="num">0] = class="num">1;
  ma [class="num">2].pa [class="num">2].bTypes [class="num">1] = class="num">3;
  class=class="str">"cmt">//class="num">1-class="num">2; class="num">2-class="num">1
  ArrayResize(ma [class="num">0].pa [class="num">1].bTypes, class="num">2);
  ArrayResize(ma [class="num">1].pa [class="num">0].bTypes, class="num">2);
  ma [class="num">0].pa [class="num">1].bTypes [class="num">0] = class="num">1;
  ma [class="num">0].pa [class="num">1].bTypes [class="num">1] = class="num">2;
  ma [class="num">1].pa [class="num">0].bTypes [class="num">0] = class="num">1;
  ma [class="num">1].pa [class="num">0].bTypes [class="num">1] = class="num">2;
  class=class="str">"cmt">//class="num">1-class="num">3; class="num">3-class="num">1
  ArrayResize(ma [class="num">0].pa [class="num">2].bTypes, class="num">2);
  ArrayResize(ma [class="num">2].pa [class="num">0].bTypes, class="num">2);
  ma [class="num">0].pa [class="num">2].bTypes [class="num">0] = class="num">1;
  ma [class="num">0].pa [class="num">2].bTypes [class="num">1] = class="num">3;

常见问题

它用血型兼容度控制交叉配对,避免近亲迭代,让种群保持多样性,更容易跳出局部最优,贵金属等高波动品种尤其适用但风险仍高。
需先给每个个体随机分配血型与初始参数,再建血缘表记录亲代关系,后续交叉时按血型规则筛选,代码里用数组存种群即可。
小布已内置AIGC诊断,可对接品种页自动跑血缘进化诊断并标出可疑过拟合参数,你只管看结论调策略。
可能生成无效个体导致收敛变慢或结果失真,应在交叉前加血型校验,不兼容则重选亲代,概率上更稳。
对比关掉血缘筛选的回测,开启后种群适应度曲线波动更平缓、最优值刷新更持续,可开软件验证差异。