Скачать MetaTrader 5
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Code Base поможет в усвоении теоретических знаний. Заходи и изучай!
zaskok3
624
zaskok3 2016.01.25 11:52 

ТС в режиме оптимизации в ~10 (на глаз) раз быстрее вычисляется, чем в одиночном прогоне.

В логи ничего не принтую. Пробовал сделать read-only SSD-папку tester/logs/ - не помогает.

Под конец прогона OrdersHistoryTotal() ~1200, количество модификаций ~500К.

Как сделать, чтобы одиночный прогон не тормозил?

Yuri Evseenkov
2291
Yuri Evseenkov 2016.01.25 12:20  

Для МТ4. Если одиночный прогон без визуализации , то по идее время на тестирование и один проход оптимизации не должны сильно отличаться. Наблюдал  разность времен вычислений тестера и тестера в режиме оптимизации у ТС использующих генератор случайных чисел.

Для МТ5 не знаю. Знаю что там оптимизация распределяется параллельно по ядрам.

zaskok3
624
zaskok3 2016.01.25 13:13  

Набросал советник для тестирования производительности тестера:

#property strict

input int AmountSystems = 10;
input int Step = 100;
input double Lots = 0.1;

ulong MicrosecondCount;
int handle = 0;

void OnInit( void )
{
//  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 GetOrder( const int MagicNumber )
{
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
      if (OrderMagicNumber() == MagicNumber)
        return(TRUE);

  return(FALSE);
}

void System( int &AmountBars )
{
  for (int i = 0; i < AmountSystems; i++)
    if (AmountBars % AmountSystems == i)
    {
      if (GetOrder(i))
        OrderClose(OrderTicket(), OrderLots(), Bid, 0);

      OrderSend(Symbol(), OP_BUY, Lots, Ask, 0, 0, 0, NULL, i);
    }
    else if (GetOrder(i))
      OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), OrderOpenPrice() * 2 * (i %2 ), 0);

  AmountBars++;

  return;
}

#define MILLION 1000000.0

void Bench( const int AmountBars )
{
  static int PrevHistoryTotal = 0;
  static int PrevAmountBars = 0;

  if (handle <= 0)
    return;

  const int HistoryTotal = OrdersHistoryTotal();

  if (HistoryTotal > PrevHistoryTotal + Step)
  {
    const ulong NewMicrosecondCount = GetMicrosecondCount();

    const double Velocity = MILLION * (AmountBars - PrevAmountBars) / (NewMicrosecondCount - MicrosecondCount);

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

    MicrosecondCount = NewMicrosecondCount;

    PrevHistoryTotal = HistoryTotal;
    PrevAmountBars = AmountBars;
  }

  return;
}

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

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

  PrevTime = Time[0];

  System(AmountBars);
  Bench(AmountBars);

  return;
}

Результат "по ценам открытия":

На графике зависимость производительности тестера (баров в секундуд) от количества ордеров в истории. Хорошо видно, что при оптимизации производительность в разы выше, чем при одиночном прогоне. Также у тестера проваливается на ~30% производительно аккурат, как переваливает 10К ордеров в истории, и аж в ~5 еще раз, когда число ордеров в истории переваливает точненько 100К штук. В режиме включенной оптимизации ничего подобного не происходит -производительность на зависит от числа ордеров в историию.

Воспроизводится эта картина каждый раз. Каждый может убедиться. На других же ТС, как сказал выше, всего при 1200 ордеров и 500К модификаций скорость падает в одиночном прогоне в ~10 раз.

Как победить?

ЗЫ Присмотрелся к красному графику (тестер в режиме оптимизации). Там провал производительности происходит при увеличении числа ордеров на истории четко на 50К штук. Но потом скорость восстанавливается к прежним значениям.

zaskok3
624
zaskok3 2016.01.25 13:24  
Не совсем понимаю стиль написания тестера, когда в его исходник жестко прописываются круглые человеческие числа: 10К, 50К, 100К... Попахивает не хорошим проявлением человеческого фактора.
Vasiliy Sokolov
21150
Vasiliy Sokolov 2016.01.25 14:13  
zaskok3:

ТС в режиме оптимизации в ~10 (на глаз) раз быстрее вычисляется, чем в одиночном прогоне.

В логи ничего не принтую. Пробовал сделать read-only SSD-папку tester/logs/ - не помогает.

Под конец прогона OrdersHistoryTotal() ~1200, количество модификаций ~500К.

Как сделать, чтобы одиночный прогон не тормозил?

При единичном прогоне в МТ4 используется одно ядро ЦП, а при оптимизации - сразу несколько ядер. Отсюда и разница в скорости (да, мт4 тоже тоже может использовать несколько ядер!). 

zaskok3
624
zaskok3 2016.01.25 14:35  
Vasiliy Sokolov:

При единичном прогоне в МТ4 используется одно ядро ЦП, а при оптимизации - сразу несколько ядер. Отсюда и разница в скорости (да, мт4 тоже тоже может использовать несколько ядер!). 

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

Vasiliy Sokolov
21150
Vasiliy Sokolov 2016.01.25 14:56  
zaskok3:

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

Не воспроизводится. При единичном прогоне время оптимизации стандартного советника MovingAverage занимает около 4-5 секунд (все тики, 1 год). При оптимизации с еденичным прогоном время примерно тоже - 4 секунды. 

Vasiliy Sokolov
21150
Vasiliy Sokolov 2016.01.25 14:58  
Единичный прогон может быть медленнее единичной оптимизации, т.к. в первом случае требуется также сгенерировать график баланса и отчет (графические функции весьма медленные). В любом случае, десятикратная разница не воспроизводится.
Vasiliy Sokolov
21150
Vasiliy Sokolov 2016.01.25 15:05  
zaskok3:

Набросал советник для тестирования производительности тестера:

Ваш советник весьма странно работает в тестере. Первый раз при единичном прогоне действительно прогоняется достаточно медленно. Но со второго прогона начинает работать гораздо быстрее. Прогоняется до половины, а затем моментально завершает оставшуюся часть.
zaskok3
624
zaskok3 2016.01.25 15:16  
Vasiliy Sokolov:
Ваш советник весьма странно работает в тестере. Первый раз при единичном прогоне действительно прогоняется достаточно медленно. Но со второго прогона начинает работать гораздо быстрее. Прогоняется до половины, а затем моментально завершает оставшуюся часть.

Скорее всего, эквити около нуля, вот и реакция. Увеличьте начальный баланс.

А скорость можно увидеть в текстовом файле в папке tester/files/. По нему и строил график выше. Разница в разы будет не только ощущаться, но и подкрепляться конкретными цифрами.

Vasiliy Sokolov:
Единичный прогон может быть медленнее единичной оптимизации, т.к. в первом случае требуется также сгенерировать график баланса и отчет (графические функции весьма медленные). В любом случае, десятикратная разница не воспроизводится.
Если не переключаться на вкладку "График", то генерироваться он не будет. Однако, данные по каждой модификации будут сохраняться. Представим, что надо сохранить 500К модификаций. Для этого же достаточно выделить память и просто заполнять массив. Никаких доп. расчетов не требуется по сравнению с включенной оптимизацией. Только еще один массив хранить. Ну и разница в разы даже на тестовом советнике наблюдается хорошо.
zaskok3
624
zaskok3 2016.01.25 15:27  

Заставил обратить внимание на тормоза тестера следующий случай. Стратегии пишу в виде классов. И вот захотелось посмотреть, как выглядит объединенная ТС из нескольких таких стратегий. Для этого было достаточно создать несколько соответствующих объектов, получив очередное удовольствие от удобства ООП. Объединил все пять ТС таким образом в одну. Запустил одиночный прогон и.... вместо пятикратного увеличения времени, получил замедление в сотни раз: 40 минут тестер делал прогон, при этом никак не реагирую на нажатия ("Не отвечает"). Однако, не стал убивать его, т.к. видно было, что в tester/logs он все же пишет. Дождался. Получил, как и ожидал, в конце профит в виде суммы профита пяти соответствующих ТС. Но какой ценой!

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

/ /123456
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий