Indicator not refreshing. Help is needed.

 
My knowledge of the mql5 programming language is minimal. But I wrote a simple custom indicator, the task of which is to display arrows near candles that meet certain conditions. First, all points with index i are found that satisfy the condition high[i]>high[i-1] && high[i]>high[i+1] (or low). then, for the selected candles, the same check is performed for comparison with neighbors (2th order) . And again (3rd order). But my indicator does not update with new candles, and my knowledge is not enough to understand how to fix it. Please, help.

//------------------------------------------------------------------+
#property copyright "© frfr, 2016, MetaQuotes Software Corp."
#property link      "www.forex-tsd.com, www.mql5.com"
//------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   4
#property indicator_label1  "Kellinger Arrow SOLD"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrLightBlue
#property indicator_width1  1
#property indicator_label2  "Kellinger Arrow BUY"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_width2  1
#property indicator_label3  "Kellinger Arrow TEST"
#property indicator_type3   DRAW_ARROW
#property indicator_color3  clrLightBlue
#property indicator_width3  1
#property indicator_label4  "Kellinger Arrow TEST2"
#property indicator_type4   DRAW_ARROW
#property indicator_color4  clrRed
#property indicator_width4  1
#include <Arrays\ArrayInt.mqh>
input ushort               ArrowCodeUp        = 174;           // Symbol code for Arrow Up
input ushort               ArrowCodeDown      = 174;           // Symbol code for Arrow Down
input ushort               ThirdOrderCodeUp        = 117;           // Symbol code for Arrow Up
input ushort               ThirdOrderCodeDown      = 117;           // Symbol code for Arrow Down
input int                  ArShift            = 25;             // Arrows Shift
double ArrBuffUp[], ArrBuffDown[], ArrThirdOrderUp[], ArrThirdOrderDown[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0,ArrBuffUp,INDICATOR_DATA);
   SetIndexBuffer(1,ArrBuffDown,INDICATOR_DATA);
   SetIndexBuffer(2,ArrThirdOrderUp,INDICATOR_DATA);
   SetIndexBuffer(3,ArrThirdOrderDown,INDICATOR_DATA);
   PlotIndexSetInteger(0,PLOT_ARROW,ArrowCodeUp);
   PlotIndexSetInteger(1,PLOT_ARROW,ArrowCodeDown);
   PlotIndexSetInteger(2,PLOT_ARROW,ThirdOrderCodeUp);
   PlotIndexSetInteger(3,PLOT_ARROW,ThirdOrderCodeDown);
//--- Set the vertical shift of arrows in pixels
   PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,-ArShift);
   PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,ArShift);
   PlotIndexSetInteger(2,PLOT_ARROW_SHIFT,-ArShift-10);
   PlotIndexSetInteger(3,PLOT_ARROW_SHIFT,ArShift+10);
//--- Set as an empty value 0
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   IndicatorSetString(INDICATOR_SHORTNAME,"PivotPoints Second Order");

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) { return; }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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[])
  {
   CArrayInt *firstorderhigh=new CArrayInt;
   CArrayInt *firstorderlow=new CArrayInt;
   CArrayInt *secondorderhigh=new CArrayInt;
   CArrayInt *secondorderlow=new CArrayInt;
   int i,limit;
   int lookback=2;
   if(prev_calculated<3)
     {
      limit=2;
      //--- clean up arrays
      ArrayInitialize(ArrBuffUp,EMPTY_VALUE);
      ArrayInitialize(ArrBuffDown,EMPTY_VALUE);
      ArrayInitialize(ArrThirdOrderDown,EMPTY_VALUE);
      ArrayInitialize(ArrThirdOrderUp,EMPTY_VALUE);
     }
   else
      limit=rates_total-2;
   for(i=limit; i<rates_total-1 && !IsStopped(); i++)
     {
      if((high[i] > high[i - 1]) && (high[i] > high[i + 1]))
         firstorderhigh.Add(i);
      if((low[i] < low[i - 1]) && (low[i] < low[i + 1]))
         firstorderlow.Add(i);
     }
   for(int j=1; j<firstorderhigh.Total()-1; j++)
     {
      if((high[firstorderhigh[j]] > high[firstorderhigh[j-1]]) && (high[firstorderhigh[j]] > high[firstorderhigh[j+1]]))
        {
         ArrBuffUp[firstorderhigh[j]]= high[firstorderhigh[j]];
         secondorderhigh.Add(firstorderhigh[j]);
        }
      else
        {
         ArrBuffUp[firstorderhigh[j]]=EMPTY_VALUE;
        }
     }
   for(int k=1; k<firstorderlow.Total()-1; k++)
     {
      if((low[firstorderlow[k]] < low[firstorderlow[k-1]]) && (low[firstorderlow[k]] < low[firstorderlow[k+1]]))
        {
         ArrBuffDown[firstorderlow[k]]= low[firstorderlow[k]];
         secondorderlow.Add(firstorderlow[k]);
        }
      else
        {
         ArrBuffDown[firstorderlow[k]]=EMPTY_VALUE;
        }
     }
   for(int j=1; j<secondorderhigh.Total()-1; j++)
     {
      if((high[secondorderhigh[j]] > high[secondorderhigh[j-1]]) && (high[secondorderhigh[j]] > high[secondorderhigh[j+1]]))
        {
         ArrThirdOrderUp[secondorderhigh[j]]= high[secondorderhigh[j]];
        }
      else
        {
         ArrThirdOrderUp[secondorderhigh[j]]=EMPTY_VALUE;
        }
     }
   for(int k=1; k<secondorderlow.Total()-1; k++)
     {
      if((low[secondorderlow[k]] < low[secondorderlow[k-1]]) && (low[secondorderlow[k]] < low[secondorderlow[k+1]]))
        {
         ArrThirdOrderDown[secondorderlow[k]]= low[secondorderlow[k]];
        }
      else
        {
         ArrThirdOrderDown[secondorderlow[k]]=EMPTY_VALUE;
        }

     }
   return(rates_total);
  }
//+------------------------------------------------------------------+
Files:
pivotpoints.mq5  13 kb
 
fRoompel:
My knowledge of the mql5 programming language is minimal. But I wrote a simple custom indicator, the task of which is to display arrows near candles that meet certain conditions. First, all points with index i are found that satisfy the condition high[i]>high[i-1] && high[i]>high[i+1] (or low). then, for the selected candles, the same check is performed for comparison with neighbors (2th order) . And again (3rd order). But my indicator does not update with new candles, and my knowledge is not enough to understand how to fix it. Please, help.

First, fix your objects please.

Following lines need to be split into global section and OnInit function.

Declare the variables in global, assign them a value in OnInit.

(Haven't checked the rest)
   CArrayInt *firstorderhigh=new CArrayInt;
   CArrayInt *firstorderlow=new CArrayInt;
   CArrayInt *secondorderhigh=new CArrayInt;
   CArrayInt *secondorderlow=new CArrayInt;
EDIT:

Delete the objects in OnDeinit with the delete operator.
 
fRoompel:
My knowledge of the mql5 programming language is minimal. But I wrote a simple custom indicator, the task of which is to display arrows near candles that meet certain conditions. First, all points with index i are found that satisfy the condition high[i]>high[i-1] && high[i]>high[i+1] (or low). then, for the selected candles, the same check is performed for comparison with neighbors (2th order) . And again (3rd order). But my indicator does not update with new candles, and my knowledge is not enough to understand how to fix it. Please, help.


It's not updating because you limit the loop.

   for(i=limit; i<rates_total-1 && !IsStopped(); i++)

Remove the -1 from all your loops.

 

I would take Dominiks advice and move the array objects to OnInit


//global definitions
CArrayInt *firstorderhigh;
CArrayInt *firstorderlow;
CArrayInt *secondorderhigh;
CArrayInt *secondorderlow;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0,ArrBuffUp,INDICATOR_DATA);
   SetIndexBuffer(1,ArrBuffDown,INDICATOR_DATA);
   SetIndexBuffer(2,ArrThirdOrderUp,INDICATOR_DATA);
   SetIndexBuffer(3,ArrThirdOrderDown,INDICATOR_DATA);
   PlotIndexSetInteger(0,PLOT_ARROW,ArrowCodeUp);
   PlotIndexSetInteger(1,PLOT_ARROW,ArrowCodeDown);
   PlotIndexSetInteger(2,PLOT_ARROW,ThirdOrderCodeUp);
   PlotIndexSetInteger(3,PLOT_ARROW,ThirdOrderCodeDown);
//--- Set the vertical shift of arrows in pixels
   PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,-ArShift);
   PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,ArShift);
   PlotIndexSetInteger(2,PLOT_ARROW_SHIFT,-ArShift-10);
   PlotIndexSetInteger(3,PLOT_ARROW_SHIFT,ArShift+10);
//--- Set as an empty value 0
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   IndicatorSetString(INDICATOR_SHORTNAME,"PivotPoints Second Order");
   
   firstorderhigh=new CArrayInt;
   firstorderlow=new CArrayInt;
   secondorderhigh=new CArrayInt;
   secondorderlow=new CArrayInt;

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

 
void OnDeinit(const int reason)
{
   // Clean up and release memory
   delete firstorderhigh;
   delete firstorderlow;
   delete secondorderhigh;
   delete secondorderlow;
   return;
}
 
phade #:

I would take Dominiks advice and move the array objects to OnInit


Hello. There is a good chance that it will not be able to move these objects in oninit because of the range of the variables
 
I couldn't solve the problem. If use the tips above, then either everything stops working, or stops updating altogether, or the schedule freezes completely.
 

Can you be clear about what you mean by saying that the indicator does not update? It does not update when changing the timeframe? or it does not update arrow signals with time? I'm having an issue myself with one of my MA indicators whereby the MA plot slopes down horizontally away from the chart on occasion, and I have to click the refresh button on the chart to fix it.

You should probably initialize the arrays on every calculation and not just only when prev_calculated < 3, so move this code out of the condition

   //--- clean up arrays
   ArrayInitialize(ArrBuffUp,EMPTY_VALUE);
   ArrayInitialize(ArrBuffDown,EMPTY_VALUE);
   ArrayInitialize(ArrThirdOrderDown,EMPTY_VALUE);
   ArrayInitialize(ArrThirdOrderUp,EMPTY_VALUE);
      
   if(prev_calculated<3)
     {
      limit=2;
     }
   else
      limit=rates_total-2;

I made some other changes and I'm attaching the script, but can't tell if the signals update with time as the market is currently closed. The buffers refresh a lot faster now when changing between timeframes


It's a good idea to not only unload the indicator, but close the chart where you added the indicator as well to remove the memory leaks when unloading the indicator/changing timeframe (you had to deallocate the memory on the heap with OnDeInit if you declare pointers to the object)

Files:
 

You can avoid using pointers entirely and then you can avoid manual memory management...please see this version of the script, I also tested it to see that it works fine.

Files:
 

I'm not sure if you're active anymore, but this version fixes the problem that future signals don't paint, it was deeper than a refresh problem. I see in the strategy tester that it works, but now with a few more frequent unwanted signals

//------------------------------------------------------------------+
#property copyright "© frfr, MetaQuotes Software Corp."
#property link      "www.forex-tsd.com, www.mql5.com"
//------------------------------------------------------------------+
#include <Arrays\ArrayInt.mqh>

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   4
#property indicator_label1  "Kellinger Arrow SOLD"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrLightBlue
#property indicator_width1  1
#property indicator_label2  "Kellinger Arrow BUY"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_width2  1
#property indicator_label3  "Kellinger Arrow TEST"
#property indicator_type3   DRAW_ARROW
#property indicator_color3  clrLightBlue
#property indicator_width3  1
#property indicator_label4  "Kellinger Arrow TEST2"
#property indicator_type4   DRAW_ARROW
#property indicator_color4  clrRed
#property indicator_width4  1

input ushort               ArrowCodeUp        = 174;           // Symbol code for Arrow Up
input ushort               ArrowCodeDown      = 174;           // Symbol code for Arrow Down
input ushort               ThirdOrderCodeUp        = 117;           // Symbol code for Arrow Up
input ushort               ThirdOrderCodeDown      = 117;           // Symbol code for Arrow Down
input int                  ArShift            = 25;             // Arrows Shift
double ArrBuffUp[], ArrBuffDown[], ArrThirdOrderUp[], ArrThirdOrderDown[];

CArrayInt firstorderhigh;
CArrayInt firstorderlow;
CArrayInt secondorderhigh;
CArrayInt secondorderlow;

int OnInit()
{
    SetIndexBuffer(0, ArrBuffUp, INDICATOR_DATA);
    SetIndexBuffer(1, ArrBuffDown, INDICATOR_DATA);
    SetIndexBuffer(2, ArrThirdOrderUp, INDICATOR_DATA);
    SetIndexBuffer(3, ArrThirdOrderDown, INDICATOR_DATA);

    PlotIndexSetInteger(0, PLOT_ARROW, ArrowCodeUp);
    PlotIndexSetInteger(1, PLOT_ARROW, ArrowCodeDown);
    PlotIndexSetInteger(2, PLOT_ARROW, ThirdOrderCodeUp);
    PlotIndexSetInteger(3, PLOT_ARROW, ThirdOrderCodeDown);

    PlotIndexSetInteger(0, PLOT_ARROW_SHIFT, -ArShift);
    PlotIndexSetInteger(1, PLOT_ARROW_SHIFT, ArShift);
    PlotIndexSetInteger(2, PLOT_ARROW_SHIFT, -ArShift - 10);
    PlotIndexSetInteger(3, PLOT_ARROW_SHIFT, ArShift + 10);

    PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
    PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
    PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
    PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);

    IndicatorSetString(INDICATOR_SHORTNAME, "PivotPoints Second Order");

    return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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;

    // Set the limit based on prev_calculated
    if (prev_calculated < 5)
    {
        limit = 2;
        // Clean up arrays
        ArrayInitialize(ArrBuffUp, EMPTY_VALUE);
        ArrayInitialize(ArrBuffDown, EMPTY_VALUE);
        ArrayInitialize(ArrThirdOrderDown, EMPTY_VALUE);
        ArrayInitialize(ArrThirdOrderUp, EMPTY_VALUE);
    }
    else
    {
        limit = rates_total - 3;
    }

    for (int i = limit; i < rates_total - 2; i++)
    {
        // Find first-order highs and lows
        if (high[i] > high[i - 1] && high[i] > high[i + 1])
        {
            firstorderhigh.Add(i);
        }
        if (low[i] < low[i - 1] && low[i] < low[i + 1])
        {
            firstorderlow.Add(i);
        }

        // Find second-order highs and lows
        if (firstorderhigh.Total() > 1)
        {
            int highIndex = firstorderhigh.Total() - 1;
            int lowIndex = firstorderlow.Total() - 1;
            
            if (highIndex > 0 && high[firstorderhigh[highIndex]] > high[firstorderhigh[highIndex - 1]])
            {
                ArrBuffUp[firstorderhigh[highIndex]] = high[firstorderhigh[highIndex]];
                secondorderhigh.Add(firstorderhigh[highIndex]);
            }

            if (lowIndex > 0 && low[firstorderlow[lowIndex]] < low[firstorderlow[lowIndex - 1]])
            {
                ArrBuffDown[firstorderlow[lowIndex]] = low[firstorderlow[lowIndex]];
                secondorderlow.Add(firstorderlow[lowIndex]);
            }  
        }

        // Find third-order highs and lows
        if (secondorderhigh.Total() > 1)
        {
            int highIndex = secondorderhigh.Total() - 1;
            
            if (highIndex > 0 && high[secondorderhigh[highIndex]] > high[secondorderhigh[highIndex - 1]])
            {
                ArrThirdOrderUp[secondorderhigh[highIndex]] = high[secondorderhigh[highIndex]];
            }
        }

        if (secondorderlow.Total() > 1)
        {
            int lowIndex = secondorderlow.Total() - 1;
            
            if (lowIndex > 0 && low[secondorderlow[lowIndex]] < low[secondorderlow[lowIndex - 1]])
            {
                ArrThirdOrderDown[secondorderlow[lowIndex]] = low[secondorderlow[lowIndex]];
            }
        }
    }

    return rates_total;
}
Reason: