MQL5 中艾略特波浪自动分析的实施(基础篇)
◍ 在 MT5 里跑通艾略特波浪自动识别
艾略特波浪的手动数浪在 MT5 上很费眼,尤其当品种是 XAUUSD 或 EURUSD 这种波动快的高风险标的,错判驱动浪与调整浪会直接带歪仓位。MQL5 提供了直接用代码抓取价格分形并套波浪规则的能力,不必依赖肉眼。 一个朴素的实现思路是:先取最近 N 根 K 线的极值(分形点),再按波浪的 5+3 结构做模式匹配。下面这段示例骨架能在 MT5 策略测试器里直接建文件跑,验证它能否在你的图表上标出前三个驱动浪。 外汇与贵金属杠杆高,自动数浪只是辅助,信号失效时回撤可能超出预期,任何结论都只是概率倾向。
「为什么需要自动标记器」
艾略特波浪理论在交易圈里算是最常被拿来做市场结构解读的框架之一,但实际手动画浪对多数人来说是体力活,拐点确认和层级嵌套极易出错。 为了把主观判断从图表上剥离,引入自动标记器是务实的选择——它按既定规则扫描价格序列,直接把疑似波浪结构画出来。 本文后续会用 MQL5 写一套自动分析程序来干这件事。默认你已经懂波浪理论的基本划分;若还没系统学过,先补一下推动浪与调整浪的规范再往下看,否则代码跑出来的标记你看不懂。
推与调的嵌套循环:艾略特波浪骨架
艾略特波浪把市场波动拆成推动波和调整波的交替循环,背后假设是群体心理驱动价格,而非随机游走。推动波固定为五段价格运动,调整波则是三段或五段,二者在形态和规则上都有硬约束。 以最基础的推动波为例:第二波终点不破第一波起点,第三波必然越过第一波顶且绝不会是最短的一波,第四波不破第一波顶。这些规则在 MT5 上调出任意周期图表都能肉眼复核,是手动数浪的第一道过滤器。 调整波的分类更杂,锯齿、平顶、双锯齿、三角形等共 11 类基础模型,每类对 A/B/C(或 W/X/Y)的内部结构都有明确限制,比如扩散三角形里 C 长度必大于 B、D 必大于 C。原文图 1–11 还揭示一个关键点:每个大波内部用虚线标出的更小波,本质是同构的分形嵌套,大级别五波里套着小级别五波。 外汇和贵金属市场高杠杆、易跳空,经典波浪规则在极端行情常失效;现代研究补充了滑动三角形、第二波带三角形推动等变体,实盘标注时别只守教科书。打开 MT5 的波浪自动标记脚本前,先拿这几条不破位规则当标尺,能少数错一半的假浪。
◍ 自动标记靠分形递归还是穷举路径
艾略特波浪手工划分费时且主观,自动标记通常走两条路线:一是顺着分形从大周期往小周期拆,二是直接把点位组合穷举出来再过滤。两条路线不互斥,工程上经常叠加使用。 以推动波为例,先用 Zigzag 在选定时间区间抓拐点。分析推动波需要 6 个关键点:1 个起点加 5 个顶点;若是锯齿波则只需 4 个(3 顶点 + 1 起点)。Zigzag 刚好抓到 6 点,就能直接映射成 1~5 浪的端点。 实战里 Zigzag 常抓出 8 个点而非 6 个。此时系统会枚举全部组合,推动波场景下可能产生 5 种不同颜色的候选标记,再逐条按波浪规则校验。通过校验的标记,其子浪会以同样逻辑继续向下递归拆分。外汇与贵金属市场波动剧烈,自动标记仅作概率参考,实盘仍需人工确认。
「自动标记里的波浪状态分类」
在 MT5 里做艾略特波浪的自动识别,最大的麻烦是:顶层区间往往无法确定某段浪的起点、终点与完成状态。程序因此把这类没法定位的浪打上两种标记——未开始(用编号后加 < 表示)和未结束(编号后加 > 表示),二者可单独出现,也可叠加在同一组结构上。 具体拆分看,未开始类里从缺第 1 波到第 5 波都有对应模板:比如缺第 1 波的推动波记为 1-2-3-4-5,程序需要后续补 5 个点;只缺第 5 波的推动波记为 5,仅需补 1 个点。未结束类则反过来,从 1> 到 1-2-3-4-5 分别对应缺尾段的不同完成度,像 1> 的平顶波只差 1 个点收口。 还有一类既未开始又未结束,例如 W<-X> 表示三重三波里 W 波没起头、X 波没收尾,程序此时只需 1 个点就能推进判定;而 1-2-3-4-5> 这种缺 Z 波的三重三结构,则要等 4 个点。已完成浪最吃点数:五段式 1-2-3-4-5 需 6 个点确认,三段式 1-2-3 需 4 个点。 实际看图时,若见到 A-B-C 中 A 带 <、W 带 <-X> 带 >,就是典型的部分完成形态。把这些状态映射成点数阈值后,你能在 EA 里用分支逻辑决定何时触发重绘,外汇与贵金属波动无序,这类自动标记仅作概率参考,不代表走势必然延续。
自动数浪程序里的核心数据结构
在 MT5 里写艾略特波浪自动识别,第一步不是画指标,而是把波浪的层级关系和数据落点用结构固化下来。原文给出的七类结构覆盖了从单浪描述到整棵波浪树的存储:波浪模板描述、具体浪参数、锯齿顶点、树节点、锯齿命中点、已分析区间、图表标记预存。 下面这段声明直接决定了后续递归能不能跑通。TWaveDescription 用 Subwaves[6] 存该浪可能的子浪名,NumWave 限制子浪数量;TWave 则把每一浪的端点价 ValueVertex[6] 和 K 线索引 IndexVertex[6] 绑在一起,Level 字段区分浪级。 // The structure of the description of the analyzed waves in the program struct TWaveDescription { string NameWave; // name of the wave int NumWave; // number of sub-waves in a wave string Subwaves[6]; // the names of the possible sub-waves in the wave }; // A class for storing the parameters of a wave class TWave { public: string Name; // name of the wave string Formula; // the formula of the wave (1-2-3-4-5, <1-2-3 etc.) int Level; // the level of the wave double ValueVertex[6]; // the value of the top of the wave int IndexVertex[6]; // the indexes of the top of the waves }; // A class for storing the values of vertexes and indexes of the zigzag class TZigzag:public CObject { public: CArrayInt *IndexVertex; // indexes of the vertexes of the zigzag CArrayDouble *ValueVertex; // value of the vertexes of the zigzags }; // A class for the presentation of the tree of the waves class TNode:public CObject { public: CArrayObj *Child; // the child of the given tree node TWave *Wave; // the wave, stored in the given tree node string Text; // text of the tree node TNode *Add(string Text,TWave *Wave=NULL) // the function of adding the node to the tree { TNode *Node=new TNode; Node.Child=new CArrayObj; Node.Text =Text; Node.Wave=Wave; Child.Add(Node); return(Node); } }; // The structure for storing the points, found by the zigzag struct TPoints { double ValuePoints[]; // the values of the found points int IndexPoints[]; // the indexes of the found points int NumPoints; // the number of found points }; // A class for storing the parameters of the already analyzed section, corresponding to the wave tree node class TNodeInfo:CObject { public: int IndexStart,IndexFinish; // the range of the already analyzed section double ValueStart,ValueFinish; // the edge value of the already analyzed section string Subwaves; // the name of the wave and the group of the waves TNode 的 Add 方法用 Child.Add(Node) 把新节点挂到当前节点下,返回 Node 指针,这让波浪树能用递归向下生长;TPoints 用动态数组 ValuePoints[] 接锯齿指标吐出的拐点,NumPoints 实时计数。 实盘里外汇与贵金属波动受杠杆和跳空影响,波浪端点可能被影线刺穿,用 IndexVertex 锁 K 线序号比只存价格更抗重绘。开 MT5 新建 EA 把上面结构粘进头文件,先编译过一遍,再决定子浪匹配逻辑怎么写。
class=class="str">"cmt">// The structure of the description of the analyzed waves in the program class="kw">struct TWaveDescription { class="type">class="kw">string NameWave; class=class="str">"cmt">// name of the wave class="type">int NumWave; class=class="str">"cmt">// number of sub-waves in a wave class="type">class="kw">string Subwaves[class="num">6]; class=class="str">"cmt">// the names of the possible sub-waves in the wave }; class=class="str">"cmt">// A class for storing the parameters of a wave class TWave { class="kw">public: class="type">class="kw">string Name; class=class="str">"cmt">// name of the wave class="type">class="kw">string Formula; class=class="str">"cmt">// the formula of the wave(class="num">1-class="num">2-class="num">3-class="num">4-class="num">5, <class="num">1-class="num">2-class="num">3 etc.) class="type">int Level; class=class="str">"cmt">// the level of the wave class="type">class="kw">double ValueVertex[class="num">6]; class=class="str">"cmt">// the value of the top of the wave class="type">int IndexVertex[class="num">6]; class=class="str">"cmt">// the indexes of the top of the waves }; class=class="str">"cmt">// A class for storing the values of vertexes and indexes of the zigzag class TZigzag:class="kw">public CObject { class="kw">public: CArrayInt *IndexVertex; class=class="str">"cmt">// indexes of the vertexes of the zigzag CArrayDouble *ValueVertex; class=class="str">"cmt">// value of the vertexes of the zigzags }; class=class="str">"cmt">// A class for the presentation of the tree of the waves class TNode:class="kw">public CObject { class="kw">public: CArrayObj *Child; class=class="str">"cmt">// the child of the given tree node TWave *Wave; class=class="str">"cmt">// the wave, stored in the given tree node class="type">class="kw">string Text; class=class="str">"cmt">// text of the tree node TNode *Add(class="type">class="kw">string Text,TWave *Wave=NULL) class=class="str">"cmt">// the function of adding the node to the tree { TNode *Node=new TNode; Node.Child=new CArrayObj; Node.Text =Text; Node.Wave=Wave; Child.Add(Node); class="kw">return(Node); } }; class=class="str">"cmt">// The structure for storing the points, found by the zigzag class="kw">struct TPoints { class="type">class="kw">double ValuePoints[]; class=class="str">"cmt">// the values of the found points class="type">int IndexPoints[]; class=class="str">"cmt">// the indexes of the found points class="type">int NumPoints; class=class="str">"cmt">// the number of found points }; class=class="str">"cmt">// A class for storing the parameters of the already analyzed section, corresponding to the wave tree node class TNodeInfo:CObject { class="kw">public: class="type">int IndexStart,IndexFinish; class=class="str">"cmt">// the range of the already analyzed section class="type">class="kw">double ValueStart,ValueFinish; class=class="str">"cmt">// the edge value of the already analyzed section class="type">class="kw">string Subwaves; class=class="str">"cmt">// the name of the wave and the group of the waves