如何利用 MQL5 创建简单的多币种智能交易系统(第 1 部分):基于 ADX 指标的信号,并结合抛物线 SAR(基础篇)
用 ADX 搭配抛物线 SAR 搭多币种 EA 骨架
在 MT5 里做多币种交易,核心不是同时盯多少品种,而是先把单一信号逻辑写稳,再靠符号循环去横向铺开。本篇先用 ADX 判断趋势强度,再用抛物线 SAR 给进出场方向,两者组合能过滤掉一批震荡市的假突破。 ADX 默认周期 14,低于 20 通常视为趋势不足;SAR 的步长 0.02、最大值 0.2 是 MT5 内置默认值,信号翻转时价格与 SAR 点位置关系是直接可读的。实盘前建议在策略测试器里用 2023 年 EURUSD、XAUUSD 的 M15 数据各跑一遍,观察信号翻转滞后是否超过 3 根 K 线。 外汇与贵金属杠杆高,多币种同开会放大回撤,任何信号都只是概率倾向,必须先在模拟盘验证参数适应性。
◍ 为什么多币种EA在MT5上还很少见
这里说的多币种智能交易系统,指的是挂在一个品种图表上,却能对该图表以外的多个货币对执行开仓、平仓和订单管理的机器人。它和只盯一个对的普通EA最大的区别,就是交易标的跨出了宿主图表。 目前自动化交易需求很热,但MQL5社区里真正公开的多币种机器人程序不多,很多实现方式可能还被程序员捏在手里。 我们想补这个空档:用MQL5原生能力搭一个轻量多币种EA,信号源选平均方向走势指标(ADX,原文写ADM应为笔误)叠加抛物线SAR,逻辑不复杂但能直接跑。外汇和贵金属杠杆高,多币种同跑会放大回撤,实盘前务必在策略测试器里验。
「三十个品种上的双指标信号与订单管理逻辑」
这套多币种系统覆盖 28 个常见外汇直盘与交叉盘,再加 XAUUSD、XAGUSD 两个贵金属对,合计 30 个品种。它依赖经纪商标准命名,带前后缀的自定义符号名不在适用范围内,外汇与贵金属杠杆波动大,实盘前需在 MT5 策略测试器里先验证品种映射。 主信号用周期 7 的 ADX,确认信号用抛物线 SAR,两者默认取智能系统设定的同一时间帧;SAR 额外参考 M15 与 M5 来判别趋势强弱。ADX 的触发写法是 +DI 与 -DI 的跨柱比较,其中 difference 固定为 0.34,即前一根柱满足 +DI[1] > -DI[1]+0.34 视为买入条件成立,反之为卖出条件。 V0 与 V1 把正负 DI 的比值转成百分比差:V0=(当前柱 PLUSDI/MINUSDI×100)-100,V1 取前一根柱。只要 V0>V1,ADX 条件偏上行;V0<V1 则偏下行。SAR 的破位很简单——PRICE_LOW[0]>iSAR[0] 算上行,PRICE_HIGH[0]<iSAR[0] 算下行。 订单管理分四块:止损可关也可开,开了还能选自动计算或手填点数;止盈同理。尾随止损/止盈若开自动,就贴着 SAR 值走,否则用输入项里的数值,系统会同时拖俩。面板还给了三个手动键:一键给全部订单补 SL/TP、一键全平、一键只平盈利单,省得在 30 个品种间来回切图。
多币种EA的程序骨架与信号触发链
做多币种自动交易,第一步是把品种、指标句柄和风控参数塞进一个类里统一管理。OnInit() 里最先跑的是 ADXPSAR_MCEA_Config(),它负责把要用到的 30 个品种(对)、各周期指标句柄和核心函数全部配置好,避免在 OnTick() 里反复声明。 跳价函数 OnTick() 只做一件事:调用 ExpertActionTrade()。这个函数包揽了开单、平单、尾随止损/止盈等全部活动,相当于把多币种工作流的主循环收口到一处。 开平仓信号不是直接读指标,而是走 GetOpenPosition(symbol)。它内部串起四个子函数:DirectionMove 查当前周期K线方向,PARSAR15 查 M15 的 iSAR 升降,PARSAROp 查信号周期 iSAR 升降,iADXCross 查信号周期 ADX 的 +DI/-DI 交叉。其中 iADXCross 还会再调 iADXpct() 算两条线的百分比差,过滤假交叉。 要拿到指标值,每个品种都得先通过 PairsIdxArray(symbol) 取回句柄索引编号 x,否则多币种并发时会读错对象。以 PARSAR15() 为例,必须用对应品种的 iSAR 句柄去取 M15 抛物线数据,硬编码句柄在多币种环境里必然崩。 界面交互靠 ChartEvent:M 键弹出手动面板,可批量设止损止盈、全平或只平盈利单;C 键换图表品种(面板含 30 个货币对/贵金属对,点击即切换);R 键卸载 EA。外汇与贵金属波动剧烈,这类一键全平功能在滑点扩大时可能成交在预期外价格,实盘前务必在 MT5 策略测试器用历史数据跑一遍。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Include | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#include <Trade\Trade.mqh> class="macro">#include <Trade\PositionInfo.mqh> class="macro">#include <Trade\SymbolInfo.mqh> class="macro">#include <Trade\AccountInfo.mqh> class=class="str">"cmt">//-- CTrade mc_trade; class=class="str">"cmt">// 交易操作对象,封装下单/平仓/改单 CSymbolInfo mc_symbol; class=class="str">"cmt">// 品种信息对象,取点值/止损位等 CPositionInfo mc_position; class=class="str">"cmt">// 持仓信息对象,遍历当前仓位 CAccountInfo mc_account; class=class="str">"cmt">// 账户对象,读净值/杠杆 class=class="str">"cmt">//--- enum YN class=class="str">"cmt">// 是否类枚举,用于输入项开关 { No, Yes }; class=class="str">"cmt">//-- enum mmt class=class="str">"cmt">// 手数管理枚举:固定或动态 { FixedLot, class=class="str">"cmt">// 固定手数 DynamLot class=class="str">"cmt">// 动态手数(按权益风险) }; class=class="str">"cmt">//-- enum TFX class=class="str">"cmt">// 信号周期枚举,覆盖 H1 到 D1 { TFH1, class=class="str">"cmt">// PERIOD_H1 TFH2, class=class="str">"cmt">// PERIOD_H2 TFH3, class=class="str">"cmt">// PERIOD_H3 TFH4, class=class="str">"cmt">// PERIOD_H4 TFH6, class=class="str">"cmt">// PERIOD_H6 TFH8, class=class="str">"cmt">// PERIOD_H8 TFH12, class=class="str">"cmt">// PERIOD_H12 TFD1 class=class="str">"cmt">// PERIOD_D1 }; class=class="str">"cmt">//-- class=class="str">"cmt">//--- class="kw">input group "=== Global Strategy EA Parameter ==="; class=class="str">"cmt">// 全局策略参数分组 class="kw">input TFX TimeFrames = TFH4; class=class="str">"cmt">// 选信号周期,默认 H4 class="kw">input class="type">int ADXPeriod = class="num">7; class=class="str">"cmt">// ADX 周期参数 class="kw">input group "=== Money Management Lot Size Parameter ==="; class=class="str">"cmt">// 资金管理分组 class="kw">input mmt mmlot = DynamLot; class=class="str">"cmt">// 资金管理方式,默认动态 class="kw">input class="type">class="kw">double Risk = class="num">10.0; class=class="str">"cmt">// 每笔风险占净值百分比,class="num">1%~class="num">10% class="kw">input class="type">class="kw">double Lots = class="num">0.01; class=class="str">"cmt">// 固定手数模式下用手数 class=class="str">"cmt">//--Day Trading On/Off
◍ 按交易日与风控开关切EA行为
EA 的 input 分组把「哪天能跑」和「订单怎么管」拆成两块,直接决定策略在 MT5 上何时下单、止损止盈怎么挂。外汇与贵金属波动受时段影响明显,周日、周六默认关掉(ttd0=No、ttd6=No),周一到周五全开,这种设定倾向避开流动性最差的周末跳空。 下面这段是原文里的参数声明,逐行拆一下: input group "=== Day Trading On/Off ==="; // 建一个输入分组,专门放交易日开关 input YN ttd0 = No; // 周日不允许交易 input YN ttd1 = Yes; // 周一允许交易 input YN ttd2 = Yes; // 周二允许交易 input YN ttd3 = Yes; // 周三允许交易 input YN ttd4 = Yes; // 周四允许交易 input YN ttd5 = Yes; // 周五允许交易 input YN ttd6 = No; // 周六不允许交易 //--Trade & Order management Parameter input group "=== Trade & Order management Parameter ==="; // 建第二个分组管订单 input YN use_sl = No; // 总开关:不手动用止损 input YN autosl = Yes; // 但开自动止损计算 input double SLval = 30; // 若不用自动止损,则固定 30 点 input YN use_tp = No; // 总开关:不手动用止盈 input YN autotp = Yes; // 但开自动止盈计算 input double TPval = 50; // 若不用自动止盈,则固定 50 点 input YN TrailingSLTP = Yes; // 开跟踪止损止盈 input YN autotrl = No; // 但不走自动跟踪 input double TSval = 5; // 手动跟踪距离 5 点 注意 SLval=30、TPval=50 只在 autosl/autotp 为 No 时才生效;当前 autosl=Yes、autotp=Yes,所以这两个值只是备胎。真要验证,把 autotrl 改成 Yes 看跟踪逻辑是否接管,MT5 策略测试器里跑一周数据就能比对权益曲线差异。高风险品种下,这类开关组合可能放大滑点损耗,参数落地前先跑历史回测。
class="kw">input group "=== Day Trading On/Off ==="; class=class="str">"cmt">// Day Trading On/Off class="kw">input YN ttd0 = No; class=class="str">"cmt">// Select Trading on Sunday(Yes) or(No) class="kw">input YN ttd1 = Yes; class=class="str">"cmt">// Select Trading on Monday(Yes) or(No) class="kw">input YN ttd2 = Yes; class=class="str">"cmt">// Select Trading on Tuesday(Yes) or(No) class="kw">input YN ttd3 = Yes; class=class="str">"cmt">// Select Trading on Wednesday(Yes) or(No) class="kw">input YN ttd4 = Yes; class=class="str">"cmt">// Select Trading on Thursday(Yes) or(No) class="kw">input YN ttd5 = Yes; class=class="str">"cmt">// Select Trading on Friday(Yes) or(No) class="kw">input YN ttd6 = No; class=class="str">"cmt">// Select Trading on Saturday(Yes) or(No) class=class="str">"cmt">//--Trade & Order management Parameter class="kw">input group "=== Trade & Order management Parameter ==="; class=class="str">"cmt">// Trade & Order management Parameter class="kw">input YN use_sl = No; class=class="str">"cmt">// Use Order Stop Loss(Yes) or(No) class="kw">input YN autosl = Yes; class=class="str">"cmt">// Use Automatic Calculation Stop Loss(Yes) or(No) class="kw">input class="type">class="kw">double SLval = class="num">30; class=class="str">"cmt">// If Not Use Automatic SL - Input SL value in Pips class="kw">input YN use_tp = No; class=class="str">"cmt">// Use Order Take Profit(Yes) or(No) class="kw">input YN autotp = Yes; class=class="str">"cmt">// Use Automatic Calculation Take Profit(Yes) or(No) class="kw">input class="type">class="kw">double TPval = class="num">50; class=class="str">"cmt">// If Not Use Automatic TP - Input TP value in Pips class="kw">input YN TrailingSLTP = Yes; class=class="str">"cmt">// Use Trailing SL/TP(Yes) or(No) class="kw">input YN autotrl = No; class=class="str">"cmt">// Use Automatic Trailing(Yes) or(No) class="kw">input class="type">class="kw">double TSval = class="num">5; class=class="str">"cmt">// If Not Use Automatic Trailing Input Trailing value in Pips
「把参数和类骨架落进 EA 里」
EA 尾部这组 input 决定了风控开关与识别号:TSmin=5 表示浮盈满 5 点后才启动追踪止损;Close_by_Opps 与 SaveOnRev 都设 Yes,意味着反向信号出现会平仓、弱信号也锁利润离场。magicEA=202307 是订单魔数,多 EA 同跑时靠它区分归属,外汇与贵金属杠杆高,魔数冲突可能误平别的单。 alerts=Yes 但 UseEmailAlert、UseSendnotify 均 No,说明只在图表弹消息不往外推;trade_info_display=Yes 会在图上画交易信息,盯盘时不用切终端窗口。 下面 MCEA 类先把时间分量(年/月/日/时/分/秒)和几个私有整型、双精度变量声明好,这是后续算信号和挂单的底层容器。开 MT5 把这段粘进 MQ4/MQ5 编辑器,改 TSmin 到 8~10 观察回撤变化,比直接跑默认更稳。
class="kw">input class="type">class="kw">double TSmin = class="num">5; class=class="str">"cmt">// Minimum Pips to start Trailing Stop class="kw">input YN Close_by_Opps = Yes; class=class="str">"cmt">// Close Trade By Opposite Signal(Yes) or(No) class="kw">input YN SaveOnRev = Yes; class=class="str">"cmt">// Close Trade and Save profit due to weak signal(Yes) or(No) class=class="str">"cmt">//--Others Expert Advisor Parameter class="kw">input group "=== Others Expert Advisor Parameter ===" ; class=class="str">"cmt">// Others EA Parameter class="kw">input YN alerts = Yes; class=class="str">"cmt">// Display Alerts / Messages(Yes) or(No) class="kw">input YN UseEmailAlert = No; class=class="str">"cmt">// Email Alert(Yes) or(No) class="kw">input YN UseSendnotify = No; class=class="str">"cmt">// Send Notification(Yes) or(No) class="kw">input YN trade_info_display = Yes; class=class="str">"cmt">// Select Display Trading Info on Chart(Yes) or(No) class="kw">input class="type">ulong magicEA = class="num">202307; class=class="str">"cmt">// Expert ID(Magic Number) class=class="str">"cmt">//--- class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Class for working Expert Advisor | class=class="str">"cmt">//+------------------------------------------------------------------+ class MCEA { class=class="str">"cmt">//--- class="kw">private: class=class="str">"cmt">//---- class="type">int x_year; class=class="str">"cmt">// Year class="type">int x_mon; class=class="str">"cmt">// Month class="type">int x_day; class=class="str">"cmt">// Day of the month class="type">int x_hour; class=class="str">"cmt">// Hour in a day class="type">int x_min; class=class="str">"cmt">// Minutes class="type">int x_sec; class=class="str">"cmt">// Seconds class=class="str">"cmt">//-- class="type">int oBm, oSm, ldig; class="type">int posCur1, posCur2; class=class="str">"cmt">//-- class="type">class="kw">double LotPS, difDi; class="type">class="kw">double slv, tpv;