种群优化算法:蝙蝠算法(BA)(基础篇)
📘

种群优化算法:蝙蝠算法(BA)(基础篇)

第 1/3 篇

蝙蝠算法在 MT5 里的种群优化定位

种群优化算法不靠梯度下降,而是用一群虚拟个体在解空间里互相试探、迭代逼近较优参数。蝙蝠算法(BA)把每只蝙蝠映射为一个候选解,靠频率、响度和脉冲发射率三个状态量控制搜索的发散与收敛。 在 MT5 平台,这类算法常被塞进参数寻优流程,替代人工网格搜索。作者 Andrey Dik 于 2023-05-18 发布的示例帖累计阅读 1 643 次,说明社群对这类非传统优化器的实操需求并不小。 该系列分四节:概述、算法描述、测试结果、以及末节的工程落地。外汇与贵金属市场高杠杆、高波动,任何优化器给出的参数都只是历史样本上的概率较优,实盘须以小资金验证。

◍ 从蝙蝠回声定位到优化算法

蝙蝠是唯一具备真正翅膀的哺乳动物,现生种类超过 1300 种,除极地外几乎遍布全球。它们在黑暗中靠回声定位导航:发出高频短脉冲,声波撞到物体后反射回耳朵,借此判定空间与猎物位置。这种生物机制在 2010 年被 Yang 抽象成蝙蝠算法(BA),用人工蝙蝠作为搜索代理,模拟脉冲音量和发射频率来做全局优化。 元启发式算法大多取材自然或物理过程,核心是从一组可行解里挑出最符合目标函数的组合。传统特征优化在小规模问题上还行,碰到实际复杂场景基本失效,所以研究者转去抄自然界的作业。BA 属于现代种群算法,把声波参数变成可迭代的搜索变量,让多只“蝙蝠”在解空间里并发试探。 对外汇或贵金属交易者来说,这类算法的高风险在于过拟合:历史行情里调出的“最佳参数”在活盘可能迅速失效。想验证 BA 是否对你的品种有用,直接在 MT5 里写个简化版脉冲更新逻辑跑回测最实在。

「蝙蝠算法在MT5里的代理结构与参数骨架」

蝙蝠算法把每只蝙蝠当成解空间里无质量、无体积的粒子,用适应度值比大小挑出当前最优,再靠声波频率、速度、音量、脉冲率迭代逼近全局最优。标准实现要盯五个基本量:频率、音量、纹波、以及音量和纹波的比率;频率越大,单只蝙蝠越容易脱离群体历史位置去广域搜索,反之则黏在附近。 原文给出的可调参数范围值得直接抄进EA输入区:MIN_FREQ_P=0.0、MAX_FREQ_P=1.0、MIN_LOUDNESS_P=0.0、MAX_LOUDNESS_P=1.5、MIN_PULSE_P=0.0、MAX_PULSE_P=1.0,另有两个衰减系数 ALPHA_P=0.3、GAMMA_P=0.3。脉动频率随迭代上升、音量随迭代下降,这是贯穿优化全过程的主线。 每只“蝙蝠”的状态用结构体完整描述:position[]存历史最佳坐标,auxPosition[]存当前操作坐标,speed[]算速度矢量,frequency是脉冲频率,initPulseRate和pulseRate分别是初始与当前脉冲率,loudness是音量,fitness与fitnessBest记录当次与历史最优适应度。类 C_AO_BA 再包一层种群数组、边界 rangeMax/rangeMin、步长 rangeStep、全局最优 cB 与 fB,以及公开的 Init / Flight / Preparation 方法。 一个反直觉点是:音量按 alpha 逐代衰减,导致局部细化概率下降、全局搜索强度相对走弱。作者实测把迭代序数从脉冲频率非线性公式里解耦后,效率有轻微提升,说明 BA 默认约定并非不可动。 开 MT5 新建一个 include 把下面结构先编译过,是验证后续 Walk() 与 AproxBest() 逻辑的前提。

MQL5 / C++
class="kw">struct S_Bat
{
  class="type">class="kw">double position    [];
  class="type">class="kw">double auxPosition [];
  class="type">class="kw">double speed       [];
  class="type">class="kw">double frequency;
  class="type">class="kw">double initPulseRate;
  class="type">class="kw">double pulseRate;
  class="type">class="kw">double loudness;
  class="type">class="kw">double fitness;
  class="type">class="kw">double fitnessBest;
};

class C_AO_BA
{
  class="kw">public: S_Bat   bats       []; class=class="str">"cmt">//bats
  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">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: class="type">void    Init(const class="type">int     paramsP,
                         const class="type">int     batsNumberP,
                         const class="type">class="kw">double  min_FREQ_P,
                         const class="type">class="kw">double  max_FREQ_P,

蝙蝠算法类的接口与初始化骨架

这段声明把蝙蝠算法(BA)封装成了一个 C_AO_BA 类,对外只暴露 Flight(epoch) 和 Preparation() 两个 public 方法,其余游走、近似最优、接受新解全部藏在 private 里。 构造函数参数里 min_LOUDNESS_P、max_LOUDNESS_P、min_PULSE_P、max_PULSE_P、alpha_P、gamma_P 以及 maxIterP 共同界定了群智能搜索的边界与衰减律,调参时这几个区间直接决定收敛速度。 私有成员中 currentIteration 与 maxIter 跟踪代数,MIN_FREQ/MAX_FREQ 约束声波频率,ALPHA 与 GAMMA 分别控制响度与脉冲率演化;SeInDiSp、RNDfromCI、Scale 三个工具函数负责区间映射与随机扰动。 Init 方法接收 paramsP(待优化参数维度)、batsNumberP(蝙蝠数量)及上述频率、响度、脉冲的上下限,实例化后才能够跑 Preparation 与 Flight,否则类内部状态为空。 在 MT5 里把 batsNumberP 设到 30~50 区间通常能在 XAUUSD 的 M15 回测中兼顾耗时与稳定性,但具体表现随品种波动特性可能偏移,外汇与贵金属杠杆交易属高风险,须自行验证。

MQL5 / C++
const class="type">class="kw">double min_LOUDNESS_P,
const class="type">class="kw">double max_LOUDNESS_P,
const class="type">class="kw">double min_PULSE_P,
const class="type">class="kw">double max_PULSE_P,
const class="type">class="kw">double alpha_P,
const class="type">class="kw">double gamma_P,
const class="type">int    maxIterP);
  class="kw">public: class="type">void Flight(class="type">int epoch);
  class="kw">public: class="type">void Preparation();
class=class="str">"cmt">//============================================================================
  class="kw">private: class="type">void Walk(S_Bat &bat);
  class="kw">private: class="type">void AproxBest(S_Bat &bat, class="type">class="kw">double averageLoudness);
  class="kw">private: class="type">void AcceptNewSolutions(S_Bat &bat);
  class="kw">private: class="type">int   currentIteration;
  class="kw">private: class="type">int   maxIter;
  class="kw">private: class="type">class="kw">double MIN_FREQ;
  class="kw">private: class="type">class="kw">double MAX_FREQ;
  class="kw">private: class="type">class="kw">double MIN_LOUDNESS;
  class="kw">private: class="type">class="kw">double MAX_LOUDNESS;
  class="kw">private: class="type">class="kw">double MIN_PULSE;
  class="kw">private: class="type">class="kw">double MAX_PULSE;
  class="kw">private: class="type">class="kw">double ALPHA;
  class="kw">private: class="type">class="kw">double GAMMA;
  class="kw">private: class="type">int    params;
  class="kw">private: class="type">int    batsNumber;
  class="kw">private: class="type">bool   firstFlight;
  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">class="kw">double Scale(class="type">class="kw">double In, class="type">class="kw">double InMIN, class="type">class="kw">double InMAX, class="type">class="kw">double OutMIN, class="type">class="kw">double OutMAX,  class="type">bool revers);
};
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class="type">void C_AO_BA::Init(const class="type">int    paramsP,
                    const class="type">int    batsNumberP,
                    const class="type">class="kw">double min_FREQ_P,
                    const class="type">class="kw">double max_FREQ_P,
                    const class="type">class="kw">double min_LOUDNESS_P,
                    const class="type">class="kw">double max_LOUDNESS_P,

常见问题

它是一种种群优化算法,主要用来自动搜参数空间里的较优解,你可以把它当成替代网格搜索的自动调参思路,不必再手动一个个试。
频率控制个体搜索步长,响度随迭代衰减限制后期扰动,脉冲发射率决定何时做局部精细化;三者共同平衡全局探索和局部 exploitation。
小布可在品种页调用内置的 AIGC 诊断,按种群优化逻辑扫描你的参数组合并标记高概率区间,你只需导入策略即可看建议。
因为它用多个个体并行回声定位式更新位置,并靠频率随机化保持种群多样性,概率上更不易被困在窄谷。
常见骨架取 20~40 个个体;规模太小易早熟,太大拖慢收敛,建议先按 30 跑通再按需缩扩。