prev_calculated - page 2

 
Alexey Kozitsyn:
How about just recalculating the whole indicator when 0? Seems like the best solution to me.
For a heavy indicator with tons of graphics - not the best. No, the solution is simple - to use your own variable instead of prev_calculated, static or global. But it is a crutch and we want something else.
 
Alexey Kozitsyn:
:) That's what I do...
That's what I understood, I was just quoting your question, but really I was answeringAlexander Puzanov. :)
 
Alexander Puzanov:
For a heavy indicator with tons of graphics is not the best solution. The solution is simple - to use your own variable instead of prev_calculated, static or global. But it is a crutch and we want something else.

A person using the word "crutch":

  • is either too lazy to read the documentation
  • or does not know yet how it should be correct.
The only correct solution: at prev_calculate==0 recalculate indicator.

 
Alexander Puzanov:
For a heavy indicator with tons of graphics - not the best. No, the solution is simple - to use own variable instead of prev_calculated, static or global. But it is a crutch and we want something else.
Not a crutch at all. That's how I do it.
 
Karputov Vladimir:
And if the history has been swapped, it means that there may be new bars that have been missed or not calculated before - i.e. the indicator readings will already be wrong.

Slawa:

If prev_calculated=0, it means that a full recalculation has to be done. All standard indicators are fully recalculated in this case.

It's all clear, but alas, it all doesn't cancel this:

Alexander Puzanov:

This is all useful, but it cannot be used according to its direct purpose - to show how many 'bars were processed at the previous call' - prev_calculated

Indicators are different; some don't need bars for calculations at all, some need only live ticks, some have limitations on the calculation depth - they don't care what has changed next in the history, some need to track graphical objects, etc. They don't need additional functions to track changes in history attached to prev_calculated, they only need this - 'processed bars on previous call'. They don't need it.

Anyway, Mr. programmers, please don't distract the joiner from 'catching the event'.

 
Alexey Kozitsyn:
What if I simply recalculate the entire indicator at 0? In my opinion, it is the best solution.

I wouldn't say it's the best solution. At least not yet.

I decided to write an indicator that registers the current drawdown on the account, so I don't have to recalculate anything in the history. The first line looked like this at first.

if(prev_calculated == 0)  return(rates_total);
But after start I found out that buffers are not empty and not zeroed. There's some price in the buffers of unknown origin. I had to force the buffers to zero... Next, another problem was discovered. The prev_calculate is zeroed and the indicator is recalculated, respectively, zeroizing all buffers until the last bar. Anyway, I've given up the idea for now.
 
Alexey Viktorov:

I wouldn't say it's the best solution. At least not yet.

I decided to write an indicator that registers the current drawdown on the account, so I don't have to recalculate anything in the history. At first the first line looked like this.

if(prev_calculated == 0)  return(rates_total);
But after startup I found that the buffers are not empty and not zeroed. There is some price in the buffers that I don't know where it came from. Had to force the buffers to zero... Next, another problem was discovered. The prev_calculate is zeroed and the indicator is recalculated, respectively, zeroizing all buffers until the last bar. Anyway, I've given up the idea for now.

"... some price that I don't know where it came from... " - that's rubbish of UNINITIALIZED elements of indicator buffer array. What should be done:

  • at prev_calculate==0 go through all elements of the indicator buffer in the loop and assign values to them. In this case, you need to monitor the situation when a new bar appears (rates_total minus prev_calculate will be greater than zero) - the indicator buffer increases accordingly and this new element should also be initialized.

 

Forum on trading, automated trading systems and trading strategy testing

Bugs, bugs, questions

Alexey Viktorov, 2016.10.17 09:58

Do you understand what you wrote?

Better explain how to get rid of rubbish FIRST run of the indicator. Where does this rubbish come from? Shouldn't there be initialization when linking the buffer to the array? Or is it during initialization that space rubbish gets into the array??? Why is there no such rubbish in mql4?

Give me an example how to sift the trash from the normal values without using extraneous additional static or global variables.

Everyone is good enough to quote the documentation.


 

Nobody owes anybody anything. So there will be rubbish in the indicator buffer, after binding, until you initialise all elements of the array yourself.

Added:

I'm going to create an example now...

//+------------------------------------------------------------------+
//|                                              prev_calculated.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrGray
#property indicator_label1  "prev_calculated"
//---- buffers
double ExtBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtBuffer,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[])
  {
//---
   if(prev_calculated==0)
     {
      //--- инициализация элементов индикаторного буфера при первом запуске или при подкачке истории
      for(int i=0;i<rates_total;i++)
         ExtBuffer[i]=1.01;
      return(rates_total);
     }
//--- пересчитываем самый правый бар или самый правый бар и один предыдущий при появлении нового бара
   int limit=rates_total-prev_calculated+1;
   for(int i=rates_total-limit;i<rates_total;i++)
     {
      //--- визуализация пересчёта самого правого бара
      static bool drive=false;
      if(!drive)
         ExtBuffer[i]=1.03;
      else
         ExtBuffer[i]=1.02;
      drive=!drive;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Run it on M1. You will see that only the rightmost bar is recalculated.
Files:
 
Karputov Vladimir:

Nobody owes anybody anything. So there will be rubbish in the indicator buffer, after binding, until you initialise all elements of the array yourself.

Added:

I'm going to create an example now...

//+------------------------------------------------------------------+
//|                                              prev_calculated.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrGray
#property indicator_label1  "prev_calculated"
//---- buffers
double ExtBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtBuffer,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[])
  {
//---
   if(prev_calculated==0)
     {
      //--- инициализация элементов индикаторного буфера при первом запуске или при подкачке истории
      for(int i=0;i<rates_total;i++)
         ExtBuffer[i]=1.01;
      return(rates_total);
     }
//--- пересчитываем самый правый бар или самый правый бар и один предыдущий при появлении нового бара
   int limit=rates_total-prev_calculated+1;
   for(int i=rates_total-limit;i<rates_total;i++)
     {
      //--- визуализация пересчёта самого правого бара
      static bool drive=false;
      if(!drive)
         ExtBuffer[i]=1.03;
      else
         ExtBuffer[i]=1.02;
      drive=!drive;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Run it on M1. You will see that only the rightmost bar is recalculated.

Amazing ability to answer the wrong question...

Now explain to me what happens if:

1. Counted 100 bars, entered into buffers from 0 to 99 inclusive (let's consider direction as time series) value 1.03

2. Suddenly history is loaded and prev_calculated becomes 0

From which bar it will be 1.03?

Reason: