Специально проверил с секундомером.Вывод неутешительный-любой доп. код типа проверки маржи спреда и т .д увеличивают время тестирование и чтобы 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).
Специально проверил с секундомером.Вывод неутешительный-любой доп. код типа проверки маржи спреда и т .д увеличивают время тестирование и чтобы 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_MARGIN_FREE и без закрытия позиции (описанный в статье) давал тот же результат, если смотреть на депозит, но в результатах это было не отражено, оно как бы подразумевалось. Теперь же всё отображено правильно.
Было вот так:

Ресурсоемкие проверки принудительной остановки прохода часто можно прописывать только в OnTimer, который вызывать раз в сутки.
Лучше использовать TesterStop - быстрее будет.
Ресурсоемкие проверки принудительной остановки прохода часто можно прописывать только в 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); }

несколько микросекунд на 1 секунду тестируемого времени (процедура 3 раза в секунду работает) - приемлимые потери.
Про функцию TesterStop не знал. По старинке ExpertRemove использовал.
Большого ускорения тестирования не заметил. Ускорение тестирования меньше одного процента.
Тестил на H1 за год по ценам открытия.
- www.mql5.com
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Использование функции ExpertRemove() значительно уменьшает время тестирования:
Использование функции ExpertRemove() значительно уменьшает время тестирования
Автор: lucik