Архив версий МТ. - страница 4

 
Roman:

В данном контексте разве мы не можем делать проверку?

К сожалению, эта проверка ничего не дала...

 
Roman:

Приведя пример с IsStopped() я как раз пытался ответить на первую часть.
Иногда надо перед завершением работы советника завершить обработку события до конца, иногда как в вашем случае срочно завершить.
Прочтите в документации описание этой функции IsStopped(), может наведёт на некоторые мысли.
Но вам показалось это из другой оперы. Если из другой, тогда сорри за возможное предположение.
Но как говориться в возможных предложениях, и решается поиск проблемы.
Однозначного решения не кто не скажет, так как не кто не знает всю логику его кода, и вероятно вникать в него не будет. 

Роман, вот опять-же не до конца цитируете. А ведь выделил среди всего выделенного.

Ну, хорошо, допустим запущено принудительное завершение работы. А мне надо чтобы событие в котором запущено это завершение выполнилось до конца и сложность вычислений превышает 3 секунды. И как я могу предотвратить завершение программы и дать возможность отработать до конца? Именно в этом и проблема. Разговор был не о том, как завершить, а как предотвратить неправильно вызванное завершение. Или не предотвратить, а отложить до определённого момента, в частности до завершения обработки события.

 
Сергей Таболин:

Вот проверил Ваш вариант. Всё закончилось таким вот сообщением:

В общем - тупик...

Значит и предложенный вариант

bool                 tester_stop = false;                 // флаг проверки выхода по TesterStop
.......
void OnTick()
{
//--- пропустить бесполезные проходы оптимизации
   if(!check_init && (MQLInfoInteger(MQL_OPTIMIZATION) || MQLInfoInteger(MQL_TESTER)))
   {
      if(недопустимый параметр)          tester_stop = TesterStop();
........
}
double OnTester()
{
   if(tester_stop) return(-99999999999.99);

будет отработан точно так-же. И опять получите "тупик". Но тупик не в mql, а простите в голове. Нельзя так заниматься программированием. Прежде чем что-то ожидать от кода, надо представить себя на месте идиота и пройти тупо, как это делает компьютер, по всему коду несколько раз. Убедиться куда должно передаться выполнение в том или ином случае. Какие параметры должны быть получены в том или ином случае. Потом запустив выполнение проверить, а получаем-ли то что ожидаем? Если нет, то надо найти в каком месте получаем то, что видим во время отладки.

Иначе быть не может. А по кускам кода отладить выполнение абсолютно невозможно.

 
Alexey Viktorov:

Роман, вот опять-же не до конца цитируете. А ведь выделил среди всего выделенного.

Ну, хорошо, допустим запущено принудительное завершение работы. А мне надо чтобы событие в котором запущено это завершение выполнилось до конца и сложность вычислений превышает 3 секунды. И как я могу предотвратить завершение программы и дать возможность отработать до конца? Именно в этом и проблема. Разговор был не о том, как завершить, а как предотвратить неправильно вызванное завершение. Или не предотвратить, а отложить до определённого момента, в частности до завершения обработки события.

Ждать завершения вычисления.

В mql к сожалению нет таких функций типа await.
Можно попробовать поэкспериментировать с Sleep() но слип это не явный признак завершения, по этому не сильно подходит.
Попробовать создать условие по другому, if(вычисление выполнилось) тогда уже запускать принудительное завершение.

 
Alexey Viktorov:

Значит и предложенный вариант

будет отработан точно так-же. И опять получите "тупик". Но тупик не в mql, а простите в голове. Нельзя так заниматься программированием. Прежде чем что-то ожидать от кода, надо представить себя на месте идиота и пройти тупо, как это делает компьютер, по всему коду несколько раз. Убедиться куда должно передаться выполнение в том или ином случае. Какие параметры должны быть получены в том или ином случае. Потом запустив выполнение проверить, а получаем-ли то что ожидаем? Если нет, то надо найти в каком месте получаем то, что видим во время отладки.

Иначе быть не может. А по кускам кода отладить выполнение абсолютно невозможно.

Так в том то и дело, что до обновления всё работало, а теперь я просто не знаю что делать.

К тому же, в принципе весь код открыт. 

Более того, я уже хотел открыть ветку обсуждения-доработки своего варианта OnTester(), а тут такое...

Как выяснилось, проблема не в нём а в изменившемся выполнении TesterStop(). Который, в принципе, прямого отношения к OnTester() не имеет, но настроение испортил...

Сейчас попробую кое что ещё...

 
Сергей Таболин:

Так в том то и дело, что до обновления всё работало, а теперь я просто не знаю что делать.

К тому же, в принципе весь код открыт. 

Более того, я уже хотел открыть ветку обсуждения-доработки своего варианта OnTester(), а тут такое...

Как выяснилось, проблема не в нём а в изменившемся выполнении TesterStop(). Который, в принципе, прямого отношения к OnTester() не имеет, но настроение испортил...

Сейчас попробую кое что ещё...

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

 
Alexey Viktorov:

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

Так я и попробовал. Поставил 2007 билд и там всех этих проблем нет. Я специально просмотрел весь журнал после оптимизации. Нашёл 4 (только 4 !) ошибки деления на ноль. Это те, которые возникали при отсутсвии трейдов. Это, конечно, нужно бы было исправить, но на общий результат оптимизации это никакого влияния не оказывало! А на новом билде ошибки просто валом повалили и оптимизация стала невозможна.

Теперь, что касается подсказки от @Roman.

Спасибо, это оказался правильный посыл. Только, в моём случае, для TesterStop() это оказалось бесполезным ибо TesterStop() требует, чтобы тест уже был пройден на какой-то_неизвестный_процент. И об этом в документации нет ни слова.

А вот с ExsprtRemove() это сработало. Для этой функции не важно сколько там теста прошло. Правда пришлось весь рабочий код завернуть в if

   if(!IsStopped())
   {
      тут рабочий код
   }

В общем, с костылями, робастасть кода восстановил. Спасибо ещё раз.

П.С. Собственно говоря пришлось делать костыль для другого костыля. Улыбнуло )))

 
Сергей Таболин:

П.С. Собственно говоря пришлось делать костыль для другого костыля. Улыбнуло )))

Не верю я что нет вариантов. Если нравится программировать костыли к костылям, я препятствовать не имею права. Slava по этому поводу ответил

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Slava, 2019.06.16 14:04

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

TesterStop даёт команду на завершение тестирования. Это означает, что после завершения текущего обработчика OnInit, OnTick, OnTimer, OnChartEvent, никакие события тестера больше не будут обрабатываться, так как цикл обработки будет завершён. А вызовется OnTester и OnDeinit

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

Так я и попробовал. Поставил 2007 билд и там всех этих проблем нет. Я специально просмотрел весь журнал после оптимизации. Нашёл 4 (только 4 !) ошибки деления на ноль. Это те, которые возникали при отсутсвии трейдов. Это, конечно, нужно бы было исправить, но на общий результат оптимизации это никакого влияния не оказывало! А на новом билде ошибки просто валом повалили и оптимизация стала невозможна.

Теперь, что касается подсказки от @Roman.

Спасибо, это оказался правильный посыл. Только, в моём случае, для TesterStop() это оказалось бесполезным ибо TesterStop() требует, чтобы тест уже был пройден на какой-то_неизвестный_процент. И об этом в документации нет ни слова.

А вот с ExsprtRemove() это сработало. Для этой функции не важно сколько там теста прошло. Правда пришлось весь рабочий код завернуть в if

В общем, с костылями, робастасть кода восстановил. Спасибо ещё раз.

П.С. Собственно говоря пришлось делать костыль для другого костыля. Улыбнуло )))

Это не костыль, а рекомендованная практика от разработчиков.
Эту функцию я обнаружил в описании к циклу while

while(!IsStopped())
{

}

По этому пришла мысль, если эта функция проверяет факт принудительного завершения программы, то почему бы её не использовать для TesterStop().
Жаль что она не срабатывает для TesterStop(), будем теперь знать об этом.
Хотя справедливо бы задать вопрос разработчикам, должна ли функция IsStopped() срабатывать для функции TesterStop() ?
Может это баг?

Но главное нашлось решение проблемы.

 
Alexey Viktorov:

Не верю я что нет вариантов. Если нравится программировать костыли к костылям, я препятствовать не имею права. Slava по этому поводу ответил

Возможно вы использовали косяк допущенный разработчиками в предыдущем билде. А теперь этот косяк исправлен и надо искать правильное решение.

Я всё понимаю  и костыли мне без надобности. А костыль пришлось искать вот тут почитайте для чего

Возможно. Но я что-то не припомню, чтобы на это кто-то жаловался. 

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