基于MQL5的自动化交易策略(第一部分):Profitunity系统(比尔·威廉姆斯的《交易混沌》)·进阶篇
🐊

基于MQL5的自动化交易策略(第一部分):Profitunity系统(比尔·威廉姆斯的《交易混沌》)·进阶篇

(2/3)· 接上篇概念铺垫,本篇把比尔·威廉姆斯的混沌指标拆成可运行代码与回测框架

含代码示例实战向 第 2/3 篇
很多交易者把分形和鳄鱼线当装饰画看,等到价格穿透嘴唇才慌忙追单。其实在MQL5里把AO与AC的穿越逻辑写成函数,信号会比肉眼早半根K线成型。这篇就带你把混沌系统的四个指标真正跑起来。

◍ 混沌交易系统的指标句柄预声明

Bill Williams 的 Trading Chaos 体系在 MT5 里落地,第一道坎不是信号逻辑,而是指标句柄的初始化顺序。Fractals、Alligator、AO、AC 四个核心指标必须各自拿到有效 handle,否则后续取值全是 INVALID_HANDLE 导致的空数组。 下面这段代码把四个句柄先统一赋成 INVALID_HANDLE,再用 iFractals / iAlligator 等函数向当前图表(_Symbol、_Period)申请真实句柄。Alligator 这里用的是 13/8/8/5/5/3 的 SMMA 中价参数组合,和原著默认设置一致。 初始化函数里只要任一句柄申请失败就 Print 报错并返回 INIT_FAILED,EA 不会偷偷带着残句柄跑。外汇与贵金属杠杆高,句柄失效若未被拦截,可能让策略在错误数据上出信号,实盘前务必在 MT5 策略测试器里确认四个指标均正常加载。 别把句柄当全局常量 句柄是运行时向图表申请的引用,切换品种或周期后旧 handle 会失效。把初始化写死在 OnInit 一次就不管,切换周期容易读不到数据,正确做法是周期变动时重新申请或做有效性检查。

MQL5 / C++
class="macro">#class="kw">property link      "https:class=class="str">"cmt">//forexalgo-trader.com"
class="macro">#class="kw">property description "class="num">1. PROFITUNITY(TRADING CHAOS BY BILL WILLIAMS)"
class="macro">#class="kw">property version   "class="num">1.00"
class="macro">#include <Trade/Trade.mqh>
CTrade obj_Trade;
class="type">int handle_Fractals = INVALID_HANDLE; class=class="str">"cmt">//--- Initialize fractals indicator handle with an invalid handle value
class="type">int handle_Alligator = INVALID_HANDLE; class=class="str">"cmt">//--- Initialize alligator indicator handle with an invalid handle value
class="type">int handle_AO = INVALID_HANDLE; class=class="str">"cmt">//--- Initialize Awesome Oscillator(AO) handle with an invalid handle value
class="type">int handle_AC = INVALID_HANDLE; class=class="str">"cmt">//--- Initialize Accelerator Oscillator(AC) handle with an invalid handle value

class="type">class="kw">double fractals_up[]; class=class="str">"cmt">//--- Array to store values for upward fractals
class="type">class="kw">double fractals_down[]; class=class="str">"cmt">//--- Array to store values for downward fractals
class="type">class="kw">double alligator_jaws[]; class=class="str">"cmt">//--- Array to store values for Alligator&class="macro">#x27;s Jaw line
class="type">class="kw">double alligator_teeth[]; class=class="str">"cmt">//--- Array to store values for Alligator&class="macro">#x27;s Teeth line
class="type">class="kw">double alligator_lips[]; class=class="str">"cmt">//--- Array to store values for Alligator&class="macro">#x27;s Lips line
class="type">class="kw">double ao_values[]; class=class="str">"cmt">//--- Array to store values of the Awesome Oscillator(AO)
class="type">class="kw">double ac_color[]; class=class="str">"cmt">//--- Array to store class="type">class="kw">color status of the Accelerator Oscillator(AC)
class="macro">#define AC_COLOR_UP class="num">0 class=class="str">"cmt">//--- Define constant for upward AC class="type">class="kw">color state
class="macro">#define AC_COLOR_DOWN class="num">1 class=class="str">"cmt">//--- Define constant for downward AC class="type">class="kw">color state

class="type">class="kw">double lastFractal_value = class="num">0.0; class=class="str">"cmt">//--- Variable to store the value of the last detected fractal
enum fractal_direction {FRACTAL_UP, FRACTAL_DOWN, FRACTAL_NEUTRAL}; class=class="str">"cmt">//--- Enum for fractal direction states
fractal_direction lastFractal_direction = FRACTAL_NEUTRAL; class=class="str">"cmt">//--- Variable to store the direction of the last fractal
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Expert initialization function                                     |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int OnInit(){
   class=class="str">"cmt">//---
   class=class="str">"cmt">//---
   class="kw">return(INIT_SUCCEEDED); class=class="str">"cmt">//--- Return successful initialization status
}
   handle_Fractals = iFractals(_Symbol,_Period); class=class="str">"cmt">//--- Initialize the fractals indicator handle
   if (handle_Fractals == INVALID_HANDLE){ class=class="str">"cmt">//--- Check if the fractals indicator failed to initialize
      Print("ERROR: UNABLE TO INITIALIZE THE FRACTALS INDICATOR. REVERTING NOW!"); class=class="str">"cmt">//--- Print error if fractals initialization failed
      class="kw">return (INIT_FAILED); class=class="str">"cmt">//--- Exit initialization with failed status
   }
   handle_Alligator = iAlligator(_Symbol,_Period,class="num">13,class="num">8,class="num">8,class="num">5,class="num">5,class="num">3,MODE_SMMA,PRICE_MEDIAN); class=class="str">"cmt">//--- Initialize the alligator indicator with specific settings
   if (handle_Alligator == INVALID_HANDLE){ class=class="str">"cmt">//--- Check if the alligator indicator failed to initialize
      Print("ERROR: UNABLE TO INITIALIZE THE ALLIGATOR INDICATOR. REVERTING NOW!"); class=class="str">"cmt">//--- Print error if alligator initialization failed
      class="kw">return (INIT_FAILED); class=class="str">"cmt">//--- Exit initialization with failed status
   }

把四大指标句柄挂上图表窗口

在 MT5 的 EA 初始化阶段,先拿指标句柄再往图表上挂,是避免运行时报空引用的第一步。下面这段直接在 OnInit 里把 AO、AC 以及主图的 Fractals、Alligator 全部接好,并逐个判断 INVALID_HANDLE,任一失败就 return(INIT_FAILED) 让 EA 停止加载。 注意 ChartIndicatorAdd 的第二个参数:主图窗口编号是 0,AO 被塞进子窗口 1,AC 进子窗口 2。若你手动拖过指标导致子窗口序号变动,这段代码可能挂错位置,需要在 MT5 里先清空图表再测。 最后用 ArraySetAsSeries 把 fractals_up、fractals_down、alligator_jaws 等数组设为时间序列(true),保证 buffer[0] 对应最新 K 线。外汇与贵金属杠杆高,指标初始化失败若没拦住,后续取 buffer 会直接崩策略,务必在回测前确认四个句柄 ID 都正常打印。

MQL5 / C++
  handle_AO = iAO(_Symbol,_Period); class=class="str">"cmt">//--- Initialize the Awesome Oscillator(AO) indicator handle
  if (handle_AO == INVALID_HANDLE){ class=class="str">"cmt">//--- Check if AO indicator failed to initialize
      Print("ERROR: UNABLE TO INITIALIZE THE AO INDICATOR. REVERTING NOW!"); class=class="str">"cmt">//--- Print error if AO initialization failed
      class="kw">return (INIT_FAILED); class=class="str">"cmt">//--- Exit initialization with failed status
  }
  handle_AC = iAC(_Symbol,_Period); class=class="str">"cmt">//--- Initialize the Accelerator Oscillator(AC) indicator handle
  if (handle_AC == INVALID_HANDLE){ class=class="str">"cmt">//--- Check if AC indicator failed to initialize
      Print("ERROR: UNABLE TO INITIALIZE THE AC INDICATOR. REVERTING NOW!"); class=class="str">"cmt">//--- Print error if AC initialization failed
      class="kw">return (INIT_FAILED); class=class="str">"cmt">//--- Exit initialization with failed status
  }
  if (!ChartIndicatorAdd(class="num">0,class="num">0,handle_Fractals)){ class=class="str">"cmt">//--- Add the fractals indicator to the main chart window and check for success
      Print("ERROR: UNABLE TO ADD THE FRACTALS INDICATOR TO CHART. REVERTING NOW!"); class=class="str">"cmt">//--- Print error if fractals addition failed
      class="kw">return (INIT_FAILED); class=class="str">"cmt">//--- Exit initialization with failed status
  }
  if (!ChartIndicatorAdd(class="num">0,class="num">0,handle_Alligator)){ class=class="str">"cmt">//--- Add the alligator indicator to the main chart window and check for success
      Print("ERROR: UNABLE TO ADD THE ALLIGATOR INDICATOR TO CHART. REVERTING NOW!"); class=class="str">"cmt">//--- Print error if alligator addition failed
      class="kw">return (INIT_FAILED); class=class="str">"cmt">//--- Exit initialization with failed status
  }
  if (!ChartIndicatorAdd(class="num">0,class="num">1,handle_AO)){ class=class="str">"cmt">//--- Add the AO indicator to a separate subwindow and check for success
      Print("ERROR: UNABLE TO ADD THE AO INDICATOR TO CHART. REVERTING NOW!"); class=class="str">"cmt">//--- Print error if AO addition failed
      class="kw">return (INIT_FAILED); class=class="str">"cmt">//--- Exit initialization with failed status
  }
  if (!ChartIndicatorAdd(class="num">0,class="num">2,handle_AC)){ class=class="str">"cmt">//--- Add the AC indicator to a separate subwindow and check for success
      Print("ERROR: UNABLE TO ADD THE AC INDICATOR TO CHART. REVERTING NOW!"); class=class="str">"cmt">//--- Print error if AC addition failed
      class="kw">return (INIT_FAILED); class=class="str">"cmt">//--- Exit initialization with failed status
  }

  Print("HANDLE ID FRACTALS = ",handle_Fractals); class=class="str">"cmt">//--- Print the handle ID for fractals
  Print("HANDLE ID ALLIGATOR = ",handle_Alligator); class=class="str">"cmt">//--- Print the handle ID for alligator
  Print("HANDLE ID AO = ",handle_AO); class=class="str">"cmt">//--- Print the handle ID for AO
  Print("HANDLE ID AC = ",handle_AC); class=class="str">"cmt">//--- Print the handle ID for AC
  ArraySetAsSeries(fractals_up,true); class=class="str">"cmt">//--- Set the fractals_up array as a time series
  ArraySetAsSeries(fractals_down,true); class=class="str">"cmt">//--- Set the fractals_down array as a time series

  ArraySetAsSeries(alligator_jaws,true); class=class="str">"cmt">//--- Set the alligator_jaws array as a time series

「把鳄鱼与震荡指标塞进时间序列」

在 MT5 的 EA 初始化阶段,先把几个数组按时间序列排好,是后续取「最新值」不出错的前提。下面四行把 alligator_teeth、alligator_lips、ao_values、ac_color 全部设为 true,意味着索引 0 永远对应当前 K 线,回看历史只要加下标即可。 ArraySetAsSeries(alligator_teeth,true); // 将牙齿线数组设为时间序列 ArraySetAsSeries(alligator_lips,true); // 将嘴唇线数组设为时间序列 ArraySetAsSeries(ao_values,true); // 将 AO 数值数组设为时间序列 ArraySetAsSeries(ac_color,true); // 将 AC 颜色数组设为时间序列 OnInit 里依次用 iFractals、iAlligator、iAO、iAC 拿句柄,参数上鳄鱼用的是 (13,8,8,5,5,3) 这组经典设置,平滑方式 MODE_SMMA、价格 PRICE_MEDIAN。任何一个句柄返回 INVALID_HANDLE 就 Print 报错并 return INIT_FAILED,EA 不会带着残废指标硬跑。 外汇与贵金属杠杆高,指标初始化失败若被忽略,可能让策略在错误数据上开仓,实盘前务必在策略测试器里确认四个句柄都正常返回。最后用 ChartIndicatorAdd(0,0,handle_Fractals) 把分形画到主图,返回 false 同样走 INIT_FAILED,避免主图缺了分形导致形态识别逻辑失效。

MQL5 / C++
ArraySetAsSeries(alligator_teeth,true); class=class="str">"cmt">//--- Set the alligator_teeth array as a time series
ArraySetAsSeries(alligator_lips,true);   class=class="str">"cmt">//--- Set the alligator_lips array as a time series

ArraySetAsSeries(ao_values,true);       class=class="str">"cmt">//--- Set the ao_values array as a time series

ArraySetAsSeries(ac_color,true);        class=class="str">"cmt">//--- Set the ac_color array as a time series

class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Expert initialization function                                     |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int OnInit(){
  class=class="str">"cmt">//---

  handle_Fractals = iFractals(_Symbol,_Period); class=class="str">"cmt">//--- Initialize the fractals indicator handle
  if (handle_Fractals == INVALID_HANDLE){ class=class="str">"cmt">//--- Check if the fractals indicator failed to initialize
    Print("ERROR: UNABLE TO INITIALIZE THE FRACTALS INDICATOR. REVERTING NOW!"); class=class="str">"cmt">//--- Print error if fractals initialization failed
    class="kw">return (INIT_FAILED); class=class="str">"cmt">//--- Exit initialization with failed status
  }
  handle_Alligator = iAlligator(_Symbol,_Period,class="num">13,class="num">8,class="num">8,class="num">5,class="num">5,class="num">3,MODE_SMMA,PRICE_MEDIAN); class=class="str">"cmt">//--- Initialize the alligator indicator with specific settings
  if (handle_Alligator == INVALID_HANDLE){ class=class="str">"cmt">//--- Check if the alligator indicator failed to initialize
    Print("ERROR: UNABLE TO INITIALIZE THE ALLIGATOR INDICATOR. REVERTING NOW!"); class=class="str">"cmt">//--- Print error if alligator initialization failed
    class="kw">return (INIT_FAILED); class=class="str">"cmt">//--- Exit initialization with failed status
  }
  handle_AO = iAO(_Symbol,_Period); class=class="str">"cmt">//--- Initialize the Awesome Oscillator(AO) indicator handle
  if (handle_AO == INVALID_HANDLE){ class=class="str">"cmt">//--- Check if AO indicator failed to initialize
    Print("ERROR: UNABLE TO INITIALIZE THE AO INDICATOR. REVERTING NOW!"); class=class="str">"cmt">//--- Print error if AO initialization failed
    class="kw">return (INIT_FAILED); class=class="str">"cmt">//--- Exit initialization with failed status
  }
  handle_AC = iAC(_Symbol,_Period); class=class="str">"cmt">//--- Initialize the Accelerator Oscillator(AC) indicator handle
  if (handle_AC == INVALID_HANDLE){ class=class="str">"cmt">//--- Check if AC indicator failed to initialize
    Print("ERROR: UNABLE TO INITIALIZE THE AC INDICATOR. REVERTING NOW!"); class=class="str">"cmt">//--- Print error if AC initialization failed
    class="kw">return (INIT_FAILED); class=class="str">"cmt">//--- Exit initialization with failed status
  }

  if (!ChartIndicatorAdd(class="num">0,class="num">0,handle_Fractals)){ class=class="str">"cmt">//--- Add the fractals indicator to the main chart window and check for success
    Print("ERROR: UNABLE TO ADD THE FRACTALS INDICATOR TO CHART. REVERTING NOW!"); class=class="str">"cmt">//--- Print error if fractals addition failed
    class="kw">return (INIT_FAILED); class=class="str">"cmt">//--- Exit initialization with failed status
  }

◍ 把鳄鱼AOAC挂上图表并初始化序列

EA 初始化阶段要把比尔·威廉姆斯的几个指标句柄绑到图表上,主窗口放鳄鱼(子窗口 0),AO 放子窗口 1,AC 放子窗口 2。任何一次 ChartIndicatorAdd 返回 false 都应立刻 Print 错误并 return INIT_FAILED,否则后续 CopyBuffer 会拿到空句柄。 下面这段是实际的挂载与兜底写法,三个指标分开判断、互不牵连: if (!ChartIndicatorAdd(0,0,handle_Alligator)){ Print("ERROR: UNABLE TO ADD THE ALLIGATOR INDICATOR TO CHART. REVERTING NOW!"); return (INIT_FAILED); } if (!ChartIndicatorAdd(0,1,handle_AO)){ Print("ERROR: UNABLE TO ADD THE AO INDICATOR TO CHART. REVERTING NOW!"); return (INIT_FAILED); } if (!ChartIndicatorAdd(0,2,handle_AC)){ Print("ERROR: UNABLE TO ADD THE AC INDICATOR TO CHART. REVERTING NOW!"); return (INIT_FAILED); } 挂载成功后把四个句柄 ID 用 Print 打出来,方便在 MT5 Experts 日志里核对 handle_Fractals / handle_Alligator / handle_AO / handle_AC 是否非零。外汇与贵金属波动剧烈,指标句柄失效可能导致信号误判,实盘前务必在策略测试器跑一遍初始化日志。 所有用于计算的数组都要用 ArraySetAsSeries(...,true) 设成时间序列,否则 fractals_up、alligator_jaws、ao_values 这类数组下标 0 会指向最旧一根 K 线,CopyBuffer 取到的就不是当前柱。初始化末尾 return INIT_SUCCEEDED 即代表挂载与序列设置完成。 OnTick 里先把分形上沿数据拉进来,从偏移 2 开始取 3 根(跳过当前未闭合的两根): if (CopyBuffer(handle_Fractals,0,2,3,fractals_up) < 3){ Print("ERROR: UNABLE TO COPY THE FRACTALS UP DATA. REVERTING!"); return; } 少于 3 个值说明复制失败,直接 return 不往下走,避免空数组参与条件判断。

MQL5 / C++
if (!ChartIndicatorAdd(class="num">0,class="num">0,handle_Alligator)){
   Print("ERROR: UNABLE TO ADD THE ALLIGATOR INDICATOR TO CHART. REVERTING NOW!");
   class="kw">return (INIT_FAILED);
}
if (!ChartIndicatorAdd(class="num">0,class="num">1,handle_AO)){
   Print("ERROR: UNABLE TO ADD THE AO INDICATOR TO CHART. REVERTING NOW!");
   class="kw">return (INIT_FAILED);
}
if (!ChartIndicatorAdd(class="num">0,class="num">2,handle_AC)){
   Print("ERROR: UNABLE TO ADD THE AC INDICATOR TO CHART. REVERTING NOW!");
   class="kw">return (INIT_FAILED);
}

Print("HANDLE ID FRACTALS = ",handle_Fractals);
Print("HANDLE ID ALLIGATOR = ",handle_Alligator);
Print("HANDLE ID AO = ",handle_AO);
Print("HANDLE ID AC = ",handle_AC);
ArraySetAsSeries(fractals_up,true);
ArraySetAsSeries(fractals_down,true);
ArraySetAsSeries(alligator_jaws,true);
ArraySetAsSeries(alligator_teeth,true);
ArraySetAsSeries(alligator_lips,true);
ArraySetAsSeries(ao_values,true);
ArraySetAsSeries(ac_color,true);

class="kw">return(INIT_SUCCEEDED);
}
class="type">void OnTick(){
}
if (CopyBuffer(handle_Fractals,class="num">0,class="num">2,class="num">3,fractals_up) < class="num">3){
   Print("ERROR: UNABLE TO COPY THE FRACTALS UP DATA. REVERTING!");
   class="kw">return;
}

把鳄鱼与分形数据搬进缓冲区再判新K

在 MT5 自定义指标里,先把分形、鳄鱼三线和 AO、AC 的缓冲区一次性拉满,是后续信号判断的前提。下面这段逻辑对每个 CopyBuffer 都做了小于 3 的返回值校验——也就是说,若任意一项连最近 3 根 K 的数据都拷不下来,直接打印错误并 return,避免拿空数组去算信号。 向下分形取的是缓冲区索引 1、起始位置 2、要 3 个值;鳄鱼颚线(0)、齿线(1)、唇线(2)都从当前柱(0)开始取 3 个;AO 取 0 号缓冲 3 个;AC 取 1 号缓冲(颜色数据)3 个。实际跑的时候,若你切换到了 tick 数据少的品种,这类拷贝失败会在日志里直接看到 REVERTING 提示。 新 K 线判定用了一个静态变量 prevBars 存上次柱数,iBars(_Symbol,_Period) 拿到当前柱数,不等就说明出了新 bar。这个写法比用时间比对省事,但注意它只认「柱数变化」,若历史回拔导致柱数回退不会触发。 最后用 index_fractal=0 去读最新一根分形:向上分形不为 EMPTY_VALUE 就记 lastFractal_value 并标 FRACTAL_UP,向下同理标 FRACTAL_DOWN。外汇与贵金属杠杆高,分形假突破频繁,这个方向标记只作概率参考,实盘须结合鳄鱼开口状态过滤。

MQL5 / C++
  if (CopyBuffer(handle_Fractals,class="num">1,class="num">2,class="num">3,fractals_down) < class="num">3){ class=class="str">"cmt">//--- Copy downward fractals data; check if copying is successful
        Print("ERROR: UNABLE TO COPY THE FRACTALS DOWN DATA. REVERTING!"); class=class="str">"cmt">//--- Print error message if failed
        class="kw">return;
  }
  if (CopyBuffer(handle_Alligator,class="num">0,class="num">0,class="num">3,alligator_jaws) < class="num">3){ class=class="str">"cmt">//--- Copy Alligator&class="macro">#x27;s Jaw data
        Print("ERROR: UNABLE TO COPY THE ALLIGATOR JAWS DATA. REVERTING!");
        class="kw">return;
  }
  if (CopyBuffer(handle_Alligator,class="num">1,class="num">0,class="num">3,alligator_teeth) < class="num">3){ class=class="str">"cmt">//--- Copy Alligator&class="macro">#x27;s Teeth data
        Print("ERROR: UNABLE TO COPY THE ALLIGATOR TEETH DATA. REVERTING!");
        class="kw">return;
  }
  if (CopyBuffer(handle_Alligator,class="num">2,class="num">0,class="num">3,alligator_lips) < class="num">3){ class=class="str">"cmt">//--- Copy Alligator&class="macro">#x27;s Lips data
        Print("ERROR: UNABLE TO COPY THE ALLIGATOR LIPS DATA. REVERTING!");
        class="kw">return;
  }
  if (CopyBuffer(handle_AO,class="num">0,class="num">0,class="num">3,ao_values) < class="num">3){ class=class="str">"cmt">//--- Copy AO data
        Print("ERROR: UNABLE TO COPY THE AO DATA. REVERTING!");
        class="kw">return;
  }
  if (CopyBuffer(handle_AC,class="num">1,class="num">0,class="num">3,ac_color) < class="num">3){ class=class="str">"cmt">//--- Copy AC class="type">class="kw">color data
        Print("ERROR: UNABLE TO COPY THE AC COLOR DATA. REVERTING!");
        class="kw">return;
  }
if (isNewBar()){ class=class="str">"cmt">//--- Check if a new bar has formed
class=class="str">"cmt">//---
}
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|  IS NEW BAR FUNCTION                                            |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">bool isNewBar(){
   class="kw">static class="type">int prevBars = class="num">0; class=class="str">"cmt">//--- Store previous bar count
   class="type">int currBars = iBars(_Symbol,_Period); class=class="str">"cmt">//--- Get current bar count for the symbol and period
   if (prevBars == currBars) class="kw">return (false); class=class="str">"cmt">//--- If bars haven&class="macro">#x27;t changed, class="kw">return false
   prevBars = currBars; class=class="str">"cmt">//--- Update previous bar count
   class="kw">return (true); class=class="str">"cmt">//--- Return true if new bar is detected
}
const class="type">int index_fractal = class="num">0;
if (fractals_up[index_fractal] != EMPTY_VALUE){ class=class="str">"cmt">//--- Detect upward fractal presence
   lastFractal_value = fractals_up[index_fractal]; class=class="str">"cmt">//--- Store fractal value
   lastFractal_direction = FRACTAL_UP; class=class="str">"cmt">//--- Set last fractal direction as up
}
if (fractals_down[index_fractal] != EMPTY_VALUE){ class=class="str">"cmt">//--- Detect downward fractal presence
   lastFractal_value = fractals_down[index_fractal];
   lastFractal_direction = FRACTAL_DOWN;
}
让小布替你跑这套诊断
这些指标叠加与信号触发逻辑小布盯盘的AIGC已内置,打开对应品种页即可看到分形突破与鳄鱼张嘴的实时标注,你只需判断概率优势。

常见问题

默认5根K线包裹的模式过滤了更多噪音,但在MQL5中若用于高频纪律执行,周期2配合鳄鱼分离确认可减少滞后,具体看品种波动率。
当颚齿唇收敛且AO在零轴附近摆动时,系统本身倾向空仓;代码层可加入AC柱体连续两根同向才发单的约束来压低回撤概率。
可以,小布的品种页已集成混沌指标组与分形标记,不需要你自己编译ea也能看到同类信号提示,适合先做人工复核。
一般取AC当前柱大于前一根且AO同为绿柱作为加速初段;写进OnTick里用数组偏移读取即可,注意不同时间帧数值缩放差异。
XAUUSD在伦敦段滑点可能到15点,MQL5测试器用真实tick并设对应点差模型,结果才具备参考性,外汇贵金属属高风险品类。