OnTimer problem

 

Here is the mql4 code (and below it the mql5 code) of an OnTimer function that works well in MT4. It flashes an object and plays a sound for one second when a new bar is created. It also warns me when a Symbol has not had a new tick for two minutes.

Have tried to convert the code to mql5 and have found some strange behaviour. The timing only works correctly when i output the time in seconds (datetime TSeconds = seconds.sec;) to the  Comment() function. What am i doing wrong here?

void OnTimer()
  {
   datetime TS = TimeSeconds(TimeLocal());
//   
   if((TimeMinute(TimeLocal())-Minute())>1)
     {
      if(TS==1 || TS==3 || TS==5 || TS==7 || TS==9 || TS==11 || TS==13 || TS==15 || TS==17 || TS==19 || TS==21 || TS==23 || TS==25 || TS==27 || TS==29 || TS==31 || TS==33 || TS==35 || TS==37 || TS==39 || TS==41 || TS==43 || TS==45 || TS==47 || TS==49 || TS==51 || TS==53 || TS==55 || TS==57 || TS==59)
        {
         PlaySound("beep3.wav");
         ObjectCreate("ServerFault",OBJ_LABEL,0,0,0);
         ObjectSet("ServerFault",OBJPROP_XDISTANCE,10);
         ObjectSet("ServerFault",OBJPROP_YDISTANCE,20);
         ObjectSet("ServerFault",OBJPROP_CORNER,3);
         ObjectSet("ServerFault",OBJPROP_HIDDEN,1);
         ObjectSet("ServerFault",OBJPROP_ANCHOR,ANCHOR_RIGHT);
         ObjectSetText("ServerFault","Server Fault",25,"Arial",Magenta);
        }
      else
         ObjectDelete("ServerFault");
     }
   else
      ObjectDelete("ServerFault");
//
   static int counter=0;
   static int counter1=0;
   static datetime LastBar=0;
   datetime CurrentBar=Time[0];
   if(LastBar!=CurrentBar)
     {
      if(counter1<1)
        {
         PlaySound("beep.wav");
         counter1=counter1+1;
        }
//
      if(TS==1 || TS==3 || TS==5 || TS==7 || TS==9 || TS==11 || TS==13 || TS==15 || TS==17 || TS==19 || TS==21 || TS==23 || TS==25 || TS==27 || TS==29 || TS==31 || TS==33 || TS==35 || TS==37 || TS==39 || TS==41 || TS==43 || TS==45 || TS==47 || TS==49 || TS==51 || TS==53 || TS==55 || TS==57 || TS==59)
        {
         ObjectCreate("Flash",OBJ_RECTANGLE_LABEL,0,0,0);
         ObjectSet("Flash",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
         ObjectSet("Flash",OBJPROP_XDISTANCE,2000);
         ObjectSet("Flash",OBJPROP_YDISTANCE,0);
         ObjectSet("Flash",OBJPROP_XSIZE,2000);
         ObjectSet("Flash",OBJPROP_YSIZE,1000);
         ObjectSet("Flash",OBJPROP_BGCOLOR,Magenta);
         ObjectSet("Flash",OBJPROP_BORDER_TYPE,BORDER_FLAT);
         ObjectSet("Flash",OBJPROP_BORDER_COLOR,clrNONE);
         ObjectSet("Flash",OBJPROP_HIDDEN,true);
         ObjectSet("Flash",OBJPROP_SELECTABLE,false);
         counter=counter+1;
        }
      else
        {
         ObjectDelete("Flash");
        }
// 
      if(counter==1)
        {
         LastBar=CurrentBar;
         counter=0;
         counter1=0;
        }
     }
   else
      ObjectDelete("Flash");
  }
void OnTimer()
        {
        MqlDateTime minutes;
        TimeCurrent(minutes);
        TimeLocal(minutes);
        datetime tc = minutes.min;
        datetime tl = minutes.min;
        MqlDateTime seconds;
        TimeLocal(seconds);
        datetime TSeconds = seconds.sec;
        string strsec = TimeToString(TSeconds, TIME_SECONDS);
        string sec = StringSubstr(strsec, 6, 2);
        int TS = StringToInteger(sec);
        Comment(TS);
        datetime Time[];               
        CopyTime(_Symbol, _Period, 0, 1, Time);
//        
      if(tc - tl > 1)
        {
      if(TS == 1 || TS == 3 || TS == 5 || TS == 7 || TS == 9 || TS == 11 || TS == 13 || TS == 15 || TS == 17 || TS == 19 || TS == 21 || TS == 23 || TS == 25 || TS == 27 || TS == 29 || TS == 31 || TS == 33 || TS == 35 || TS == 37 || TS == 39 || TS == 41 || TS == 43 || TS == 45 || TS == 47 || TS == 49 || TS == 51 || TS == 53 || TS == 55 || TS == 57 || TS == 59)
        {
         PlaySound("beep3.wav");
         ObjectCreate(0, "ServerFault", OBJ_LABEL, 0, 0, 0);
         ObjectSetInteger(0, "ServerFault", OBJPROP_XDISTANCE, 10);
         ObjectSetInteger(0, "ServerFault", OBJPROP_YDISTANCE, 20);
         ObjectSetInteger(0, "ServerFault", OBJPROP_CORNER, 2);
         ObjectSetInteger(0, "ServerFault", OBJPROP_HIDDEN, 1);
         ObjectSetInteger(0, "ServerFault", OBJPROP_ANCHOR, ANCHOR_RIGHT);
         ObjectSetString(0, "ServerFault", OBJPROP_TEXT, "Server Fault");
         ObjectSetInteger(0, "ServerFault", OBJPROP_COLOR, Magenta);
         ObjectSetInteger(0, "ServerFault", OBJPROP_FONTSIZE, 25);
         ObjectSetString(0, "ServerFault", OBJPROP_FONT, "Arial");
        }
      else
         ObjectDelete(0, "ServerFault");
        }
      else
         ObjectDelete(0, "ServerFault");
//
        static int counter = 0;
        static int counter1 = 0;
        static datetime LastBar = 0;
        datetime CurrentBar = Time[0];
//        
      if(LastBar != CurrentBar)
        {
      if(counter1 != 1)
        {
         PlaySound("beep.wav");
         counter1 = counter1 + 1;
        };
//
      if(TS == 1 || TS == 3 || TS == 5 || TS == 7 || TS == 9 || TS == 11 || TS == 13 || TS == 15 || TS == 17 || TS == 19 || TS == 21 || TS == 23 || TS == 25 || TS == 27 || TS == 29 || TS == 31 || TS == 33 || TS == 35 || TS == 37 || TS == 39 || TS == 41 || TS == 43 || TS == 45 || TS == 47 || TS == 49 || TS == 51 || TS == 53 || TS == 55 || TS == 57 || TS == 59)
        {
         ObjectCreate(0, "Flash", OBJ_RECTANGLE_LABEL, 0, 0, 0);
         ObjectSetInteger(0, "Flash", OBJPROP_CORNER, CORNER_RIGHT_UPPER);
         ObjectSetInteger(0, "Flash", OBJPROP_XDISTANCE, 2000);
         ObjectSetInteger(0, "Flash", OBJPROP_YDISTANCE, 0);
         ObjectSetInteger(0, "Flash", OBJPROP_XSIZE, 2000);
         ObjectSetInteger(0, "Flash", OBJPROP_YSIZE, 1000);
         ObjectSetInteger(0, "Flash", OBJPROP_BGCOLOR, Magenta);
         ObjectSetInteger(0, "Flash", OBJPROP_BORDER_TYPE, BORDER_FLAT);
         ObjectSetInteger(0, "Flash", OBJPROP_BORDER_COLOR, clrNONE);
         ObjectSetInteger(0, "Flash", OBJPROP_HIDDEN, true);
         ObjectSetInteger(0, "Flash", OBJPROP_SELECTABLE, false);
         counter = counter + 1;
        }
      else
         ObjectDelete(0, "Flash");
// 
      if(counter == 1)
        {
         LastBar = CurrentBar;
         counter = 0;
         counter1 = 0;
        };
        }
      else
         ObjectDelete(0, "Flash");
        }


 
Warble68:

Here is the mql4 code (and below it the mql5 code) of an OnTimer function that works well in MT4. It flashes an object and plays a sound for one second when a new bar is created. It also warns me when a Symbol has not had a new tick for two minutes.

Have tried to convert the code to mql5 and have found some strange behaviour. The timing only works correctly when i output the time in seconds (datetime TSeconds = seconds.sec;) to the  Comment() function. What am i doing wrong here?


Have meanwhile found that the timing still does not work correctly in all situations. Setting the event timer to 100 milliseconds instead of to one second has fixed that. Also found serious errors in my code that i have fixed. See below...

void OnTimer()
        {
        MqlDateTime seconds;
        TimeLocal(seconds);
        datetime ts = seconds.sec;
        string strsec = TimeToString(ts, TIME_SECONDS);
        string sec = StringSubstr(strsec, 6, 2);
        int TS = StringToInteger(sec);
//        
        MqlDateTime minutes1;
        TimeCurrent(minutes1);
        datetime tc = minutes1.min;
        string strmin1 = TimeToString(tc, TIME_SECONDS);
        string min1 = StringSubstr(strmin1, 6, 2);
        int TC = StringToInteger(min1);        
//        
        MqlDateTime minutes2;        
        TimeLocal(minutes2);
        datetime tl = minutes2.min;
        string strmin2 = TimeToString(tl, TIME_SECONDS);
        string min2 = StringSubstr(strmin2, 6, 2);
        int TL = StringToInteger(min2);        
//        
        Comment(TS, " ", TC, " ", TL);
        datetime Time[];               
        CopyTime(_Symbol, _Period, 0, 1, Time);
//        
      if(TL - TC > 1 || TC - TL > 2)


Still, i have to use the Comment() function to make it all work correctly. Does anybody have any ideas of what is going on here?

 
Warble68: Does anybody have any ideas of what is going on here?
  1. Just a confused mind not thinking clearly.
  2. You want
    It flashes an object and plays a sound for one second when a new bar is created. It also warns me when a Symbol has not had a new tick for two minutes.
    So code it just that way
    datetime lastTick;
    void OnTick(){
      lastTick = TimeLocal();
      static datetime timeCur=0; datetime timePre = timeCur; timeCur = Time(0);
      bool  isNewBar = timeCur != timePre;
      if(isNewBar) FlashAndPlay();
      :
    }
    void OnTimer(){
       if(TimeLocal() - lastTick > 120) NoTicks();
    }
    datetime Time(int s){
       datetime time[]; CopyTime(_Symbol, _Period, 0, 1, time);
       return time[0];
    }

  3. You will get lots of alerts during the Asian session. "Free-of-Holes" Charts - MQL4 Articles
 
whroeder1:

  1. Just a confused mind not thinking clearly.
  2. You want So code it just that way
  3. You will get lots of alerts during the Asian session. "Free-of-Holes" Charts - MQL4 Articles


Thank you very much for taking the time to look into my problem!


On point 1.

Guilty as charged :-)

have read a lot and experimented a lot while trying to figure out this problem and so the code has become a confusing mess.  Sorry, should have cleaned it up and explained myself better!

I will try to simplify the problem but still use the way i had coded it , because it works and i am trying to understand why this is happening.

Ok, here the simplified code;


void OnTimer()
        {
        datetime tc = TimeCurrent();
        datetime tl = TimeLocal();
        int TS = StringToInteger(StringSubstr(TimeToString(tl, TIME_SECONDS), 6, 2));
        datetime time[];               
        CopyTime(_Symbol, _Period, 0, 1, time);
//        
        static int counter = 0;
        static int counter1 = 0;
        static datetime LastBar = 0;
        datetime CurrentBar = time[0];
//        
      if(LastBar != CurrentBar)
        {
      if(counter1 != 1)
        {
         PlaySound("beep.wav");
         counter1 = 1;
        };
//
      if(TS == 1 || TS == 3 || TS == 5 || TS == 7 || TS == 9 || TS == 11 || TS == 13 || TS == 15 || TS == 17 || TS == 19 || TS == 21 || TS == 23 || TS == 25 || TS == 27 || TS == 29 || TS == 31 || TS == 33 || TS == 35 || TS == 37 || TS == 39 || TS == 41 || TS == 43 || TS == 45 || TS == 47 || TS == 49 || TS == 51 || TS == 53 || TS == 55 || TS == 57 || TS == 59)
        {
         ObjectCreate(0, "Flash", OBJ_RECTANGLE_LABEL, 0, 0, 0);
         ObjectSetInteger(0, "Flash", OBJPROP_CORNER, CORNER_RIGHT_UPPER);
         ObjectSetInteger(0, "Flash", OBJPROP_XDISTANCE, 2000);
         ObjectSetInteger(0, "Flash", OBJPROP_YDISTANCE, 0);
         ObjectSetInteger(0, "Flash", OBJPROP_XSIZE, 2000);
         ObjectSetInteger(0, "Flash", OBJPROP_YSIZE, 1000);
         ObjectSetInteger(0, "Flash", OBJPROP_BGCOLOR, Magenta);
         ObjectSetInteger(0, "Flash", OBJPROP_BORDER_TYPE, BORDER_FLAT);
         ObjectSetInteger(0, "Flash", OBJPROP_BORDER_COLOR, clrNONE);
         ObjectSetInteger(0, "Flash", OBJPROP_HIDDEN, true);
         ObjectSetInteger(0, "Flash", OBJPROP_SELECTABLE, false);
         counter = 1;
        }
      else
         ObjectDelete(0, "Flash");
// 
      if(counter == 1)
        {
         LastBar = CurrentBar;
         counter = 0;
         counter1 = 0;
        };
        }
      else
         ObjectDelete(0, "Flash");
//
         Comment(" ");
        }


This code is supposed to simply play a beep sound and then flash an object at the start of a new Bar. The object should only flash for one second. This works, provided i add the empty Comment() function. If i leave it out , i get the beep, but no flash at the start of a new Bar!

In MQL4 it worked without needing this weird workaround.

Why?!


On point 3.

Yes, so true. Luckily i don't usually trade the Asian sessions. Need the warning only because of occasional server dropouts where the terminal for some reason does not auto reconnect. 









 

Below an even simpler example. Here the Bid and Ask lines are supposed to change color every second. Again, the timing only works properly if i add the empty Comment()!?


void OnTimer()
        {
        datetime tc = TimeCurrent();
        datetime tl = TimeLocal();
        int TS = StringToInteger(StringSubstr(TimeToString(tl, TIME_SECONDS), 6, 2));
//        
      if(TS == 1 || TS == 3 || TS == 5 || TS == 7 || TS == 9 || TS == 11 || TS == 13 || TS == 15 || TS == 17 || TS == 19 || TS == 21 || TS == 23 || TS == 25 || TS == 27 || TS == 29 || TS == 31 || TS == 33 || TS == 35 || TS == 37 || TS == 39 || TS == 41 || TS == 43 || TS == 45 || TS == 47 || TS == 49 || TS == 51 || TS == 53 || TS == 55 || TS == 57 || TS == 59)
        {
        ChartSetInteger(0, CHART_COLOR_BID, clrBlack);
        ChartSetInteger(0, CHART_COLOR_ASK, clrBlack);         
        }
      else
        {
        ChartSetInteger(0, CHART_COLOR_BID, clrSpringGreen);
        ChartSetInteger(0, CHART_COLOR_ASK, clrSpringGreen);         
        } 
//
        Comment(" ");
        }
 
Warble68: timing only works properly if i add the empty Comment()!?
  1. Try using ChartRedraw - Chart Operations - MQL4 Reference instead. No tick so it may think that the chart hasn't changed.
  2. Simplify your code
    datetime tl = TimeLocal();
    int TS = StringToInteger(StringSubstr(TimeToString(tl, TIME_SECONDS), 6, 2));
    if(TS == 1 || TS == 3 || TS == 5 || TS == 7 || TS == 9 || TS == 11 || TS == 13 || TS == 15 || TS == 17 || TS == 19 || TS == 21 || TS == 23 || TS == 25 || TS == 27 || TS == 29 || TS == 31 || TS == 33 || TS == 35 || TS == 37 || TS == 39 || TS == 41 || TS == 43 || TS == 45 || TS == 47 || TS == 49 || TS == 51 || TS == 53 || TS == 55 || TS == 57 || TS == 59)
    datetime tl = TimeLocal();
    int TS = t1 % 60;
    if(TS % 2 == 1)
    if(TimeLocal() % 2 == 1)

 
whroeder1:
  1. Try using ChartRedraw - Chart Operations - MQL4 Reference instead. No tick so it may think that the chart hasn't changed.
  2. Simplify your code
    datetime tl = TimeLocal();
    int TS = StringToInteger(StringSubstr(TimeToString(tl, TIME_SECONDS), 6, 2));
    if(TS == 1 || TS == 3 || TS == 5 || TS == 7 || TS == 9 || TS == 11 || TS == 13 || TS == 15 || TS == 17 || TS == 19 || TS == 21 || TS == 23 || TS == 25 || TS == 27 || TS == 29 || TS == 31 || TS == 33 || TS == 35 || TS == 37 || TS == 39 || TS == 41 || TS == 43 || TS == 45 || TS == 47 || TS == 49 || TS == 51 || TS == 53 || TS == 55 || TS == 57 || TS == 59)


That is brilliant!

if(TimeLocal() % 2 == 1)

Thank you very much whroeder1. Nice for a beginner to be taught such elegant simplifications.

ChartRedraw(0);

also does the trick.

Qustion is, why is this needed in an MQL5 OnTimer() function and why does it work in MQL4 without a chart redraw? And the even bigger mystery, why does adding an empty Comment() also work? Does Comment() perhaps force a redraw of the chart?