Repainting bars that stay on screen

 

Hi all,

I need to repaint the bars on my charts and I came up with the following half solution:

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
//----

int i;

for(i=0; i<500; i++){ //repaint

   string barName = "barBody" + i;
   string barCloseName = "barClose" + i;
   int type = OBJ_TREND;
   int window = 0;
   datetime barTime = Time[i];
   double barHigh = High[i];
   double barLow = Low[i];
   double barClose = Close[i];
   datetime time3=0;
   double price3=0;
   color colour = Black;

   // On every click, all objects are deleted to avoid having objects piling up on each iteration
   if(i==0){ //delete objects
      ObjectsDeleteAll();
   }// end delete objects

   // Checks if the current bar closed at the same level, higher or lower than the previous bar and assigns a different colour to each state
   if(Close[i]==Close[i+1]){ //close chech
      colour = Yellow; } else
   {
      if(Close[i]<Close[i+1]){
         colour = Red;
      } else {
         colour = Blue;
      }
   }//end close check
   
   //bar vertical repaint
   ObjectCreate(barName, type, window, barTime, barHigh, barTime, barLow);
   ObjectSet(barName, OBJPROP_COLOR, colour);
   ObjectSet(barName, OBJPROP_STYLE, STYLE_SOLID);
   ObjectSet(barName, OBJPROP_WIDTH, 2);
   ObjectSet(barName, OBJPROP_RAY, false);
   //end bar vertical repaint

   //bar close repaint
   ObjectCreate(barCloseName, type, window, barTime, barClose, barTime, barClose);
   ObjectSet(barCloseName, OBJPROP_COLOR, colour);
   ObjectSet(barCloseName, OBJPROP_STYLE, STYLE_SOLID);
   ObjectSet(barCloseName, OBJPROP_WIDTH, 6);
   ObjectSet(barCloseName, OBJPROP_RAY, false);
   //end bar close repaint
   
} //end repaint

The problem here is using the ObjectsDeleteAll(); on every tick, because it wipes the screen on every tick, including any trendlines or objects I draw manually.

So I guess my question is divided in 2:

1) How can I repaint the bars without having to use the ObjectsDeleteAll(); function (when I put it on the "Custom indicator initialization function" block, it stops repainting the current and future bars), and keep repainting the current and future bars?

2) How can I repaint all bars instead of having to have a predefined number of bars to paint (in this case 500)? Performance maybe an issue here, so any suggestions on how to improve are very welcomed, like only painting the bars currently displayed on the chart.

This will also help me with another open issue I have at https://www.mql5.com/en/forum/144643.

Many thanks in advance for any pointers in the right direction! 

 
dquelhas:

Hi all,

I need to repaint the bars on my charts and I came up with the following half solution:

The problem here is using the ObjectsDeleteAll(); on every tick, because it wipes the screen on every tick, including any trendlines or objects I draw manually.

So I guess my question is divided in 2:

1) How can I repaint the bars without having to use the ObjectsDeleteAll(); function (when I put it on the "Custom indicator initialization function" block, it stops repainting the current and future bars), and keep repainting the current and future bars?

2) How can I repaint all bars instead of having to have a predefined number of bars to paint (in this case 500)? Performance maybe an issue here, so any suggestions on how to improve are very welcomed, like only painting the bars currently displayed on the chart.

This will also help me with another open issue I have at https://www.mql5.com/en/forum/144643.

Many thanks in advance for any pointers in the right direction! 

ObjectsDeleteAll() is a very lazy and dangerous way of deleting Objects.  Why should your Indicator delete my Objects on my chart ?  if you want to delete your Objects then just delete your Objects.  Why do you need to re-draw your Objects ?  can't you just move them or adjust them using ObjectSet() ?  
 

I agree that using ObjectsDeleteAll() is lazy and dangerous, I'm taking my own poison here at the moment :-)

So, I'm back to point 1)  How can I repaint the bars without having to use the ObjectsDeleteAll(); function (when I put it on the "Custom indicator initialization function" block, it stops repainting the current and future bars), and keep repainting the current and future bars?

Am I getting this wrong? 

 
dquelhas:

I agree that using ObjectsDeleteAll() is lazy and dangerous, I'm taking my own poison here at the moment :-)

So, I'm back to point 1)  How can I repaint the bars without having to use the ObjectsDeleteAll(); function (when I put it on the "Custom indicator initialization function" block, it stops repainting the current and future bars), and keep repainting the current and future bars?

Am I getting this wrong?  

Yes you are getting it wrong.

Option 1.  Don't use Objects use Indicator buffers and histograms,  for each color of bar you use 2 buffers so you are limited to 4 colours.

Option 2.   For the bars that aren't going to change paint them in the init() function,  when a new bar 1 forms paint it in start() and, if you must,  paint bar 0 for each tick as it is forming.  There is no need to delete and re-draw your trendlines for each tick,  you only need to modify, using ObjectSet() , the trendline for bar 0.  Doing it this way you don't limit yourself to 500 bars just keep incrementing the count.

 
dquelhas: I need to repaint the bars on my charts and I came up with the following half (ASS) solution:
  1. Why do you need to repaint at all. Use the standard method
    int counted_bars    = IndicatorCounted();   if (counted_bars < 0)   return;
    if(counted_bars == 0){ // one time initialization }
    if(counted_bars < LOOK_BACK) counted_bars = LOOK_BACK; // SMA(x): lookback=x
    for(int iBar = Bars - 1 - counted_bars; iBar >= 0; iBar--){
       :
    your look back is one: iClose[i]<Close[i+1]
  2. string barName = "barBody" + i;
    string barCloseName = "barClose" + i;
    "i" changes each bar you can't use barBody0 once a new bar starts to form. Use unique names.
    string barName = "barBody" + Time[i];
    string barCloseName = "barClose" + Time[i];

  3. Never use objectDeleteALL. Instead use a unique pattern (such as your bar*) and only delete those
    #define ONDA_BEGINS   0
    #define ONDA_CONTAINS 1
    void ObjectNameDeleteAll(string name, int where=ONDA_BEGINS, int type=EMPTY){
        for(int iObj=ObjectsTotal()-1; iObj >= 0; iObj--){
            string on   = ObjectName(iObj);
            int    iPos = StringFind(on, name);
            if (iPos < 0)                         continue;
            if (iPos > 0 && where == ONDA_BEGINS) continue;
            if      (type == EMPTY))         ObjectDelete(on);
            else if (type == ObjectType(on)) ObjectDelete(on);
        }
    }
    

  4. Best way is to use indicator buffers histogram. See Download the newly updated GRaB 2.0 plug in for MT4 - Official website for trader and author Raghee Horner | Official website for trader and author Raghee Horner