Why does this indicator keep looping in MT4?

 

Dear all

When I added this indicator to chart, MT4 keeped looping all the time!  (indicator "pha_1" ran normally)

What's the problem?

Thanks for your help!

 

wing 

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 SandyBrown
#property indicator_color2 Chartreuse

//---- indicator parameters

extern double tf=60;

//---- buffers

double BufferA[];
double BufferB[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

int init()
  {
   IndicatorBuffers(2);
   IndicatorDigits(Digits);

//---- indicators
   SetIndexBuffer(0,BufferA);
   SetIndexBuffer(1,BufferB);

//---- drawing settings
   SetIndexStyle(0,DRAW_LINE);
   SetIndexStyle(1,DRAW_LINE);

//----
   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);

//----
   IndicatorShortName("td dir2");
   SetIndexLabel(0,"tdup");
   SetIndexLabel(1,"tddn");

//----
   return(0);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   ObjectsDeleteAll();
   
  }

//+------------------------------------------------------------------+
//| Bollinger Bands                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int i;
   int Counted_bars=IndicatorCounted();
   double rge;
   
   if( tf == 60 ) { rge = 0.0020; }
   
//---- bar check   
   if( Bars < 1 ) return(-1);

//---- last counted bar will be recounted    
   int limit = Bars - Counted_bars;
   if(Counted_bars > 0) limit++;
   if( Counted_bars == 0 ) limit--;

   for(i = 1; i < limit; i++)
   {
      if( iCustom(Symbol(),tf,"pha_1",1,i) > 0 ) { BufferA[i] = iClose(Symbol(),tf,i) + rge; }
      else if( iCustom(Symbol(),tf,"pha_1",1,i) < 0 ) { BufferB[i] = iClose(Symbol(),tf,i) - rge; }
      
      if( i > 1 && iCustom(Symbol(),tf,"pha_1",2,i) > 0 )
         { Text(iTime(Symbol(),tf,i), iHigh(Symbol(),tf,i)+rge+rge, DoubleToStr(2.0,Digits), 
            "tu", iTime(Symbol(),tf,i), Blue); }
      
      if( i > 1 && iCustom(Symbol(),tf,"pha_1",3,i) < 0 )
         { Text(iTime(Symbol(),tf,i), iLow(Symbol(),tf,i)-rge-rge, DoubleToStr(1.0,Digits), 
            "to", iTime(Symbol(),tf,i), Green); }
  }   
   
//----
   return(0);
  }
//+------------------------------------------------------------------+

//+-----------------------------------------------------------------+
//| price display                                                   |
//+-----------------------------------------------------------------+

string Text(datetime time, double price, string text, string name, int period, color clr)
{  
   string Name = name + IntegerToString(period);
   
   ObjectCreate(Name, OBJ_TEXT, 0, time, price); 
   ObjectSetText(Name, text, 5, "Times New Roman", clr); 
   return(Name);
}

 

 

 

Thanks 

 
wing: When I added this indicator to chart, MT4 keeped looping all the time!
  1. All indicators run "all the time" that's how they update their display.
  2. Get in the habit of always counting down. Don't use future values to calculate past ones (repainting)
    No need for the decrement/increment Contradictory information on IndicatorCounted() - MQL4 forum
       int limit = Bars - Counted_bars;
       if(Counted_bars > 0) limit++;
       if( Counted_bars == 0 ) limit--;
    
       for(i = 1; i < limit; i++)
    
    Do look backs properly. In your case LOOKBACK == 0
       for(i = Bars -1 - MathMax(LOOKBACK, Counted_bars); i >= 1; i--)

  3. Your code breaks when chart time frame is not equal to tf. Don't mix apples and oranges.
        if( iCustom(Symbol(),tf,"pha_1",1,i) > 0 ) { BufferA[i] = iClose(Symbol(),tf,i) + rge; }
    Variable i is the bar index for the current chart. You can NOT use it when referencing other timeframes
    int iTf = iBarShift(NULL, tf, Time[i]);
    if( iCustom(Symbol(),tf,"pha_1",1,iTf) > 0 ) { BufferA[i] = iClose(Symbol(),tf,iTf) + rge; }
    :
 

WHRoeder,

Thanks for your detail information! 

On the other hand,

My explanation is not clear enough.  "looping all the time" means the cursor still changes to circle.  I think it represents MT4 repaints the chart time by time.  It means IndicatorCounted() function doesn't work properly but I have no idea on the reason.

1. When I take a look on Fractal, it counts from right to left.  Then I check CCI and find it counts from left to right.  It is because pha_1 indicator counts from right to left, I choose to count from right to left for this indicator.

2. In pha_1, it needs 3 to 10 bars (i.e. bar[i] to bar[i+9]) to find out a value, then the indicator will assign it to one of the bars from buffervalue[i+1] to buffervalue[i+9] (something like Fractals).  Therefore, if I can't use future values to calculate past ones, how can I find the value?

3. In fact, I quite confuse with the concept of "IndicatorCounted" and "limit".  If my understanding is correct, IndicatorCounted() records the values of buffers from last time indicator ran by terminal.  It means terminal will not recalculate those values again when new bar comes or next time terminal restarts.  Therefore, Bars - counted bars will find out how many new bars arrived.  Counted bar = 0 means it is the first time indicator is added to the chart.  Counted bar > 0 means those "counted" bars will not be recalculated again.  Referring to my indicator, If counted bar = 0, limit = bar.  As 1st bar is bar 0, limit should be reduced by 1 to reflect the "real" oldest bar number.  Am I right?

4. What I don't understand is, why limit needs to add 1 if counted bar > 0?  (I just copy it from other indicator)  If 100 bars were counted last time, and a new bar comes, limit will be 101-100, it equals to 1, why is it needed to add 1 to limit but not decrease 1?

5. You said the line should change to "for(i = Bars -1 - MathMax(LOOKBACK, Counted_bars); i >= 1; i--)", does it mean that I should add an integer "LOOKBACK" and put it to the line?  If yes, what's the value of LOOKBACK?  is it a constant or variable?

6.  I don't understand the concept of SetIndexEmptyValue.  If buffer value is zero by default, what's the usage of SetIndexEmptyValue?

7. Also, I find that whether I add "IndicatorBuffers(2);" or not, the chart seems run normally.  Besides, I have added "#property indicator_buffers 2" on top.  Is it necessary to add   "IndicatorBuffers(2);" in init()?

8. What's the different between return(0) and return(-1)?  I know both of them will end the start() loop and restart start() again.  Does it also means journal will show error message or something?

Thanks a lot!

 

Wing 

 
  1. "looping all the time" means the cursor still changes to circle.
    Perhaps you mean Windows changes into a clock during paging. You have insufficient RAM for everything on your machine. Try changing Max Bars in Chart to something reasonable like 1000.
  2. I can't use future values to calculate past ones, how can I find the value?
    Bar zero is the current one, bar 1 is one period back. bar[i+9] is nine periods back from bar i. You are using past values not future ones.
  3. I quite confuse with the concept of "IndicatorCounted" and "limit" As 1st bar is bar 0, limit should be reduced by 1 ..r. Am I right?
    The first time IC is zero and limit would be Bar so you compute [0 .. Bar-1], i.e. all bars. The next tick IC is Bars-1 (not reduced by 1) and limit would be 1 you compute just bar zero. When a new bar starts, you compute bar 1 (any final tick) and bar zero. Read the link I posted.

  4. What I don't understand is, why limit needs to add 1 if counted bar > 0?  (I just copy it from other indicator) 
    You don't, see my example. You copied an indicator that followed a 10 year old, wrong, Metaquotes example, probably was trying to handle a look back of one.
  5. I should add an integer "LOOKBACK" and put it to the line? what's the value of LOOKBACK?
    You posted the answer: "In pha_1, it needs 3 to 10 bars (i.e. bar[i] to bar[i+9]) to find out a value" Your maximum look back is 9.
  6. I don't understand the concept of SetIndexEmptyValue. If buffer value is zero by default, what's the usage of SetIndexEmptyValue?
    When a buffer element contains the empty value it doesn't draw that bar. The default value is NOT zero, it is EMPTY_VALUE. If you want to use another value as empty tell it.
  7. #property indicator_buffers 2" on top.  Is it necessary to add "IndicatorBuffers(2);" in init()?
    Property says how many buffers are displayed. IndicatorBuffers says how many additional buffers you need. If you don't need any it's not.
  8. What's the different between return(0) and return(-1)?  I know both of them will end the start() loop and restart start() again.
    They return different values to the terminal which ignores it. Only the new OnInit can look at the return code.
 
WHRoeder:
  1. "looping all the time" means the cursor still changes to circle.
    Perhaps you mean Windows changes into a clock during paging. You have insufficient RAM for everything on your machine. Try changing Max Bars in Chart to something reasonable like 1000.
  2. I can't use future values to calculate past ones, how can I find the value?
    Bar zero is the current one, bar 1 is one period back. bar[i+9] is nine periods back from bar i. You are using past values not future ones.
  3. I quite confuse with the concept of "IndicatorCounted" and "limit" As 1st bar is bar 0, limit should be reduced by 1 ..r. Am I right?
    The first time IC is zero and limit would be Bar so you compute [0 .. Bar-1], i.e. all bars. The next tick IC is Bars-1 (not reduced by 1) and limit would be 1 you compute just bar zero. When a new bar starts, you compute bar 1 (any final tick) and bar zero. Read the link I posted.

  4. What I don't understand is, why limit needs to add 1 if counted bar > 0?  (I just copy it from other indicator) 
    You don't, see my example. You copied an indicator that followed a 10 year old, wrong, Metaquotes example, probably was trying to handle a look back of one.
  5. I should add an integer "LOOKBACK" and put it to the line? what's the value of LOOKBACK?
    You posted the answer: "In pha_1, it needs 3 to 10 bars (i.e. bar[i] to bar[i+9]) to find out a value" Your maximum look back is 9.
  6. I don't understand the concept of SetIndexEmptyValue. If buffer valueis zero by default, what's the usage of SetIndexEmptyValue?
    When a buffer element contains the empty value it doesn't draw that bar. The default value is NOT zero, it is EMPTY_VALUE. If you want to use another value as empty tell it.
  7. #property indicator_buffers 2" on top.  Is it necessary to add "IndicatorBuffers(2);" in init()?
    Property says how many buffers are displayed. IndicatorBuffers says how many additional buffers you need. If you don't need any it's not.
  8. What's the different between return(0) and return(-1)?  I know both of them will end the start() loop and restart start() again.
    They return different values to the terminal which ignores it. Only the new OnInit can look at the return code.

Thanks a lot!

 

wing 

Reason: