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

 
Renat Fatkhullin:

...starts making calls with different parameters, multiplies indicators, loses all handles, and then wonders about brakes and memory consumption.

To be honest, I haven't understood how one can lose a handle, if it is stored behind the scenes of MetaTrader.

p.s. In general, let the author of the article join the discussion and explain a few points regarding his vision of working with indicator handles in MT5.

 
Vasiliy Sokolov:
To be honest, I never understood how one can lose a handle if it is memorised behind the scenes of MetaTrader.

With this approach to code quality, I have no more questions.

 
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 here is based on the fact that iMACD and similar functions cache inside themselves the previously returned handle, so there should be no recreation of the indicator.


Yes, I had an initial idea to show that in MQL5 you should work with indicators in a fancy way: one handle should be created in OnInit(), and access to indicator data should be obtained through CopyXXXX functions, and if you use the MQL4 style re-creation of handles, it is very wrong and will be a disaster: it will eat up memory. But in the process it turned out that the MQL5 kernel is so clever (obviously there is internal caching of identical handles) that it does not allow recreating handles.

The side effect is that the MQL5 kernel is so well designed that it allows MQL5 to work in a non-fashionable way.

 
Vasiliy Sokolov:

I did not see any similarities.

Both articles offer the same thing - writing the simplest MQL4-style variant in MQL5. Compare this

Forum on Trading, Automated Trading Systems and Testing Trading Strategies

Discussion of the article "LifeHack for trader: cooking fast food from indicators"

Vasiliy Sokolov, 2018.01.25 16:05

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

and this

double iMACDMQL4(string symbol,
                 int tf,
                 int fast_ema_period,
                 int slow_ema_period,
                 int signal_period,
                 int price,
                 int mode,
                 int shift)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   ENUM_APPLIED_PRICE applied_price=PriceMigrate(price);
   int handle=iMACD(symbol,timeframe,
                    fast_ema_period,slow_ema_period,
                    signal_period,applied_price);
   if(handle<0)
     {
      Print("Объект iMACD не создан: Ошибка ",GetLastError());
      return(-1);
     }
   else
      return(CopyBufferMQL4(handle,mode,shift));
  }

In fact, it is the same thing.

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

They should not, judging by the title. But the article touches upon MQL4-style work with time series. And without it, we get an incomplete solution. Almost everyone uses "High[i]" in MQL4. Moreover, the implementation of it is easy to find.

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

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).

MQL4-style is still a concept, but not a clear adherence to the syntax.

 
Vladimir Karputov:

If you use MQL4 style re-creation of handles, it is very wrong and will cause trouble: memory will be consumed.

That's why the question arises, why did they implement incorrect work when it could be done correctly and in the style of MQL4?

MQL5 is not smart, it just has foolproof protection. Otherwise, any accidental error would lead to unfortunate consequences. But the foolproof protection, as performance measurements show, is designed in such a way that there is a failure in performance. That's why it is necessary to shift "re-creation of handle" to MQL5 wrapper, hiding it (a small part of OOP capabilities) from the user's eyes.

 
fxsaber:

... But also the foolproofing, as performance measurements show, is done in such a way that there is a dip in performance ...

Yeah, that's interesting. I'll measure the speed and post my findings here.

 
Vasiliy Sokolov:

Measured it on the simplest of blanks.

Name of expertDescriptionPerformance
iMACDclassic MT5 style hendle workEURUSD,M5: 26189141 ticks, 74266 bars generated. Environment synchronised at 0:00:01.045. Test passed in 0:00:12.121 (including ticks preprocessing 0:00:01.966).
MACD MQL4 style EA shortWork in MQL4 styleEURUSD,M5: 26189141 ticks, 74266 bars generated. Environment synchronised at 0:00:00.047. Test passed in 0:00:34.960 (including ticks preprocessing 0:00:01.872).

The overhead is about three times. So, yes, MetaTrader 5 takes a lot of time to find a cached handle.


I had an idea to test this: an EA similar to"MACD MQL4 style EA short", only in it you can address not two, but three, four, five indicators .... In this context, "indicator" means (using MACD as an example) an indicator with different parameters but one symbol each.

 

I deleted my previous post because I noticed that MACD MQL4 style EA additionally accesses the graphics subsystem:

//+------------------------------------------------------------------+
//| Expert tick function|
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double macd_main_1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MAIN_LINE,1);
   Comment("MACD, main buffer, index 1: ",DoubleToString(macd_main_1,Digits()+1));
  }

I.e. the testing done was performed incorrectly. After commenting the Comment function, the performance is almost equal:

EURUSD,M5: 26189141 ticks, 74266 bars generated. Environment synchronized in 0:00:00.047. Test passed in 0:00:15.444 (including ticks preprocessing 0:00:01.872).

Conclusions: MetaTrader 5 still effectively finds the previously created cache and it is possible to use the proposed codestyle.

fxsaber:

But the foolproof protection, as performance measurements show, is made in such a way that there is a performance failure. That's why it is necessary to shift "re-creation of the handle" to the MQL5 wrapper, hiding it (a small part of OOP features) from the user's eyes.

If the last test is done correctly, it turns out that shifting to the OOP wrapper will do nothing. The speeds are almost equal.
 
Vasiliy Sokolov:

MetaTrader 5 requires quite a lot of time to find a cached handle.

There is no certainty that a user can speed up this process in a general way. Obviously, the overhead is spent on calculating the hash function.

One variant of such an indicator hash function in a general form was posted here

  static string GetMyUniqueName( void )
  {
    const int handle = GetMyHandle();

    MqlParam Params[];
    ENUM_INDICATOR Type;

    const int Total = ::IndicatorParameters(handle, Type, Params);
    ::IndicatorRelease(handle);

    uchar Bytes[];

    for (int i = 1; i < Total; i++)
    {
      ::ArrayCopy(Bytes, _R(Params[i].double_value).Bytes, ::ArraySize(Bytes));
      ::ArrayCopy(Bytes, _R(Params[i].integer_value).Bytes, ::ArraySize(Bytes));
      ::ArrayCopy(Bytes, _R(Params[i].string_value).Bytes, ::ArraySize(Bytes));
    }

    return("::" + (string)::ChartID() + (string)INIT_SYNC::crc64(Bytes) + ::MQLInfoString(MQL_PROGRAM_NAME));
  }

I didn't care about performance there, but it was clear that any hash function input must be an array of MqlParam-values. And this can't work fast taking into account the fact that there is a slow string-field.

Therefore, writing a universal indicator fast hash function much faster than what is built into MT5 is an open task. But I am categorically against calling indicators from somewhere. That's why I don't even want to understand the issue.


There is another thought about smart MQL5. There are a lot of Expert Advisors, where the same indicator is called on each bar, but with different input parameters. MQL5 "shoots" unnecessary handles over time. But this is a universal solution. And in an Expert Advisor, the author can take this responsibility on himself, killing handles by himself. It is obvious that it is super-wasteful in terms of computational resources and memory to carry the baggage of a hundred handles through a hundred bars. But I haven't seen EAs in the same kodobase that would nail a handle like this. Everything is given to the "cleverness of MQL5", thus forcing the authors to be not clever at all.


But again, indicators and bars are evil.

 
fxsaber:

There is no certainty that a user can speed up this process in a general way. Obviously, the overhead is spent on calculating the hash function.

One variant of such an indicator hash function in a general form was posted here


Well, you wanted to dump a lot of information on the reader in one article. But regarding your method - it is a head-on solution, have you tried others? And compared the performance?