Советники: Использование функции ExpertRemove() значительно уменьшает время тестирования

 

Использование функции ExpertRemove() значительно уменьшает время тестирования:

Использование функции ExpertRemove() значительно уменьшает время тестирования

Использование функции ExpertRemove() значительно уменьшает время тестирования

Автор: lucik

 
Доброго дня. Спасибо. Полезный хак.
 
Специально проверил с секундомером.Вывод неутешительный-любой доп. код     типа проверки маржи спреда и т .д увеличивают время тестирование и чтобы 1-2 реально отработала функция ExpertRemove на вашем периоде времени теста сов должен постоянно отслеживать изменения маржи спреда и т.д. Все это тормозит скорость тестирования.        
 
jensen11 #:
Специально проверил с секундомером.Вывод неутешительный-любой доп. код     типа проверки маржи спреда и т .д увеличивают время тестирование и чтобы 1-2 реально отработала функция ExpertRemove на вашем периоде времени теста сов должен постоянно отслеживать изменения маржи спреда и т.д. Все это тормозит скорость тестирования.        

не совсем понятна ваша методика тестирования и поэтому трудно вам возразить, возможно, при тестировании в ваших условиях вы и правы, но сколько раз я не делал эти тесты, во всех своих идеях я применяю эту функцию и результаты её работы действительно экономят огромное количество часов тестирования. использование AccountInfoDouble(ACCOUNT_MARGIN_FREE) в тестере занимает микросекунды, а продолжение прогона при нулевом депозите (или меньшим изначального) и достаточно большом временном интервале занимает минуты! потеря нескольких секунд на один проход в обмен на экономию нескольких минут кажется очевидно эффективной. пока я пишу этот текст тестируется одна идея с ограничением 800 (от изначального депозита в 1000) и длительностью 19 дней (с начала месяца по текущее число). то есть, в тестере я вижу много отрицательных результатов от проходов, которые заканчиваются сразу же как только ACCOUNT_MARGIN_FREE станет меньше 800, тестер не продолжает этот проход до минимально возможной маржи для инструмента, потому что зачем? убедиться что этот проход сливает депозит в ноль? :) слишком много таких проходов будет и слишком много времени это займет. можно было вообще задать ограничение 999, но я добрый, допускаю некоторую просадку, поэтому 800. есть проходы с 1-2 сделками, есть проходы с 38-42 сделками, но результат один - просадка на 200+ и вылет из тестирования. мы все тут вроде про "заработать денежек, а не потерять" :) я понимаю, что вряд ли мой ответ вас в чем-то переубедит, но как мне кажется, использование связки  AccountInfoDouble(ACCOUNT_MARGIN_FREE)<=FreeMargin (или любого другого условия) и ExpertRemove() способно в разы уменьшить время на тестирование. даже в примере из статьи можно посмотреть на скриншоты с расчетным временем и увидеть что без функции 1 проход тестирования проходил тест за 20 секунд, а с функцией за 3 секунды пробежало 52 прохода, потому что все из них сливали депозит до нужного условия (<=90).

 
jensen11 #:
Специально проверил с секундомером.Вывод неутешительный-любой доп. код     типа проверки маржи спреда и т .д увеличивают время тестирование и чтобы 1-2 реально отработала функция ExpertRemove на вашем периоде времени теста сов должен постоянно отслеживать изменения маржи спреда и т.д. Все это тормозит скорость тестирования.        

без контроля маржи


с контролем свободной маржи


как видно из скриншотов, контроль за свободной маржей (депозитом) очень-очень сильно-сильно ускоряет тестирование!

 

Сейчас, проведя небольшие дополнительные тесты пришел к выводу, что для контроля лучше использовать ACCOUNT_EQUITY, а не ACCOUNT_MARGIN_FREE, как я указал ранее (и в статье, в том числе) и закрывать позицию перед использованием ExpertRemove().

Сейчас использую такой код для контроля просадки при тестировании:

extern int     FreeEquity           = 900;    //Минимальные свободные средства, валюта депозита
 if(IsTesting() && AccountInfoDouble(ACCOUNT_EQUITY)<=FreeEquity)
  {
   if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES))
     if(!OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0))
       Print(__FUNCTION__," Ошибка закрытия позиции. Код ошибки=",GetLastError());

   ExpertRemove();
  }

То есть - закрываем текущую позицию, как только видим просадку ниже безопасного уровня и выходим из тестирования этого набора параметров. Это дает более правильное отображение результатов тестирования данного набора параметров.

Получаются вот такие результаты.

ACCOUNT_EQUITY_and_closing

Ранний вариант с ACCOUNT_MARGIN_FREE и без закрытия позиции (описанный в статье) давал тот же результат, если смотреть на депозит, но в результатах это было не отражено, оно как бы подразумевалось. Теперь же всё отображено правильно.

Было вот так:

ACCOUNT_MARGIN_FREE

 

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

Лучше использовать TesterStop - быстрее будет.

 
fxsaber #:

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

Лучше использовать TesterStop - быстрее будет.

TesterStop в MQL4 нету :(

void CheckFreeMargin()
{
 ulong FirstMicroseconds=GetMicrosecondCount();
 double UsedEquity=UsedEquityPercent*(AccountInfoDouble(ACCOUNT_EQUITY)/100);
 double NeedEquity=Lot*MarketInfo(NULL,MODE_MARGINREQUIRED);
 double MinLot = MarketInfo(NULL,MODE_MINLOT);
 double MinEquity = MinLot*MarketInfo(NULL,MODE_MARGINREQUIRED);
 
 if(IsTesting() && AccountInfoDouble(ACCOUNT_EQUITY)<=FreeEquity)
   {
/*    Print("ACCOUNT_BALANCE ",AccountInfoDouble(ACCOUNT_BALANCE));
    Print("ACCOUNT_EQUITY ",AccountInfoDouble(ACCOUNT_EQUITY));
    Print("ACCOUNT_MARGIN_FREE ",AccountInfoDouble(ACCOUNT_MARGIN_FREE));
    Print("ACCOUNT_MARGIN ",AccountInfoDouble(ACCOUNT_MARGIN));
*/
    if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES))
      if(!OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0))
         Print(__FUNCTION__," Ошибка закрытия позиции. Код ошибки=",GetLastError());
//      else
//        Print("Profit =",OrderClosePrice()-OrderOpenPrice());
    
/*
    Print("ACCOUNT_BALANCE ",AccountInfoDouble(ACCOUNT_BALANCE));
    Print("ACCOUNT_EQUITY ",AccountInfoDouble(ACCOUNT_EQUITY));
    Print("ACCOUNT_MARGIN_FREE ",AccountInfoDouble(ACCOUNT_MARGIN_FREE));
    Print("ACCOUNT_MARGIN ",AccountInfoDouble(ACCOUNT_MARGIN));
*/  
    ulong SecondMicroseconds=GetMicrosecondCount();
    Print("Microseconds to check free margin ",SecondMicroseconds-FirstMicroseconds);
    ExpertRemove();
   }
 
 if(!IsTesting() && (AccountInfoDouble(ACCOUNT_EQUITY)<=FreeEquity || UsedEquity<MinEquity))
   {
    if(UsedEquity<MinEquity) FreeMarginComm="Not enough free equity :( ";
    else FreeMarginComm="Not enough free margin :( ";
    if(NewBar) Print(FreeMarginComm);
    TradeAllowed=false;
    if(OrderBUYSTOPTicket>0) ClosePendingBUYSTOPOrder();
    if(OrderSELLSTOPTicket>0) ClosePendingSELLSTOPOrder();
//    return;
   }   
 else
   {
    FreeMarginComm=NULL;
    LastError=NULL;
    TradeAllowed=true;
   }

 if(LastError==134)
  {
   FreeMarginComm="ERR_NOT_ENOUGH_MONEY ";
   TradeAllowed=false;
   return;
  }

 while(NeedEquity<UsedEquity)
  {
   Lot=Lot+MinLot;
   NeedEquity=Lot*MarketInfo(NULL,MODE_MARGINREQUIRED);
  }
 if(NeedEquity>UsedEquity) Lot=Lot-MinLot;
 if(Lot>LotMax) Lot=LotMax;

 MarginString1=string(UsedEquityPercent)+"% of "+StringFormat("%.2f",AccountEquity())+"="+StringFormat("%.2f",UsedEquity)+", for lot "+string(0.01)+" margin "+StringFormat("%.2f",MinEquity)+", lot is "+StringFormat("%.2f",Lot);
 MarginString2=FreeMarginComm+"TradeAllowed "+string(TradeAllowed);


 ulong ThirdMicroseconds=GetMicrosecondCount();
 Print("Microseconds to all check free margin procedure ",ThirdMicroseconds-FirstMicroseconds);
}

microseconds to check free margin

несколько микросекунд на 1 секунду тестируемого времени (процедура 3 раза в секунду работает) - приемлимые потери.

 
fxsaber #:


Лучше использовать TesterStop - быстрее будет.

Про функцию  TesterStop не знал. По старинке ExpertRemove использовал.

Большого ускорения тестирования не заметил. Ускорение тестирования меньше одного процента.

Тестил  на H1 за год по ценам открытия.

Документация по MQL5: Общие функции / TesterStop
Документация по MQL5: Общие функции / TesterStop
  • www.mql5.com
Отдает команду на завершении работы программы при тестировании . Возвращаемое значение Нет возвращаемого значения. Примечание Функция TesterStop()...