基于分形的算法(FBA)(基础篇)
📘

基于分形的算法(FBA)(基础篇)

第 1/3 篇

◍ 分形逻辑怎么塞进 MT5 策略

基于分形的算法(FBA)把比尔·威廉姆斯的分形定义当成信号触发器:当左右各两根 K 线的高点都被中间 K 线超越,就记一个顶分形;低点反之记底分形。这类结构不预测方向,只标定局部极值,适合做突破或均值回归的锚点。 MT5 里用 MQL5 写分形检测,核心是先抓最高/最低价再比对邻域。下面这段在每根新 K 线收完时扫描最近 5 根,命中就返回分形类型。 外汇与贵金属杠杆高,分形假突破概率不低,实盘前务必在策略测试器用真实点差回测 2020—2025 年数据,观察回撤是否可接受。

MQL5 / C++
class="type">int FractalType(class="type">int shift=class="num">1)
{
   class="type">class="kw">double midHigh = High[iHighest(NULL,class="num">0,MODE_HIGH,class="num">5,shift)];
   class="type">class="kw">double midLow  = Low[iLowest(NULL,class="num">0,MODE_LOW,class="num">5,shift)];
   if(midHigh==High[shift+class="num">2] && midHigh>High[shift+class="num">1] && midHigh>High[shift+class="num">3] && midHigh>High[shift] && midHigh>High[shift+class="num">4])
      class="kw">return class="num">1; class=class="str">"cmt">// 顶分形
   if(midLow==Low[shift+class="num">2] && midLow<Low[shift+class="num">1] && midLow<Low[shift+class="num">3] && midLow<Low[shift] && midLow<Low[shift+class="num">4])
      class="kw">return -class="num">1; class=class="str">"cmt">// 底分形
   class="kw">return class="num">0;
}

分形搜索怎么替你省下盲猜时间

元启发式算法在复杂优化里能压住计算量,靠的是在可接受时间内给出可行解而不是穷举。遗传、粒子群、差分进化、蚁群这些老面孔之前已经拆过,这一篇换一条更冷的路:分形。

  • 年 Marjan Kaedi 提出的 FBA(Fractal-Based Algorithm)把分形的自相似性直接当成搜索逻辑用。它不靠随机扰动硬撞,而是按有前景解在子空间里的分布密度,判断哪块区域值得细挖。

具体跑起来就是反复切分搜索空间:每一轮把当前空间拆成子空间,密度高的那块留下来继续切,密度低的丢掉。迭代下去会自然长出一个朝最优解收敛的自相似结构,全局勘探和局部精修在同一套规则里完成。 外汇与贵金属参数优化属高风险场景,FBA 只是缩小搜索范围的工具,不保证找到全局最优;开 MT5 用它跑 EA 参数前,先用标准测试函数看收敛曲线再上实盘逻辑。

「分形搜索怎么在 MT5 里落地」

把解空间当棋盘,先均匀撒一批随机点测适应度,留最优 60% 当「有前景点」,再统计它们落在哪些方格,取排名前 30% 的方格继续切细——这就是 FBA 的骨架。大部分新点往这些格子灌,留一小撮做随机游走防漏检,迭代下去自然长出分形层级。 C_AO_FBA 类直接继承通用基类 C_AO,构造函数收种群规模、P1/P2/P3 占比和每维分段数;SetParams 允许跑途中改参数。内部结构体 S_Subspace 记每个子空间的上下界、前景值、层级和父空间指针,所有细分、排名、融合都绕着它转。 MutatePoints 有个坑值得记:原版对坐标加高斯噪声,实测和随机搜索几乎没差,代码已注释掉,换成幂律分布改坐标,多样性才真正起来。GenerateNewPopulation 按子空间前景评分占比分配新点,评分和小于 0.0001 时强行给每格 1.0 保底,确保总点数严格等于 popSize。 下面这段是类头最简骨架,看得出命名和继承关系,复制进 MT5 就能接着写细分逻辑。

MQL5 / C++
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class C_AO_FBA : class="kw">public C_AO
{
  class="kw">public: class=class="str">"cmt">//--------------------------------------------------------------------
  ~C_AO_FBA() { }
  C_AO_FBA()
  {
    ao_name = "FBA";

◍ 把分形算法参数塞进优化器结构体

在 MT5 自带优化框架下接一套分形算法,第一步是把算法超参做成可序列化的字段。下面这段声明把种群规模、三类比例和维度切分数直接写进类成员,并用 ArrayResize 开出一个长度为 5 的 params 数组承载它们。 popSize=50 表示每次迭代保留 50 个候选解;P1=60 意味前 60% 的点被判为「有希望点」进入下一代;P2=30 控制 30% 的子空间被标记为潜力空间;P3=0.8 给 80% 的点施加随机扰动避免早熟;m_value=10 则是每个维度切 10 段做离散化搜索。 SetParams 负责把 params 数组回灌给成员变量,注意 P3 是 double 不做强转,其余四个全转 int。Init 接口暴露了 rangeMinP/rangeMaxP/rangeStepP 三组边界与步长,外加 epochsP 默认 0 由调用方决定迭代轮数。 结构体 S_Subspace 是私有的搜索空间单元:min/max 数组框住子空间边界,promisingRank 存归一化潜力值,isPromising 打标,parentIndex 指回父空间(-1 即根空间)。开 MT5 把这套声明贴进 EA 头文件,能直接跑通参数注入。

MQL5 / C++
ao_desc = "Fractal-Based Algorithm";
ao_link = "[MQL5官方文档]
popSize = class="num">50;   class=class="str">"cmt">// population size
P1      = class="num">60;   class=class="str">"cmt">// percentage of promising points
P2      = class="num">30;   class=class="str">"cmt">// percentage of promising subspaces
P3      = class="num">0.8; class=class="str">"cmt">// percentage of points for random modification
m_value = class="num">10;   class=class="str">"cmt">// number of intervals to split each dimension into
ArrayResize(params, class="num">5);
params [class="num">0].name = "popSize"; params [class="num">0].val = popSize;
params [class="num">1].name = "P1";      params [class="num">1].val = P1;
params [class="num">2].name = "P2";      params [class="num">2].val = P2;
params [class="num">3].name = "P3";      params [class="num">3].val = P3;
params [class="num">4].name = "m_value"; params [class="num">4].val = m_value;
}
class="type">void SetParams()
{
  popSize = (class="type">int)params [class="num">0].val;
  P1      = (class="type">int)params [class="num">1].val;
  P2      = (class="type">int)params [class="num">2].val;
  P3      =      params [class="num">3].val;
  m_value = (class="type">int)params [class="num">4].val;
}
class="type">bool Init(class="kw">const class="type">class="kw">double &rangeMinP [],  class=class="str">"cmt">// minimum values
                    class="kw">const class="type">class="kw">double &rangeMaxP [],  class=class="str">"cmt">// maximum values
                    class="kw">const class="type">class="kw">double &rangeStepP [],  class=class="str">"cmt">// step change
                    class="kw">const class="type">int     epochsP = class="num">0);  class=class="str">"cmt">// number of epochs
class="type">void Moving();
class="type">void Revision();
class=class="str">"cmt">//----------------------------------------------------------------------------
class="type">int     P1;           class=class="str">"cmt">// percentage of promising points
class="type">int     P2;           class=class="str">"cmt">// percentage of promising subspaces
class="type">class="kw">double  P3;           class=class="str">"cmt">// share of points for random modification
class="type">int     m_value;      class=class="str">"cmt">// number of intervals to split each dimension into
class="kw">private: class=class="str">"cmt">//-------------------------------------------------------------------
class=class="str">"cmt">// Structure for representing a subspace
class="kw">struct S_Subspace
{
    class="type">class="kw">double min [];          class=class="str">"cmt">// minimal boundaries of the subspace
    class="type">class="kw">double max [];          class=class="str">"cmt">// maximum boundaries of the subspace
    class="type">class="kw">double promisingRank;   class=class="str">"cmt">// potential rank(normalized value)
    class="type">bool   isPromising;     class=class="str">"cmt">// flag of potential
    class="type">int    parentIndex;     class=class="str">"cmt">// index of the parent subspace(-class="num">1 for root ones)
}

子空间结构体与优化器初始化落点

上面这段把 FBA 优化器的子空间骨架和对外初始化入口摊开了。S_Subspace 里的 level 字段标记层级,原始搜索空间为 0,往下细分每深一层数值加 1;Init(int coords) 负责按坐标维度扩出 min/max 边界数组,并把 promisingRank 置 0.0、isPromising 置 false、parentIndex 置 -1,相当于每块子空间出生即「未评估」状态。 紧随其后的 subspaces 数组和那一串辅助方法(IsPointInSubspace、DivideSubspace、IdentifyPromisingPoints 等)构成了空间递归切分与排序的主链路;其中 SortByFitness 默认 ascending=false,意味着适应度越高排得越靠前,QuickSort/Partition 是它背后的裸写快排,没调标准库。 C_AO_FBA::Init 是实盘里真正会调用的入口:它先跑 StandardInit 校验区间与步长,再调 CreateInitialSpacePartitioning() 把整段参数空间切成初始子空间并返回 true。你在 MT5 里接这套逻辑时,只需保证 rangeMinP/rangeMaxP/rangeStepP 三个数组等长,优化器便会在第 0 个 epoch 前完成首轮空间划分,后续迭代才有「 promising 子空间」可言。外汇与贵金属参数寻优属高风险操作,回测结论仅代表历史样本倾向,实盘可能失效。

MQL5 / C++
  class="type">int    level;       class=class="str">"cmt">// level in hierarchy(class="num">0 for original space)
  class="type">void Init(class="type">int coords)
  {
    ArrayResize(min, coords);
    ArrayResize(max, coords);
    promisingRank = class="num">0.0;
    isPromising   = false;
    parentIndex   = -class="num">1;
    level         = class="num">0;
  }
};
S_Subspace subspaces     []; class=class="str">"cmt">// array of subspaces
class=class="str">"cmt">// Auxiliary methods
class="type">bool   IsPointInSubspace(class="kw">const class="type">class="kw">double &point [], class="kw">const S_Subspace &subspace);
class="type">void   CreateInitialSpacePartitioning();
class="type">void   DivideSubspace(class="type">int subspaceIndex);
class="type">void   IdentifyPromisingPoints(class="type">int &promisingIndices []);
class="type">void   CalculateSubspaceRanks(class="kw">const class="type">int &promisingIndices []);
class="type">void   SelectPromisingSubspaces();
class="type">void   DividePromisingSubspaces();
class="type">void   GenerateNewPopulation();
class="type">void   MutatePoints();
class="type">void   SortByFitness(class="type">class="kw">double &values [], class="type">int &indices [], class="type">int size, class="type">bool ascending = false);
class="type">void   QuickSort(class="type">class="kw">double &values [], class="type">int &indices [], class="type">int low, class="type">int high, class="type">bool ascending);
class="type">int    Partition(class="type">class="kw">double &values [], class="type">int &indices [], class="type">int low, class="type">int high, class="type">bool ascending);
};
class="type">bool C_AO_FBA::Init(class="kw">const class="type">class="kw">double &rangeMinP  [],  class=class="str">"cmt">// minimum values
                     class="kw">const class="type">class="kw">double &rangeMaxP  [],  class=class="str">"cmt">// maximum values
                     class="kw">const class="type">class="kw">double &rangeStepP [],  class=class="str">"cmt">// step change
                     class="kw">const class="type">int     epochsP = class="num">0)    class=class="str">"cmt">// number of epochs
{
  if (!StandardInit(rangeMinP, rangeMaxP, rangeStepP)) class="kw">return false;
  CreateInitialSpacePartitioning();
  class="kw">return true;
}

常见问题

用分形算法自动标记最近 N 根 K 线的局部极值,只在分形点附近挂单或观察,避免全图表盲猜,外汇贵金属波动大需严控仓位。
把历史区间交给分形搜索扫一遍,几秒列出所有潜在转折位,比手动拖趋势线快数十倍,但信号仅作概率参考。
小布可自动对打开的品种做分形诊断并标出关键位,你直接看结论就行,把重复劳动交给小布,你专注决策。
在优化器初始化时把分形周期、容差等写进对应子空间结构体,初始化落点对齐后回测才能正常遍历参数组合。
会导致参数越界或优化器跳过该维度,回测结果失真,建议初始化时打印落点值确认边界无误。