Discussion of article "LifeHack for traders: Fast food made of indicators" - page 2

 
Renat Fatkhullin:

...

In addition, inefficient retrieval by 1 value from the indicator.

...

All this is in theory. But in practice, 99% of indicators are calculated in FIFO ring buffers: delete the last element, add a new one, recalculate the indicator. That is, again in practice the addition to the calculation buffer is done by one element and 99% of all calculations in the indicator is the addition of one element. Therefore, the idea of CopyBuffer, CopyRates, CopyXXX is beautiful but does not correspond to the subject area.

 
Renat Fatkhullin:

...

Hard horror with handle leaks (why close the indicator handle?) and amazing overhead (trying to recreate the indicator, falling inside the indicator manager). And enough people will copy it without looking and without understanding.

...

It's not clear what you meant. As far as I understand, handles are not closed anywhere( there are nocalls of IndicatorRelease ). There is a constant call to standard functions of hendle creation, such as iMACD:

//+------------------------------------------------------------------+
//| iMACD function in MQL4 notation|
//| The buffer numbers are the following: |
//| MQL4 0 - MODE_MAIN, 1 - MODE_SIGNAL|
//| MQL5 0 - MAIN_LINE, 1 - SIGNAL_LINE|
//+------------------------------------------------------------------+
double   iMACD(
               string                     symbol,              // symbol name 
               ENUM_TIMEFRAMES            timeframe,           // timeframe 
               int                        fast_ema_period,     // period for Fast average calculation 
               int                        slow_ema_period,     // period for Slow average calculation 
               int                        signal_period,       // period for their difference averaging 
               ENUM_APPLIED_PRICE         applied_price,       // type of price or handle 
               int                        buffer,              // buffer 
               int                        shift                // shift
               )
  {
   
   double result=NaN;
//---
   int handle=iMACD(symbol,timeframe,fast_ema_period,slow_ema_period,signal_period,applied_price);
   if(handle==INVALID_HANDLE)
     {
      Print(__FUNCTION__,": INVALID_HANDLE error=",GetLastError());
      return(result);
     }
   double val[1];
   int copied=CopyBuffer(handle,buffer,shift,1,val);
   if(copied>0)
      result=val[0];
   else
      Print(__FUNCTION__,": CopyBuffer error=",GetLastError());
   return(result);
  }

Obviously, the whole game here is based on the fact that iMACD and similar functions cache the previously returned handle inside themselves, so there should be no recreation of the indicator.

 
Vasiliy Sokolov:

All this is in theory. But in practice, 99% of indicators are calculations in FIFO ring buffers: delete the last element, add a new one, recalculate the indicator. That is, again in practice the addition to the calculation buffer is done by one element and 99% of all calculations in the indicator is the addition of one element. Therefore, the idea of CopyBuffer, CopyRates, CopyXXX is beautiful but does not correspond to the subject area.

This is if you write the simplest and primitive last look handlers. But as soon as you make a step to the side and start checking 2 or more points, you immediately see the difference and the effect.

In general, of course, it is strange to hear that CopyXXX functions are supposedly not in the subject area.

You should try very hard to say such things about the basic functions of access to the market environment.


And also - it is not for nothing that indicators are given 100% of the whole history for calculations:

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[])
This is to prove that there are no "99% in the ring buffer". Mass access to the history, not single last values, is very much needed.
 
Vasiliy Sokolov:

It is not clear what you mean by what you said. As far as I understand, hendles are not closed anywhere( there are nocalls to IndicatorRelease ). There is a constant call to standard functions of hendle creation, such as iMACD:

Obviously, the whole game is built on the fact that iMACD and similar functions cache the previously returned handle inside themselves, so there should be no recreation of the indicator.

The whole game is built on hack and complete disregard for the control of handles.

Another trader takes this code, doesn't pay attention to the allocation of handles, starts making calls with different parameters, multiplies indicators, loses all handles, and then is surprised by brakes and memory consumption.

It is known who is to blame.

 
fxsaber:

The article is a small excerpt of another.

I didn't see any analogies.

fxsaber:

Nothing has been done to make it work efficiently. No caching of indicators and time series.

There really is room for optimisation here. Introducing caching would be a very good idea.

fxsaber:

High[i], Low[i], etc. are missing.

Should they be present? I think the title of the article (or rather its description) clearly says only about indicators?

fxsaber:

No iCustom.

Unfortunately, MQL does not support functions with an arbitrary number of parameters, so iCustom is not possible to implement "just like in MT4"

fxsaber:

It was expected to see something completely different. Moreover, what is the point of fast food in EAs, if it doesn't even smell in the sources anyway?

I don't think it is possible to write a whole full-fledged engine fully emulating MT4 style within one article. The topic was clearly stated: working with indicators in MQL4 style (it's a pity the title of the article does not reflect the topic, which is confusing).

 
Renat Fatkhullin:

...

This is to prove that there is no "99% in the ring buffer". It is mass accesses to history, not single last values, that are very much needed.

There are and are used a little more often than constantly. There are just no special means and developers have to create nested loops. Open any indicator with double nested for's: congratulations, the ring buffer has been found. Here is an example of your super-efficient calculation of the MFI indicator:

//+------------------------------------------------------------------+
//| Calculate MFI by volume from argument |
//+------------------------------------------------------------------+
void CalculateMFI(const int nPosition,
                  const int nRatesCount,
                  const double &HiBuffer[],
                  const double &LoBuffer[],
                  const double &ClBuffer[],
                  const long &VolBuffer[],
                  const datetime &time[])
  {
   for(int i=nPosition;i<nRatesCount && !IsStopped();i++)
     {
      double dPositiveMF=0.0;
      double dNegativeMF=0.0;
      double dCurrentTP=TypicalPrice(HiBuffer[i],LoBuffer[i],ClBuffer[i]);
      if(time[i] == D'2016.05.23')
         int dbg = 4;
      for(int j=1;j<=ExtMFIPeriod;j++)
        {
         int    index=i-j;
         double dPreviousTP=TypicalPrice(HiBuffer[index],LoBuffer[index],ClBuffer[index]);
         if(dCurrentTP>dPreviousTP)
            dPositiveMF+=VolBuffer[index+1]*dCurrentTP;
         if(dCurrentTP<dPreviousTP)
            dNegativeMF+=VolBuffer[index+1]*dCurrentTP;
         dCurrentTP = dPreviousTP;
        }
      if(dNegativeMF!=0.0) ExtMFIBuffer[i]=100.0-100.0/(1+dPositiveMF/dNegativeMF);
      else                 ExtMFIBuffer[i]=100.0;
     }
  }

Well, it is obvious that the calculation speed of this indicator depends on the averaging period, and it should not be so. And there are a lot of such examples, some of which are written by MQ itself, and you say there are no ring buffers.

 
Vasiliy Sokolov:

There are and they are used a little more often than all the time. It's just that there are no special tools and developers have to create nested loops. Open any indicator with double nested for's: congratulations, the ring buffer has been found. Here is an example of your super-efficient calculation of the MFI indicator:

Well, it is obvious that the calculation speed of this indicator depends on the averaging period, and it should not be so. And there are a lot of such examples, some of which are written by MQ itself, and you say there are no ring buffers.

They are absent in 99% of cases. And in 90% of cases there are no ring buffers and in 50% of cases there are no ring buffers. But there is a 100% volume of initial data (for the entire depth of history) in the OnCalculate parameters.

And it's not even about calculating indicators, but about using both the results of indicators and access to the source data. Access is required on a massive scale, not a single one.

You are trying to present the situation in such a way that "the whole analysis market is represented by the last indicator value" and "CopyXXXX does not correspond to the subject area".

You are trying very hard to sketch.

 
Renat Fatkhullin:

...

And it is not even a question of calculating indicators, but of using both the results of indicators and access to the original data. Access is required on a massive scale, not a single one.

...

Please pay attention to request #1923700. There are some problems with frequent access to large amounts of data.

It has been a long time since there have been comments and questions to provide additional input to help figure out the reason for this result.

 
Renat Fatkhullin:

Another trader takes this code, doesn't pay attention to allocation of handles, starts making calls with different parameters, multiplies indicators, loses all handles, and then is surprised by brakes and memory consumption.

Similarly, this other trader can start making calls to standard iHandles with different parameters. If the parameters are different, different indicators will be created, regardless of whether you work with the handle directly or use MQL4-Style.

 
Renat Fatkhullin:

You're trying very hard to sketch.

And this is a shame.

And it's not even about calculating indicators, but about using them as results of indicators.

Yes.

Renat Fatkhullin:

...

Anyway, I will not argue, as it is pointless. It would be interesting to collect statistics on the use of Copy*** functions. How many items users copy on average would show a lot.