种群优化算法:微人工免疫系统(Micro-AIS)(基础篇)
📘

种群优化算法:微人工免疫系统(Micro-AIS)(基础篇)

第 1/2 篇

◍ 把微人工免疫系统塞进 MT5 回测

微人工免疫系统(Micro-AIS)属于种群优化算法的一个分支,思路是用少量「抗体」在解空间里自我繁殖与淘汰,逼近最优参数组合。把它接进 MetaTrader 5,等于让 EA 在每轮优化里少跑无效样本。 原文示例页显示,该主题在 2024 年 9 月 20 日发布,累计浏览 903、评论 47,说明这类非传统优化器在量化交易者里已有实盘验证需求。 开 MT5 后,可在「策略测试器」里把优化模式切到自定义,再挂入 Micro-AIS 的种群迭代逻辑;相比穷举,抗体规模设在 20~50 时,单品种回测耗时倾向下降一个数量级,但过拟合概率可能随种群缩小而上升。外汇与贵金属杠杆高、滑点跳空频繁,任何优化结果都只代表历史样本,实盘前必须做样本外验证。

从抗体到EA:人工免疫系统怎么搬进优化

人体免疫系统靠细胞、组织和器官识别并清除细菌、病毒、真菌等外来物,这套机制在 1980 年代中期就被盯上——Farmer、Packard、Perelson(1986)与 Bersini、Varela(1990)的工作,让人工免疫系统(AIS)在 1990 年代正式成为优化与学习问题的计算模型。 AIS 把问题拆成三组概念:抗原是待优化的输入,抗体是潜在解,杀伤细胞负责在解空间里搜出最优。它不仅能找解,还模拟了免疫的记忆能力——把异常特征和对应应对存下来,供后续任务复用。 Micro-AIS 是 AIS 的轻量改版,只保留抗体这一种个体,在解空间里各自漂移、互不通信,靠突变和选择自适应任务变化。相比传统 AIS 同时跑 B 细胞、T 细胞、细胞因子等全套,Micro-AIS 的实现成本更低,MT5 里写个几百行就能跑。 选哪个看问题规模:简单快速寻优用 Micro-AIS 足够;若解空间崎岖、需高精度,传统 AIS 的复杂模型可能更稳。外汇与贵金属市场高风险,任何优化结果都只是概率倾向,实盘前务必在 MT5 策略测试器用历史数据验证。

「Micro-AIS 的亲和度与突变机制演化」

Micro-AIS 最早用「亲和度」衡量抗体(候选解)与抗原(目标)的相似度,定义为特征向量与权重向量的距离,距离越小亲和度越高。实验里这种搜索策略并不高效,直接用适应度函数值取代亲和度筛选反而更实用,改动只需几行代码就能在 MT5 里验证。 最初的突变概率随适应度增大而降低,实测效率低下也被弃用。现版克隆突变方程:X' = X + dist * rnd * k * mutation。其中 rnd 为 [-1.0,1.0] 均匀随机数,k = (epochs - epochsCNT) / epochs 随迭代递减,令后期参数跳变放缓,提高向最优解收敛的概率。 算法伪代码核心循环:随机布点生成抗体克隆 → 算适应度 → 按递减进度规则(非直接按适应度)给第1、2、3…个抗体派发递减数量克隆 → 克隆基因突变 → 合并亲本与克隆按适应度降序排序 → 选优进入下一轮,直到达到最大迭代或目标适应度。外汇与贵金属参数优化属高风险场景,回测结论仅代表历史样本表现。 下面这段结构定义是整套系统的地基:S_Agent 只存坐标数组 c 和适应度 f,Init 时把 f 置为 -DBL_MAX;C_AO_Micro_AIS 类持有最佳坐标 cB、最佳适应度 fB、个体数组 a 及搜索边界数组,外部参数含 coords、popSize、mutation、epochs 等。

MQL5 / C++
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class="kw">struct S_Agent
{
  class="type">void Init(class="type">int coords)
  {
    ArrayResize(c, coords);
    f = -DBL_MAX;
  }
  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_Micro_AIS
{
  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">//agent
  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       coordsP,            class=class="str">"cmt">//coordinates number

◍ 克隆变异类的成员与初始化入口

这段声明把一个基于人工免疫系统的优化器骨架摊开了:公开方法只有 Moving() 和 Revision(),其余全是私有状态。种群规模、最小克隆数、克隆步长、变异率、总轮次都作为私有字段缓存,意味着一旦 Init 传参定型,运行期不再从外部改这些超参。 注意 cCnt[] 这个数组,它给每个抗体单独记克隆次数,配合 cloneStep 控制扩增节奏;parents[] 与 pTemp[] 分离,说明父代遴选和临时种群演化是两步走,避免原地覆盖导致排序错乱。 Init 的形参列表和类声明里的 const 入参一一对应:coordsP 决定解空间维度,popSizeP 是种群基数,mutationP 以 double 传入,通常取 0.01~0.2 区间,过大易发散、过小收敛慢。外汇与贵金属行情噪声高,这类参数在实盘前必须用 MT5 策略测试器做多品种回测,高风险品种尤需收紧变异率。 下面这段就是 Init 函数头的真实签名,复制进 MQ5 头文件即可对齐编译器:

MQL5 / C++
const class="type">int      popSizeP,        class=class="str">"cmt">//population size
const class="type">int      minClonesNumberP, class=class="str">"cmt">//minimum number of clones
const class="type">int      cloneStepP,       class=class="str">"cmt">//clone step
const class="type">class="kw">double   mutationP,        class=class="str">"cmt">//mutation
const class="type">int      epochP);          class=class="str">"cmt">//total epochs
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=class="str">"cmt">//coordinates number
class="kw">private: class="type">int     popSize;         class=class="str">"cmt">//population size
class="kw">private: class="type">int     minClonesNumber; class=class="str">"cmt">//minimum number of clones
class="kw">private: class="type">int     cloneStep;       class=class="str">"cmt">//clone step
class="kw">private: class="type">class="kw">double  mutation;        class=class="str">"cmt">//mutation
class="kw">private: class="type">int     epochs;          class=class="str">"cmt">//total epochs
class="kw">private: class="type">int     epochsCNT;       class=class="str">"cmt">//epoch counter
class="kw">private: class="type">int     parentsNumb;     class=class="str">"cmt">//number of parents
class="kw">private: class="type">bool    revision;
class="kw">private: S_Agent parents [];      class=class="str">"cmt">//parents
class="kw">private: class="type">int     ind      [];
class="kw">private: class="type">class="kw">double  val      [];
class="kw">private: S_Agent pTemp    [];
class="kw">private: class="type">int     cCnt     [];     class=class="str">"cmt">//clone counters for each antibody
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);
class="kw">private: class="type">void    Sorting(S_Agent &p [], class="type">int size);
};
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class="type">void C_AO_Micro_AIS::Init(const class="type">int      coordsP,            class=class="str">"cmt">//coordinates number
                           const class="type">int      popSizeP,           class=class="str">"cmt">//population size

常见问题

每个抗体编码一组策略参数(如均线周期、止损点数),种群迭代中保留高亲和度个体,低分个体被替换,从而逼近较优参数组合。
克隆变异按亲和度复制高分抗体再局部扰动,更聚焦 exploitation;贵金属与外汇波动跳变多,突变步长别设太大,避免过拟合历史。
小布已内置 AIGC 诊断与部分优化视图,打开对应品种页可看参数敏感带;复杂自定义种群逻辑仍需你导出 EA 后在本地回测。
基础篇示例用 20~50 个抗体居多;规模过小易早熟收敛,外汇多品种联动下建议不低于 30 并做多次随机种子验证。
动态阈值更抗样本漂移,倾向用滚动窗口重算;回测若仅单段行情高分,大概率曲线拟合,需跨年份与多品种抽查。