自动化·

MT5 新闻过滤器:用内置日历还是 API?

MetaTrader 5 自带财经日历,EA 无需下载就能读取。什么时候够用、什么时候不够,以及怎样改用免费的日历 API,两种方式都附 MQL5 代码。

为 MetaTrader 5 编写 EA(智能交易系统),您多了一个 MT4 用户没有的选择:终端自带财经日历,MQL5 用几个函数就能读取。不用下载,不用允许 URL,也不用解析任何东西。

那为什么还要用外部 API?因为内置日历有短板,其中三点对新闻过滤器很关键。本指南先给出原生代码,再给出 API 代码,最后说明怎么选。

⚖️ 两种方式对比

MQL5 内置日历ShowMyTrades 日历 API
设置无在“工具 → 选项 → 智能交易系统”(Tools → Options → Expert Advisors)中允许 https://showmytrades.com
数据来源MetaQuotes,经由经纪商的服务器提供ShowMyTrades 合并多个公开日历来源,主要数据的发布日期会与发布机构和央行核对(confidence: official)
适用范围开启了日历的经纪商(大多数都开了,部分白标服务器没有)任何经纪商,任何能上网的终端
也能用于 MT4否是,同一个文件
可在策略测试器中使用是,带历史数据否(测试器不能联网)
时区交易服务器时间,与 UTC 的时差得自己推算UTC(ts 为 Unix 秒),每次响应还附带服务器当前的 UTC 时间,EA 因此完全不依赖经纪商或 VPS 的时钟
数值预期值、前值、公布值,含修正预期值、前值、公布值
费用免费免费,无需密钥

🧱 方式 A:内置日历

下面的函数判断:图表品种的两种货币里,有没有哪一种的高影响数据发布落在暂停窗口内。时间用的是交易服务器时间,这正是 CalendarValueHistory() 要求的。

NativeNewsFilter.mqh
//--- MQL5 内置日历:当图表货币的高影响数据发布
//--- 处于当前时间的 [-minutesBefore, +minutesAfter] 范围内时返回 true
bool NativeNewsTime(const int minutesBefore, const int minutesAfter, string &reason)
{
   reason = "";
   datetime now  = TimeTradeServer();
   datetime from = now - minutesAfter * 60;
   datetime to   = now + minutesBefore * 60;

   string currencies[2];
   currencies[0] = SymbolInfoString(_Symbol, SYMBOL_CURRENCY_BASE);
   currencies[1] = SymbolInfoString(_Symbol, SYMBOL_CURRENCY_PROFIT);

   for(int c = 0; c < 2; c++)
   {
      if(c == 1 && currencies[1] == currencies[0]) break;
      MqlCalendarValue values[];
      if(CalendarValueHistory(values, from, to, NULL, currencies[c]) <= 0) continue;
      for(int i = 0; i < ArraySize(values); i++)
      {
         MqlCalendarEvent ev;
         if(!CalendarEventById(values[i].event_id, ev)) continue;
         if(ev.importance != CALENDAR_IMPORTANCE_HIGH) continue;
         reason = currencies[c] + ": " + ev.name;
         return true;
      }
   }
   return false;
}

在 OnTick() 里调用它,和调用其他过滤器没有区别:

string news;
if(NativeNewsTime(30, 30, news)) { Comment("新闻过滤器:", news); return; }

用它之前,有三点要清楚:

  1. 它依赖经纪商。日历经由交易服务器送到终端。如果在您的经纪商那里,CalendarValueHistory() 返回 -1、错误码 5402,说明该服务器没有开启日历,代码再怎么改也没用。
  2. 它用的是服务器时间,不是 UTC。在实时图表上没问题,一旦要和别的数据对照就很麻烦。
  3. 它只支持 MT5。如果您的 EA 也出 MT4 版本,就得再写一套。

🌐 方式 B:日历 API

另一个选择是免费的 HTTP 端点:按您选择的货币和影响级别,返回未来几天的新闻,格式为 CSV 或 JSON:

https://showmytrades.com/api/public/calendar/v1?currency=EUR,USD&impact=high&days=2&format=csv

读取它的包含文件 SMT_NewsFilter.mqh,完整代码见 MT4 指南和 API 参考。它在 MQL5 中无需修改即可编译:保存到 MQL5\Include,在“工具 → 选项 → 智能交易系统”中允许 https://showmytrades.com,然后这样调用:

#include <SMT_NewsFilter.mqh>

void OnTick()
{
   string news;
   if(SMT_IsNewsTime(news)) { Comment("新闻过滤生效中:", news); return; }
   Comment("");
   // ……您的入场逻辑……
}

它每 15 分钟下载一次,用 TimeGMT() 按 UTC 比较时间,输入参数(SMT_Currencies、SMT_Impact、事前和事后的分钟数)都放在 EA 的设置对话框里。

🎯 选哪一个

您的情况选择
只用 MT5,经纪商提供日历,还要回测过滤器内置
同一个 EA 要同时跑 MT4 和 MT5API:一个文件,行为一致
经纪商没有日历(5402)API
您还在 cTrader 上跑 cBotAPI:cTrader 上用的是同一份数据
想把新闻和交易一起记下来,方便日后复盘都行;API 给的是 UTC 时间戳,和您其他日志对得上

两者也可以同时用:内置日历有响应就用它,没响应就用 API。不过实际上,一个就够了。

🧪 回测新闻过滤器

两者之中只有内置日历能在策略测试器里用,因为测试器不能联网。即便如此,也要想清楚新闻过滤器的回测到底证明了什么:测试用的是今天掌握的日历,时间是修正过的,还包含事后才补上的事件。而实盘中的过滤器,只知道当时已经排定的内容。

❓ 常见问题

MT5 内置日历免费吗? 免费。它是终端自带的功能,经由您经纪商的服务器提供,您这边不需要开启任何设置。

为什么在我的经纪商那里,CalendarValueHistory() 什么都不返回? 有些服务器(往往是白标服务器)不转发日历。查一下 GetLastError():5402 表示日历不可用。这种情况就用 API。

能按另一个品种的货币来过滤吗? 可以。直接传入想要的货币代码,不必从 _Symbol 读取。API 版本以字符串参数的形式接收:EUR,USD,GBP。

API 需要账户吗? 不需要。不用密钥,不用登录。限制是每个 IP 地址每分钟 600 次请求;每 15 分钟请求一次的话,开再多图表也远远用不完。

🔗 相关内容


不管选哪种日历,效果都会体现在业绩记录上:在行情突变时开的单更少,回撤也更平稳。免费追踪您的 MT5 账户,在图表上亲眼看到变化。