您应当知道的 MQL5 向导技术(第 56 部分):比尔·威廉姆斯(Bill Williams)分形·综合运用
🧩

您应当知道的 MQL5 向导技术(第 56 部分):比尔·威廉姆斯(Bill Williams)分形·综合运用

(3/3)·单看一个分形信号常被假突破骗线,本篇把 5 类形态拼成可跑的向导逻辑

含代码示例 第 3/3 篇

很多交易者把分形当成孤立的转折箭头,看到信号就冲,结果在震荡里反复止损。比尔·威廉姆斯分形真正有价值的是形态之间的关系——连续同向、缝隙、突破、与更大时间帧的印证。这一篇我们把前面铺垫的概念收拢成可落地的 MQL5 向导组合。

「分形卡在缺口边上的多空信号」

价格缝隙(缺口)附近出现分形,是价格行为里值得盯的位置。看涨情形下,低位看涨分形贴近缝隙,往往发生在高波动或新闻驱动行情中,此时缝隙更像一层支撑;若缺口被回填或守住,上行概率倾向放大。看跌则反过来,高位看跌分形贴在缝隙上沿,缝隙成了阻力,卖方在那儿防守,价格若再向下破,跌势可能延续。 这套逻辑在 MQL5 里实现得很轻量,核心只关心缺口与分形的相对位置,和形态-6 的写法接近。我们跑过 USDJPY 的 2023 年 H4 前瞻漫游测试:缺口与分形突破重合时,价格走势通常被放大,且这种重合在新闻事件段更频繁。外汇与贵金属属高风险品种,信号仅作概率参考,实盘须自验。 下面这段是判定形态-8 的函数,逐行拆一下: // 函数入口,按持仓方向 T 分流多空判定 bool CSignalFractals::IsPattern_8(ENUM_POSITION_TYPE T) // 买方向:X()+2 处有看涨分形(返回值非 0)才继续 if(T == POSITION_TYPE_BUY && FractalLow(X() + 2) != 0.0) // 前一根低点高于分形位、当前收盘≥分形位,视为缺口支撑生效 if(Low(X() + 1) > High(X() + 2) && Close(X()) >= High(X() + 2)) // 满足条件直接返回 true return(true); // 卖方向对称:X()+2 有看跌分形 else if(T == POSITION_TYPE_SELL && FractalHigh(X() + 2) != 0.0) // 前一根高点低于分形位、当前收盘≤分形位,阻力成立 if(High(X() + 1) < Low(X() + 2) && Close(X()) <= Low(X() + 2)) // 返回 true 锁定看跌 return(true); // 其余情况不通不过 return(false); 开 MT5 把这段代码塞进你的分形信号类,调 X() 的偏移窗口,能直接看 USDJPY H4 上这类重合点的分布密度。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Check for Pattern class="num">8.                                                        |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">bool CSignalFractals::IsPattern_8(class="type">ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY && FractalLow(X() + class="num">2) != class="num">0.0)
   {  if(Low(X() + class="num">1) > High(X() + class="num">2) && Close(X()) >= High(X() + class="num">2))
      {  class="kw">return(true);
      }
   }
   else if(T == POSITION_TYPE_SELL && FractalHigh(X() + class="num">2) != class="num">0.0)
   {  if(High(X() + class="num">1) < Low(X() + class="num">2) && Close(X()) <= Low(X() + class="num">2))
      {  class="kw">return(true);
      }
   }
   class="kw">return(false);
}

◍ 分形碰上斐波那契级别的双重确认

低位分形若与关键斐波那契回撤位重合,支撑区强度会被明显加固,价格维持该区域时倾向出现反弹或趋势延续的可能;高位分形叠加密集斐波那契阻力,则价格难以突破并向下反转时看跌信号倾向确认。外汇与贵金属杠杆高,这类重合仅作区域确认,不等于方向必现。 自动化里最别扭的就是「画」斐波那契:手工一眼看出的关键位,机器得靠函数采样。下面 Is_Fibo_Level() 取过去三个月窗口(_size = 3*月秒/当前周期秒),用最高价向量 _h 与最低价向量 _l 算区间幅度 _r,再以 ATR(ind) 作容差带,判断收盘价是否落在 0、0.236、0.382、0.5、0.618 及顶部附近。 //+------------------------------------------------------------------+

//Check for Pattern 9.

//+------------------------------------------------------------------+ bool CSignalFractals::IsPattern_9(ENUM_POSITION_TYPE T) { if(T == POSITION_TYPE_BUY && FractalLow(X()) != 0.0) { if(Is_Fibo_Level(X())) { return(true); } } else if(T == POSITION_TYPE_SELL && FractalHigh(X()) != 0.0) { if(Is_Fibo_Level(X())) { return(true); } } return(false); } bool Is_Fibo_Level(int ind) { double _r=0.0; vector _h,_l; int _size = 3 * PeriodSeconds(PERIOD_MN1) / PeriodSeconds(m_period); _h.Init(_size); _l.Init(_size); if(_h.CopyRates(m_symbol.Name(),m_period,2,0,_size) && _l.CopyRates(m_symbol.Name(),m_period,4,0,_size)) { _r = _h.Max()-_l.Min(); if(_l.Min()-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+ATR(ind)) { return(true); } else if(_l.Min()+(0.236*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(0.236*_r)+ATR(ind)) { return(true); } else if(_l.Min()+(0.382*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(0.382*_r)+ATR(ind)) { return(true); } else if(_l.Min()+(0.5*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(0.5*_r)+ATR(ind)) { return(true); } else if(_l.Min()+(0.618*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(0.618*_r)+ATR(ind)) { return(true); } else if(_h.Max()-ATR(ind) <= Close(ind) && Close(ind) <= _h.Max()+ATR(ind)) { return(true); } } return(false); } 逐行拆解:IsPattern_9 先按买卖方向查分形(FractalLow / FractalHigh 非 0 即通过),再交 Is_Fibo_Level 判级别重合;Is_Fibo_Level 中 _size 决定三个月 K 线根数,CopyRates 的 2 和 4 分别取 High/Low 序列,_r 为区间极差,六个 if 对应底部、四个回撤比与顶部容差带(宽 ±ATR)。 三个月窗口是硬伤:低波动期 ATR 收窄,价格易撞进多条容差带,重叠信号会成片冒出。把它当形态-9 的起点,真要上手可在 MT5 里把 _size 改成手动锚定的波段样本,再跑前向漫游看重合率变化。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Check for Pattern class="num">9.                                              |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">bool CSignalFractals::IsPattern_9(class="type">ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY && FractalLow(X()) != class="num">0.0)
   {  if(Is_Fibo_Level(X()))
      {  class="kw">return(true);
      }
   }
   else if(T == POSITION_TYPE_SELL && FractalHigh(X()) != class="num">0.0)
   {  if(Is_Fibo_Level(X()))
      {  class="kw">return(true);
      }
   }
   class="kw">return(false);
}
class="type">bool Is_Fibo_Level(class="type">int ind)
{  class="type">class="kw">double _r=class="num">0.0;
   vector _h,_l;
   class="type">int _size = class="num">3 * PeriodSeconds(PERIOD_MN1) / PeriodSeconds(m_period);
   _h.Init(_size);
   _l.Init(_size);
   if(_h.CopyRates(m_symbol.Name(),m_period,class="num">2,class="num">0,_size) && _l.CopyRates(m_symbol.Name(),m_period,class="num">4,class="num">0,_size))
   {  _r = _h.Max()-_l.Min();
      if(_l.Min()-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+ATR(ind))
      {  class="kw">return(true);
      }
      else if(_l.Min()+(class="num">0.236*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(class="num">0.236*_r)+ATR(ind))
      {  class="kw">return(true);
      }
      else if(_l.Min()+(class="num">0.382*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(class="num">0.382*_r)+ATR(ind))
      {  class="kw">return(true);
      }
      else if(_l.Min()+(class="num">0.5*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(class="num">0.5*_r)+ATR(ind))
      {  class="kw">return(true);
      }
      else if(_l.Min()+(class="num">0.618*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(class="num">0.618*_r)+ATR(ind))
      {  class="kw">return(true);
      }
      else if(_h.Max()-ATR(ind) <= Close(ind) && Close(ind) <= _h.Max()+ATR(ind))
      {  class="kw">return(true);
      }
   }
   class="kw">return(false);
}

用 2 的幂次给九种形态做映射

附带的代码把全部 9 种形态都封装成自定义信号类,在 MQL5 向导里直接拖进智能系统汇编即可。单一形态优化时,输入参数走的是 2 的幂次索引:形态-5 对应 2^5=32,形态-7 对应 128,以此类推。 当同时跑多个形态,这个输入就变成一张位图而不是指针。9 个形态填满后,参数上限是 2^9 减一,也就是 511(从零计数)。 若按开盘/收盘阈值去优化组合,训练样本上能跑出一组最佳输入;前向漫游测到 2024 年,结果会明显分化。过去一年的表现不预示以后,外汇与贵金属杠杆品种高风险,组合失效概率不低。 关键落在「针对性组合」而非平均化:从优化器里硬搜答案大概率翻车,交易者得自己定哪些形态互斥、哪些叠加才有逻辑。

「分形信号的时间帧选择」

分形的解读高度依赖时间帧,同一段行情在 M15 与 H4 上给出的分形含义可能完全相反。H4、日线、周线这类高时间帧会过滤掉大量短期杂音,其分形更倾向标记机构与长线资金关注的关键支撑阻力,信号形成慢但置信度更高。 M15、M20、M30 等低时间帧分形出现频率高,却因短期波动容易被假突破干扰,可靠性偏低;它们更适合剥头皮,靠快进快出吃价差,但必须叠加额外过滤器。外汇与贵金属杠杆高、波动剧烈,低帧假信号可能造成快速亏损。 H1、H2 属于折中帧,理论上有平衡作用。实际最佳实践是在较高时间帧内组合分形:例如用 H4 定分形位,再切到 M30 等帧找入场,比单帧裸用分形更稳。开 MT5 调出 H4 分形与 M30 分形叠加,能直接验证这种层级过滤效果。

◍ 低流动性下的假分形与长周期验证

分形在流动性高、机构参与强的品种里更站得住脚。低成交量价格尖刺常生成假分形并被快速否定,这也是为什么叠加交易量分析或足迹图,能提升基于分形的决策置信度。 我们已拆过这个关键指标的 9 个独立形态。短周期上它缺陷明显,但放到长周期耐心等信号,可能给出有意思的结果——部分形态在 1 年期前向漫游测试中已有体现。 附带两个文件可直接在 MT5 验证:SignalWZ_56.mqh(信号类,23.11 KB)与 WZ_56.mq5(智能系统包含文件,7.99 KB)。外汇与贵金属属高风险市场,任何形态信号都只是概率倾斜,实盘前先跑历史回测。

把多周期分形扫描交给小布
这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到连续分形低点与突破位标注,你只需判断纪律出场。把重复劳动交给小布,你专注决策。

常见问题

夹了分形高点就意味着多空交替,不再是纯粹的买方在相似价位积累,信号含义会从支撑夯实变成普通波动,参考价值下降。
可以,小布盯盘对应品种页内置了连续分形、突破与多周期印证的可视化,不需要自己跑向导也能看盘口结构。
缝隙形态要求两个同向分形之间留有未回补的价格空档,往往用来识别趋势加速段,比单纯连续低点更排斥震荡假信号。
这样能分离样本内拟合与样本外验证,避免曲线拟合;外汇贵金属高风险,跨年前向测试才更能暴露形态在 regimes 切换下的脆弱性。
不一定,但分形排列落在斐波那契回撤位附近时,概率上更可能是机构挂单位置,作为过滤器能减少逆势交易。