Analog clockface animation running on chart as EA Timer task

 

My first MQL5 programming article ever :-()

I found this piece of code in a MQL5 forum that animates a primitive clock face in the chart.
I am not sure who created it, if you know tell me so I can give due credit.
This represents an example of how to render graphical objects on the trading chart.



In the shape I found this code it runs as a single task script to illustrate chart graphic display techniques.
See this original for reference, attached as 'ClockTest.mq5'.

As a monolith script it does not allow anything else to happen at the same time.

So I figured it could be possible to integrate this clock widget into an EA by dividing it into two parts,
(1) a short initialization step run part of OnInit(), + a few EA global varables, and (2) a timer task that runs the update portion.
And it worked !
So this article describes how I turned the clockface script into a EA timer task.

A timer task "ClockTime()" runs once a second to update the clock face (See attached).

//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   ClockTime();
  }

In the global variables section of the EA I place some runtime variables for the clock:

//--- CLOCK TEST ----------
// width and height of the canvas (used for drawing)
#define IMG_WIDTH  200
#define IMG_HEIGHT 200
//--- drawing array (buffer) 
uint ExtImg[IMG_WIDTH*IMG_HEIGHT];
uint   w,h; // variables for receiving text string sizes   
uint   nm=2700;      // minute corner
uint   nh=2700*12;   // hour counter
//-------------------------

In the OnInit() method of the EA
I start a timer task ClockTime:

     ClockInit();       // Initialization of clock object    
     EventSetTimer(1);  // Update clock widget at 1 second interval

ClockInit() looks like this:

void ClockInit() {
  // Initialization of clock object
  // Timer task ClockTime() operates on this object
  
    //--- create OBJ_BITMAP_LABEL object for drawing    
   ObjectCreate(0,"CLOCK",OBJ_BITMAP_LABEL,0,0,0);
//--- specify the name of the graphical resource for writing in CLOCK object
   ObjectSetString(0,"CLOCK",OBJPROP_BMPFILE,"::IMG");
 
   ObjectSetInteger(0, "CLOCK", OBJPROP_XDISTANCE, 2700);
   ObjectSetInteger(0, "CLOCK", OBJPROP_YDISTANCE, 160);
}

And here is ClockTime(), the timer job that updates the watch face in the chart:

void ClockTime() {
  // Timer task that updates clock widget 
   double a;            // arrow corner
   int    x,y;          // variables for calculation of the current coordinates of text string anchor points
        //--- clear the clock drawing buffer array
      ArrayFill(ExtImg,0,IMG_WIDTH*IMG_HEIGHT,0);
      //--- set the font for drawing digits for the clock-face
      TextSetFont("Arial",-100,FW_EXTRABOLD,0);
      //--- draw the clock-face
      for(int i=1;i<=12;i++)
        {
         //--- receive the size of the current hour on the clock-face
         TextGetSize(string(i),w,h);
         //--- calculate the coordinates of the current hour on the clock-face
         a=-((i*300)%3600*M_PI)/1800.0;
         x=IMG_WIDTH/2-int(sin(a)*80+0.5+w/2);
         y=IMG_HEIGHT/2-int(cos(a)*80+0.5+h/2);
         //--- output the hour on the clock-face to ExtImg[] buffer
         TextOut(string(i),x,y,TA_LEFT|TA_TOP,ExtImg,IMG_WIDTH,IMG_HEIGHT,0xFFFFFFFF,clr_format);
        }
      //--- now, specify the font for drawing the minute hand      
      TextSetFont("Arial",-100,FW_EXTRABOLD,-int(nm%3600));
      //--- receive the size of the minute hand
      TextGetSize("----->",w,h);
      //--- calculate the coordinates of the minute hand on the clock-face
      a=-(nm%3600*M_PI)/1800.0;
      x=IMG_WIDTH/2-int(sin(a)*h/2+0.5);
      y=IMG_HEIGHT/2-int(cos(a)*h/2+0.5);
      //--- output of the minute hand to the clock-face in ExtImg[]buffer
      TextOut("---->",x,y,TA_LEFT|TA_TOP,ExtImg,IMG_WIDTH,IMG_HEIGHT,0xFFFFFFFF,clr_format);
 
      //--- now, set the font for drawing the hour hand      
      TextSetFont("Arial",-100,FW_EXTRABOLD,-int(nh/12%3600));
      TextGetSize("==>",w,h);
      //--- calculate the coordinates of the hour hand on the clock-face
      a=-(nh/12%3600*M_PI)/1800.0;
      x=IMG_WIDTH/2-int(sin(a)*h/2+0.5);
      y=IMG_HEIGHT/2-int(cos(a)*h/2+0.5);
      //--- output of the hour hand on the clock-face to ExtImg[] buffer
      TextOut("==>",x,y,TA_LEFT|TA_TOP,ExtImg,IMG_WIDTH,IMG_HEIGHT,0xFFFFFFFF,clr_format);
 
      //--- update the graphical resource
      ResourceCreate("::IMG",ExtImg,IMG_WIDTH,IMG_HEIGHT,0,0,IMG_WIDTH,clr_format);
      //--- forced chart update
      ChartRedraw();
 
      //--- increase hour and minute counters
      nm+=60;
      nh+=60;
}

This is pretty much the untouched code by its author, I only adjusted some font sizes so the watch face displays well.
So to summarize :
By dividing up the original script into an Init part,  some global variables, and the interval timer run "ClockTime()" function
the clock can now run on the chart while the rest of the EA works undisturbed.
I tweaked the location of the watch face using a crude offset so it appears on the right hand.

See this line

ObjectSetInteger(0, "CLOCK", OBJPROP_XDISTANCE, 2700);

of the ClockInit() code where the "2700" value is a vertical pixel offset on chart to where the clockface rendering starts.

If you try this code for basic learning you could experiment with OBJPROP_XDISTANCE ,  OBJPROP_YDISTANCE values to position your clock. 


What is missing to make it a full fledged watch is the Hour indicator
So I will try to add this soon :)

So this can be an example of the kind of threaded activity a timer tasks will enable.
Why do this ?  I found it a fun test case to gain courage in placing custom stuff on the chart.
The primitive clock face was a ready-made gimmick that lended itself to experimentation.

How to Order a Trading Robot in MQL5 and MQL4
How to Order a Trading Robot in MQL5 and MQL4
  • www.mql5.com
"Freelance" is the largest freelance service for ordering MQL4/MQL5 trading robots and technical indicators. Hundreds of professional developers are ready to develop a custom trading application for the MetaTrader 4/5 terminal.
Files:
clocktest.mq5  4 kb
 
Slight flaw in what I wrote; the clock face is designed with Minute and Hour arms.  I assumed it would animate a seconds arm.
So I update it once a second while in the current shape it would need a 1 minute timer.

I will update the code so the clock get a seconds arm as well.
It seems my ability to update the post got disabled ?