mql5 and buffer always printing

 

Hi

I have just started to use metatrader 5 (coming from metatrader 4). To build a simple indikator which prints an arrow (or whatever) in a certain situation was a bit different from mql4. In mql5 the buffer is always sending out data to the terminal. I guess that is by design, but what is the proper way to get the buffer to print when I want it to print? Here in this simple example I used Label1Buffer[i] = EMPTY_VALUE to silence the output. Is it a better way?

   for (int i=0; i<limit; i++) 
   {
      if (high[i] < close[i+2])
      {
         Label1Buffer[i] = low[i];
      } else {
         Label1Buffer[i] = EMPTY_VALUE;
      }
   }


Here is a the very simple indicator in full:

//+------------------------------------------------------------------+
//|                                                     Arrow v1.mq5 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrYellow
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
//--- indicator buffers
double         Label1Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Label1Buffer,INDICATOR_DATA);
   
//---
   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 = 0;
   if (prev_calculated>rates_total || prev_calculated <=0)
   {
      limit = rates_total;
   } else {
      limit = rates_total-prev_calculated;
      if (prev_calculated>0) limit++;
   }
   
   for (int i=0; i<limit; i++) 
   {
      if (high[i] < close[i+2])
      {
         Label1Buffer[i] = low[i];
      } else {
         Label1Buffer[i] = EMPTY_VALUE;
      }
   }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


Regards

Claes
 

 

Hello Claes . 

You can use PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0) 

(more here : https://www.mql5.com/en/forum/315171 )

and mind the data you are accessing as well 

//+------------------------------------------------------------------+
//|                                                     Arrow v1.mq5 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrYellow
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
input int compare_with=2;//compare with i + ...
//--- indicator buffers
double         Label1Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   
   SetIndexBuffer(0,Label1Buffer);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---
   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 = 0;
   if (prev_calculated>rates_total || prev_calculated <=0)
   {
      limit = rates_total-compare_with-1;
   } else {
      limit = rates_total-prev_calculated;
      if (prev_calculated>0) limit++;
   }
   
   for (int i=0; i<limit; i++) 
   {
      Label1Buffer[i]=0;
      if (high[i] < close[i+compare_with])
      {
      Label1Buffer[i] = low[i];
      } 
   }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
 
      limit = rates_total-prev_calculated;
      if (prev_calculated>0) limit++;
   }
   
   for (int i=0; i<limit; i++) 
   {
      if (high[i] < close[i+2])
  1. You don't set the direction of your arrays. As is, you are looking at a future candle.
  2. When i equals limit-1, i+2 is beyond the size of the array, and your indicator crashes. Your lookback is two.
              How to do your lookbacks correctly #9 - #14 & #19

 

Thanks a lot guys for your help.