I want to understand why my indicator repaints

 

Anybody can please help me understand why my indicator repaints.

It firstly fill an Array (PRatio) and then has to fill another Array (MA) with the MA of PRatio[]. Then filles the 3rd Array (DV) with Standard Deviation of PRatio[].

And After all fills the Main Buffer (ZScore) with : (PRatio- MA) / DV.

I didn't find out why it repaints.


Any help would be appreciated.

 #property strict
#property indicator_separate_window
//---
#property indicator_buffers 4
#property indicator_color1 clrRosyBrown //PRatio
#property indicator_width1  1
#property indicator_color2 clrYellow //MA
#property indicator_width2  1
#property indicator_color3 clrAqua//Standard DV
#property indicator_width3  1
#property indicator_color4 clrGreen
#property indicator_width2  1
//---
#property indicator_level1 0
#property indicator_levelcolor clrGray
#property indicator_levelstyle STYLE_DOT
#property indicator_levelwidth 0
//---
input string    symb_1    = "EURUSD"; // Symbol 1
input string    symb_2    = "GBPUSD"; // Symbol 1
extern int LookBack = 50;//Look Back (Bars)
//---
//input string __inputSeperator1;//<<< Settings used in Pric-Ratio MA >>>
int      Period_MA = 50;        // MA Period
ENUM_MA_METHOD Method_MA = MODE_SMA; //MA Method
//input string __inputSeperator2;//<<< MA settings used in Standard Deviation >>>
int      MA_Period_DV = 50;        // MA in Standard DV
ENUM_MA_METHOD MA_Method_DV = MODE_SMA; //MA Method in Standard DV
//---
ENUM_TIMEFRAMES TF = PERIOD_CURRENT;
//---
double ZS_Buffer[];
double PRatio[];
double MA[];
double DV[];
bool IsFirstScan_MA = true;
bool IsFirstScan_DV = true;
bool IsFirstScan_ZScore = true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   Comment("");
   if(LookBack < 1)
     {
         Alert("********* Attention: 'Look Back' has to be equal or greater than 1. It automatically changed to 50.");
      LookBack = 50;
     }
//---
   Period_MA = LookBack;
   MA_Period_DV = LookBack;
   Method_MA = MODE_SMA;
   MA_Method_DV = MODE_SMA;
//---
   IsFirstScan_MA = true;
   IsFirstScan_DV = true;
   IsFirstScan_ZScore = true;
//--- indicator buffers mapping
   SetIndexBuffer(0, PRatio);
   SetIndexStyle(0, DRAW_NONE);
   SetIndexLabel(0, "Price Ratio");
   SetIndexBuffer(1, MA);
   SetIndexStyle(1, DRAW_NONE);
   SetIndexLabel(1, "MA of Price Ratio");
   SetIndexBuffer(2, DV);
   SetIndexStyle(2, DRAW_NONE);
   SetIndexLabel(2, "Standart DV");
   SetIndexBuffer(3, ZS_Buffer);
   SetIndexStyle(3, DRAW_LINE);
   SetIndexLabel(3, "Z-Score");
   IndicatorDigits(Digits + 3);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   int limit = rates_total - (prev_calculated > 0 ? prev_calculated : 1);
   for(int i = limit; i >= 0 && !_StopFlag; i--)
     {
      PRatio[i] = Price_Ratio(i, symb_1, symb_2);
     }
   if(IsFirstScan_MA)
     {
      for(int i = limit - Period_MA; i >= 0 && !_StopFlag; i--)
        {
         MA[i] = iMAOnArray(PRatio, 0, Period_MA, 0,Method_MA, i);
        }
      IsFirstScan_MA = false;
     }
   else
     {
      for(int i = limit; i >= 0 && !_StopFlag; i--)
        {
         MA[i] = iMAOnArray(PRatio, 0, Period_MA, 0,Method_MA, i);
        }
     }
//---
   if(IsFirstScan_DV)
     {
      for(int i = limit - MA_Period_DV; i >= 0 && !_StopFlag; i--)
        {
         DV[i] = iStdDevOnArray(PRatio, 0, MA_Period_DV, 0,MA_Method_DV, i);
        }
      IsFirstScan_DV = false;
     }
   else
     {
      for(int i = limit; i >= 0 && !_StopFlag; i--)
        {
         DV[i] = iStdDevOnArray(PRatio, 0, MA_Period_DV, 0,MA_Method_DV, i);
        }
     }
   if(IsFirstScan_ZScore)
     {
      for(int i = (limit - Period_MA) - 1; i >= 0 && !_StopFlag; i--)
        {
         ZS_Buffer[i] = Z_Score(i);
        }
      IsFirstScan_ZScore = false;
     }
   else
     {
      for(int i = limit; i >= 0 && !_StopFlag; i--)
        {
         ZS_Buffer[i] = Z_Score(i);
        }
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Price_Ratio(int bar, string _sym_1, string _sym_2)
  {
   double symb_1_NC, symb_2_NC; //NC = Net Change
//double symb_1_Curr = MarketInfo(_sym_1,MODE_BID);
//double symb_2_Curr = MarketInfo(_sym_2,MODE_BID);
   double symb_1_Curr = iClose(_sym_1, TF, bar); 
   double symb_2_Curr = iClose(_sym_2, TF, bar);
   double symb_1_Prev = iClose(_sym_1, TF, bar + 1);
   double symb_2_Prev = iClose(_sym_2, TF, bar + 1);
//---
   symb_1_NC = symb_1_Curr - symb_1_Prev; 
 
   symb_2_NC = symb_2_Curr - symb_2_Prev; 
 
//---
   return symb_1_NC - symb_2_NC;          
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Z_Score(int shift)
  {
   if(DV[shift] == 0)
     {
      return 0 ;
     }
   return (PRatio[shift] - MA[shift]) / DV[shift];
  }
 
Because the calculations are being performed on the current bar. Add a '+1' to the 'i' in all the calculations and it won't repaint.
 
   int limit = rates_total - (prev_calculated > 0 ? prev_calculated : 1);
   for(int i = limit; i >= 0 && !_StopFlag; i--)
     {
      PRatio[i] = Price_Ratio(i, symb_1, symb_2);
     }
   if(IsFirstScan_MA)
     {
      for(int i = limit - Period_MA; i >= 0 && !_StopFlag; i--)

It's not repainting, it's not computing. After the first run you compute limit=rt-rt=0 and i=limit-Period_MA means you don't do anything.
          How to do your lookbacks correctly.

 
Frederick Langemark:
Because the calculations are being performed on the current bar. Add a '+1' to the 'i' in all the calculations and it won't repaint.

Thanks  Frederick Langemark

But I need the indicator to show me the value of current bar too, which is the only bar in which the value one the chart can be variable.
Thanks

 
William Roeder:

It's not repainting, it's not computing. After the first run you compute limit=rt-rt=0 and i=limit-Period_MA means you don't do anything.
          How to do your lookbacks correctly.

Thanks  William Roeder

You are right

I printed the " i "  int the first loop and saw what you are talking about.
Thanks

 
All indicators repaint. The only indicator that doesn’t repaint is the naked chart. Price action trading is the way to go. 
 
Hussain Patel:
All indicators repaint. The only indicator that doesn’t repaint is the naked chart. Price action trading is the way to go. 
No, all indicators do not repaint.
 
Most indicators continuously update the forming bar; that is not repainting. Older bars don't change and neither should the indicator.
 
William Roeder:
Most indicators continuously update the forming bar; that is not repainting. Older bars don't change and neither should the indicator.

Bingo.

 
Reza nasimi:

Anybody can please help me understand why my indicator repaints.

It firstly fill an Array (PRatio) and then has to fill another Array (MA) with the MA of PRatio[]. Then filles the 3rd Array (DV) with Standard Deviation of PRatio[].

And After all fills the Main Buffer (ZScore) with : (PRatio- MA) / DV.

I didn't find out why it repaints.


Any help would be appreciated.

 MA[i] = iMAOnArray(PRatio, 0, Period_MA, 0,Method_MA, i);
double Price_Ratio(int bar, string _sym_1, string _sym_2)
  {
   double symb_1_NC, symb_2_NC; //NC = Net Change
//double symb_1_Curr = MarketInfo(_sym_1,MODE_BID);
//double symb_2_Curr = MarketInfo(_sym_2,MODE_BID);
   double symb_1_Curr = iClose(_sym_1, TF, bar);  <--- variable when bar = 0
   double symb_2_Curr = iClose(_sym_2, TF, bar);
   double symb_1_Prev = iClose(_sym_1, TF, bar + 1); <--- non variable when bar = 0
   double symb_2_Prev = iClose(_sym_2, TF, bar + 1);
//---
   symb_1_NC = symb_1_Curr - symb_1_Prev; 
 
   symb_2_NC = symb_2_Curr - symb_2_Prev; 
 
//---
   return symb_1_NC - symb_2_NC;          
  }

You're using the close price. In MT, the close price is the last price until bar (1) has closed and new bar (0) opened.

 
Icham Aidibe:

You're using the close price. In MT, the close price is the last price until bar (1) has closed and new bar (0) opened.

Hi  Icham Aidibe

Thanks , I appreciate your help.
But actually I know that and did it by purpose. That's not the problem. I want the indicator to be variable in the current bar, but not on the previous bars.

I think the problem is solved by the new loop I made as described on William Roeder's link.

Regards