Problem Description
Solution
To check the trend on a Daily chart while trading on an Hourly chart in MQL4, you must use the Multi-Timeframe (MTF) capabilities of the built-in indicator functions.
In MQL4, almost every technical indicator function (like iMA, iRSI, iMACD) accepts a timeframe parameter. By setting this parameter to PERIOD_D1, you can retrieve Daily data regardless of the chart the EA is currently running on.
Implementation Strategy
The most common method to determine the daily trend is comparing the current price against a Daily Moving Average (e.g., 200 SMA).
- Uptrend: Current Price > Daily 200 SMA.
- Downtrend: Current Price < Daily 200 SMA.
MQL4 Code Example
Here is a complete, structural example of an Expert Advisor that runs on an H1 chart but filters trades based on the D1 trend.
//+------------------------------------------------------------------+
//| DailyTrendFilter.mq4 |
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//--- Input Parameters
input int MagicNumber = 123456;
input double LotSize = 0.1;
input int StopLoss = 50; // In Pips
input int TakeProfit = 100; // In Pips
//--- Trend Filter Settings
input ENUM_TIMEFRAMES TrendTimeframe = PERIOD_D1; // Timeframe to check trend
input int TrendMAPeriod = 200; // Period for Daily MA
input int TrendMAMethod = MODE_SMA; // Method (SMA, EMA, etc.)
//--- H1 Entry Settings (Example: Fast MA Cross)
input int FastMAPeriod = 12;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Check if history for the requested timeframe exists
if(iBars(Symbol(), TrendTimeframe) < TrendMAPeriod)
{
Print("Error: Not enough history data for ", EnumToString(TrendTimeframe));
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// 1. Check for Open Orders to avoid opening multiple trades per signal
if(OrdersTotal() > 0) return;
// 2. Get Daily Trend Data
// We use 'TrendTimeframe' (PERIOD_D1) in the iMA function
double dailyMA = iMA(NULL, TrendTimeframe, TrendMAPeriod, 0, TrendMAMethod, PRICE_CLOSE, 0);
// 3. Determine Trend Direction
bool isDailyUptrend = (Bid > dailyMA);
bool isDailyDowntrend = (Bid < dailyMA);
// 4. Get H1 Entry Signals (Example: Price crossing H1 MA)
double h1MA = iMA(NULL, PERIOD_CURRENT, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
// 5. Execute Trades based on H1 Signal AND Daily Trend
// BUY Logic: H1 Price > H1 MA AND Daily Trend is UP
if(Bid > h1MA && isDailyUptrend)
{
OpenTrade(OP_BUY);
}
// SELL Logic: H1 Price < H1 MA AND Daily Trend is DOWN
if(Bid < h1MA && isDailyDowntrend)
{
OpenTrade(OP_SELL);
}
}
//+------------------------------------------------------------------+
//| Helper function to open trades |
//+------------------------------------------------------------------+
void OpenTrade(int type)
{
double sl = 0, tp = 0;
double price = (type == OP_BUY) ? Ask : Bid;
// Calculate SL/TP based on points
if(StopLoss > 0)
sl = (type == OP_BUY) ? price - StopLoss * Point * 10 : price + StopLoss * Point * 10;
if(TakeProfit > 0)
tp = (type == OP_BUY) ? price + TakeProfit * Point * 10 : price - TakeProfit * Point * 10;
int ticket = OrderSend(Symbol(), type, LotSize, price, 3, sl, tp, "Trend Filter EA", MagicNumber, 0, clrNONE);
if(ticket < 0)
Print("OrderSend failed with error #", GetLastError());
}
Key Functions Explained
1. The iMA Function
The core logic lies in this line:
double dailyMA = iMA(NULL, TrendTimeframe, TrendMAPeriod, 0, TrendMAMethod, PRICE_CLOSE, 0);
NULL: Specifies the current symbol.TrendTimeframe: This is set toPERIOD_D1via the inputs. This forces the function to calculate the Moving Average based on Daily candles, even if the EA is attached to an H1 chart.0(Shift): This gets the value of the MA for the current day. If you want the value of the MA at the close of yesterday (to ensure the value doesn't repaint during the day), change the last parameter to1.
2. Data Synchronization
When accessing data from a timeframe different from the current chart (e.g., accessing D1 data while on H1), MetaTrader 4 must have the history data for D1 downloaded.
- If the data is missing,
iMAmight return0or an incorrect value on the very first tick. - The
OnInitcheckiBars(Symbol(), TrendTimeframe)helps ensure data exists before the EA starts trading.
Alternative Trend Checks
If you prefer Price Action over Moving Averages, you can check if yesterday's candle was Bullish or Bearish.
// Get the Open and Close of the previous Daily bar (Shift 1)
double d1Open = iOpen(NULL, PERIOD_D1, 1);
double d1Close = iClose(NULL, PERIOD_D1, 1);
bool isDailyUptrend = (d1Close > d1Open); // Yesterday was Green
bool isDailyDowntrend = (d1Close < d1Open); // Yesterday was Red
Q&A: Multi-Timeframe Logic in MQL4
Q: Why does my EA not trade in the Strategy Tester when using Daily filters?
A: The Strategy Tester in MT4 requires historical data for all timeframes accessed by the code. If you are testing on H1 but checking D1, ensure you have downloaded history for both H1 and D1 in the History Center (F2) before starting the test.
Q: Can I use custom indicators for the Daily trend?
A: Yes. You use the iCustom() function. Like iMA, iCustom has a timeframe parameter.
- Example:
iCustom(NULL, PERIOD_D1, "SuperTrend", ...)
Q: How do I prevent the "Repainting" of the trend signal?
A: If you check the trend on the current Daily bar (Shift 0), the trend status can change back and forth throughout the day as the price moves. To get a fixed trend for the whole day, check the trend based on the closed bar of the previous day (Shift 1).