通道突破形态·综合运用
📈

通道突破形态·综合运用

(3/3)·从通道类型辨析到智能系统实测,补齐前 two 篇没讲透的突破回踩入场与风控闭环

实战向 第 3/3 篇
很多人在通道被刺穿的瞬间就追单,结果价格回抽扫掉止损才真正发动。把突破和回踩混为一谈,是通道策略里最烧钱的习惯。本篇收尾整套方法,只讲怎么让系统替你等那个返回边界的确认点。

◍ 通道突破后的下单与通道回收逻辑

这段处理的是通道对象被突破后怎么落地成实际动作。先声明一组状态变量:订单类型 type、止损 stop_loss 初始为 -1 表示未定、是否突破 breaked、突破时间 breaked_time 与成交时间 deal_time。随后调用 ar_Channels[i].Calculate() 算出当前通道的状态,并把最新突破时间用 fmax 合并进 dt_last_break。 如果通道被突破且恰好是最后一个(i==total-1),就跑 SearchNewChannel(breaked_time) 看要不要补一个新通道。这里有个细节:已存在通道数 total>=5 时不扩容,只把索引 i 回退一格重新算;不足 5 个才 total++ 增加通道。 deal_time>=0 且 stop_loss>=0 意味着通道给出了有效交易指令。代码用 Bars() 统计从信号时间到当前的 K 线根数,若 bars<=2 才允许下单——也就是说信号发出后最多只认接下来 2 根 K 线内的触发,过期不候。 下单前会检查反向持仓:比如收到 BUY 但已有 SELL 持仓,先 PositionClose 平掉再 Trade.Buy。手数取 SYMBOL_VOLUME_MIN 最小单位,止损取 fmax(stop_loss,0) 防止负数。成交后 DeleteChannel(i) 删掉该通道,i-- 且 total-- 维持数组连续。外汇与贵金属杠杆高,这种自动平反手加开仓在滑点行情中可能连续触发,实盘前务必在 MT5 策略测试器用历史数据验证 bars<=2 的触发频率。

MQL5 / C++
ENUM_ORDER_TYPE type;
class="type">class="kw">double stop_loss=-class="num">1;
class="type">bool breaked=class="kw">false;
class="type">class="kw">datetime breaked_time=class="num">0;
class="type">class="kw">datetime deal_time=class="num">0;
if(ar_Channels[i].Calculate(type,stop_loss,deal_time,breaked,breaked_time))
  {
   dt_last_break=fmax(dt_last_break,breaked_time);
   if(breaked && i==(total-class="num">1))
     if(SearchNewChannel(breaked_time))
       {
        if(total>=class="num">5)
          i--;
        else
          total++;
       }
   if(deal_time>=class="num">0 && stop_loss>=class="num">0)
     {
      class="type">int bars=Bars(_Symbol,PERIOD_CURRENT,deal_time,TimeCurrent());
      class="type">class="kw">double lot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
      class="kw">switch(type)
        {
         case ORDER_TYPE_BUY:
           if(PositionSelect(_Symbol) && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
             Trade.PositionClose(_Symbol);
           if(bars<=class="num">2)
             Trade.Buy(lot,_Symbol,class="num">0,fmax(stop_loss,class="num">0));
           class="kw">break;
         case ORDER_TYPE_SELL:
           if(PositionSelect(_Symbol) && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
             Trade.PositionClose(_Symbol);
           if(bars<=class="num">2)
             Trade.Sell(lot,_Symbol,class="num">0,fmax(stop_loss,class="num">0));
           class="kw">break;
        }
      DeleteChannel(i);
      i--;
      total--;
     }
  }
}
class="type">bool SearchNewChannel(class="type">class="kw">datetime time)
  {

通道数组的滚动回收与删除逻辑

在 MT5 里用对象指针数组维护价格通道时,内存不会自动释放。上面这段把通道数组上限压到 5 个:当数组长度超过 4,就先释放前面多余的 CChannel 指针,再把最后 4 个前移,最后若总长大于 5 则缩容到 5。 若数组还没到 5 个,则走 else 分支直接 ArrayResize 加 1,再在末尾 new 一个 CChannel 绑定当前品种与 PERIOD_CURRENT。返回前用 CheckPointer 确认指针有效,避免空对象参与后续绘制。 DeleteChannel 负责按索引删:越界直接返回 false;删除后把后续元素前移,若原数组只有 1 个则 ArrayFree 彻底释放。外汇与贵金属波动剧烈,这类手动回收能降低 EA 长时间挂机时的内存泄漏概率,建议开 MT5 用 iCustom 加载后观察 ar_Channels 长度是否稳定在 5 以内。

MQL5 / C++
  if(zz_handle==INVALID_HANDLE)
      class="kw">return class="kw">false;
  class="type">int total=ArraySize(ar_Channels);
  if(total>class="num">4)
     {
      for(class="type">int i=class="num">0;i<total-class="num">4;i++)
        {
         if(CheckPointer(ar_Channels[i])!=POINTER_INVALID)
            class="kw">delete ar_Channels[i];
        }
      for(class="type">int i=class="num">0;i<class="num">4;i++)
        ar_Channels[i]=ar_Channels[total-class="num">4+i];
      if(total>class="num">5)
        {
         if(ArrayResize(ar_Channels,class="num">5)>class="num">0)
            total=class="num">5;
         else
            class="kw">return class="kw">false;
        }
     }
  else
     {
      if(ArrayResize(ar_Channels,total+class="num">1)>class="num">0)
         total++;
      else
         class="kw">return class="kw">false;
     }
  ar_Channels[total-class="num">1]=new CChannel(zz_handle,time,_Symbol,PERIOD_CURRENT);
  class="kw">return (CheckPointer(ar_Channels[total-class="num">1])!=POINTER_INVALID);
  }
class="type">bool DeleteChannel(class="type">int pos)
  {
   class="type">int total=ArraySize(ar_Channels);
   if(pos<class="num">0 || pos>=total)
      class="kw">return class="kw">false;
   class="kw">delete ar_Channels[pos];
   for(class="type">int i=pos;i<total-class="num">1;i++)
      ar_Channels[i]=ar_Channels[i+class="num">1];
   if(total==class="num">1)
      {
       ArrayFree(ar_Channels);
       class="kw">return true;
      }
   class="kw">return (ArrayResize(ar_Channels,total-class="num">1)>class="num">0);
  }

「H1 与 M15 下的 EA 实测算账」

把 EA 直接丢进 2017 年 EURUSD 的 H1 周期跑,不做任何参数预优化,结果开了 10 次仓、共 26 笔交易,80% 平仓盈利,盈利因子 4.06,余额曲线走得相当平。每年只触发 10 次对实盘来说太稀疏,于是保持参数不动,切到 M15 再看。 M15 上交易笔数涨到 63,但总利润只有 130.60 美元,H1 反而是 133.46 美元;盈利交易占比从 80% 掉到 41.27%,盈利因子跌到 1.44,差不多是 H1 的三分之一,余额图也碎得多。小周期只是把噪音放大了,并没有带来质的变化。 换品种用 H1 同参数扫一遍:GBPUSD 盈利因子 1.47、恢复因子 0.23;EURGBP 五笔全亏、盈利因子 0;USDJPY 盈利因子 0.72。EURGBP 虽然信号方向没错,但平均持仓拉长到近 1000 小时,趋势早反转了。外汇与贵金属杠杆高、滑点跳空频繁,这类长持通道突破策略回测好看不代表实盘能复刻,开 MT5 用 2017 年数据自测是第一步。

◍ 通道突破 EA 的测试边界与可补强处

基于通道突破形态跑出来的 EA 样例,回测里能稳定吐出入场信号,但信号频率偏低——属于准而稀的那一类。测试还显示,在较高时间帧(如 H4、D1)上形态识别效果明显优于 M1、M5,信号质量随周期拉长而抬升。 不过光有入场不够。策略本身没有离场逻辑,浮盈经常扛到回撤变亏,实测中不少单子从盈利翻成本金亏损。想提成功率,得另接一套离场判定,比如反向通道破位或 ATR 跟踪停。 这套 EA 不含资金管理和报错处理,计算或下单异常时可能直接卡死,外汇与贵金属杠杆高、滑点跳空频繁,故不建议挂真仓。代码层留了口子,任何人都能补模块。 原文另列了旗形形态、HTML 图解与通用之字折线作延伸素材,这几块不在本节展开,留给你开 MT5 对照图形自己验证形态识别。

随包附带的工程文件怎么用

这套通道突破策略不是只给文字,作者把可跑的工程直接打了包。MT5 里加载 Break_of_channel_DNG.mq5 这个 EA 就能回测,它依赖 Channel.mqh 里的价格通道与信号类,iUniZigZagSW.ex5 则负责画通用之字折线辅助判别。 项目描述文件 Break_of_channel_DNG.mqproj 让你在 MetaEditor 一键打开整个工程,不用手动拼路径。Reports.zip 里是 241.95 KB 的测试报告,先翻一遍再决定要不要上实盘。 外汇与贵金属杠杆高、滑点跳空频繁,EA 历史回测顺不代表未来能复制,跑之前先把点差和隔夜费填进测试设置。 想验证就现在开 MT5 把 MQL5.zip(204.37 KB)解到 Indicators/Experts 目录,编译完切到策略测试器选 EURUSD 小时图跑一遍,比看十篇帖子里的水帖有用。

把形态扫描交给小布盯盘
这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到实时通道与突破回踩标记,你只需要在确认信号后做仓位决策,不用自己盯边界重绘。

常见问题

回归通道基于统计偏差,边界随斜率自适应,相比等距通道在趋势中段假突破概率倾向更低,但横盘期两者都容易反复,需结合返回确认。
原文采用每类只处理一个形态并存入数组,触发开单后即销毁实例,从而支持多通道并行;这样新突破进入搜索不会阻塞旧形态的回踩监控。
周期越大噪声越少,但回踩耗时更长,止损空间要重算;跨周期直接搬用参数容易在贵金属跳空时放大风险。
可以,品种页的 AIGC 模块会标注被突破通道及价格返回边界的位置,并推送确认点,省去手动重绘和守屏。
价格常返回边界再走新趋势, immediate 入场易被回抽扫损;等返回后入场虽牺牲部分空间,但外汇贵金属高风险下胜率更可控。