Drawing a Rectangle_Label with Dynamic Text using MQL4

A subpar design with potential I/O-blocking due to RDBMS processing or other factors could result in Trading Terminal crashes. This is an undesirable outcome for anyone, whether in the live-trading or back-testing phase. Essentially, the code functions as an event-driven factory triggered by the asynchronous flow of incoming Market Events, except for the aforementioned scenario.

Question:

My goal is to create a Rectangle Label containing text that updates every tick. I am using a Label to display the text, but I’m struggling to ensure that it fits perfectly within the Rectangle_Label. Unfortunately, I haven’t been able to position it correctly yet.

My intention is to design a class that has the ability to handle everything at once. This class would function similar to a rectangular shape containing text, with a fixed position and size.

Assistance of any kind would be highly valued.

 bool createRectangleLabel(long chart_ID,string name,string labelName,int shift,double price,string text,double xSize,double ySize,double xOffSet,double yOffSet,double xDistance,double yDistance)
     {
      if(ObjectCreate(chart_ID,labelName,OBJ_RECTANGLE_LABEL,0,TimeCurrent()-shift,price))
    {
     Print(xDistance+"  "+yDistance);
     ObjectSetInteger(chart_ID,labelName,OBJPROP_BGCOLOR,clrBlack);
     ObjectSetInteger(chart_ID,labelName,OBJPROP_XDISTANCE,xDistance);
     ObjectSetInteger(chart_ID,labelName,OBJPROP_YDISTANCE,yDistance);
     ObjectSetInteger(chart_ID,labelName,OBJPROP_YSIZE,ySize);
     ObjectSetInteger(chart_ID,labelName,OBJPROP_XSIZE,xSize);
     ObjectSetString(chart_ID,labelName,OBJPROP_TEXT,text);
     ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,ANCHOR_CENTER);
     return true;
    }
  else
    {
     Print("createRectangleLabel return error code: ",GetLastError());
     Print("+--------------------------------------------------------------+");
     return false;
    }
 }
   bool createLineText(long chart_ID,string name,string labelName,int shift,double price,string text)
 {
  int xDistance=0;
  int yDistance=0;
  int xSize,xOffSet;
  int ySize,yOffSet;
  bool i=ChartTimePriceToXY(chart_ID,0,TimeCurrent(),price,xDistance,yDistance);
  if(ObjectCreate(chart_ID,name,OBJ_LABEL,0,TimeCurrent()-shift,price))
    {
     ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,clrWhite);
     ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,xDistance);
     ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,yDistance);
     ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
     ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,ANCHOR_CENTER);
     ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clrWhite);
     ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,10);
     xSize = ObjectGet(name,OBJPROP_XSIZE);
     ySize = ObjectGet(name,OBJPROP_YSIZE);
     xOffSet = ObjectGet(name,OBJPROP_XOFFSET);
     yOffSet = ObjectGet(name,OBJPROP_YOFFSET);
     TextGetSize(name,xSize,ySize);
     createRectangleLabel(chart_ID,name,labelName,shift,price,text,xSize,ySize,xOffSet,yOffSet,xDistance,yDistance);
     return true;
    }
  else
    {
     Print("createLineText return error code: ",GetLastError());
     Print("+--------------------------------------------------------------+");
     return false;
    }
 }



Solution 1:

Calling

ObjectCreate()

repeatedly is not possible as it will result in an error 4200. To avoid this, you can check if the object exists before creating it. Another way is to create the object and set its required properties such as its color and anchor in a single block and then move it in a separate block.

if(ObjectFind(chart_id,labelName)<0){
   if(ObjectCreate(chart_ID,labelName,OBJ_RECTANGLE_LABEL,0,TimeCurrent()-shift,price)){
      ObjectSetInteger(chart_ID,labelName,OBJPROP_BGCOLOR,clrBlack);//etc.
   }
   ObjectSetInteger(chart_ID,labelName,OBJPROP_XDISTANCE,xDistance);
   ObjectSetInteger(chart_ID,labelName,OBJPROP_YDISTANCE,yDistance);//if you need to move the object or take other steps each tick, e.g. update text - do it here
}


Solution 2:


Your idea of creating a class is commendable, and luckily, the

standard library

comes with all the necessary classes to produce chart objects. Additionally, the documentation also covers these classes.

Example Indicator:

#property strict
#property indicator_chart_window
#include 
class MyRectLabel : public CChartObjectRectLabel
{
   CChartObjectLabel m_label;
public:
   bool Create(long chart, const string name, const int window, 
               const int X, const int Y, const int sizeX, const int sizeY)
   {
      if(!CChartObjectRectLabel::Create(chart,name,window,X,Y,sizeX,sizeY))
         return false;
      return m_label.Create(chart, name + "_", window, X + 8, Y + 12);
   }
   bool Color(const color clr){
      return m_label.Color(clr);
   }
   bool Description(const string text){
      return m_label.Description(text);
   }
   bool FontSize(const int size){
      return m_label.FontSize(size);
   }
   bool ToolTip(const string text){
      return (this.ToolTip(text) && m_label.Tooltip(text));
   }
};
//+------------------------------------------------------------------+
MyRectLabel rect_label;
//+------------------------------------------------------------------+
int OnInit()
{
   if(!rect_label.Create(0, "rlabel", 0, 5, 25, 100, 50)
      || !rect_label.BackColor(clrWhiteSmoke)
      || !rect_label.Description("LABEL!")
      || !rect_label.Tooltip("I am a rectangle label")
      || !rect_label.Color(clrBlack)
      || !rect_label.FontSize(18)
   )
      return INIT_FAILED;
   return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
int start()
{ 
   static double last_price = 0.;
   rect_label.Description(DoubleToString(Bid, _Digits));
   if(Bid > last_price)
      rect_label.Color(clrLimeGreen);
   else
      rect_label.Color(clrRed);
   last_price = Bid;
   return 0; 
}

Frequently Asked Questions

Posted in Uncategorized