В MT4-тестере одиночный прогон в ~10 раз медленнее, чем в режиме оптимизации - страница 4

 
zaskok3:
В режиме оптимизации в ГА очень часто несколько проходов считаются многие минуты. Хотел бы разобраться, на каких входных параметрах это происходит. К сожалению, тестер не выдает никакой информации о текущем проходе в режиме оптимизации.

Каким образом это можно узнать?

Неожиданно удобным оказалось решение прописывания в OnInit вызова CopyTextToClipboard. Теперь в буфере обмена вся инфа о текущем проходе оптимизатора.

 
zaskok3:

Неожиданно удобным оказалось решение прописывания в OnInit вызова CopyTextToClipboard. Теперь в буфере обмена вся инфа о текущем проходе оптимизатора.

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

#property strict

input int exTmp = 0;

int Ticket1, Ticket2;

void OnInit( void )
{
  Ticket1 = OrderSend(Symbol(), OP_BUYLIMIT, 1, NormalizeDouble(Ask / 2, _Digits), 0, 0, 0);
  Ticket2 = OrderSend(Symbol(), OP_SELLLIMIT, 1, NormalizeDouble(Bid  * 2, _Digits), 0, 0, 0);

  return;
}

bool ChangeOrder( const int Ticket, const int Add )
{
  return(OrderSelect(Ticket, SELECT_BY_TICKET) ? OrderModify(OrderTicket(), OrderOpenPrice() + Add * _Point, 0, 0, 0) : FALSE);
}

void System( void )
{
  static int Add = 1;

  ChangeOrder(Ticket1, Add);
  ChangeOrder(Ticket2, Add);

  Add = -Add;

  return;
}

void OnTick( void )
{
  static datetime PrevTime = 0;

  if (PrevTime == Time[0])
    return;

  PrevTime = Time[0];

  System();

  ObjectsDeleteAll(); // https://www.mql5.com/ru/forum/71870/page3#comment_2214874

  return;
}

Файл логов тестера специально сделал read only.


Прошу форумчан поделиться результатами прогона этого советника у себя в тестере. Воспроизводятся тормоза или нет?

 
zaskok3:

стало возможным написание простого советника, демонтсрирующего страшные тормоза и в одиночном прогоне и в режиме оптимизации

Добавил замер производительности:

#property strict

input int exStep = 100;

int Ticket1, Ticket2;

ulong MicrosecondCount;
int handle = 0;

void OnInit( void )
{
  Ticket1 = OrderSend(Symbol(), OP_BUYLIMIT, 1, NormalizeDouble(Ask / 2, _Digits), 0, 0, 0);
  Ticket2 = OrderSend(Symbol(), OP_SELLLIMIT, 1, NormalizeDouble(Bid  * 2, _Digits), 0, 0, 0);

//  if (!IsOptimization())
  {
    handle = FileOpen(WindowExpertName() + ".txt", FILE_WRITE | FILE_IS_TEXT);

    MicrosecondCount = GetMicrosecondCount();
  }

  return;
}

void OnDeinit( const int Reason )
{
  if (handle > 0)
    FileClose(handle);
    
  return;
}

bool ChangeOrder( const int Ticket, const int Add )
{
  return(OrderSelect(Ticket, SELECT_BY_TICKET) ? OrderModify(OrderTicket(), OrderOpenPrice() + Add * _Point, 0, 0, 0) : FALSE);
}

void System( void )
{
  static int Add = 1;

  ChangeOrder(Ticket1, Add);
  ChangeOrder(Ticket2, Add);

  Add = -Add;

  return;
}

#define MILLION 1000000.0

void Bench( void )
{
  static int Step = 0;
  static int AmountBars = 0;

  if (handle <= 0)
    return;

  AmountBars++;
  Step++;

  if (Step >= exStep)
  {
    const double Velocity = MILLION * Step / (GetMicrosecondCount() - MicrosecondCount);

    FileWrite(handle, (string)AmountBars + " " + (string)Velocity);

    MicrosecondCount = GetMicrosecondCount();
    
    Step = 0;
  }

  return;
}

void OnTick( void )
{
  static datetime PrevTime = 0;

  if (PrevTime == Time[0])
    return;

  PrevTime = Time[0];

  System();
  Bench();

  ObjectsDeleteAll(); // https://www.mql5.com/ru/forum/71870/page3#comment_2214874

  return;
}

Результат:


Падение производительности MT4-тестера настолько огромное, что пришлось применить логарифмическую шкалу. Баров < 150K, время на один прогон > 250 секунд, через 40К баров с начала теста производительность падает до 1000 баров в секунду, дальше - только хуже: 250 баров в секунду!


Уважаемые разработчики, как избежать такой катастрофы с производительностью тестера? Невозможно оптимизировать многие ТС!

На старых билдах (< 950) не пробовал. Кто-нибудь воспроизвел?

ЗЫ Показать конкурентам - засмеют...

 

zaskok3:

На старых билдах (< 950) не пробовал.

Переписал советник под любой билд MT4:

// Компилируется на любых билдах MT4

extern int exTmp = 0; // чтобы замерить производительность в режиме оптимизации

int Ticket1, Ticket2;

void init()
{
  Ticket1 = OrderSend(Symbol(), OP_BUYLIMIT, 1, NormalizeDouble(Ask / 2, Digits), 0, 0, 0);
  Ticket2 = OrderSend(Symbol(), OP_SELLLIMIT, 1, NormalizeDouble(Bid  * 2, Digits), 0, 0, 0);

  return;
}

bool ChangeOrder( int Ticket, int Add )
{
  if (OrderSelect(Ticket, SELECT_BY_TICKET))
    return(OrderModify(OrderTicket(), OrderOpenPrice() + Add * Point, 0, 0, 0));

  return(FALSE);
}

void System()
{
  static int Add = 1;

  ChangeOrder(Ticket1, Add);
  ChangeOrder(Ticket2, Add);

  Add = -Add;

  return;
}

void start()
{
  static datetime PrevTime = 0;

  if (PrevTime == Time[0])
    return;

  PrevTime = Time[0];

  System();

  ObjectsDeleteAll(); // https://www.mql5.com/ru/forum/71870/page3#comment_2214874

  return;
}
В билде 409 аналогичные тормоза...
 
zaskok3:

Добавил замер производительности:

Кто-нибудь воспроизвел?

Одиночный тест, EURUSD H1 по ценам открытия, 2000-2016, MQ-демо, билд 950:

 

Файл в прицепе 

Файлы:
komposter.txt  24 kb
 
Andrey Khatimlianskii:

Одиночный тест, EURUSD H1 по ценам открытия, 2000-2016, MQ-демо, билд 950:

Спасибо за конструктив! Один в один результат - проблема точно не на моей стороне.
 
Andrey Khatimlianskii:

Одиночный тест, EURUSD H1 по ценам открытия, 2000-2016, MQ-демо, билд 950:

При отключении ObjectsDeleteAll результаты практически такие же:

 

Я думаю, дело в графической подсистеме.

На оптимизации воспроизводится? 

Файлы:
komposter2.txt  24 kb
 
Andrey Khatimlianskii:

На оптимизации воспроизводится? 

Отвечаю сам себе - да, воспроизводится.

Надо еще работу с файлом исключить, может в ней тормоза.. Сейчас проверю. 

 
Andrey Khatimlianskii:

Надо еще работу с файлом исключить, может в ней тормоза.. Сейчас проверю. 

Запись в файл влияет, без нее замедление меньше:

 

Вместо файла пишу в гл. переменные (temp - номер прогона для оптимизатора):

GlobalVariableSet( WindowExpertName() + "_" + (string)temp + "_" + IntegerToString( AmountBars, 6, '0' ), Velocity );
 
Andrey Khatimlianskii:

Запись в файл влияет, без нее замедление меньше:

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

ЗЫ Как такие большие картинки генерировать?

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