Trading Time Filter for Any MT5 Expert Advisor

Trading Time Filter for Any MT5 Expert Advisor

18 May 2026, 20:51
Ryan L Johnson
0
155

I recently created a new scalping EA. When I say "new," I really mean new because I've strictly been an algorithmic swing trader up until now. Anyway, I found myself in need of a higher resolution time filter because scalping EA's trade more frequently than swing trading EA's. So...

Here is a snippet of my new trading time filter code. You can select one of three forms of time in the TimeForm input:

  • SimPCtime ─ simulated broker-dealer server time based on the ticking of the clock in your local device;
  • PCtime ─ time based on the arrival of data ticks "shifted" to the time zone of your local device; and
  • BrokerTime ─ broker-dealer server time based on the arrival of data ticks.

The first filtered out time block will auto-detect an overnight timespan (wraparound through midnight), or can alternatively use a regular chronological time span if you don't trade overnight. The second and third time blocks only use regular chronological timespans (because there is only one midnight per day). Set the hours and minutes of the timespan during which you want your EA to trade.

A daily filter consisting of one settable day, and a monthly filter consisting of three settable months, have also been added. If you need to edit the code to filter out additional days, it should be fairly self-explanatory. Sunday is 0, Monday is 1... and so on up to Saturday which is 6. If you only need to filter out one or two months, setting any skipped month to 0 will allow that because months are 1 to 12 (there is no month 0). Set the months and day that you do not want your EA to trade.

Corresponding Print() statements are inside each timespan, daily, and monthly conditions, respectively, for the purpose of tracking what happened when and where. All such statements are automatically printed to the Experts tab in the Toolbox window in the MT5 terminal when triggered─on an ongoing basis.

Of course, you can edit the code to use a "blanket" message in the actual trading conditions instead, but I'd personally rather not be printing strings while trading conditions are being evaluated. If you need more filtered out timespans, you might consider creating a custom function or functions so that you can "recycle" the calculations therein.

All times are typecasted into ulong variables which store milliseconds, unlike datetime variables. This means that you don't have to wait a full next second for start and stop times to trigger.

I reduced the amount of nested if-statements and reposted this code on May 21, 2026 (New York time).

In the global scope of your code, insert:

enum SELECTED_TIME
 {
  PCtime,
  SimPCtime,
  BrokerTime,
 };

input SELECTED_TIME TimeForm = SimPCtime;
input bool UseOvernightTimesA = true;
input string StartTimeOvernightA = "02:00";
input string StopTimeOvernightA = "16:00";
input bool UseTimesB = false;
input string StartTimeB = "00:00";
input string StopTimeB = "00:00";
input bool UseTimesC = false;
input string StartTimeC = "00:00";
input string StopTimeC = "00:00";
input bool SkipDays = true;
input int DayA = 0;
input bool SkipMonths = false;
input int MonthA = 0;
input int MonthB = 0;
input int MonthC = 0;
input bool UseSleep = true;

datetime dLocalTime, dStartTimeOvernightA, dStopTimeOvernightA,
         dStartTimeB, dStopTimeB, dStartTimeC,
         dStopTimeC;

ulong uLocalTime, uStartTimeOvernightA, uStopTimeOvernightA,
      uStartTimeB, uStopTimeB, uStartTimeC,
      uStopTimeC;

int timeRunBotA, timeRunBotB, timeRunBotC;

bool timesAchrono, dayRunBot, monthRunBot;

int timerAprinted, timerBprinted,
    timerCprinted, dayPrinted, monthPrinted;

In OnInit(), insert:

   dStartTimeOvernightA = StringToTime(StartTimeOvernightA);
   uStartTimeOvernightA = ulong(dStartTimeOvernightA);
   
   dStopTimeOvernightA = StringToTime(StopTimeOvernightA);
   uStopTimeOvernightA = ulong(dStopTimeOvernightA);
   
   if(uStartTimeOvernightA < uStopTimeOvernightA) // intraday start trading time is set earlier than intraday stop trading time (linearly)
     {
      timesAchrono = true;
     }
   
   if(uStartTimeOvernightA > uStopTimeOvernightA) // intraday start trading time is set later than intraday stop trading time (wrap-around)
     {
      timesAchrono = false;
     }

In OnTick(), insert:

   switch(TimeForm)
     {
      case PCtime:
        dLocalTime = TimeLocal();
        break;
      case SimPCtime:
        dLocalTime = TimeTradeServer();
        break;
      case BrokerTime:
        dLocalTime = TimeCurrent();
        break;
     }
  
   dStartTimeOvernightA = StringToTime(StartTimeOvernightA);
   uStartTimeOvernightA = ulong(dStartTimeOvernightA);
   
   dStopTimeOvernightA = StringToTime(StopTimeOvernightA);
   uStopTimeOvernightA = ulong(dStopTimeOvernightA);

   dStartTimeB = StringToTime(StartTimeB);
   uStartTimeB = ulong(dStartTimeB);
   
   dStopTimeB = StringToTime(StopTimeB);
   uStopTimeB = ulong(dStopTimeB);

   dStartTimeC = StringToTime(StartTimeC);
   uStartTimeC = ulong(dStartTimeC);
   
   dStopTimeC = StringToTime(StopTimeC);
   uStopTimeC = ulong(dStopTimeC);

   uLocalTime = ulong(dLocalTime);

   // overnight trading times. Any times including midnight, 00:00, (if any) must be set in overnight times inputs--auto detection supported
   if(UseOvernightTimesA == true
    && timesAchrono == true) // intraday start trading time is set earlier than intraday stop trading time (linearly)
     {
      if(uLocalTime >= uStartTimeOvernightA
       && uLocalTime < uStopTimeOvernightA)
        {
         timeRunBotA = 1;
        
         if(timerAprinted != 1)
           {
            Print("Time Filter A is ON. Current time is within set trading times A.");
            timerAprinted = 1;
           }
        }
      else
        {
         timeRunBotA = 2;
        
         if(timerAprinted != 2)
           {
            Print("Time Filter A is ON. Current time is outside of set trading times A.");
            timerAprinted = 2;
           }
        }
     }
   
   if(UseOvernightTimesA == true
    && timesAchrono == false) // intraday start trading time is set later than intraday stop trading time (wrap-around)
     {
      if(uLocalTime >= uStopTimeOvernightA
       && uLocalTime < uStartTimeOvernightA)
        {
         timeRunBotA = 2;

         if(timerAprinted != 2)
           {
            Print("Time Filter A is ON. Current time is outside of set trading times A.");
            timerAprinted = 2;
           }
        }
      else
        {
         timeRunBotA = 1;

         if(timerAprinted != 1)
           {
            Print("Time Filter A is ON. Current time is within set trading times A.");
            timerAprinted = 1;
           }
        }
     }

   if(UseOvernightTimesA == false) 
     {
      timeRunBotA = 3;
     
      if(timerAprinted != 3)
        {
         Print("Time Filter A is OFF.");
         timerAprinted = 3;
        }
    }

   // trading times B. Trading times set in B times inputs must be linear (not overnight)
   if(UseTimesB == true)
     {
      if(uLocalTime >= uStartTimeB // intraday start trading time must be set earlier than intraday stop trading time (linearly)
       && uLocalTime < uStopTimeB)
        {
         timeRunBotB = 1;
        
         if(timerBprinted != 1)
           {
            Print("Time Filter B is ON. Current time is within set trading times B.");
            timerBprinted = 1;
           }
        }
      else
        {
         timeRunBotB = 2;
        
         if(timerBprinted != 2)
           {
            Print("Time Filter B is ON. Current time is outside of set trading times B.");
            timerBprinted = 2;
           }
        }
     }

   if(UseTimesB == false) 
     {
      timeRunBotB = 3;
     
      if(timerBprinted != 3)
        {
         Print("Time Filter B is OFF.");
         timerBprinted = 3;
        }
     }

   // trading times C. Trading times set in C times inputs must be linear (not overnight)
   if(UseTimesC == true
    && uStartTimeC < uStopTimeC) // intraday start trading time must be set earlier than intraday stop trading time (linearly)
    {
     if(uLocalTime >= uStartTimeC
       && uLocalTime < uStopTimeC)
       {
        timeRunBotC = 1;
        
        if(timerCprinted != 1)
          {
           Print("Time Filter C is ON. Current time is within set trading times C.");
           timerCprinted = 1;
          }
       }
     else
       {
        timeRunBotC = 2;
        
        if(timerCprinted != 2)
          {
           Print("Time Filter C is ON. Current time is outside of set trading times C.");
           timerCprinted = 2;
          }
       }
    }

   if(UseTimesC == false)
     {
      timeRunBotC = 3;
     
      if(timerCprinted != 3)
        {
         Print("Time Filter C is OFF.");
         timerCprinted = 3;
        }
     }
   
   datetime tm = dLocalTime;
   MqlDateTime stm;
   TimeToStruct(tm, stm);
   
   if(SkipDays == true
      && stm.day_of_week != DayA)
     {
      dayRunBot = true;
      
      if(dayPrinted != 1)
        {
         Print("Daily Filter is ON. Current day is within set trading days.");
         dayPrinted = 1;
        }
     }
   else
     {
      dayRunBot = false;
      
      if(dayPrinted != 2)
        {
         Print("Daily Filter is ON. Current day is outside of set trading days.");
         dayPrinted = 2;
        }
     }
   
   if(SkipDays == false)
     {
      dayRunBot = true;
      
      if(dayPrinted != 3)
        {
         Print("Daily Filter is OFF.");
         dayPrinted = 3;
        }
     }

   if(SkipMonths == true
      && (stm.mon != MonthA
       || MonthA == 0)
      && (stm.mon != MonthB
       || MonthB == 0)
      && (stm.mon != MonthC
       || MonthC == 0))
      {
       monthRunBot = true;
       
       if(monthPrinted != 1)
         {
          Print("Monthly Filter is ON. Current month is within set trading months.");
          monthPrinted = 1;
         }
      }

  if(SkipMonths == true
     && (stm.mon == MonthA
      || stm.mon == MonthB
      || stm.mon == MonthC))
     {
      monthRunBot = false;
      
      if(monthPrinted != 2)
        {
         Print("Monthly Filter is ON. Current month is outside of set trading months.");
         monthPrinted = 2;
        }
     }

   if(SkipMonths == false)
     {
      monthRunBot = true;
      
      if(monthPrinted != 3)
        {
         Print("Monthly Filter is OFF.");
         monthPrinted = 3;
        }
     }
 
   
   
   //--- trading conditions ---//

   if(((timeRunBotA == 1
       || timeRunBotB == 1
       || timeRunBotC == 1)
      ||(UseOvernightTimesA == false
       && UseTimesB == false
       && UseTimesC == false))
      && dayRunBot == true
      && monthRunBot == true)
     {
      // your additional trading conditions here
     }