头肩形态算法:从形态架构到MQL5落地的零基础拆解(基础篇)
(1/3)· 多数交易者手动画头肩常漏掉颈线突破确认,本篇用代码把反转捕捉变成可回测的EA雏形
「用 MQL5 识别头肩形态的起点」
头肩形态是价格行为里被反复验证的反转结构,但在 MT5 里把它变成可执行的算法,第一步不是写下单逻辑,而是先定义什么是「头」与「肩」。很多自制 EA 失败,原因就在于形态判定阈值拍脑袋,导致信号在震荡市里频繁误触发。 在 MQL5 中,我们通常用 iHigh / iLow 这类内置函数抓取指定 K 线的高低点,再比较中间波峰与两侧波峰的高度差。一个可验证的粗糙起点:当中间波峰高于两侧至少 15 点(标准账户 EURUSD 点值),且两侧波峰高度差不超过 8 点,才初步判定为头肩雏形。 外汇与贵金属杠杆高、滑点大,这类形态算法在实盘只代表概率倾向,不代表反转必然发生。建议先在策略测试器用 2023—2024 年 H1 数据跑一遍,看信号密度是否过度。
◍ 从订单块切到头肩算法
上一部分我们在 MQL5 里落地了缓解订单块策略,靠机构价格区去跟单。这一节把重心挪到头肩形态:用算法把这种经典反转结构自动化,目标是在转折点附近更干净地进场。 本篇要拆的四块很直接——形态结构怎么看、代码怎么写、回测怎么跑、以及最后能落出什么。外汇和贵金属杠杆高,形态失效比想象中频繁,任何信号都只是概率倾斜。 读完你能做一件事:开 MT5 新建一个 EA 工程,把后面给的头肩识别逻辑贴进去跑历史数据,先别急着上实盘。
头肩结构在EA里的几何定义
头肩形态分标准与反向两类,核心都是三峰或三谷加一条颈线。标准头肩出现在上升趋势:左肩高点、头部高点、右肩高点依次排列,头部必须明显高出两肩,右肩高度接近左肩;连接两个谷底得到颈线。价格跌破颈线可触发空头,止损放右肩上方,止盈按头到颈线的垂直距离向下投射。 反向头肩在下降趋势中由三个谷底构成:左肩低点、头部更低的低点、右肩与左肩接近的低点,颈线连接两个峰值。上破颈线做多,止损在右肩下方,止盈为颈线到头部距离向上延伸。两肩接近对称、头部突出,是程序判定形态的硬约束。 原文提到可集成可选移动止损来锁利,这部分在后续代码层实现。外汇与贵金属杠杆高,形态失败率不低,任何突破都只是概率信号,实盘前用MT5可视化回放验证颈线绘制逻辑。
「头肩形态EA的骨架怎么搭」
打开 MetaEditor 后别急着写逻辑,先把全局依赖和形态容器定清楚。引入 Trade.mqh 并用 CTrade 实例化交易对象,是后续下单与持仓区分的前提;输入参数里 LookbackBars 默认 50 根、ThresholdPoints 默认 70.0 点、ShoulderTolerancePoints 默认 15.0 点、TroughTolerancePoints 默认 30.0 点,这几个值直接决定形态识别的灵敏度,上 MT5 后第一件事就是拿历史图回看调参。 用 struct 定义 Extremum 和 TradedPattern 是两个关键动作。前者存极值点(bar 索引、time、price、isPeak),后者靠 leftShoulderTime / leftShoulderPrice 锁已交易形态,避免一根 K 线内重复触发。声明 tradedPatterns 数组配合每根 K 线只跑一次的机制,能把重复开仓概率压下去。 图表可视化不能省。ChartGetInteger 取 chart_width、chart_height、chart_scale、chart_first_vis_bar、chart_vis_bars,ChartGetDouble 取 chart_prcmin、chart_prcmax,再写 BarWidth / ShiftToX / PriceToY 三个小函数把 K 线索引和价格映射到画布坐标,头肩图形才画得准。 OnInit 里给 obj_Trade.SetExpertMagicNumber 打魔术码,ArrayResize(tradedPatterns,0) 清旧数据;OnTick 用 iTime 比 lastBarTime 防重算,PositionsTotal 有持仓就提前 return。FindExtrema 用 CopyHigh/CopyLow 填数组、按 ThresholdPoints 反转切趋势,吐出的 extrema[] 就是 DetectHeadAndShoulders 和反向版的喂料。 标准头肩检测要求 extrema 至少 6 点,峰谷交替且头部为最高峰,右肩用 iLow 跌破颈线 ThresholdPoints 确认;IsPatternTraded 用 MathAbs 比 leftShoulderTime/Price 容差,命中就跳过。下完这些函数,MT5 里挂上 EA 就能看到形态标线和交易动作。
◍ 把形态画出来并自动跟单出场
颈线是否穿过某根 K 线,用 iHigh 取最高价、iLow 取最低价,只要 necklinePrice 落在 low~high 区间内就返回 true,这一步决定形态延伸是否成立。验证通过后,图形化才启动:DrawTrendLine 用 ObjectCreate 拉线、ObjectSetInteger 设颜色样式宽度、OBJPROP_BACK 压到 K 线后方;DrawTriangle 用三个点填珊瑚色阴影突出肩头结构;DrawText 按 ChartGetInteger 的 chartscale 算动态字号,把 LS / HEAD / RS / NECKLINE 标到对应位置,颈线标签还用 atan 和 M_PI 算角度旋转对齐。 实盘触发很直接:形态确认后市价 Sell,entryPrice 置 0;止损取右肩价加 BufferPoints,止盈用头部与颈线价差 patternHeight 在收盘价下方扣减。开仓前校验 sl 必须在 closePrice 之上、tp 在其下,成交后 AddTradedPattern 以左肩时间价为锚记录,数组满 MaxTradedPatterns 就左移丢最旧条目。 持仓管理交给 ApplyTrailingStop:SymbolInfoDouble 取 bid/ask,PositionsTotal 遍历持仓,买单用 bid 算浮盈、卖单用 ask,达到 minTrailPoints+trailingPoints 就 NormalizeDouble 重算 newSL 并 PositionModify。OnDeinit 里 ArrayFree 释放 tradedPatterns,ObjectsDeleteAll 清掉 HS_ 与 IHS_ 前缀对象再 ChartRedraw。外汇与贵金属杠杆高,移动止损只降低回撤概率,不保证盈利。 想自己验,把下面 EA 头贴进 MT5 编译,接上前面形态识别函数就能跑出带标注的倒头肩与跟单日志。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Head & Shoulders Pattern EA.mq5 | class=class="str">"cmt">//| Copyright class="num">2025, Allan Munene Mutiiria. | class=class="str">"cmt">//| https://t.me/Forex_Algo_Trader | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Copyright class="num">2025, Allan Munene Mutiiria." class="macro">#class="kw">property link "https:class=class="str">"cmt">//youtube.com/@ForexAlgo-Trader?" class="macro">#class="kw">property version "class="num">1.00"
头肩形态识别的参数骨架
把头肩形态做成 EA,第一件事是把肉眼看的图形翻译成可校验的数字边界。下面这段输入参数和结构定义,就是整套识别逻辑的门槛设定。 回看窗默认 50 根 bar,反转判定要求至少 70 点波动;左右肩差价容忍 15 点,颈线谷/峰之间容忍 30 点。这些数直接决定策略在 EURUSD 这类平均波幅 50~80 点的品种上,是灵敏还是废信号频发。 关键点的时间间隔被卡在 5~30 根 bar 之间,且最长间隔不得超过最短间隔的 2 倍,避免形态被拉得太散。右肩突破距离限制为形态区间的 1.5 倍以内,配合突破后 3 根 bar 验证,过滤假突破。 已交易形态最多存 20 条,匹配容差 5 点,用于防重复开仓。追踪止损默认关,开启后需浮盈满 50 点才激活,跟价 30 点。外汇与贵金属杠杆高,参数未经历史回测直接上实盘可能迅速放大回撤。 Extremum 结构只存了两个字段:bar 索引和 time 时间戳,后续峰谷扫描都靠它定位,轻量但够用。
class="macro">#include <Trade\Trade.mqh> class=class="str">"cmt">//--- Include the Trade.mqh library for trading functions CTrade obj_Trade; class=class="str">"cmt">//--- Trade object for executing and managing trades class=class="str">"cmt">// Input Parameters input class="type">int LookbackBars = class="num">50; class=class="str">"cmt">// Number of historical bars to analyze for pattern detection input class="type">class="kw">double ThresholdPoints = class="num">70.0; class=class="str">"cmt">// Minimum price movement in points to identify a reversal input class="type">class="kw">double ShoulderTolerancePoints = class="num">15.0; class=class="str">"cmt">// Maximum allowable price difference between left and right shoulders input class="type">class="kw">double TroughTolerancePoints = class="num">30.0; class=class="str">"cmt">// Maximum allowable price difference between neckline troughs or peaks input class="type">class="kw">double BufferPoints = class="num">10.0; class=class="str">"cmt">// Additional points added to stop-loss for safety buffer input class="type">class="kw">double LotSize = class="num">0.1; class=class="str">"cmt">// Volume of each trade in lots input class="type">class="kw">ulong MagicNumber = class="num">123456; class=class="str">"cmt">// Unique identifier for trades opened by this EA input class="type">int MaxBarRange = class="num">30; class=class="str">"cmt">// Maximum number of bars allowed between key pattern points input class="type">int MinBarRange = class="num">5; class=class="str">"cmt">// Minimum number of bars required between key pattern points input class="type">class="kw">double BarRangeMultiplier = class="num">2.0; class=class="str">"cmt">// Maximum multiple of the smallest bar range for pattern uniformity input class="type">int ValidationBars = class="num">3; class=class="str">"cmt">// Number of bars after right shoulder to validate breakout input class="type">class="kw">double PriceTolerance = class="num">5.0; class=class="str">"cmt">// Price tolerance in points for matching traded patterns input class="type">class="kw">double RightShoulderBreakoutMultiplier = class="num">1.5; class=class="str">"cmt">// Maximum multiple of pattern range for right shoulder to breakout distance input class="type">int MaxTradedPatterns = class="num">20; class=class="str">"cmt">// Maximum number of patterns stored in traded history input class="type">bool UseTrailingStop = class="kw">false; class=class="str">"cmt">// Toggle to enable or disable trailing stop functionality input class="type">int MinTrailPoints = class="num">50; class=class="str">"cmt">// Minimum profit in points before trailing stop activates input class="type">int TrailingPoints = class="num">30; class=class="str">"cmt">// Distance in points to maintain behind current price when trailing class=class="str">"cmt">// Structure to store peaks and troughs class="kw">struct Extremum { class="type">int bar; class=class="str">"cmt">//--- Bar index where extremum occurs class="type">class="kw">datetime time; class=class="str">"cmt">//--- Timestamp of the bar