构建三线突破图表指标(基础篇)
📘

构建三线突破图表指标(基础篇)

第 1/3 篇

「用三线突破重画价格走势」

三线突破(Three Line Break)把连续 K 线压缩成只关心涨跌幅度的砖块图,忽略时间轴,适合抓趋势中段。MT5 自带的「三线突破」图表模板默认取最近 3 根砖的极值做反转判定,但原生模板不能叠加均线或自定义警报。 想自己重画这套图,核心是先按收盘价比较:若新高超过前 N 根砖的最高价就向上补砖,跌破前 N 根最低价才向下翻砖,中间波动直接丢弃。下面这段 MQL5 片段演示了如何取前 3 根砖的极值。 外汇与贵金属品种用三线突破容易在震荡市出现连续假突破,属高风险用法,建议先在 XAUUSD 的 H1 上跑历史回看验证信号密度。

MQL5 / C++
class="type">class="kw">double lastHigh = iHigh(_Symbol, PERIOD_CURRENT, class="num">0);
class="type">int bars = class="num">3;
class="type">class="kw">double maxPrev = class="num">0;
for(class="type">int i=class="num">1; i<=bars; i++) {
   class="type">class="kw">double h = iHigh(_Symbol, PERIOD_CURRENT, i);
   if(h > maxPrev) maxPrev = h;
}
if(lastHigh > maxPrev) class=class="str">"cmt">// 向上突破前3根砖高点
   DrawUpBrick();

◍ 三线突破图的构造逻辑与 EURUSD 实例

三线突破图(Three Line Break)据传源于日本,Steve Nison 在 1994 年出版的《Beyond Candlesticks》中将其引入西方视野。原著第 185 页列了 11 条绘制规则,可压缩为三条核心:以初始收盘价定首根阴阳线并标记极值;价格跌破最低或升超最高才出新线;反向线必须穿过前低或前高,且连续同色线达两根时取最近两线极值、三根及以上取最近三线的极值。 它基于固定时间帧的收盘价过滤小幅噪声,和 Renko、Kagi 同属 20 世纪图表家族,但构建时机不依赖固定涨跌点数,而依赖已成形 K 线的收盘。 以 EURUSD H1 为例,2014.06.27 00:00 收盘 1.3613 为起点,01:00 收 1.3614 出首根阳线;02:00 收 1.3612 低于前低反成阳线(规则二下的同向延伸)。03:00 至 09:00 多头将价推至 1.3634,连续阳线后第 9 根阳线需穿过三个最低价 1.3626、1.3623、1.3619。 12:00 跌至 1.3612 出阴线,但随后五小时多头夺回并破前高 1.3626,17:00 收 1.3641 再出阳线;18:00 空方未破前低,之后五小时每小时创新高至 1.3649。该品种单日 H1 数据即呈现 6 次以上方向切换,外汇高杠杆下此类突破信号误触概率偏高,实盘前应在 MT5 用历史数据自测。

三线突破如何吃下四种价格类型

三线突破指标和传统版本最大的不同,在于它不再只绑定某一种价格来画图。经典构造通常只认收盘价或单一价格源,而现代实现把开盘、最高、最低、收盘四个标准价格条全部纳入,并在视觉上用类似日本蜡烛的“阴影”呈现,观感更接近 K 线。 这种多价格源并行会带来一个问题:四类价格序列之间可能出现缺失或错位。指标提供两种同步模式——局部同步(图例左侧)和完整同步(图例右侧)。完整同步下,缺失数据按设置里的优选价格补位,所有柱子都画出来;若选局部同步,则只画数据完整的烛条,缺失段直接跳过。 周期分离是另一个实用点。MT5 原生图表用垂直虚线切分周期,而该指标改用一条变色垂直线标记(图例 3),并允许在指标内部按指定时间帧切换,不和主图周期强绑定。 指标还内嵌了 iMA 均线,依据主图价格建立但会与指标数据做时间同步,相当于用均线对突破信号再过滤一层(图例 4)。此外可设绘图最小移动点数与反转所需线数,这两项是额外的滤波参数,能压低噪音信号。外汇与贵金属市场波动剧烈、杠杆风险高,参数调小未必更灵敏,建议先在 MT5 用历史数据跑一遍看信号密度。

「三线突破指标的内部骨架」

这个指标的逻辑并不绕,核心就是三步:把行情数据拷进来,按三线突破规则算一遍,再把结果写进缓冲器交给图表渲染。代码按职责拆成多个函数,彼此只通过输入参数和内部数组打交道,方便单独改某一段逻辑。 输入参数里最值得盯的是 line_to_back_f,它决定反转要几根线确认,经典玩法填 3;step_min_f 是新列最小步长,必须大于 0,否则图表可能不画新线。time_frame 是计算周期,time_redraw 控制重算节奏,实盘里按键盘 R 能强制重绘,不用等新柱。 OnInit 里声明了 6 个缓冲器——因为图表 ABCTB 用 DRAW_COLOR_CANDLES 占 4 个,附加均线 LINE_TLB 占 2 个。同时在这里建 iMA 句柄,若参数非法直接改回最小值并报警,避免图表过载。 数据复制走 MqlRates 结构,把开高低收、成交量、点差和时间一次性搬进中间数组;缺失段会补一个时段再永久更新。计算函数只填 line_info 结构数组,不碰绘图,其中 func_regrouping 把同向连续线压缩,每次新线进来索引 0 更新、其余下移,line_to_back_f 精确限制存储深度。 绘图阶段分经典和修改两种:修改模式忽略 chart_price,先算四种价格再按优先级同步(收盘>开盘>最高>最低),经典模式直接调计算函数灌缓冲器。彩色函数靠 MqlDateTime 判周期边界,但 W1 和 MN 因结构不含周数,用 time_variable 扣一周秒数来补。 键盘 R 和 OnCalculate 里的 func_new_bar 共同管重绘,后者是 IsNewBar 的简化版,只在选定周期出了新柱才触发自动重算。外汇与贵金属杠杆高,这类自绘图表仅作结构参考,信号失效概率不低,上 MT5 前先开模拟盘验证参数。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                 ABCTB.mq5 |
class=class="str">"cmt">//|                     "Azotskiy Aktiniy ICQ:class="num">695710750" |
class=class="str">"cmt">//|                                                                     |
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">// ABCTB - Auto Build Chart Three Line Break
class="macro">#class="kw">property copyright "Azotskiy Aktiniy ICQ:class="num">695710750"
class="macro">#class="kw">property link      ""
class="macro">#class="kw">property version   "class="num">1.00"
class="macro">#class="kw">property indicator_separate_window
class="macro">#class="kw">property indicator_buffers class="num">6
class="macro">#class="kw">property indicator_plots   class="num">2
class=class="str">"cmt">//--- plot ABCTB
class="macro">#class="kw">property indicator_label1  "ABCTB"
class="macro">#class="kw">property indicator_type1   DRAW_COLOR_CANDLES
class="macro">#class="kw">property indicator_color1  clrBlue,clrRed,clrGreenYellow

◍ 指标绘制与输入参数的骨架

这段声明决定了自定义指标在 MT5 图表上的两条绘制线,以及外部可调的计算开关。第一条线(buffer 1)用实线、宽度 1、默认色;第二条线标记为 LINE_TLB,类型 DRAW_LINE、红色、同样实线宽度 1,用于承载反转参考线。 代码里先定义了三个枚举:type_price 把计算源价格映射为 0~3(收盘/开盘/最高/最低),type_build 区分经典与修正两种构建法,priority 给收盘价优先级从低到高分 1~4 四档。 输入参数段才是实盘能直接改的地方:magic_numb 默认 65758473787389 仅作标识;time_frame 取当前周期,time_redraw 锁定 M1 作为重绘节拍;first_date_start 写死 2013.03.13 作为历史起点。 step_min_f=4 表示新列最小步长必须大于 0,line_to_back_f=3 控制反转显示回溯线数。chart_type 默认 classic,chart_color_period 与 chart_synchronization 均开 true,意味着换周期变色且只在完全同步后构建。外汇与贵金属波动剧烈,这类参数组合仅决定绘制逻辑,不预示任何方向,实盘前请在策略测试器用历史数据验证。

MQL5 / C++
class="macro">#class="kw">property indicator_style1  STYLE_SOLID
class="macro">#class="kw">property indicator_width1  class="num">1
class=class="str">"cmt">//--- plot LINE_TLB
class="macro">#class="kw">property indicator_label2  "LINE_TLB"
class="macro">#class="kw">property indicator_type2   DRAW_LINE
class="macro">#class="kw">property indicator_color2  clrRed
class="macro">#class="kw">property indicator_style2  STYLE_SOLID
class="macro">#class="kw">property indicator_width2  class="num">1
class=class="str">"cmt">//--- Price type for calculation
enum type_price
  {
  close=class="num">0, class=class="str">"cmt">// Close
  open=class="num">1,  class=class="str">"cmt">// Open
  high=class="num">2,  class=class="str">"cmt">// Hight
  low=class="num">3,   class=class="str">"cmt">// Low
  };
class=class="str">"cmt">//--- type of chart construction
enum type_build
  {
  classic=class="num">0,  class=class="str">"cmt">// Classic
  modified=class="num">1, class=class="str">"cmt">// Modified
  };
class=class="str">"cmt">//--- priority
enum priority
  {
  highest_t=class="num">4, class=class="str">"cmt">// Highest
  high_t=class="num">3,    class=class="str">"cmt">// High
  medium_t=class="num">2,  class=class="str">"cmt">// Medium
  low_t=class="num">1,     class=class="str">"cmt">// Low
  };
class=class="str">"cmt">//--- input parameters
input class="type">long                magic_numb=class="num">65758473787389;                    class=class="str">"cmt">// Magic number
input ENUM_TIMEFRAMES     time_frame=PERIOD_CURRENT;                    class=class="str">"cmt">// Calculation time range
input ENUM_TIMEFRAMES     time_redraw=PERIOD_M1;                        class=class="str">"cmt">// Period of chart updates
input class="type">class="kw">datetime            first_date_start=D&class="macro">#x27;class="num">2013.03.class="num">13 class="num">00:class="num">00:class="num">00&class="macro">#x27;;      class=class="str">"cmt">// Start date
input type_price          chart_price=close;                            class=class="str">"cmt">// Price type for calculation(class="num">0-Close, class="num">1-Open, class="num">2-High, class="num">3-Low)
input class="type">int                 step_min_f=class="num">4;                                 class=class="str">"cmt">// Minimum step for a new column(>class="num">0)
input class="type">int                 line_to_back_f=class="num">3;                             class=class="str">"cmt">// Number of lines to display a reversal(>class="num">0)
input type_build          chart_type=classic;                           class=class="str">"cmt">// Type of chart construction(class="num">0-classic, class="num">1-modified)
input class="type">bool                chart_color_period=true;                      class=class="str">"cmt">// Changing class="type">color for a new period
input class="type">bool                chart_synchronization=true;                   class=class="str">"cmt">// Constructing a chart only upon complete synchronization
input priority            chart_priority_close=highest_t;               class=class="str">"cmt">// Priority of the closing price

把多优先级报价塞进指标缓冲区

这段声明直接决定了后面绘图逻辑怎么跑:开、高、低三类价格各自带一个优先级枚举,默认全设成 highest_t,意味着同根 K 线里这几个分量都按最高优先处理,回测时若切到 lowest_t 可能让支撑阻力线整体下移。 ma_draw 开关默认 true,配合 ma_price=PRICE_CLOSE、ma_method=MODE_EMA、ma_period=14,就是在收盘价上叠一条 14 期指数均线;想看裸价格行为就把 ma_draw 改 false,少一层视觉干扰。 ABCTBBuffer1~4 加 ABCTBColors 是图表主体缓冲区,LINE_TLBBuffer 单独留给均线;rates_array 用 MqlRates 接 K 线数据,date_start/date_stop 框定计算窗口。 两个结构体是后面共享线判定的地基:line_price 只存 up/down 高低值,line_info 多带 type 和 time,并派生出 line_main_open/high/low 三个数组分别装三类价格的历史线信息。开 MT5 把这段贴进自定义指标头部,编译过即说明缓冲区与结构体没冲突。

MQL5 / C++
input priority        chart_priority_open=highest_t;          class=class="str">"cmt">// Priority of the opening price
input priority        chart_priority_high=highest_t;          class=class="str">"cmt">// Priority of the maximum price
input priority        chart_priority_low=highest_t;           class=class="str">"cmt">// Priority of the minimum price
input class="type">bool            ma_draw=true;                           class=class="str">"cmt">// Draw the average
input ENUM_APPLIED_PRICE ma_price=PRICE_CLOSE;                class=class="str">"cmt">// Price type for constructing the average
input ENUM_MA_METHOD  ma_method=MODE_EMA;                     class=class="str">"cmt">// Construction type
input class="type">int             ma_period=class="num">14;                           class=class="str">"cmt">// Averaging period
class=class="str">"cmt">//--- indicator buffers
class=class="str">"cmt">//--- buffer of the chart
class="type">class="kw">double    ABCTBBuffer1[];
class="type">class="kw">double    ABCTBBuffer2[];
class="type">class="kw">double    ABCTBBuffer3[];
class="type">class="kw">double    ABCTBBuffer4[];
class="type">class="kw">double    ABCTBColors[];
class=class="str">"cmt">//--- buffer of the average
class="type">class="kw">double    LINE_TLBBuffer[];
class=class="str">"cmt">//--- variables
class="type">MqlRates rates_array[];class=class="str">"cmt">// bar data array for analysis
class="type">class="kw">datetime date_stop;    class=class="str">"cmt">// current date
class="type">class="kw">datetime date_start;   class=class="str">"cmt">// start date variable for calculation
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Struct Line Price                                                |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="kw">struct line_priceclass=class="str">"cmt">// structure for storing information about the past lines
  {
   class="type">class="kw">double          up;  class=class="str">"cmt">// value of the high price
   class="type">class="kw">double          down;class=class="str">"cmt">// value of the low price
  };
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Struct Line Information                                          |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="kw">struct line_infoclass=class="str">"cmt">// structure for storing information about the shared lines
  {
   class="type">class="kw">double          up;
   class="type">class="kw">double          down;
   class="type">char            type;
   class="type">class="kw">datetime        time;
  };
line_info line_main_open[];  class=class="str">"cmt">// data on the opening prices chart
line_info line_main_high[];  class=class="str">"cmt">// data on the maximum prices chart
line_info line_main_low[];   class=class="str">"cmt">// data on the minimum prices chart

常见问题

当白线被反向突破且新线出现在对侧时,原趋势可能终结;可对照原文 EURUSD 实例中四种价格类型的切换点手动验证。
默认用前一根线长度的固定倍数(如 3 倍)作阈值;先在图表上目测近期波动幅度再微调,避免频繁假突破。
小布可读取品种页上的重画走势,标出最新突破线与反转边界,你只需确认信号强弱,不必自己数 K 线。
这是多优先级报价塞进缓冲区后的正常压缩:未达反转阈值的同向价格只延伸当前线,不新开线。
贵金属跳空更频繁,反转阈值建议适当放大;属高风险品种,信号仅作概率参考,需结合仓位控制。