You've spent weeks optimizing your EA. The backtest looks gorgeous — equity curve climbing like a staircase, drawdown under 10%. You deploy it on a demo account, and within two hours, a CPI release shreds 4% off your balance. Sound familiar?
Most algorithmic traders learn this lesson the hard way. Your strategy doesn't fail because the logic is wrong. It fails because you didn't account for the market's violent reaction to scheduled economic data. The fix isn't complicated: you need your EA to know when high-impact news is coming and stand aside until the dust settles.
MT5 actually gives you a built-in economic calendar that your MQL5 code can read directly. No external DLLs, no third-party data feeds, no manual intervention. You can build an MQL5 news filter EA that checks upcoming events before every trade decision. This article walks through exactly how to do it — with working code, honest limitations, and the backtest quirks you'll hit along the way.
Why Your EA Needs a Calendar Filter
Think about what happens around a high-impact news event. In the seconds after a NFP or CPI number drops, spreads widen from their normal 0.5 pips to 5, 10, even 20 pips on some brokers. Price gaps through your stop loss. Your pending order fills at a terrible price. Even if your strategy is fundamentally sound, one bad news spike can wipe out a week of steady gains.
I've seen traders argue that news volatility is "just another market condition" and their EA should handle it. That's fine if you're running a scalper with tight risk or a grid system designed to survive chaos. But for most strategies — especially trend-following or mean-reversion systems — sitting out the 30-60 minutes around a major release is simply smart survival.
The question becomes: how do you automate that awareness? You could hard-code event times, but economic calendars change. You could subscribe to a third-party news API, but that adds cost and complexity. MT5's built-in calendar solves both problems — it's free, it's already in your terminal, and MQL5 exposes it through the CalendarValueHistory() and related functions.
Understanding MT5's Calendar API
Before diving into code, you need to understand what MT5's calendar actually provides. The calendar data lives in the terminal, updated automatically when your MT5 is running. Your EA can query it through a set of functions introduced in build 2000 and later.
The core functions you'll use:
CalendarValueHistory()— retrieves historical calendar events by currency, impact, and time rangeCalendarEventById()— gets details for a specific event IDCalendarCountryById()— gets country information for an event
Each calendar event comes with an impact level: CALENDAR_IMPORTANCE_LOW, CALENDAR_IMPORTANCE_MODERATE, or CALENDAR_IMPORTANCE_HIGH. For a high impact news filter, you'll typically focus on the high-importance events, though some traders also filter moderate ones depending on their strategy's sensitivity.
One thing that trips up new developers: the calendar functions return data in the terminal's local time zone, not UTC. You need to account for this when comparing against TimeCurrent(), which also runs in local time. As long as you're consistent, it works fine — but mixing time zones will silently break your filter.
Building the MQL5 News Filter EA
Let's write a practical implementation. The approach is straightforward: before each trade entry, scan the calendar for high-impact events within a configurable window. If any exist, skip the trade.
Here's the core filtering function:
//+------------------------------------------------------------------+
//| Check if a high-impact news event is within the filter window |
//+------------------------------------------------------------------+
bool IsNewsWindow(ENUM_TIMEFRAMES timeframe, int minutesBefore, int minutesAfter)
{
datetime now = TimeCurrent();
datetime windowStart = now - minutesBefore * 60;
datetime windowEnd = now + minutesAfter * 60;
MqlCalendarValue values[];
MqlCalendarEvent events[];
// Get all calendar values for the current week, all countries
if(CalendarValueHistory(values, windowStart, windowEnd, NULL))
{
for(int i = 0; i < ArraySize(values); i++)
{
// Get event details to check importance
if(!CalendarEventById(events, values[i].event_id))
continue;
for(int j = 0; j < ArraySize(events); j++)
{
// Filter for high-impact events
if(events[j].importance == CALENDAR_IMPORTANCE_HIGH)
{
// Check if this event affects our trading symbol's currency
string symbolCurrency = SymbolInfoString(_Symbol, SYMBOL_CURRENCY_BASE);
string eventCurrency = CalendarCountryById(events[j].country_id).currency;
if(symbolCurrency == eventCurrency)
{
Print("News filter: High impact event for ", symbolCurrency,
" at ", TimeToString(values[i].time));
return true;
}
}
}
}
}
return false;
}This function checks whether any high-impact event for your symbol's base currency falls within the window. The minutesBefore parameter controls how far before the event you stop trading; minutesAfter controls how long after you wait before resuming.
There's a subtlety here. The code above filters by base currency only. If you're trading EURUSD, a high-impact USD event matters just as much as a EUR event. You should check both base and quote currencies. Here's the refined check:
string baseCurrency = SymbolInfoString(_Symbol, SYMBOL_CURRENCY_BASE);
string quoteCurrency = SymbolInfoString(_Symbol, SYMBOL_CURRENCY_PROFIT);
string eventCurrency = CalendarCountryById(events[j].country_id).currency;
if(baseCurrency == eventCurrency || quoteCurrency == eventCurrency)
{
// This event affects our pair
return true;
}Now integrate this into your EA's trade logic. The typical place is in the OnTick() handler, right before you call your entry conditions:
void OnTick()
{
// News filter check
if(IsNewsWindow(PERIOD_CURRENT, NewsMinutesBefore, NewsMinutesAfter))
{
// Skip trading during news window
Comment("News filter: trading paused");
return;
}
// Your normal trading logic here
if(CheckEntryConditions())
{
OpenTrade();
}
}For pending orders, you'll want to check the filter in OnTradeTransaction() or before placing the order in your entry function. The principle stays the same: if a high-impact event is near, don't place new positions.
Input Parameters for Your News Filter EA
Expose the filter settings as input parameters so you can tune them without recompiling. Here's a sensible set:
| Parameter | Type | Default | Description |
|---|---|---|---|
| NewsFilterEnabled | bool | true | Master switch for the news filter. |
| NewsMinutesBefore | int | 30 | Minutes before event to stop trading. |
| NewsMinutesAfter | int | 30 | Minutes after event before resuming trading. |
| NewsMinImpact | enum | HIGH | Minimum impact level to filter (LOW/MODERATE/HIGH). |
| NewsFilterCurrency | string | "AUTO" | Currency code to filter, or AUTO to detect from symbol. |
The NewsMinImpact parameter deserves attention. A high impact news filter is the default for good reason — those events move markets hardest. But if you're trading a currency pair sensitive to moderate events (like AUD during Chinese GDP), you might want to filter those too. The trade-off is fewer trading opportunities, so test carefully.
Handling Existing Positions
What about positions you already have open when news hits? That's a separate decision. Some traders close everything before high-impact events; others let their stops handle it. I prefer to let the EA's normal exit logic work — my news filter prevents new entries, but exiting is governed by the strategy's own rules. Forcing a close based on the calendar can lock in losses that might have recovered.
That said, if you're running a scalper with tight targets, you might want an option to flatten positions before news. Add a boolean input like CloseOnNews and implement it in the IsNewsWindow() check — if it returns true and you have open positions, close them.
Backtesting Your News Filter EA
Here's where things get tricky. MT5's Strategy Tester has a checkbox for "Economic calendar" in the Settings tab. If you don't enable it, your backtest won't include calendar data — the CalendarValueHistory() function returns empty arrays, and your filter silently does nothing. You'll backtest a version of your EA that never skips a trade, which defeats the entire purpose.
Enable it: open the Strategy Tester (Ctrl+R), go to the Settings tab, and check "Economic calendar" under the "Model" section. You'll also want to set the correct "Period" for your test range so historical calendar data loads properly.
One limitation you'll discover: the backtest calendar is a snapshot of when the data was recorded. If an event was revised later, the backtest uses the original release. That's actually realistic — your live EA also sees initial releases, not revisions. So this isn't a bug; it's the correct behavior for testing news filters.
Another gotcha: the calendar data in the tester depends on your broker's terminal build. Some brokers run older builds that don't support calendar functions. Check your terminal version (Help → About) and ensure it's at least build 2000. If you're on an older build, the functions won't compile — you'll get an "unresolved external" error.
Pros, Cons, and Honest Risks
The built-in calendar approach has real advantages. It's free, it requires no external dependencies, and it works out of the box with MT5. For a news trading EA MQL5 strategy, it's the cleanest way to avoid catastrophic slippage.
But it's not perfect. Here's my honest assessment:
| Aspect | Pros | Cons / Risks |
|---|---|---|
| Data Source |






