MQL5新闻过滤器的编码与实现-可选择重大新闻期间交易或不交易
一般在重大新闻发生时,外汇市场会发生较大的波动,我们既可以选择这些波动获利,也可以过滤掉这些巨大波动,从而实现策略的平稳运行。本篇文章介绍了新闻过滤器的编码实现,非常适合嵌入到外汇自动交易机器人中使用。
下面直接展示代码。首先,我们需要定义新闻相关的参数:
input group "====新闻设定==========" enum sep_dropdown{comma=0, semicolon=1}; input sep_dropdown separator = 0; //新闻关键词分隔符 input int NewsImportant = 0; //新闻重要性(0-3):0-所有新闻;3-影响最大的新闻 input string KeyNews = "CPI,PPI,PMI,UoM,Rate,GDP,Unemployment,Employment"; //新闻关键词 input string NewsCurrencies = "USD"; //新闻相关的货币 input int NewsMinituesBefore = 60; //新闻发生多少分钟前 input int NewsMinituesAfter = 60; //新闻发生多少分钟后 bool FlagTradingNews = false; //存储根据新闻确定的是否可交易状态 ushort sep_code; string NewsTo[]; datetime LastNewsTime=0; //最新新闻发生时间
接着,我们需要判断是否属于新闻发生期间,封装成一个函数:
bool IsUpCommingNews() { if(FlagTradingNews && TimeCurrent()-LastNewsTime<NewsMinituesAfter*PeriodSeconds(PERIOD_M1)) return true; FlagTradingNews = false; string sep; switch(separator) { case 0:sep=",";break; case 1:sep=";";break; } sep_code = StringGetCharacter(sep,0); int k = StringSplit(KeyNews, sep_code, NewsTo); MqlCalendarValue values[]; datetime starttime = TimeCurrent(); datetime endtime = starttime+NewsMinituesBefore*PeriodSeconds(PERIOD_M1); CalendarValueHistory(values, starttime, endtime, NULL, NULL); for(int i=0; i<ArraySize(values); i++) { MqlCalendarEvent event; CalendarEventById(values[i].event_id, event); MqlCalendarCountry country; CalendarCountryById(event.country_id, country); if(StringFind(NewsCurrencies, country.currency, 0)<0) continue; for(int j=0; j<k; j++) { string currentevent = NewsTo[j]; string currentnews = event.name; bool checkImportant = true; if(NewsImportant==1) { checkImportant = (event.importance==CALENDAR_IMPORTANCE_LOW || event.importance==CALENDAR_IMPORTANCE_MODERATE || event.importance==CALENDAR_IMPORTANCE_HIGH); } else if(NewsImportant==2) { checkImportant = (event.importance==CALENDAR_IMPORTANCE_MODERATE || event.importance==CALENDAR_IMPORTANCE_HIGH); } else if(NewsImportant==3) { checkImportant = (event.importance==CALENDAR_IMPORTANCE_HIGH); } if(StringFind(currentnews, currentevent)<0 || !checkImportant ) { continue; } Comment(values[i].time, ":", country.currency, "->", event.name); LastNewsTime = values[i].time; FlagTradingNews = true; return true; } } return false; }
如果是新闻发生期间,函数返回true,否则返回false。
第三步就是在OnTick函数中需要的地方调用新闻:
void OnTick() { if(IsUpCommingNews()) { //新闻发生期间 } else { //新闻没有到来 } }
需要注意的是,新闻是无法在回测中进行测试的,需要在现实环境中测试。