自动构造支撑和阻力线(基础篇)
📘

自动构造支撑和阻力线(基础篇)

第 1/3 篇

◍ 用分形自动画支撑阻力

MT5 里支撑阻力不必手动画。基于 Bill Williams 分形(至少 5 根 K 线,中间最高/最低,两侧各两根更低/更高)即可自动识别关键价位。 原文作者 Vladimir Mametov 于 2018-02-27 在 MT5 社区发布该思路,截至统计显示阅读 22 752、评论 20,说明手动画线痛点普遍。 核心做法:遍历历史 K 线,用 iFractal 抓取上/下分形,把最近 N 个未突破的分形连成 zone。注意外汇与贵金属杠杆高、滑点大,分形假突破概率不低,仅作区域参考而非触发依据。

「为什么要把支撑阻力线交给程序画」

支撑和阻力线是货币对与贵金属技术分析的基础骨架,但手工在 MT5 图表上逐个锚点连线,既耗时间又受主观偏移影响。把这条流程自动化,分析师能把精力挪到形态判别和仓位决策上。 外汇与贵金属属高杠杆品种,画线偏差可能直接放大进场误差,用确定性算法替代手绘,至少能把‘线画歪了’这类低级风险压下去。 文内给出的指标逻辑不只服务于肉眼盯盘,其输出的价格区间还能直接喂给 EA 的入场条件。也就是说,同一套支撑阻力判定,既能做人机协同的辅助,也能做全自动系统的底层信号源。

用 ZigZag 抓全周期极点值

支撑阻力线的根基是图表的局部波峰与波底,人工肉眼找容易漏,直接借之字折线(ZigZag)指标把极点自动标出来更稳。它的输入参数决定了回撤灵敏度,调参等于在设定“什么级别的反转才算一个波峰或波底”。 同一套 ZigZag 参数可以跨时间帧套用,极点值会随周期变形:30 分钟图上标出的拐点,放到 4 小时图上可能直接被平滑掉。这意味着你在小周期画的支撑阻力,到大周期未必成立,贵金属和外汇这种高波动品种尤其要双向核对。 实操上,先在 MT5 插入 ZigZag,把 deviation 和 backlog 按你交易品种波幅定好,再切到目标时间帧看极点分布,据此手绘水平线,比凭感觉画更有依据。

◍ 贴着价格挑极点才画得出有效线

支撑阻力线只在贴近当前价时才对交易有参考意义, 太远的极点只是历史噪音。要让线的斜率跟价格咬合, 下降趋势里取阻力极点必须不低于前一个波峰, 上升趋势里取支撑极点不能高于前一个波底, 这样连线才不会穿价。 原文示例里第一张图适用的极点序列是 1-2-3-4-5-7, 第二张是 1-2-3-6-7-8, 差别就在是否按上述规则剔除了反向极点。 代码上先建 ZigZag 句柄, 再逐根扫之字折线的 buffer, 把符合高低点条件的极点写进结构数组。下面这段是 OnInit 与极点筛选的核心, 可直接粘进 MT5 看效果。 外汇和贵金属杠杆高, 这类线只是概率参考, 实盘仍可能随时被扫。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class="kw">struct trade_points               class=class="str">"cmt">// 定义极点值的结构
  {
   class="type">class="kw">double              price;       class=class="str">"cmt">// 价格
   class="type">int                 pos;         class=class="str">"cmt">// 位置, 柱线的索引
   class="type">bool                hpoint;      class=class="str">"cmt">// 为真, 则是波峰 
   class="type">bool                lpoint;      class=class="str">"cmt">// 为真, 则是波底
  };
class="type">int OnInit()
  {
   ZZ_handle=iCustom(_Symbol,_Period,"ZigZag",ExtDepth,ExtDeviation,ExtBackstep);
   class="kw">return(INIT_SUCCEEDED);
  }
class="type">class="kw">double max=close[class="num">1];
   class="type">class="kw">double min=close[class="num">1];
   class="type">int z=class="num">0;
   for(shift=class="num">0;shift<rates_total && !IsStopped();shift++)
    {
     CopyBuffer(ZZ_handle,class="num">0,shift,class="num">1,ZigzagBuffer);
     if(ZigzagBuffer[class="num">0]>class="num">0)
      {
       if(ZigzagBuffer[class="num">0]>=max && ZigzagBuffer[class="num">0]==high[shift])
        {
         ArrayResize(mass,z+class="num">1);
         max=ZigzagBuffer[class="num">0];
         mass[z].price=ZigzagBuffer[class="num">0];
         mass[z].pos=shift;
         mass[z].hpoint=true;
         mass[z].lpoint=false;
         z++;
        }
       if(ZigzagBuffer[class="num">0]<=min && ZigzagBuffer[class="num">0]==low[shift])
        {
         ArrayResize(mass,z+class="num">1);
         min=ZigzagBuffer[class="num">0];
         mass[z].price=ZigzagBuffer[class="num">0];
         mass[z].pos=shift;
         mass[z].lpoint=true;
         mass[z].hpoint=false;
         z++;
        }
       }
    }

「给趋势线设门槛:七条过滤标准怎么落地」

极点数组成型后,并不是任意两点连成的斜线都配叫支撑或阻力。随着行情推进,不少线会慢慢失效,堆在图表上只是噪音。所以要用一组标准做排序和淘汰,只留当下还有参考意义的线。 核心判断逻辑围绕七个维度展开:AB 与 BC 段的长度比率、价格穿越 AB 段的次数、穿越 BC 段的次数、点 C 到现价的间距、趋势线最小和最大长度、线条斜率,以及价格处在阻力线上方还是下方。这些维度可以组合使用,参数也能按自己的盘感往后改。 比率这块用斐波那契数卡下限比较稳。把最小允许比率设成 0.25 或 0.382,等价于要求 AB/AC ≥ 0.382 且 BC/AC ≥ 0.382,输入里直接给一个 fibo 参数就行。距离过滤也很实用:只画离现价不超过 50~100 点的线,能砍掉一大半失去相关性的旧线。 斜率方向必须和趋势性质对齐——上升支撑线斜率 ≥ 0,下跌阻力线斜率 ≤ 0,这是开仓线的基本门槛。穿越次数建议区分收盘价突破和影线触碰,前者更硬,后者仅作参考。下面这段是下跌阻力线筛选的局部实现,注意它边算比率边查最小长度,再核对端点偏离容忍度。 别把正态当圣经 代码里的 tolerance*_Point 是端点贴合容差,不是胜率保证。外汇和贵金属波动大、滑点凶,实盘里这套过滤最多帮你少看几根废线,拦不住跳空击穿,仓位自己控。 两种用法都留着:一种顺着未折返的线跟趋势,一种等反向破线再动手。指标里两者都绘制,切换只看你当天的交易倾向。

MQL5 / C++
class=class="str">"cmt">// 判断这些趋势线是否符合我们的标准并填写下跌趋势矩阵。
  for(j=z-class="num">1; j>=class="num">0; j--)
    {
      if(mass[j].hpoint)
        for(i=j-class="num">1; i>=class="num">0; i--)
          {
            if(mass[i].hpoint)
              if(i<j)
                {
                  a=mass[j].pos;
                  b=mass[i].pos;
                  class="type">class="kw">double ratio=class="type">class="kw">double((a-b)*class="num">100/a);     class=class="str">"cmt">// 定义 AB 段与 AC 总长度的比率
                  if(ratio>fibo && ratio<(class="num">100-fibo))      class=class="str">"cmt">// 定义是否符合标准 class="num">1, АB/BС 段的比例
                    if(b>Min_dist &&(a-b)>Min_dist)      class=class="str">"cmt">// 定义是否满足标准 class="num">5, АB 和 BС 段的最小长度
                      {
                        ax=mass[j].price;
                        bx=mass[i].price;
                        coef=(ax-bx)/(a-b);
                        price=close[class="num">1];
                        deviation=(ax+coef*bx)-price;
                        cross_bc=class="num">0;
                        cross_ab=class="num">0;
                        if(MathAbs(deviation)<tolerance*_Point)   class=class="str">"cmt">// 定义是否满足条件4 (点 С 到前一根柱线收盘价的距离)
                          {
                            class=class="str">"cmt">// 从 a 点到 b 点的交叉次数 
                            for(class="type">int n=a; n>b; n--)
                              if((close[n]-(ax+coef*(b-n)))>class="num">0)
                                cross_ab++;
                            class=class="str">"cmt">// 从 b 点到端点的交叉次数  

常见问题

只取贴着当前价格、且被至少两根K线确认的极点,过滤掉远离盘面的旧分形,线就会变少变准。
以你实际下单的周期为主周期,用更高一级周期做方向过滤,避免小周期噪音把线画歪。
可以,小布能按分形和ZigZag逻辑自动识别极点并生成支撑阻力线,你打开对应品种页就能直接看。
先调「极点确认K线数」和「偏离均线阈值」,这两条能砍掉大部分无效线,其余再慢慢加。
程序只认价格真实触碰的极点,不夹带主观延长,所以线更贴成交区,被触碰概率自然高一些。