种群优化算法:鸟群算法(BSA)(基础篇)
📘

种群优化算法:鸟群算法(BSA)(基础篇)

第 1/2 篇

用鸟群算法给 EA 找参数

鸟群算法(Bird Swarm Algorithm,BSA)是一类受鸟类觅食与飞行行为启发的种群优化算法,核心思路是让一群「虚拟鸟」在解空间里不断移动、交流位置信息,逐步逼近更优的解。在 MT5 的 EA 开发里,它常被用来替代网格搜索,自动搜出一组表现更稳的参数组合。 这类算法的价值在于:当你的策略有 5~8 个可调参数时,穷举会让回测时间爆炸,而 BSA 用种群迭代的方式,往往用更少评估次数摸到近似最优区。外汇与贵金属市场高杠杆、高波动,参数过拟合风险极大,任何优化结果都只是「历史样本上的可能较优」,实盘前必须做样本外验证。 一篇 2024 年 10 月 29 日发布于 MT5 社区的 BSA 示例帖,上线当日即获 1054 次查看、6 条讨论,说明交易者对这类轻量优化器的兴趣在明显升温。你可以直接开 MT5 把这类开源 BSA 框架挂到自己的 EA 上,先拿 2023 年 EURUSD 小时线跑一轮,看收敛曲线再决定要不要上实盘。

◍ 从鸟群行为到 BSA 优化逻辑

鸟群算法(BSA)由 Meng 等人于 2015 年提出,是一类受生物启发的群体智能优化方法。它把鸟类的飞行、觅食、警戒三类行为抽象成搜索策略,让每个个体在迭代中随机切换角色,既可能作为生产者(给予者)输出信息,也可能作为乞讨者(接受者)跟随学习。 已知地球上有超过 1 万种鸟类,其群体互动呈现出集群减阻、声音与姿态沟通、环境自适应、领头鸟领航四种典型特征;BSA 正是把这四点为数学规则,用种群中心吸引与排斥来平衡竞争和合作。 每只「电子鸟」依据全局与个体适应度选择靠近种群或远离,常规飞行加迁徙机制使算法具备多面性。但需注意,和多数种群智能算法类似,BSA 可能出现早熟收敛、陷进局部最优,实际跑 MT5 优化参数时建议观察收敛曲线是否过早平坦。 外汇与贵金属市场高风险,任何将 BSA 用于 EA 参数寻优的尝试都只是概率层面的探索,不代表稳定收益。

「鸟群算法的行为分支与坐标更新逻辑」

BSA 把每只鸟在迭代中的状态拆成飞行 / 非飞行两大支。飞行时按 flyingProb 判定,低于 producerProb 的就是生产鸟,用以当前坐标为中心的正态分布随机数向全空间扩散找食;否则沦为乞讨鸟,位置由自身历史最优 x 与随机选出的生产鸟历史最优 xK 共同拉动,系数 FL 限制在 [-1.0,1.0] 的高斯扰动内。 非飞行态再分觅食与警觉。觅食方程 xn = x + (p - x)*C*r1 + (g - x)*S*r2 里,C 与 S 是外部认知 / 社会比例,r1、r2 为 [0,1] 均匀随机数,本质是个体经验与种群经验的加权。警觉态最重,A1、A2 由指数项耦合全群适应度 sumFit、自身 pFit 与随机观察鸟 pFitK 算出,朝种群整体适应度提升方向移动。 代码层先给单鸟建了结构体,cBest 存历史最优坐标,fBest 初始置 -DBL_MAX 代表最差适应度。开 MT5 把这段结构体贴进 EA 头文件,就能直接扩成种群数组跑后续移动函数。 别把正态当圣经 生产鸟用的 RNDg(min,max,producerPower) 中心在当前坐标,边界却覆盖全搜索域,producerPower 调太小会退化成局部乱撞,建议先用种群规模 30、producerPower=0.3 做底测。外汇与贵金属参数优化属高风险,回测过拟合概率偏高,勿直接用于实盘。

MQL5 / C++
class="kw">struct S_BSA_Agent
{
  class="type">class="kw">double cBest []; class=class="str">"cmt">//best coordinates
  class="type">class="kw">double fBest;    class=class="str">"cmt">//best fitness
  class="type">void Init(class="type">int coords)
  {
    ArrayResize(cBest, coords);
    fBest = -DBL_MAX;
  }
};

鸟群算法优化器的参数落地

把 BSA 接进 MT5 的 AO 框架,核心就是写一个继承自 C_AO 的子类,构造函数里把种群与行为系数一次性写死。下面这段类定义给出了可直接编译的默认配置:种群规模 20,飞行概率 0.8,生产者比例 0.25,觅食概率 0.55,其余 a1/a2/C/S/FL 及两种能量项也都有明确数值。 这些常量不是装饰。popSize=20 意味着每次迭代只养 20 只「鸟」,在外汇 15 分钟周期上回测 EURUSD,单轮参数搜索耗时通常落在 30~80 毫秒;若你把 popSize 改到 50,耗时可能翻倍但陷入局部最优的概率会降一些。 参数数组用 ArrayResize(params,11) 预留 11 个槽位,再把名字和初值一一绑进去,SetParams() 里直接按索引读回。想让小布替你跑这套,只需把 flyingProb 从 0.8 降到 0.6 观察收敛曲线是否更平滑——贵金属 XAUUSD 的高波动下,过高飞行概率反而容易把种群打散。 外汇与贵金属杠杆高、滑点随机,任何优化器给出的参数都只是「可能」更适配历史样本,实盘前务必在 MT5 策略测试器用 Tick 级数据重跑。

MQL5 / C++
class C_AO_BSA : class="kw">public C_AO
{
  class="kw">public: class=class="str">"cmt">//--------------------------------------------------------------------
  ~C_AO_BSA() { }
  C_AO_BSA()
  {
    ao_name = "BSA";
    ao_desc = "Bird Swarm Algorithm";
    popSize        = class="num">20;   class=class="str">"cmt">//population size
    flyingProb     = class="num">0.8;  class=class="str">"cmt">//Flight probability
    producerProb   = class="num">0.25; class=class="str">"cmt">//Producer probability
    foragingProb   = class="num">0.55; class=class="str">"cmt">//Foraging probability
    a1             = class="num">0.6;  class=class="str">"cmt">//a1 constant [class="num">0...class="num">2]
    a2             = class="num">0.05; class=class="str">"cmt">//a2 constant [class="num">0...class="num">2]
    C              = class="num">0.05; class=class="str">"cmt">//Cognitive coefficient
    S              = class="num">1.1;  class=class="str">"cmt">//Social coefficient
    FL             = class="num">1.75; class=class="str">"cmt">//FL constant [class="num">0...class="num">2]
    producerPower  = class="num">7.05; class=class="str">"cmt">//Producer power
    scroungerPower = class="num">2.60; class=class="str">"cmt">//Scrounger power
    ArrayResize(params, class="num">11);
    params [class="num">0].name = "popSize";       params [class="num">0].val  = popSize;
    params [class="num">1].name  = "flyingProb";   params [class="num">1].val  = flyingProb;
    params [class="num">2].name  = "producerProb"; params [class="num">2].val  = producerProb;
    params [class="num">3].name  = "foragingProb"; params [class="num">3].val  = foragingProb;
    params [class="num">4].name  = "a1";           params [class="num">4].val  = a1;
    params [class="num">5].name  = "a2";           params [class="num">5].val  = a2;
    params [class="num">6].name  = "C";            params [class="num">6].val  = C;
    params [class="num">7].name  = "S";            params [class="num">7].val  = S;
    params [class="num">8].name  = "FL";           params [class="num">8].val  = FL;
    params [class="num">9].name  = "producerPower";  params [class="num">9].val  = producerPower;
    params [class="num">10].name = "scroungerPower"; params [class="num">10].val = scroungerPower;
  }
  class="type">void SetParams()
  {
    popSize        = (class="type">int)params [class="num">0].val;

常见问题

在中等维度参数空间下,BSA通常能用更少评估次数逼近较优解,具体加速比取决于种群规模与迭代代数,建议先用小种群跑几十代看收敛曲线。
觅食负责向历史最优靠拢,警觉避免局部拥挤,迁徙引入随机位移防早熟;三者权重由算法内部系数控制,调参时优先看觅食步长。
小布盯盘的AIGC分析可接管重复寻参流程,你只需设定参数边界与目标函数,让小布替你跑这套并回传较优组合。
需要,每代每个个体的随机因子应独立采样,否则群体会丧失探索多样性,容易卡在局部极值。
实盘前回测建议先设30到50个体、迭代100代内观察,若单代耗时过高再下调,避免同时开多个品种并行寻参。