MQL5 趋势反转 EA 构建:从趋势线交互到自动交易的基础篇(基础篇)
(1/3)·很多图表形态本质都依赖趋势线突破或反转,本篇先把这条主线拆透再写 EA
「从零搭一个趋势反转 EA 的由头」
MQL5 里做趋势反转 EA,核心不是预测顶底,而是用结构破坏确认原趋势乏力。2026 年 1 月 26 日发布的这套思路,在 MT5 社区拿到 938 次浏览、5 条讨论,说明手动抓反转的人很多但系统化落地少。 外汇与贵金属反转交易高风险,杠杆放大下假突破造成的回撤可能超过账户承受度,任何信号都只代表概率倾斜。 开 MT5 按 F4 进 MetaEditor,新建 EA 模板后把反转逻辑单独写成函数,比把所有判断塞进 OnTick 更易排错。先跑 EURUSD 的 M1 回测,观察最近 3 个月哪类结构破坏后反转概率更高,再决定参数边界。
从单一形态跳到趋势线交互
上一部分我们用 EA 自动识别头肩形态并下单、画图,算是把图表形态跑通了一遍。但真要继续写旗形、楔形这类延续形态时发现,它们骨架高度雷同——核心都落在趋势线的突破或反转上。 所以这一节不盯某一个形态,直接做一套能识别并交易趋势线突破 / 反转的 EA。把趋势线取值、附近 K 线行为、时间有效性这几个点吃透,后面换任何形态都只是改参数。 具体要落地的技术点包括:用 ObjectGetValueByTime() 取某根烛形对应时刻趋势线的精确价格;靠趋势线附近的影线、收盘价判断是价格拒绝还是真突破;用基于时间的比较丢掉过期信号。外汇与贵金属波动大、滑点凶,这类突破策略实盘前务必在 MT5 策略测试器跑多周期验证。
◍ 趋势线不是水平线
穿过两个或更多价格点的斜线就是趋势线,它顺着市场自然方向走,可能向上、向下或近横向,与固定水平的支撑阻力不是一回事。摆对了位置,它能帮你看清当下趋势方向,也给出潜在的介入参考。 许多图表形态本身就是用趋势线搭出来的。比如价格被两条收敛的趋势线夹住,往往对应下跌或上涨楔形的突破;旗形、三角旗形里,趋势线框出了行情延续前的盘整带。 上升趋势线连的是更高的低点,扮演支撑。价格跌破它,可能暗示趋势反转或更深回撤,回调到线上则是倾向买入的参考。下降趋势线连更低的高点,是阻力,短暂反弹触线常是卖出机会;但若被有效突破,反而可能迎来买入窗口。 重点不是背形态,而是理解线被突破时多空力量的切换。这种视觉上的清晰度和战术入场点,在写 MQL5 的 EA 时尤其有用——外汇、贵金属波动大、杠杆高,任何信号都只是概率,真要跑自动化得先在 MT5 策略测试器里验证。
「EA 怎么用趋势线自动抓反转和突破」
这套 EA 的核心逻辑是让程序自己读图:先根据近期的摆动高/低点画出上升或下降趋势线,再盯着价格与线的接触方式决定动手。它不挑形态,楔形、旗形、三角形、通道都能套,因为底层都靠趋势线动态。 顺势反转那一类,EA 找两个波动低点拉上升趋势线,等价格回踩不破、收出阳线就视为反弹有效,随即挂买;找两个波动高点拉下降趋势线,价格触碰收阴则挂卖。止损可设在入场价或反弹烛形极值外若干点,止盈按高于/低于入场的点数给。 突破回测那一类更凶:上升线被跌破后等价格从下方向上回摸趋势线,收阴且最低低于线则确认看跌回测,挂卖;下降线被涨破后等从上往回踩,收阳且最高高于线则确认看涨回测,挂买。两类用户都可自定义 SL/TP 点数。 外汇与贵金属杠杆高、滑点跳空频繁,这类基于形态识别的 EA 在实盘前必须用 MT5 策略测试器跑足样本回测,本文项目仅作 MQL5 图表处理思路演示,不直接用于真金白银。
让EA自己抓波动点画趋势线
做自动趋势线识别,第一步不是画图,是把图表历史柱形拉进数组。没有 OHLC 和时间序列,EA 连低点高点都分不清,更谈不上画支撑阻力。上面这段代码在 OnInit() 里用 ArraySetAsSeries(..., true) 把五个数组全部翻转,使索引 0 对应最近一根已收盘烛形,索引 1 是前一根——这种从新向旧推的索引方式,和人工盯图习惯一致。 默认 time_frame = PERIOD_CURRENT,EA 吃当前图表周期;bars_check = 500 意味着只检查最近 500 根已完成烛形,正在形成的那根直接跳过,因为价变太快、形态不可靠。 上升趋势线靠两个更高的低点锚定。IsSwingLow(low[], index, lookback) 用 for 循环把当前最低价和左右各 lookback 根的比,只有它是局部最低才返回 true。allow_uptrend 开 true 时,代码先扫出最近波动低点存进 first_low / first_low_time,再往更早方向找更低的 second_low,两步搜索保证「旧低更低、新低更高」的结构成立,然后用 ObjectCreate 连线,OBJPROP_RAY_RIGHT 向右延伸,染蓝、线宽 3。 下降趋势线逻辑镜像:IsSwingHigh 找局部峰值,第二个高点必须早于且高于第一个,线向下倾斜连接较低高点,可能成为价格拒绝的阻力区。外汇和贵金属波动剧烈,这类自动线只作结构参考,实盘触发仍带较高风险,参数 lookback 调小会更敏感、调大更严苛。
class=class="str">"cmt">// Timeframe to use for retrieving candlestick data(class="kw">default is the current chart timeframe) input ENUM_TIMEFRAMES time_frame = PERIOD_CURRENT; class=class="str">"cmt">// Number of past bars(candlesticks) to check class="type">int bars_check = class="num">500; class=class="str">"cmt">// Arrays to store candlestick data class="type">class="kw">double close_price[]; class=class="str">"cmt">// Stores close prices class="type">class="kw">double open_price[]; class=class="str">"cmt">// Stores open prices class="type">class="kw">double low_price[]; class=class="str">"cmt">// Stores low prices class="type">class="kw">double high_price[]; class=class="str">"cmt">// Stores high prices class="type">class="kw">datetime time_price[]; class=class="str">"cmt">// Stores time data for each candle class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Expert initialization function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int OnInit() { class=class="str">"cmt">// Set arrays as series so the newest bar is index class="num">0 ( start from the latest bar) ArraySetAsSeries(close_price, true); ArraySetAsSeries(open_price, true); ArraySetAsSeries(low_price, true); ArraySetAsSeries(high_price, true); ArraySetAsSeries(time_price, true); class="kw">return(INIT_SUCCEEDED); class=class="str">"cmt">// Signal that the EA initialized successfully } class=class="str">"cmt">//+------------------------------------------------------------------+
◍ 把K线数据塞进数组等画图
EA 的骨架搭完了,剩下的是把图表上的 OHLC 和时间真正抓进内存。OnDeinit 这里留空,说明卸载时没做额外清理,图表对象靠 MT5 自身回收,实盘里若手动拖了多个实例得留意对象名冲突。 OnTick 里用 CopyOpen / CopyClose / CopyLow / CopyHigh / CopyTime 一次性搬最近 500 根柱(bars_check=500)到各自数组,起点偏移 1 表示跳过正在形成的当前根,只取已闭合的历史。time_frame 默认 PERIOD_CURRENT,换周期不用改代码,挂不同周期图即可。 allow_uptrend 这个布尔输入默认 true,控制后续是否允许画上升趋势线;LookbackBars=5 决定找摆动低点时往回看几根。first_low / second_low 及对应时间变量,就是给后面连两点成线准备的容器,ChartID() 存进 chart_id 方便精准操作对象。 初始化 OnInit 里先 ArraySetAsSeries 把 close_price 和 open_price 设成时间序列,索引 0 是最新已收杆,后面判高低点直接下标访问就行。外汇与贵金属杠杆高,这类裸画图 EA 不替你下单,但误连低点可能发出错误结构信号,建议先开 MT5 策略测试器用历史数据跑一遍验证连线逻辑。
class=class="str">"cmt">//| Expert deinitialization function | //+------------------------------------------------------------------+ class="type">void OnDeinit(const class="type">int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ class="type">void OnTick() { // Copy the latest candlestick data into the arrays CopyOpen(_Symbol, time_frame, class="num">1, bars_check, open_price); // Open prices CopyClose(_Symbol, time_frame, class="num">1, bars_check, close_price); // Close prices CopyLow(_Symbol, time_frame, class="num">1, bars_check, low_price); // Low prices CopyHigh(_Symbol, time_frame, class="num">1, bars_check, high_price); // High prices CopyTime(_Symbol, time_frame, class="num">1, bars_check, time_price); // Candle times } // Timeframe to use for retrieving candlestick data(class="kw">default is the current chart timeframe) input ENUM_TIMEFRAMES time_frame = PERIOD_CURRENT; // Input to enable or disable drawing of the ascending trend line(true = allow drawing) input class="type">bool allow_uptrend = true; // Number of candles to look back when identifying swing lows for drawing the trend line input class="type">int LookbackBars = class="num">5; // Number of past bars(candlesticks) to check class="type">int bars_check = class="num">500; // Arrays to store candlestick data class="type">class="kw">double close_price[]; // Stores close prices class="type">class="kw">double open_price[]; // Stores open prices class="type">class="kw">double low_price[]; // Stores low prices class="type">class="kw">double high_price[]; // Stores high prices class="type">class="kw">datetime time_price[]; // Stores time data for each candle class="type">class="kw">double first_low; // Price value of the first identified swing low class="type">class="kw">datetime first_low_time; // Time when the first swing low occurred class="type">class="kw">double second_low; // Price value of the second identified swing low class="type">class="kw">datetime second_low_time; // Time when the second swing low occurred class="type">class="kw">string up_trend = "Up Trend"; // Label used to name the ascending trend line object on the chart class="type">long chart_id = ChartID(); // Stores the current chart ID for referencing during object creation or manipulation //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ class="type">int OnInit() { // Set arrays as series so the newest bar is index class="num">0 ( start from the latest bar) ArraySetAsSeries(close_price, true); ArraySetAsSeries(open_price, true);