一个真实的惨痛教训
上个月,一个朋友跟我说他的EA在非农之夜亏了账户的12%。
那天晚上他挂着EA就去睡觉了。非农数据公布的那一秒钟,EUR/USD在30秒内暴跌了87个点,然后又反弹了65个点。他的EA在暴跌的时候追空,在反弹的时候又被止损打掉。一来一回,连续触发了4笔交易,每笔都是亏损。
最讽刺的是,非农过后半小时,价格回到了数据公布前的位置。如果EA什么都不做,一分钱都不会亏。
这种事情每个月都在发生。不是EA策略不好,而是EA不知道什么时候该停下来。
为什么重大新闻对EA来说是噩梦?
EA本质上是一套规则。它根据技术指标计算入场和出场。但重大新闻发布的那几分钟,市场不讲技术面,只讲情绪和反应速度。
具体来说,你的EA会遇到这些问题:
点差暴涨。 平时EUR/USD的点差可能是1.2个点,非农公布那一刻可能飙到8-15个点。你的EA以为自己在正常点差下入场,实际上一开仓就亏了好几个点。
滑点严重。 EA发出的订单价格和实际成交价格可能差5-10个点。你设的止损在1.0850,实际成交在1.0840,多亏了10个点。
假突破来回扫。 数据公布后价格先往一个方向冲,然后又往反方向冲。典型的whipsaw行情。趋势型EA在这种行情里会被反复打脸。
流动性断层。 极端情况下会出现价格跳空,中间根本没有成交价。你的止损可能直接被跳过,亏损远超预期。
这不是EA的问题,是市场环境的问题。解决方案很简单:在这些时间段让EA休息。
哪些新闻事件需要特别小心?
不是所有新闻都值得暂停交易。你只需要关注高影响力和部分中影响力的事件。
必须暂停的高影响力事件:
| 事件 | 影响货币 | 公布频率 | 典型波动 |
|---|---|---|---|
| 非农就业数据(NFP) | USD及所有美元对 | 每月第一个周五 | 50-150点 |
| 美联储利率决议(FOMC) | USD及所有美元对 | 每年8次 | 30-100点 |
| 欧央行利率决议(ECB) | EUR及所有欧元对 | 每6周一次 | 30-80点 |
| CPI通胀数据 | 对应货币 | 每月一次 | 30-80点 |
| GDP数据 | 对应货币 | 每季度一次 | 20-60点 |
建议暂停的中影响力事件:
| 事件 | 典型波动 |
|---|---|
| 零售销售数据 | 20-50点 |
| PMI采购经理人指数 | 15-40点 |
| 就业变化(非美国) | 15-40点 |
| 央行官员重要讲话 | 10-30点 |
这些数字是大概范围,实际波动取决于数据与预期的偏差程度。数据越出乎意料,波动越大。
新闻过滤器是怎么工作的?
原理很简单:EA在每次准备下单之前,先检查一下接下来是不是有重大新闻。如果有,就暂停交易,等新闻影响消退后再恢复。
实现的方式有三种,各有优缺点。
方法一:MQL5内置经济日历(仅MT5可用)
MT5从Build 2085开始内置了经济日历功能。你可以直接在EA代码里调用CalendarValueHistory()函数获取新闻事件列表。
优点是不需要依赖外部数据源,MT5自动更新日历,数据准确度高。缺点是MT4没有这个功能,只有MT5能用。
调用的大致思路是:获取未来几小时的事件列表,筛选出高影响力事件,判断当前时间是否在新闻窗口内。
方法二:外部数据源
最常用的是ForexFactory的经济日历。很多EA通过以下方式获取数据:
读取CSV文件。 提前下载ForexFactory或其他财经网站的周度日历,保存为CSV文件放在EA能读取的目录里。EA启动时加载这个文件,解析出每个事件的时间、影响等级和相关货币。
这种方式稳定可靠,但需要每周手动更新CSV文件,或者写一个脚本自动下载。
通过网页抓取。 有些EA会直接通过WebRequest函数访问ForexFactory或类似网站的日历页面,实时获取新闻数据。好处是不用手动更新,坏处是如果网站改版或者网络断了,过滤器就失效了。
方法三:手动设定时间过滤
这是最简单粗暴的方式。你知道每个月第一个周五有非农,每次FOMC会议的日期也是提前公布的。直接在EA参数里把这些日期和时间写死。
好处是零依赖,不需要外部数据,100%可靠。坏处是每个月都需要手动更新,如果忘了更新就没有保护。
对于只跑一两个EA的人来说,手动方式其实够用了。每周花两分钟查一下下周有什么重大新闻,更新一下EA参数就行。
暂停多久才合适?
新闻过滤器的关键参数是"提前暂停时间"和"延后恢复时间"。设太短保护不够,设太长会错过正常行情。
根据多年的经验,这是比较合理的设置:
高影响力事件(NFP、FOMC、央行利率决议):
- 提前30分钟暂停
- 延后30分钟恢复
- 总窗口:60分钟
为什么要提前30分钟?因为在重大数据公布前,市场已经开始紧张了。点差会逐渐扩大,流动性开始下降,很多大机构在这个时候撤掉挂单。你的EA如果在这个时候入场,成交条件已经不理想了。
为什么要延后30分钟?因为数据公布后的第一波反应经常是假动作。真正的方向可能要15-20分钟才能确认。等30分钟让市场消化完数据,点差恢复正常,再让EA继续工作。
中影响力事件(CPI、GDP、零售销售):
- 提前15分钟暂停
- 延后15分钟恢复
- 总窗口:30分钟
中影响力事件的波动相对小一些,15分钟的窗口通常足够了。
特别情况: 如果同一天有多个重大事件间隔很近(比如先CPI后FOMC),两个窗口可能会重叠。这种情况下,EA应该从第一个事件的开始时间一直暂停到最后一个事件的结束时间。不要在两个事件中间短暂恢复交易。
GMT偏移量这个坑一定要填对
这是新闻过滤器出问题最多的地方。
ForexFactory上显示的时间是某个时区的,MT4/MT5服务器的时间可能是另一个时区的,你本地电脑的时间又是另一个时区。如果搞混了,你的新闻过滤器就会在错误的时间暂停,该保护的时候不保护,不该暂停的时候暂停。
处理方法:
第一步:搞清楚你的MT4/MT5服务器时区。 在EA里用TimeCurrent()获取服务器时间,然后跟实际的GMT时间对比。大多数经纪商的服务器时间是GMT+2(冬令时)或GMT+3(夏令时)。
第二步:把新闻时间统一转换成服务器时间。 如果非农公布时间是GMT 13:30,你的服务器是GMT+2,那服务器时间就是15:30。你的EA应该在15:00-16:00暂停交易(前30后30)。
第三步:在EA参数里添加GMT偏移量设置。 设一个输入参数比如GMTOffset,默认值设为2。用户可以根据自己经纪商的时区调整。
千万不要用TimeLocal(),那是你电脑本地的时间,跟服务器时间可能差好几个小时。永远用TimeCurrent()来做判断。
暂停期间EA应该怎么处理已有持仓?
这个问题没有标准答案,取决于你的策略类型和风险偏好。有三种常见做法:
做法一:只暂停开新仓,已有持仓不动。
这是最常见的做法。EA不再开新仓位,但已有的仓位继续由原来的止损止盈管理。
适合的情况:你的EA设了合理的止损,即使新闻造成大波动,止损能承受。比如你的止损是50个点,新闻波动通常不会超过这个范围。
做法二:暂停开仓,同时把已有仓位移到保本位。
在暂停的同时,把所有已经盈利的仓位的止损移到开仓价(保本价)。这样即使新闻造成大反转,至少不亏钱。
适合的情况:你的持仓已经有一定浮盈,移到保本位不太容易被正常波动打掉。
做法三:直接平掉所有仓位。
最激进的保护方式。在新闻窗口开始时平掉所有持仓,新闻结束后让EA重新寻找机会。
适合的情况:你极度厌恶风险,或者你的EA持仓时间本来就很短(比如剥头皮策略)。这种EA的仓位通常浮盈很小,与其冒险不如全部平掉。
我个人的建议是:大多数情况下用做法一或做法二。做法三看起来最安全,但每次新闻都强制平仓会打乱EA的交易节奏,长期来看可能反而降低收益。
还有一个容易忽略的点:挂单(pending orders)。 暂停期间不仅要停止开新仓,还要处理EA之前下的挂单。如果EA下了一个Buy Stop在某个价位,新闻一来价格spike上去触发了挂单,这跟直接开仓没区别。建议在暂停期间删除所有EA下的挂单,恢复后重新计算。
一个实用的新闻过滤器逻辑示例
下面是伪代码,展示核心逻辑。不是完整的MQL代码,但足够让你理解思路或交给程序员实现。
// ===== 参数设置 =====
输入参数:
EnableNewsFilter = true // 是否启用新闻过滤
HighImpactMinsBefore = 30 // 高影响力事件提前暂停分钟数
HighImpactMinsAfter = 30 // 高影响力事件延后恢复分钟数
MediumImpactMinsBefore = 15 // 中影响力事件提前暂停分钟数
MediumImpactMinsAfter = 15 // 中影响力事件延后恢复分钟数
GMTOffset = 2 // 服务器GMT偏移量
CloseTradesBeforeNews = false // 暂停时是否平掉已有持仓
DeletePendingOrders = true // 暂停时是否删除挂单
// ===== 核心检查函数 =====
函数 IsNewsPeriod():
当前服务器时间 = TimeCurrent()
当前GMT时间 = 当前服务器时间 - GMTOffset * 3600
遍历新闻事件列表:
对于每个事件:
事件GMT时间 = 事件的公布时间
如果 事件影响力 == "高":
暂停开始 = 事件GMT时间 - HighImpactMinsBefore * 60
暂停结束 = 事件GMT时间 + HighImpactMinsAfter * 60
否则如果 事件影响力 == "中":
暂停开始 = 事件GMT时间 - MediumImpactMinsBefore * 60
暂停结束 = 事件GMT时间 + MediumImpactMinsAfter * 60
如果 当前GMT时间 >= 暂停开始 且 当前GMT时间 <= 暂停结束:
返回 true // 当前处于新闻期间
返回 false // 当前不在新闻期间
// ===== 在EA主逻辑中使用 =====
函数 OnTick():
如果 EnableNewsFilter 且 IsNewsPeriod():
// 进入新闻暂停模式
如果 DeletePendingOrders:
删除本EA的所有挂单()
如果 CloseTradesBeforeNews:
平掉本EA的所有持仓()
在图表上显示 "新闻过滤:交易已暂停"
返回 // 不执行任何交易逻辑
// 正常执行EA的交易逻辑
执行正常的入场判断()
执行正常的出场管理()
这段逻辑的关键点:
- 每个tick都检查是否处于新闻期间,这样不会错过任何时间窗口
- 新闻数据可以从CSV文件加载,也可以从MT5内置日历获取
- 挂单和持仓的处理是可配置的,不同策略可以选择不同方案
- 在图表上显示提示信息,方便你确认过滤器是否正常工作
新手最容易犯的几个错误
错误一:时区搞错了。
这是出现频率最高的问题。你从ForexFactory抄来的时间是EST时区的,直接填到EA参数里,但EA用的是服务器时间GMT+2。结果过滤器早了7个小时或者晚了7个小时。一定要把所有时间转换到同一个时区再比较。
错误二:忘了处理挂单。
很多人写新闻过滤器只考虑了"不开新仓",但忘了EA之前下的挂单还挂在那里。新闻一波动,挂单被触发,该亏的还是亏了。暂停交易时一定要同时删除挂单。
错误三:没考虑夏令时切换。
欧美国家每年有两次夏令时切换。美国通常在3月第二个周日切换到夏令时,11月第一个周日切换回冬令时。欧洲的切换日期又不一样。
这意味着你的GMT偏移量每年要改四次(美国两次,欧洲两次)。有些经纪商的服务器时间会跟着切换,有些不会。最保险的做法是在EA里加入自动检测夏令时的逻辑,或者至少在每次切换时手动检查一下。
错误四:过滤了不相关的货币新闻。
如果你的EA只做EUR/USD,那日本的GDP数据跟你没什么关系。但美国的CPI对所有美元相关货币对都有影响。过滤器应该只关注与交易品种相关的货币新闻,否则会过度暂停,错过太多交易机会。
错误五:从不测试过滤器是否真的在工作。
装上新闻过滤器以后,至少在下一个非农日手动盯一下。看EA是不是真的在正确的时间暂停了,暂停期间是不是真的没有开新仓,恢复后是不是正常运行。别装完就不管了。
常见问题
问:我用的EA没有新闻过滤功能,怎么办?
两个选择。第一,找开发者加上这个功能,大部分靠谱的EA开发者都愿意做这种改进。第二,用一个独立的新闻过滤EA。这种EA本身不做交易,它的唯一作用是在新闻期间关闭其他EA的自动交易权限。你可以在MQL5市场上搜"news filter"找到不少免费或便宜的工具。
问:如果我只做亚洲时段的EA,还需要新闻过滤吗?
需要,但可以简化。亚洲时段很少有美国和欧洲的重大数据发布,但有日本、澳大利亚和中国的数据。日本的央行利率决议、澳洲的就业数据这些,对AUD/JPY、USD/JPY的影响不小。另外要注意,有时候美国的数据在北京时间凌晨公布,如果你的亚洲时段EA还在运行,照样会受影响。
问:回测的时候新闻过滤器能正常工作吗?
这要看你的过滤器数据来源。如果是实时抓取网页数据的,回测时当然不能用。如果是用CSV文件的,理论上可以准备历史新闻数据的CSV来配合回测,但比较麻烦。MT5内置日历在策略测试器中也有一定的支持。老实说,大部分人回测时不开新闻过滤,而是在实盘和模拟盘上验证过滤器的效果。
问:暂停时间设长一点不是更安全吗?比如提前2小时暂停?
理论上更安全,但代价是你的EA每天可能有好几个小时不能交易。如果一天有3个高影响力事件,每个暂停4小时,你的EA大半天都在休息。对于短线EA来说,交易机会本来就不多,过度暂停会严重影响收益。30分钟的窗口是一个经过验证的平衡点。
问:有些EA宣称"能在新闻行情中获利",可信吗?
有这种策略,但对执行环境要求极高。需要超低延迟的VPS、ECN账户、极低的点差。普通零售交易者很难满足这些条件。对大多数人来说,避开新闻行情比试图从中获利要明智得多。如果一个EA把"新闻交易"当卖点,你反而应该多留个心眼。
最后说几句
新闻过滤器不是什么高深的技术,但它是EA稳定盈利的重要保障之一。不加新闻过滤的EA就像没有安全带的车,平时看不出区别,出事的时候差别就大了。
设置一次,每个月检查一下时区和日历数据是否正确,就够了。花半小时做好这件事,能帮你避开无数个"非农之夜"的噩梦。
如果你还在研究EA的选择和配置,可以在FXTool上查看更多EA评测和实用教程,帮你少走弯路。