为EA交易提供指标的现成模板(第2部分):交易量和比尔威廉姆斯指标(基础篇)
📘

为EA交易提供指标的现成模板(第2部分):交易量和比尔威廉姆斯指标(基础篇)

第 1/3 篇

「从模板起步:成交量与比尔·威廉姆斯指标怎么挂进EA」

在 MT5 里写 EA,不一定每次都从零造指标。系统自带的标准库里已经封装好一批现成指标模板,直接调用就能把成交量类与比尔·威廉姆斯(Bill Williams)系列指标接进交易逻辑。 对刚接手 MQL5 自动交易的用户来说,这类模板最实用的地方是省掉重复写缓冲区、句柄申请的代码。比如 iVolumes 和 iAlligator,参数结构在模板里已经定好,改几个外部输入就能跑。 以官方示例文章数据看,这类模板讲解帖在 2024 年 3 月 14 日发布后,页面访问量达到 1615 次、收藏 5 次,说明手动写指标句柄的需求仍然高频。打开 MT5 的 MQL5/Include/Indicators 目录,你能直接看到这些模板文件,复制改参比自己查文档快得多。 需要提醒的是,外汇与贵金属杠杆交易高风险,模板只解决「取数」问题,信号是否有效仍要在历史回测里验证,概率上未必优于裸价行为。

◍ 指标类库的模块切分

这套 MQL5 指标封装把功能按对象拆成了清晰的层级:先有交易量、集散、货币流量指数、能量潮、成交量这几类纯量价工具,再往下是比尔威廉姆斯系列,包含加速震荡、鳄鱼、动量振荡、分形、鳄鱼振荡和市场促进指数共 7 个子类。 每个子类都统一暴露四件事——参数、初始化、析构、读取数据,等于把 MT5 里散落的 iVolume、iMFI、iAO 等内置句柄调用收敛成可复用的 C++ 风格接口。 原文目录里还单列了「仪表板类的优化」一节,说明不止单指标,组合看板的资源开销也做了针对性处理;结尾的「结论」则是对整层封装的取舍做收口。 对读者来说,开 MT5 用 MetaEditor 搜这些类名,就能对照标准指标验证封装是否少包了某个缓冲区。

把交易量和大咖指标接进EA面板

这一节接着折腾EA里指标模板的复用,重点放在交易量与比尔·威廉姆斯那套指标怎么挂进自定义程序。之前系列首篇搭的仪表板会被继续复用,同时面板本身做了一些改进,具体变动留到本节末尾点一下。 对于涉及的每个指标,下面都给出现成模板:输入与全局变量、句柄初始化、反初始化、EA取数、面板显示样例,直接拷进MT5就能跑。 外汇与贵金属杠杆高、滑点跳空频繁,这类模板只解决取数显示,不暗示任何方向概率。把它当脚手架用,别当信号源。

「外汇里的交易量到底是什么」

在 MT5 里拖出 Volumes 指标,你会看到每根 K 线下方竖着一根柱。对股票或期货,这代表真实成交的合约数或金额;但外汇是场外分散交易,根本没有统一清算的成交量。 MT5 显示的『交易量』,实际是该时间周期内价格 tick 的跳动次数——也就是分时报价更新的频次。tick 越多,说明这周期内外价博弈越密集,柱体越高。 因此拿股票那套『放量突破』直接套 EURUSD 会有偏差:这里的高量只是报价活跃度,不是资金单边涌入的证据。贵金属 XAUUSD 同样适用这条定义,杠杆品种波动剧烈,误读量柱可能放大止损风险。

◍ 用 A/D 指标读透量价背离

集散指标(A/D)把成交量当作价格变动的加权系数:某根 K 线成交量越大,这段时间内的价格位移对指标值的贡献就越重。它本质是 OBV 的变体,核心目的都是借成交分布确认价格变动背后是买盘还是卖盘主导。 指标上行代表累积(净买入)概率偏高,因为大部分成交挂在上升波段;指标下行则倾向说明分散(净卖出)占优,抛压多集中在下跌时段。 A/D 与价格的背离是实战中最该盯的信号。若价格创新低而 A/D 抬升,说明低位承接量在悄悄堆积,价格随后朝指标方向修复的可能性更大;反之高点滞涨而 A/D 走低,回落概率上升。外汇与贵金属杠杆高、跳空频繁,背离失效时不设止损会迅速放大亏损,开 MT5 调出 A/D 叠加主图自行验证几次再下结论。

把集散指标句柄接进EA的参数写法

iAD() 只干一件事:返回集散指标(Accumulation/Distribution)的句柄,它只有一条缓冲区。调用时三个入参必须给清——symbol 填 NULL 就是抓当前品种;period 填 0 代表用当前图表周期,也可以塞 ENUM_TIMEFRAMES 里的具体帧;applied_volume 从 ENUM_APPLIED_VOLUME 里挑一种成交量类型。若创建失败,函数吐回 INVALID_HANDLE,不再用的句柄记得交给 IndicatorRelease() 释放,别占着内存。 在EA里跑这个指标,输入参数和全局变量得分两层声明。输入层用 input ENUM_APPLIED_VOLUME InpVolume=VOLUME_TICK 锁定成交量源;全局层至少留 handle(初始 INVALID_HANDLE)、ind_digits(指标小数位)、ind_title(描述串)三个变量,面板类文件若接仪表板也要一并包含。 为让线态判定不写死,原文扩了 ENUM_LINE_STATE 枚举,把向上、向下、反转、穿越、触碰等十三种状态列成常量。比如 LINE_STATE_CROSS_UP 表示向上穿越参考线,LINE_STATE_TOUCH_BELOW 是从下沿触碰——后续逻辑直接比枚举值即可,比硬算坐标干净。 下面这段是 MT5 里可直接编译验证的骨架,注意高亮处就是参数与全局变量的落点,复制进 .mq5 文件就能看到句柄创建入口。外汇与贵金属品种波动大、滑点随机,实盘接这套参数前务必在策略测试器用历史数据跑一遍,指标失效概率虽低但仍可能发生。

MQL5 / C++
<span class="keyword">class="type">int</span>&nbsp;&nbsp;<span class="indicators">iAD</span>(
&nbsp;&nbsp; <span class="keyword">class="type">class="kw">string</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; symbol,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="comment">class=class="str">"cmt">// symbol name</span>
&nbsp;&nbsp; <span class="macro">ENUM_TIMEFRAMES</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;period,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="comment">class=class="str">"cmt">// period</span>
&nbsp;&nbsp; <span class="macro">ENUM_APPLIED_VOLUME</span>&nbsp;&nbsp;applied_volume&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">// type of volume used for calculations</span>
&nbsp;&nbsp; );
<span class="comment">class=class="str">"cmt">//+------------------------------------------------------------------+</span>
<span class="comment">class=class="str">"cmt">//|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TestVolumeAD.mq5 |</span>
<span class="comment">class=class="str">"cmt">//|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copyright class="num">2023, MetaQuotes Ltd. |</span>
<span class="comment">class=class="str">"cmt">//|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [MQL5官方文档] |</span>
<span class="comment">class=class="str">"cmt">//+------------------------------------------------------------------+</span>
<span class="preprocessor">class="macro">#class="kw">property </span><span class="macro">copyright</span> <span class="class="type">class="kw">string">"Copyright class="num">2023, MetaQuotes Ltd."</span>
<span class="preprocessor">class="macro">#class="kw">property </span><span class="macro">link</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="class="type">class="kw">string">"[MQL5官方文档]
<span class="preprocessor">class="macro">#class="kw">property </span><span class="macro">version</span>&nbsp;&nbsp; <span class="class="type">class="kw">string">"class="num">1.00"</span>
<span class="comment">class=class="str">"cmt">//--- enums</span>
<span class="keyword">enum</span> ENUM_LINE_STATE
&nbsp;&nbsp;{
&nbsp;&nbsp; LINE_STATE_NONE,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">// Undefined state</span>
&nbsp;&nbsp; LINE_STATE_UP,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">// Upward</span>
&nbsp;&nbsp; LINE_STATE_DOWN,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">// Downward</span>
&nbsp;&nbsp; LINE_STATE_TURN_UP,&nbsp;&nbsp;&nbsp;&nbsp; <span class="comment">class=class="str">"cmt">// Upward reversal</span>
&nbsp;&nbsp; LINE_STATE_TURN_DOWN,&nbsp;&nbsp; <span class="comment">class=class="str">"cmt">// Downward reversal</span>
&nbsp;&nbsp; LINE_STATE_STOP_UP,&nbsp;&nbsp;&nbsp;&nbsp; <span class="comment">class=class="str">"cmt">// Upward stop</span>
&nbsp;&nbsp; LINE_STATE_STOP_DOWN,&nbsp;&nbsp; <span class="comment">class=class="str">"cmt">// Downward stop</span>
&nbsp;&nbsp; LINE_STATE_ABOVE,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="comment">class=class="str">"cmt">// Above value</span>
&nbsp;&nbsp; LINE_STATE_UNDER,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="comment">class=class="str">"cmt">// Below value</span>
&nbsp;&nbsp; LINE_STATE_CROSS_UP,&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">// Crossing value upwards</span>
&nbsp;&nbsp; LINE_STATE_CROSS_DOWN,&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">// Crossing value downwards</span>
&nbsp;&nbsp; LINE_STATE_TOUCH_BELOW, <span class="comment">class=class="str">"cmt">// Touching value from below </span>
&nbsp;&nbsp; LINE_STATE_TOUCH_ABOVE, <span class="comment">class=class="str">"cmt">// Touch value from above</span>
&nbsp;&nbsp; LINE_STATE_EQUALS,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">// Equal to value</span>
&nbsp;&nbsp;};
<span style="background-class="type">class="kw">color:rgb(class="num">216, class="num">232, class="num">194);"><span class="comment">class=class="str">"cmt">//--- input parameters</span>
<span class="keyword">input</span> <span class="macro">ENUM_APPLIED_VOLUME</span>&nbsp;&nbsp;InpVolume&nbsp;&nbsp; =&nbsp;&nbsp;<span class="macro">VOLUME_TICK</span>;&nbsp;&nbsp; <span class="comment">class=class="str">"cmt">/* Applied Volume */</span><span class="comment"></span></span>
<span style="background-class="type">class="kw">color:rgb(class="num">255, class="num">246, class="num">200);"><span class="comment">class=class="str">"cmt">//--- global variables</span>
<span class="keyword">class="type">int</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handle=<span class="macro">INVALID_HANDLE</span>;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">// Indicator handle</span>
<span class="keyword">class="type">int</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ind_digits=<span class="number">class="num">0</span>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="comment">class=class="str">"cmt">// Number of decimal places in the indicator values</span>
<span class="keyword">class="type">class="kw">string</span>&nbsp;&nbsp; ind_title;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">// Indicator description</span></span>
<span class="comment">class=class="str">"cmt">//+------------------------------------------------------------------+</span>
<span class="comment">class=class="str">"cmt">//|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TestVolumeAD.mq5 |</span>

常见问题

可以直接用指标类库里的交易量模板模块,把句柄创建和取值函数复制进EA,改个品种周期参数就能跑,不用从头写。
外汇是场外市场,平台量只是tick单量不是真实总成交,EA里只能当活跃度参考,别拿它当确定性信号。
小布可以读你EA里的指标句柄配置和面板输出,自动标出A/D背离漏掉的点,并提示集散指标周期是否不匹配。
按类库切分方式把鳄鱼、动量、量能分开成独立文件,EA主程序只调句柄,面板用参数写法统一挂,结构就清爽了。
在EA里取A/D双缓冲值,当价格新高而A/D走平或下行时置标志位,下一根K线满足条件的才发单,避免实时毛刺。