种群优化算法:二进制遗传算法(BGA)。第 I 部分·进阶篇
📘

种群优化算法:二进制遗传算法(BGA)。第 I 部分·进阶篇

第 2/2 篇

◍ 把二进制位串抠成整型的实战函数

在 MT5 里做位级协议解析时,经常要把一段 char 数组里的 0/1 序列直接转成 ulong。下面这个函数就是干这个的:给定起止下标,把闭区间 [startInd, endInd] 上的二进制位从左往右拼成整数。 注意它有个硬约束——startInd 等于 endInd 时直接返回 0,不会进入循环。如果你传的是单元素区间又指望拿到那一位的值,这里会落空,调用前得自己判长度。 核心就一句 result = (result << 1) + binaryStr[i]:每读一位先把已有结果左移腾坑,再加当前位。最多支持 64 位(ulong 上限),超了会静默截断,贵金属或外汇 EA 里解析自定义 tick 包时务必先确认位宽。 [CODE] ulong BinaryToInteger (const char &binaryStr [], const int startInd, const int endInd) { ulong result = 0; if (startInd == endInd) return 0; for (int i = startInd; i <= endInd; i++) { result = (result << 1) + binaryStr [i]; } return result; } [/CODE] 逐行拆一下:第 1 行声明函数,入参是 char 引用数组加起止 int;第 3 行 result 初始化为 0,承载累加结果;第 4 行单元素区间短路返回 0;第 5–9 行循环左移累加;第 10 行吐出最终 ulong。开 MT5 新建脚本把这段贴进去,传 {1,0,1,1} 和下标 0–3,应拿到 11,可即刻验证。

MQL5 / C++
class="type">class="kw">ulong BinaryToInteger(const class="type">char &binaryStr [], const class="type">int startInd, const class="type">int endInd)
{
  class="type">class="kw">ulong result = class="num">0;
  if (startInd == endInd) class="kw">return class="num">0;
  for (class="type">int i = startInd; i <= endInd; i++)
  {
    result = (result << class="num">1) + binaryStr [i];
  }
  class="kw">return result;
}

亲本选择机制怎么挑

优化算法里的选择,本质是从候选集里挑出能繁育下一代的个体。这一步直接决定搜索能力和收敛速度,没有哪种方法放之四海皆准,得看具体搜索策略。 统一选择给每个个体同等概率,好处是探索面广、多样性高,但完全不看适应度,当种群里明显有强者时,找最优解的效率会掉。想保多样性或探未知区域时它才实用。 排位选择按适应度排名,等级越高被选概率越大,可线性也可非线性。弱个体仍有机会,能缓过早收敛,类似统一选择但更偏向适者。 竞胜选择每次随机抽一小撮(竞胜组)取最强者,随机性带来跨区选亲本的可能,常和交叉、突变搭着用。轮盘选择按适应度占比分扇区,强者扇区大但弱者非零概率,差异过大时易堵死在局部最优。 精英主义可叠加任意方法:把当前最优原样传代,提速且防信息丢,但精英比例高了会损多样性。实盘调 EA 参数优化时,精英值设 1~2 通常比设 5 以上更不易过早收敛,需在保优与探索间找平衡。外汇与贵金属优化属高风险,回测优不代表实盘能复现。

「遗传算法里的交叠到底怎么切染色体」

交叠是遗传算法里模仿杂交育种的核心操作,作用在基因型层级:把两个或若干亲本独体的基因拆开再拼装,产生携带双方特征的后代。它不只是传信息,更直接影响种群的组合多样性,点错了交叠方式,搜索空间可能过早塌缩。 最直观的是二进制交叠。单点交叠在随机位置切断两条染色体,断点之后互换片段得到两个子代;多点交叠同理但设多个断点,片段在断点间交替交换;均匀交叠则让每个比特位都以 50% 概率独立取自任一亲本,不依赖位置。 遇到顺序敏感问题(如路径规划),PMX 和部分映射交叠会保留亲本元素的相对位置与顺序,OX 则先固定一个亲本的基因顺序,再从另一亲本按出现顺序补回缺失基因。这类方法在 MT5 优化器里虽不直接暴露,但理解其逻辑有助于判断参数空间是否被合理探索。 实数交叠更直接服务于 EA 参数优化。BLX-α 在亲本值加减 α 倍区间宽度的范围内随机取子项;SBX 用概率分布生成位于亲本之间的后代并考量差异程度;差分交叠把两个独体的加权差加到第三个向量上。实盘外汇或贵金属策略做 GA 寻参时,α 与交叉概率每调一档,回测曲线形态可能明显不同,这类品种杠杆高、滑点跳空频繁,任何参数优势都只是概率倾向,务必在 MT5 策略测试器里跑多品种验证。

◍ 突变算子为什么是遗传算法的命门

突变在遗传算法里负责往种群基因库塞入新信息,否则几十到几百个个体的小规模种群极易近亲繁殖、走进死胡同。现实生物靠数百万个体维持多样性,而 MT5 优化器里我们常只跑数十或数百个样本,突变几乎成了唯一的信息注入口。 常见实现把突变率压在 1–2% 左右:太高会退化为纯随机搜索,太低则收敛过快、多样性枯竭。对二进制编码,单点翻转只改一个随机 bit(如 101010 → 100010),多点翻转改若干位,完全翻转则全体取反(101010 → 010101),还有按概率逐 bit 变化的随机突变与断点互换式点翻转。 实数编码下另有高斯突变、算术/几何蠕变、幂突变、Michalewicz 非均匀算子等,它们在 EA 参数优化中更贴近连续变量搜索。只要个体间无信息交换、且操作改变了搜索空间组分,就可归为突变——具体形态取决于你给优化器设定的搜索策略。 外汇与贵金属市场高杠杆、高波动,用遗传算法调参只是概率层面的探索,不代表任何收益保证;开 MT5 策略测试器的遗传优化,把突变率从 1% 调到 5% 对比回测曲线,能直观看到多样性与过拟合的此消彼长。

别急着下结论

种群优化算法里,选择、交叉、突变这三个运算符的顺序在逻辑上高度一致,任何具体算法可能缺其中一两个,但先后排列基本固定,这种结构更偏向把有利求解的概率逐步组合起来。作者在原讨论中还提到,第四种「新个体入种群」的方法通常不单列,却实实在在影响收敛行为。 上面这段 MT5 循环片段展示了epoch驱动的移动与适应度重算: epochs 倒序跑完,每轮先 Moving() 再逐个体算 f,最后 Revision() 收口。你可以直接把 AO 换成自己写的种群类,在 MT5 里跑几十代看适应度曲线是否单调改善,外汇与贵金属品种上这类优化结果波动大,属于高风险验证。 方法学理清了不代表能直接赚钱,真正落地还得靠你改算子、调概率、换信息编码方式,或许能逼出更适合自己策略的新思路。

MQL5 / C++
for (class="type">uint i = epochCount; (class="type">bool)i--;)
{
  AO.Moving() class=class="str">"cmt">// 移动(i)
  for (class="type">uint set = ArraySize(AO.aName); (class="type">bool)set--;)
    AO.aName[set].f = FF(AO.aName[set].c);

  AO.Revision();
}

常见问题

用位移和按位与逐段提取:先按基因长度切片,再左移累加进整型。可直接套用文章里的 BinToInt 函数逐行改长度参数。
改用轮盘赌或锦标赛选择,按适应度比例或局部竞争挑,避免随机盲选。调大选择压力参数可加快收敛但易早熟。
小布可接管重复的诊断与参数扫描,你只管看收敛曲线和决策。把染色体长度和突变率交给它批量跑即可。
单点交叠在随机位切断互换尾部;多点则交替切片。切点位于基因边界能保整型语义不串味。
突变率趋零会丢失种群多样性,陷在局部最优出不来。实战里 0.01~0.05 更稳,贵金属外汇场景属高风险需回测验证。