目录

MT4市场报价品种不全 - MT4突破交易自动化实战EA编写全程记录

MT4突破交易自动化实战EA编写全程记录
做交易时间久了,你会发现那些所谓的“突破开仓”其实是最容易量化的策略之一。价格突破了某个关键水平,然后顺势进场,听起来简单,但真要靠手动盯盘去抓,几乎不可能做到每次都及时反应。尤其是半夜或者你刚好离开电脑的那几分钟,行情往往就启动了。所以用MT4自带的MetaEditor写一个EA来自动监控价格突破,就成了很多交易者绕不开的一步。这篇文章我就把这套EA的编写思路和具体实现过程完整捋一遍,从逻辑设计到代码落地,再到参数优化和回测验证,每个环节都会讲到。

突破策略的核心逻辑拆解

在动手写代码之前,先把策略逻辑彻底想清楚。所谓的“突破交易”,本质上就是价格对某个关键水平位的有效穿越。这个关键水平可以是前高、前低,也可以是布林带上下轨、斐波那契回撤位,或者你自己画的一条水平线。EA要做的,就是持续监控当前价格是否突破了这些水平,并且在你设定的条件下触发开仓指令。

这里有个容易踩坑的点:到底怎么定义“突破”?是收盘价站上去了算突破,还是盘中最高价碰到了就算?我个人的经验是,用收盘价来判断会更稳定一些,因为盘中瞬间的插针很容易造成假突破。但收盘价判断也有延迟,所以很多人会在K线收盘前几秒就提前检测。另外,突破后的确认也很重要,有些策略要求价格突破后回踩不破再进场,有些则直接追单。这个没有绝对的标准,完全看你的交易风格和风险承受能力。

在实际编写EA时,我会把“突破”的定义拆成两个条件:第一,当前K线的最高价或者最低价必须超过设定的关键价位;第二,这个突破必须发生在特定的时间范围内,比如只在伦敦开盘后的两个小时里有效。这样做的目的是过滤掉亚洲盘那种波动极小、假突破频发的时段。还有一点,关键水平位的取值最好能动态更新,比如自动取最近20根K线的最高点作为突破上轨,这样EA就能适应不同周期的市场状态。

最后,风险控制这块也必须写进逻辑里。突破交易最大的敌人就是假突破后的快速反转,所以止损的设置一定要合理。我一般会把这个关键水平位作为止损参考,如果价格突破了但又跌回水平位下方,那就说明突破失败,立刻止损离场。止盈方面可以用固定点数,也可以用移动止损来跟踪趋势。
这些逻辑全部确定好之后,才能进入代码编写阶段。

EA代码结构与关键函数详解

MT4的EA本质上是一个无限循环的程序,它的核心是OnTick函数,每当价格有新的跳动时,这个函数就会被触发一次。我们需要做的,就是把突破判断逻辑写在这个函数里。代码结构其实不复杂,主要分为初始化、主逻辑、订单管理和辅助函数四个部分。初始化部分主要用来设置一些全局变量和参数默认值,比如我们想要监控的周期是M15还是H1,突破水平位是固定值还是动态计算的。

动态突破水平的计算是代码里的重头戏。我通常会使用iHigh和iLow函数来获取指定周期内的最高价和最低价。比如要计算最近20根M15K线的最高点,就写一个循环,从1到20逐根比较,找出最大值。这里有个细节要注意,索引0代表当前未收盘的K线,所以循环要从1开始,避免用到尚未定型的数据。计算出突破水平之后,再拿当前价格和这个水平做比较,如果价格上穿且前一根K线的收盘价在下轨下方,那就符合了买入条件。

订单管理这部分相对比较标准,用OrderSend函数就能实现。但有几个参数必须认真对待:一个是滑点设置,我一般设成10个点,太小了容易下单失败,太大了又会增加成本。另一个是止损止盈的设置,这需要在订单注释里写明,方便后续EA识别自己下的单子。还有一个关键点就是防止重复下单,每次开仓前必须检查当前持仓中是否已经有这个品种的订单,否则EA会在每一根K线跳动时反复开仓,那就灾难了。

辅助函数里最重要的是一个判断突破有效性的过滤器。我的做法是记录下突破发生时的价格,然后设定一个阈值,比如20个点。如果价格在突破后继续向突破方向移动超过这个阈值,就开仓;如果价格只是刚刚碰到水平位就回落,那就放弃。这个过滤器能过滤掉相当一部分假突破,代价是会错过一些急速行情,但整体胜率会提高不少。编写时还要注意,MT4的EA是单线程的,所有操作都要在OnTick里快速完成,不能有延迟操作或者循环等待。

参数设置与回测优化的实操经验

代码写完之后,最关键的步骤来了:参数设置和回测。很多人写完EA就直接挂到模拟盘上跑,这是很危险的。我自己的习惯是先在MT4的策略测试器里跑至少三个月的历史数据,覆盖不同的市场状态。回测时有一个重要设置必须改:把“每个实时点”改成“每个报价基于真实数据”,这样可以模拟得更真实。如果回测结果里的曲线非常完美,没有回撤,那多半是EA里有什么对未来数据的引用,也就是所谓的偷价行为。

在参数优化方面,突破周期的选择非常敏感。我试过用5、10、20、50这几个不同的周期值去跑同一段历史数据,结果差异巨大。周期太短,比如5根K线,突破信号会非常多,但假突破的比例也高;周期太长,比如50根,信号又太少,一年下来开不了几次仓。最终我选了一个折中的方案:主周期用20,然后在EA里加一个“快速周期”参数,设置为5,用来做突破确认的辅助判断。
这样做的好处是既保证了信号的频率,又兼顾了准确性。

止损止盈的参数同样需要反复测试。我个人的经验是,止损设置在突破水平位外加上一个ATR(平均真实波幅)的倍数比较科学。比如用iATR函数计算当前周期的ATR值,乘以1.5作为止损缓冲。止盈的话,我倾向于用移动止损,也就是当价格向有利方向移动超过2倍ATR后,把止损移动到开仓价附近,锁定利润。这种动态止盈方式在回测中的表现比固定止盈好很多,尤其是在趋势行情里。

回测过程中你肯定还会遇到一个头疼问题:滑点和手续费。MT4的回测引擎默认是不计算这些的,但这会导致回测结果比实盘好不少。所以我都会在EA的参数里加上一个“滑点补偿”变量和“手续费补偿”变量,在计算盈亏时手动扣减。另外,回测的时间范围最好覆盖一段震荡市和一段趋势市,这样才能看出EA在不同环境下的表现。我自己的EA在震荡市里亏损比较明显,但在趋势市里收益非常可观,所以后来我加了一个简单的趋势过滤条件:只有均线多头排列时才允许做多突破。

实盘部署前必须处理的风险细节

EA写好了,回测也通过了,但离真正挂上实盘还有一段距离。首先,你得考虑VPS的问题。MT4的EA如果运行在自己的电脑上,一旦断网或者关机就全废了。我建议租一个低延迟的VPS,专门跑MT4,这样EA可以7乘24小时不间断运行。VPS的地点最好离你的交易服务器近一些,这样可以减少网络延迟,虽然这点延迟对EA来说影响不大,但总归是好的。

其次,EA的异常处理机制必须在实盘前完善。比如,当订单发出去之后,MT4服务器没有立即返回成交结果,这时候EA如果继续执行,就可能导致重复发单。我的做法是在OrderSend之后加一个等待循环,检查最后一条订单的注释和时间戳,确认是否真的成交了。如果超过3秒没有响应,就放弃这次开仓,等下一个信号。这个细节看似简单,但能避免很多诡异的问题。

还有一点,就是EA和手动交易的冲突。如果你平时也喜欢手动做一些单子,那EA在下单前一定要检查持仓中是否有自己手动开的仓位。最简单的办法是,在EA的参数里设置一个“魔术数字”,所有EA下的单子都带上这个数字,然后在下单前检查是否存在相同魔术数字的持仓单。如果已经有一个EA的单子在持仓中,那就跳过这次开仓信号,避免EA和手动单互相干扰。

最后,公布一个我踩过的坑:MT4的服务器时间和你本地时间可能不一致,这会导致EA中所有基于时间判断的逻辑全部失效。比如我之前设置了只在伦敦开盘后两小时交易,结果因为服务器时间比本地快了一个小时,EA提前一小时就开启了交易窗口,白白错失了好几次行情。解决办法是在EA里用TimeCurrent函数获取服务器当前时间,而不是用本地时间,这样就能保证时间判断的准确性。把这些细节都处理好,EA才能真正算得上是一个能安心挂在实盘上的自动化交易工具。

文章目录