Бета-версия платформы MetaTrader 5 build 2055: Интеграция с Python и массовые улучшения в тестере стратегий - страница 9

 

Я меня сейчас идет оптимизация, фреймы пишутся в файлы, сейчас 11:50, последний раз файл менялся в 11:35 (хотя новые проходы уже были сделаны) в них около 5 мб инфы.

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

Просто наблюдение, меня все устраивает.

 

2057:

Не работает сортировка по столбцу Баланс и Комментарий в таблице сделок результатов одиночного прохода в тестере стратегий.


 
elibrarius:

Я меня сейчас идет оптимизация, фреймы пишутся в файлы, сейчас 11:50, последний раз файл менялся в 11:35 (хотя новые проходы уже были сделаны) в них около 5 мб инфы.

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

Просто наблюдение, меня все устраивает.

Буферизация. Буфер сбрасывается в файл на диск либо после заполнения, либо по завершению оптимизации.

Писать каждый фрейм на диск - очень дорого. И по времени, и по цпу, и по ресурсу.

 
Slava:

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

Так вот именно об этом я и толкую.  Это собирание фрэймов на агенте приводит к напрасному расходованию объёма ресурсов на хранение.  У него может и не быть столько ресурсов.  Зачем их накапливать на агенте?  Его задача - считать и отправлять результаты (фрэймы).  Я понимаю, если бы речь шла о неком минимальном объёма пакета для передачи.  Но накапливать вообще все фрэймы - это абсурд.

Вот пример кода, где агенты в течение 10 секунд отправляют большой объём данных во фрэймах.  Можно наблюдать в диспетчере задач за процессом агента, как сначала стремительно увеличивается объём записанных данных на жёсткий диск, а в конце резко подскакивает объём используемой агентом памяти, фактически на весь объём фрэймов.  Вот куда это годится?   Но что самое забавное, ни один фрэйм в итоге не приходит,  даже после завершения оптимизации.  OnTesterPass ни разу не вызывается.  И при ручном его вызове из Deinit() тоже ничего не обнаруживается.

#property tester_no_cache true

input int Param;


uint __TickCount= GetTickCount();


bool SendFrame() // Отправляем 20 мб данных
{ 
  string name= "20 Mb frame";
  char data[];  int size=(int)20e6;
  if (ArrayResize(data, size)!=size)
    name="Resize error!";
  return FrameAdd(name, GetTickCount()-__TickCount, 0, data);
}


int OnInit() { return(INIT_SUCCEEDED); }
  

void OnDeinit(const int reason) { }


double OnTester()
  { 
   // Отправляем фрэймы в течение 10 секунд
   for (int i=0; i<100 && !IsStopped(); i++)
   {
     SendFrame();
     for (uint t= GetTickCount();  GetTickCount()<t+100; ) Sleep(1);  // Пауза 100 мс
   }
   return 0;
  }

void OnTesterInit()
  {
    Print("OnTesterInit");
  }

void OnTesterPass()
  {
   ulong  pass;
   string txt;
   long   time_ms;
   double value;
   char   data[];
   int n=0;
   while( FrameNext(pass, txt, time_ms, value, data) )
   {
     Print("Frame from agent ",pass,":  ",txt,",  ",time_ms," ms");
     Comment(TimeLocal(),"  ",n);  n++;
   }
  }
  
void OnTesterDeinit()
  { 
    Print("OnTesterDeinit");
    OnTesterPass();
  }

Результат:

2019.05.24 13:32:58.090 TestFrames2 (EURUSD,H1) OnTesterInit
2019.05.24 13:33:25.859 TestFrames2 (EURUSD,H1) OnTesterDeinit

 
Slava:

Пока вы находитесь в обработчике OnTesterPass новое событие TesterPass не кладётся в очередь. Это как с тиками.

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

Поэтому нужна нормальная реализация данного события в виде:  void OnTesterPass(ulong pass, ulong id, string name, double value, const T&[]).

 
в билде 2007 советник страшно тормозил,в 2056м-работает практически мгновенно это конечно плюс спасибо!
 
IuriiPrugov:
в билде 2007 советник страшно тормозил,в 2056м-работает практически мгновенно это конечно плюс спасибо!

Поделитесь тормозной частью этого советника.

 
Alexey Navoykov:

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

Поэтому нужна нормальная реализация данного события в виде:  void OnTesterPass(ulong pass, ulong id, string name, double value, const T&[]).

Не бессмысленным, просто используйте цикл выборки:

void OnTesterPass()
  {
   ulong  pass;
   string name;
   long   id;
   double value;
//--- process received results
   while(FrameNext(pass,name,id,value,results))
     {
      ....
     }
//---
  }

void OnTesterDeinit()
  {
//--- wait for the last frames
   OnTesterPass();
//---
   ....
  }

Не считайте, что OnTesterPass будет вызываться на каждый пакет. Без прозрачного пакетирования тестер превращается в тормоз.

К этому релизу мы кардинально улучшили и ускорили работу тестера при передаче данных, включая работу в MQL5 Cloud Network.


В вашем случае под 2 гб фреймов на агента приходится. Будем проверять, где проблема.
 
Renat Fatkhullin:

Не бессмысленным, просто используйте цикл выборки:

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

Renat Fatkhullin:

К этому релизу мы кардинально улучшили и ускорили работу тестера при передаче данных, включая работу в MQL5 Cloud Network.

Я в прошлом посте привёл пример, который приводит:  1) к переполнению памяти на агенте.  2) к полному пропуску всех фрэймов от агента (ничего не приходит вообще).  Так что рановато праздновать.

И там даже если объём меньше 2 Гб задать, то всё-равно будут проблемы.

 
Alexey Navoykov:

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

Если у вас работа построена на массовом приеме фреймов, то практически всегда можете сидеть внутри OnTesterPass и не выскакивать из эксперта в терминал. Главное, не обрабатывать один фрейм за вызов.

Если же фреймы приходят редко, то OnTesterPass все равно вызовется. OnTimer как дополнительный стимулятор можно использовать.


Я в прошлом посте привёл пример, который приводит:  1) к переполнению памяти на агенте.  2) к полному пропуску всех фрэймов от агента (ничего не приходит вообще).  Так что рановато праздновать.

И там даже если объём меньше 2 Гб задать, то всё-равно будут проблемы.

С объемыми гигабайтовыми фреймами разберемся. Там ведь они еще и сжимаются.