向导EA自定义策略实战
改标准库信号类添加专属交易模式
什么是MQL5向导与标准库交易策略类
在MetaTrader 5中,EA交易(Expert Advisor)可以通过MQL5向导快速生成,无需从零编写全部代码。向导的核心依赖是MQL5标准库中的交易策略类,特别是Expert和Signal系列包含文件。标准库已经为MT5自带的技术指标(如RSI、MA、CCI等)编写了对应的信号类,这些类封装了指标调用、模式判断和投票逻辑,使得用户只需在向导中勾选指标并配置参数,就能得到一个可运行的EA框架。
对于初学者而言,这种机制极大降低了程序化交易的门槛:你不需要深入理解订单发送、资金管理或追踪止损的实现,标准库已经处理好这些底层工作。你要做的,是理解信号类如何产生买卖“投票”,以及这些投票如何根据权重和阈值转化为实际持仓。
用向导生成基础EA并分析代码结构
在MetaEditor中,从“文件”菜单选择“新建”,然后选“EA交易(生成)”。将生成的EA命名为MyExpert,添加RSI和MA两个信号,使用默认参数或自行设置。完成后会得到MyExpert.mq5文件。该文件通过#include指令引入标准库信号类,并在OnInit中创建过滤器对象,把指标逻辑挂入EA核心。
#include <Expert\Expert.mqh> #include <Expert\Signal\SignalRSI.mqh> #include <Expert\Signal\SignalMA.mqh>
生成的代码里,filter0对应RSI,filter1对应MA。每个过滤器是CSignalRSI或CSignalMA的实例,通过signal.AddFilter加入信号池。EA初始化时会调用InitIndicators完成指标句柄创建。理解这一点后,我们就能明白:所谓“策略”,就是一组信号过滤器,它们各自投票,最后由Expert类汇总。
CSignalRSI *filter0=new CSignalRSI;
if(filter0==NULL) { printf(__FUNCTION__+": error creating filter0"); ExtExpert.Deinit(); return(-3); }
signal.AddFilter(filter0);
复制并修改信号类添加自定义过滤器
标准库信号文件位于MQL5\Include\Expert\Signal\。我们以CCI为例:将SignalCCI.mqh复制为SignalCCIxx.mqh,放在同一目录。然后在MyExpert.mq5中添加第三个过滤器filter2,并包含我们的自定义文件。这样EA就拥有了RSI、MA和CCIxx三个信号源。
#include <Expert\Signal\SignalCCIxx.mqh> // This is our own 'custom' indicator for custom Signal management of the EA
CSignalCCIxx *filter2=new CSignalCCIxx;
if(filter2==NULL) { printf(__FUNCTION__+": error creating filter2"); ExtExpert.Deinit(); return(-4); }
signal.AddFilter(filter2);
filter2.PeriodCCIxx(Signal_CCIxx_PeriodCCI);
filter2.Applied(Signal_CCIxx_Applied);
filter2.Weight(Signal_CCIxx_Weight);
在SignalCCIxx.mqh中,用CTRL+H把“CCI”替换为“CCIxx”(约41处),避免与原有CiCCI类冲突。编译应无错误。这一步本质是“半自定义”:我们复用标准指标的计算,只改写信号逻辑,因此稳定性由标准库保障。
理解模式(Pattern)与权重变量
每个信号类内部用m_pattern_0到m_pattern_3(标准)定义内置市场模型,例如CCI的“方向确认”“超买超卖反转”“背离”等。我们在自定义文件中增加m_pattern_4和m_pattern_5两个int变量,作为自己的模式。模式就是一段条件代码,成功时返回该模式的权重值(0-100),失败返回0。
int m_pattern_4; // model 4 "our own first new pattern: values cross the zero" int m_pattern_5; // model 5 "our own second new pattern: values bounce around the zero"
在构造函数中给这些模式赋默认权重,例如都设90。权重代表该模式在投票中的“票数上限”。如果设为0,等于禁用该模式。模式的买入条件写在LongCondition,卖出写在ShortCondition,通过IS_PATTERN_USAGE宏判断是否启用。
m_pattern_4 =90; // model 4 "our own first new pattern: " m_pattern_5 =90; // model 5 "our own second new pattern:
编写自定义模式:CCI零轴穿越示例
我们以CCI指标为例,添加两个未经验证仅供学习的模式。模式4:柱1的CCI>0且柱2的CCI<0,视为价格将上涨信号;反向则视为下跌。模式5:柱1>0、柱2<0、柱3>0,视为零轴附近反弹上涨;反向为下跌。代码中idx是当前柱,idx+1是前一根,以此类推。
if(IS_PATTERN_USAGE(4) && CCIxx(idx+1)>0.0 && CCIxx(idx+2)<0.0) result=m_pattern_4; // signal number 4 if(IS_PATTERN_USAGE(5) && CCIxx(idx+1)>0.0 && CCIxx(idx+2)<0.0 && CCIxx(idx+3)>0.0) result=m_pattern_5; // signal number 5
在ShortCondition中写对称逻辑:CCIxx(idx+1)<0且idx+2>0触发模式4空投投票。这样每个模式同时提供多头和空头两种方向的“选票”,符号由条件分支自然决定(多头正、空头负)。
信号强度与阈值开平仓机制详解
EA输入参数里有Signal_ThresholdOpen和Signal_ThresholdClose(0-100)。信号强度 = 某方向所有激活模式的(权重×信号类外部权重Weight)之和的平均值绝对值。例如CCIxx的Weight输入0.8,模式4权重80,则多头强度=0.8*80=64。若同时RSI模式1权重100且Weight0.7,则合计(64+70)/2=67。
input int Signal_ThresholdOpen =40; // Signal threshold value to open [0...100] input int Signal_ThresholdClose=60; // Signal threshold value to close [0...100]
开仓规则:多头强度>=ThresholdOpen时建多;若之前有空仓且强度>=ThresholdClose则平空并可能反手。空头同理用负值绝对值比较。若ThresholdClose<=ThresholdOpen,达到Close即反手;若>=则覆盖式反手。权重系统让多个指标“投票竞争”,避免单指标误判。
- 强度计算:各信号类内部模式值×外部Weight,同方向平均
- 开多:正强度>=Open阈值
- 平空:负信号绝对值>=Close阈值
- 反手:Close<=Open时信号反向即反转;Close>=Open时直接覆盖
挂单价格级别与过期参数
Signal_PriceLevel决定信号触发时是下止损单还是限价单:负值=止损单(买入止损/卖出止损),正值=限价单(买入限价/卖出限价)。例如买仓PriceLevel=-70,当前价1.2500,则挂1.2570买入止损。Signal_Expiration是挂单有效柱数,超过未触自动撤销。
input double Signal_PriceLevel =0.0; // Price level to execute a deal input int Signal_Expiration =4; // Expiration of pending orders (in bars)
这些参数让向导EA不止于市价追单,可做成突破或回踩策略。配合自定义模式,你能用极少代码实现丰富的订单逻辑。
回测验证与实战建议
编译SignalCCIxx.mqh和MyExpert.mq5后,在策略测试器用EURUSD等品种回测。原文作者用类2011锦标赛参数取得不错曲线,但强调自定义模式未实盘验证,仅作教学。你应不断调整模式条件和权重,做样本外测试。
这种方法的优势是:交易核心(下单、风控、资金)由标准库保证正确,你只改信号思想。即使不会复杂编程,也能在1小时内拼出“锦标赛友好”的EA原型。建议从复制CCI类开始,逐步尝试其他指标,形成自己的信号库。