Обсуждение статьи "LifeHack для трейдера: готовим фастфуд из индикаторов" - страница 3

 
Renat Fatkhullin:

...начинает делать вызовы с разными параметрами, размножает индикаторы, теряет все хендлы, а потом удивляется тормозам и потреблению памяти.

Если честно, так и не понял, как можно потерять хендл, если он запоминается за кулисами MetaTrader.

p.s. Корче, пусть автор статьи встрянет в обсуждение и пояснит несколько моментов касательно его виденья работы с хендлами индикаторов в МТ5.

 
Vasiliy Sokolov:
Если честно, так и не понял, как можно потерять хендл, если он запоминается за кулисами MetaTrader.

С таким подходом к качеству кода у меня вопросов больше нет.

 
Vasiliy Sokolov:

На счет сказанного непонятно, что имели в виду. Хендлы, на сколько понимаю, нигде не закрываются (вызовов IndicatorRelease не наблюдается). Есть постоянное обращение к стандартным функциям создания хендла, типа iMACD:

Очевидно, что здесь вся игра построена на том, что iMACD и подобные ей функции кешируют внутри себя уже ранее возвращенный хендл, поэтому пересоздания индикатора быть не должно.


Да, была первоначальная идея показать, что в MQL5 нужно работать с индикаторами по феншую: один хендл создавать в OnInit(), а доступ к данным индикатора получать через CopyXXXX функции, а если использовать пересоздание хендлов в стиле MQL4 - ТО это очень неправильно и будет беда: будет пожираться память. Но в процессе оказалось, что ядро MQL5 настолько умное (явно есть внутренне кеширование одинаковых хендлов), что не допускает пересоздание хендлов.

Получился побочный эффект: ядро MQL5 настолько хорошо спроектировано, что допускает в MQL5 работать не по феншую.

 
Vasiliy Sokolov:

Аналогий не увидел.

В обеих статьях предлагается одно и то же - написание на MQL5 самого простого варианта MQL4-style. Сравните это

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Обсуждение статьи "LifeHack для трейдера: готовим фастфуд из индикаторов"

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

и это

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

Фактически, это одно и то же.

А должны присутствовать? Вроде название статьи (вернее ее описание) четко говорит только о индикаторах?

Не должны, если судить по названию. Но в статье затрагиваются MQL4-style работы с таймсериями. А без этого получается неполноценное решение. В MQL4 почти все пользуются "High[i]". Тем более, реализация этого легко ищется.

К сожалению, MQL не поддерживает функции с произвольным количеством параметров, поэтому iCustom не видится возможным реализовать "так же как в MT4"

Я не думаю что в рамках одной статьи можно написать целый полноценный движок полностью эмулирующий МТ4 style. Тема была заявлена четко: работа с индикаторами в стиле MQL4 (жаль название статьи не отражает тему что и запутывает).

MQL4-style - это все же концепция, а не четкое следование синтаксису. 

 
Vladimir Karputov:

если использовать пересоздание хендлов в стиле MQL4 - ТО это очень неправильно и будет беда: будет пожираться память.

Вот поэтому и возникает вопрос, зачем реализовали неправильную работу, когда можно было сделать правильно и в стиле MQL4?

MQL5 не умный, в нем просто заложена защита от дурака. Иначе любая случайная ошибка приводила бы к печальным последствиям. Но и защита от дурака, как показывают замеры производительности, выполнена так, что происходит провал в производительности. Поэтому надо перекладывать "пересоздание хендла" на MQL5-обертку, пряча (малая часть возможностей ООП) это с глаз юзера.

 
fxsaber:

... Но и защита от дурака, как показывают замеры производительности, выполнена так, что происходит провал в производительности...

Да, это уже интересно. Замерю скорость и о выводах напишу здесь.

 
Vasiliy Sokolov:

Замерил на простейших заготовках.

Название экспертаОписаниеПроизводительность
 iMACDклассическая работа с хендлом в стиле MT5EURUSD,M5: 26189141 ticks, 74266 bars generated. Environment synchronized in 0:00:01.045. Test passed in 0:00:12.121 (including ticks preprocessing 0:00:01.966).
 MACD MQL4 style EA shortРабота в стиле MQL4EURUSD,M5: 26189141 ticks, 74266 bars generated. Environment synchronized in 0:00:00.047. Test passed in 0:00:34.960 (including ticks preprocessing 0:00:01.872). 

Оверхед где-то в три раза. Т.е., таки да, MetaTrader 5 требует весьма много времени, для нахождение кешируемого хендла.


Была идея проверить такое: советник на подобие "MACD MQL4 style EA short", только в нём обращаться не к двум, а к трем, четырём, пяти индикаторам ... В данном контексте "индикатор" подразумевает (на примере MACD) индикатор с разными параметрами, но по одному символу. 

 

Удалил свой предыдущий пост, т.к. заметил, что советник MACD MQL4 style EA дополнительно обращается к графической подсистеме:

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

Т.е. сделанное тестирование было выполнено некорректно. После комментирования функции Comment производительность практически сравнялась:

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

Выводы: MetaTrader 5 все-таки эффективно находит ранее созданный кеш и использовать предложенный codestyle выходит можно.

fxsaber:

Но и защита от дурака, как показывают замеры производительности, выполнена так, что происходит провал в производительности. Поэтому надо перекладывать "пересоздание хендла" на MQL5-обертку, пряча (малая часть возможностей ООП) это с глаз юзера.

Если последний тест сделан верно, выходит что перекладывание на обертку ООП ничего не даст. Скорости практически равны.
 
Vasiliy Sokolov:

MetaTrader 5 требует весьма много времени, для нахождение кешируемого хендла.

Нет уверенности, что юзер в общем виде может ускорить этот процесс. Очевидно, что оверхед уходит на вычисление хэш-функции.

В общем виде один вариант такой индикаторной хэш-функции выкладывал здесь

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

Там не пекся о производительности, но было понятно, что на вход любой хэш-функции нужно подавать массив MqlParam-значений. А это ну никак не может работать быстро с учетом того, что там есть тормозное string-поле.

Поэтому написание универсальной индикаторной быстрой хэш-функции много быстрее того, что встроена в MT5 - задача открытая. Но сам категорически против вызова индикаторов откуда-то либо. Поэтому даже желания разбираться в вопросе нет.


Насчет умного MQL5 еще такая мысль. Есть полно советников, где на каждом баре вызывается один и тот же индикатор, но с разными входными параметрами. MQL5 "пристреливает" со временем ненужные хендлы. Но это универсальное решение. И в советнике автор может взять эту обязанность на себя, убивая хендлы самостоятельно. Ведь очевидно, что через сотню баров тащить уже багаж из сотни хендлов - это супер-расточительно и по вычислительным ресурсам и памяти. Но я не видел в той же кодобазе советников, которые бы вот так прибивали хендл. Все отдается на "умность MQL5", тем самым заставляя быть совсем не умным авторов.


Но опять же, индикаторы и бары - зло.

 
fxsaber:

Нет уверенности, что юзер в общем виде может ускорить этот процесс. Очевидно, что оверхед уходит на вычисление хэш-функции.

В общем виде один вариант такой индикаторной хэш-функции выкладывал здесь


Ну, вы хотели чтобы в одной статье на читателя вывалили сразу кучу информации. Но касательно вашего метода - это лобовое решение, другие пробовали? И сравнивали производительность?

Причина обращения: