Indicator redraw won't work !!

 

Hi all ,

Im a new bit for MT5, and now I face a problem about the indicator redraw ...

I have a moving average and arrow in the chart, first run everything looks just fine(see attach #1)

but after cpuple minutes , the indicator redraw seems go wrong (see attach #2) 

here is my code 

//+------------------------------------------------------------------+
//|                                                    myReg v02.mq5 |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   3

//--- plot ShortAverage
#property indicator_label1  "ShortAverage"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrOrange
#property indicator_style1  STYLE_DOT
#property indicator_width1  1

//--- 
#property indicator_label2  "Up Arrows" 
#property indicator_type2   DRAW_ARROW 
#property indicator_color2  clrRed
#property indicator_width2  2

#property indicator_label3  "Down Arrows" 
#property indicator_type3   DRAW_ARROW 
#property indicator_color3  clrGreenYellow
#property indicator_width3  2

//--- input parameters
input int      ShortAvg=5;

//--- indicator buffers
double   ShortAverageBuffer[];
double   ColorUpArrowBuffer[];
double   ColorDownArrowBuffer[];
int      MA_handle;
ushort   UpCode=234;
ushort   DownCode=233;
double   offset=0.0003;
string   short_name;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ShortAverageBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,ColorUpArrowBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,ColorDownArrowBuffer,INDICATOR_DATA);

   ResetLastError();

   MA_handle=iCustom(NULL,0,"Examples\\Custom Moving Average",
                     ShortAvg,
                     0,
                     MODE_LWMA,
                     PRICE_MEDIAN  // using the close prices 
                     );
   Print("MA_handle = ",MA_handle,"  error = ",GetLastError());

   PlotIndexSetInteger(5,PLOT_ARROW,UpCode);
   PlotIndexSetInteger(5,PLOT_ARROW_SHIFT,0);
   PlotIndexSetDouble(5,PLOT_EMPTY_VALUE,0);

   PlotIndexSetInteger(6,PLOT_ARROW,DownCode);
   PlotIndexSetInteger(6,PLOT_ARROW_SHIFT,0);
   PlotIndexSetDouble(6,PLOT_EMPTY_VALUE,0);

// short_name=StringFormat("iMA(%s/%s, %d, %d, %s, %s)",name,EnumToString(period),ma_period,ma_shift,EnumToString(ma_method),EnumToString(applied_price));
   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 values_to_copy;
   int calculated=BarsCalculated(MA_handle);
   int bars_calculated=0;
   if(prev_calculated==0 || calculated!=BarsCalculated(MA_handle) || rates_total>prev_calculated+1)
     {
      if(calculated>rates_total) values_to_copy=rates_total;
      else                       values_to_copy=calculated;
     }
   else
     {
      values_to_copy=(rates_total-prev_calculated)+1;
     }

   int copy=CopyBuffer(MA_handle,0,0,rates_total,ShortAverageBuffer);
   Print("copy = ",copy,"    rates_total = ",rates_total);
   if(copy<=0)
     {
      Print("An attempt to get the values if Custom Moving Average has failed");
      return(false);
     }

// ----------------------------

   for(int i=1;i<rates_total;i++)
     {
      ColorDownArrowBuffer[i]=0;
      ColorUpArrowBuffer[i]=0;
      //--- check the condition
      if(ShortAverageBuffer[i+3]<ShortAverageBuffer[i+2] && 
         ShortAverageBuffer[i+2]<ShortAverageBuffer[i+1] && 
         ShortAverageBuffer[i+1]>ShortAverageBuffer[i])
         ColorDownArrowBuffer[i]=high[i]+high[i]*offset;
      else
         ColorDownArrowBuffer[i]=0;

      if(ShortAverageBuffer[i+3]>ShortAverageBuffer[i+2] && 
         ShortAverageBuffer[i+2]>ShortAverageBuffer[i+1] && 
         ShortAverageBuffer[i+1]<ShortAverageBuffer[i])
         ColorUpArrowBuffer[i]=low[i]-low[i]*offset;
      else
         ColorUpArrowBuffer[i]=0;

     }

   string comm=StringFormat("%s ==>  Updated value in the indicator %s: %d",
                            TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
                            short_name,
                            values_to_copy);

//--- display the service message on the chart 
   Comment(comm);
//--- memorize the number of values in the Moving Average indicator 
   bars_calculated=calculated;
   return(rates_total);
  }
//+------------------------------------------------------------------+


Any help ? 

Thank you in advance ! :D

 
int rates_zero=(int)MathMax(1,prev_calculated-1);
for(int i=rates_zero; i<rates_total; i++)

You also need an extra variable instead of rates_total for the arrow buffers. Two 'for' functions, =0 to <rates_total for MA and =1 to <rates_total-2 for arrows.


P.S. You also don't need 'offset', you can set the arrow value equal to high/low and offset it in pixels like with Fractals indicator with +-PLOT_ARROW_SHIFT. It''s one of the new things in MT5 which isn't available in MT4.

 
kypa:

You also need an extra variable instead of rates_total for the arrow buffers. Two 'for' functions, =0 to <rates_total for MA and =1 to <rates_total-2 for arrows.


P.S. You also don't need 'offset', you can set the arrow value equal to high/low and offset it in pixels like with Fractals indicator with +-PLOT_ARROW_SHIFT. It''s one of the new things in MT5 which isn't available in MT4.

Thank you for your reply, I'll try it later ! :D
 
kypa:

You also need an extra variable instead of rates_total for the arrow buffers. Two 'for' functions, =0 to <rates_total for MA and =1 to <rates_total-2 for arrows.



Still can't figurt it out , would you please tell me more detail , and any article to learn all the concept  of  "OnCalculate" ?

Many many thanks !!

 
i.Andy: descript all the concept  of  "OnCalculate" ?

See How to do your lookbacks correctly.

@Alain Verleyen It was the wrong link.

 
whroeder1:

See Detailed explanation of iCustom - MQL4 and MetaTrader 4 - MQL4 programming forum

Please stop confuse people. iCustom has nothing to do here,  and it's an mql5 topic. I removed the link.
 

This link might help:

https://www.mql5.com/en/docs/basis/function/events

You need to recalculate only the last bars' values that change with new ticks. And the last bar is rates_total-1, you can't have buffer[rates_total-1+3] (that's why the MA goes to the sky on your second screenshot).

Look at the values_to_copy calculation, understand those and you'll know what to write for your buffers.

Documentation on MQL5: Language Basics / Functions / Event Handling Functions
Documentation on MQL5: Language Basics / Functions / Event Handling Functions
  • www.mql5.com
The MQL5 language provides processing of some predefined events. Functions for handling these events must be defined in a MQL5 program; function name, return type, composition of parameters (if there are any) and their types must strictly conform to the description of the event handler function. The event handler of the client terminal...
 
Its good to have you guys' help,  Thank you all .


Now I figure out the PLOT_ARROW_SHIFT, and  I study hard every article for coding what I need since last weekend , but  unluckily it still now work . 

@kypa can you tell me more about this ? ( what a dumb am I ... 

kypa:

You also need an extra variable instead of rates_total for the arrow buffers. Two 'for' functions, =0 to <rates_total for MA and =1 to <rates_total-2 for arrows.


Thanks again !!  :D

Reason: