Здравствуйте, сообщество MQL4,
Я столкнулся с проблемой при запуске советника, включающего функцию Sleep() в тестере стратегий. Очевидно, что тестер не будет запускать советника должным образом с включенной в код функцией Sleep().
Кто-нибудь из присутствующих обнаружил альтернативный метод, отличный от функции Sleep(), для кодирования советника, чтобы "подождать" определенное количество времени, пока советник будет запущен в тестере?
Саймон,
Я решил использовать функцию 'Sleep()' потому, что Seconds() возвращает значения из последнего известного времени сервера (получение данных из последнего известного времени сервера приводит к пропуску секунд и/или паузе). Мне нужна надежность, а не универсальность.
Что вы скажете по этому поводу?
Спасибо
Саймон,
Причина, по которой я решил использовать функцию 'Sleep()', заключается в том, что Seconds() возвращает значения из последнего известного времени сервера (получение данных из последнего известного времени сервера приводит к пропуску секунд и/или паузе).
Саймон,
Итак, вы пишете: причина, по которой я могу называть эти "пропуски" и/или "паузы" в секундах, заключается в том, что между [секундами x] и [секундами y] не создаются тики. Говоря простым языком, создается тик, теперь сохраняется "секунда x". В течение трех секунд тик не создается, затем создается тик. Теперь сохраняются "секунды y". ('секунды y' = (секунды x + три секунды)) как ('секунды x' = (секунды y - три секунды)).
Что вы скажете по этому поводу?
Пока что я буду рассматривать свои варианты.
Большое спасибо за ваши ответы.
- Пока вы не вернетесь со старта. В тестере НИКОГДА не создаются тики. Сохраните TimeCurrent() в статической/общей(глобальной) переменной. Следующий тик int deltaSec = TimeCurrent() - предыдущий.
- https://www.mql5.com/en/forum/127483 сообщил, что DayOfWeek() всегда возвращает 5 в тестере (определенно не то же самое в индикаторах, как и Ask и Bid). Я никогда не использую ЛЮБЫЕ Seconds(), DayOfWeek() и т.д., потому что вам не нужно текущее время сервера, вам нужно время тика тестера. now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ....
Саймон,
Итак, вы пишете: причина, по которой я могу называть эти "пропуски" и/или "паузы" в секундах, заключается в том, что между [секундами x] и [секундами y] не создаются тики. Говоря простым языком, создается тик, теперь сохраняется "секунда x". В течение трех секунд тик не создается, затем создается тик. Теперь сохраняются "секунды y". ('секунды y' = (секунды x + три секунды)) как ('секунды x' = (секунды y - три секунды)).
Что вы скажете на это?
Уильям,
Большое спасибо за ваш ответ.
1. Пока вы не вернетесь из запуска. В тестере НИКОГДА не создаются тики. Сохраните TimeCurrent() в статической/общей(глобальной) переменной. Следующий тик int deltaSec = TimeCurrent() - предыдущий.
Я не понимаю, что вы имеете в виду под "Пока вы не вернетесь со старта". Не могли бы вы пояснить?
"В тестере НИКОГДА не создаются тики".
Разве вы не имеете в виду, что в тестере НИКОГДА не создаются настоящие тики. Разве вы не согласны с тем, что в тестере создаются искусственные тики?
"Сохраните TimeCurrent() в статической/общей(глобальной) переменной. Следующий тик int deltaSec = TimeCurrent() - предыдущий."
Сохраните TimeCurrent() в переменной. Когда наступит следующий тик, int deltaSec =TimeCurrent() - previous.
Не будет ли переменная "previous" переменной, в которую сохраняется TimeCurrent()...
deltaSec = TimeCurrent() -(TimeCurrent() сохраняется в предыдущую переменную).
Пожалуйста, поясните, Уильям.
https://www.mql5.com/en/forum/127483 сообщил, что DayOfWeek() всегда возвращает 5 в тестере. Я никогда не использую ЛЮБЫЕ Seconds(), DayOfWeek() и т.д., потому что вам нужно текущее время сервера, вам нужно время тика тестера. now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ...
"вам нужно время тика тестера".
Да, я ПОЛАГАЮ, что это ТОЧНО то, что мне нужно при тестировании советника в тестере стратегий из-за сообщения Саймона, описывающего причину того, почему секунды кажутся пропущенными и/или приостановленными.
now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ...
Другими словами...
sec = TimeSeconds(TimeCurrent()); и DOW = TimeDayOfWeek(TimeCurrent());
Что вы скажете на это?
now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ...
Другими словами...
sec = TimeSeconds(TimeCurrent()); и DOW = TimeDayOfWeek(TimeCurrent());
Я не понимаю, что вы имеете в виду, говоря: "Пока вы не вернетесь с начала". Не могли бы вы пояснить?"
В тестере никогда не создаются клещи" Не имеете ли вы в виду, что в тестере никогда не создаются настоящие клещи. Разве вы не согласны с тем, что в тестере создаются искусственные клещи?
int start(){ // do something return; // Return from start. }
int start(){ // do something // Fall off the end is a Return from start. }
- Никакие тики не создаются, пока вы не вернетесь, и он не создаст следующий и не вызовет ваш start(). Если вы вычисляете в течение 5 минут и возвращаетесь, объем (количество тиков) при следующем вызове будет +1. На живом графике, если вы рассчитываете на 5 минут, то вы пропустите 5 минут тиков, а на M1 сформируется несколько новых баров.
Нет никакой логической причины для того, чтобы sleep() работал в тестере стратегий ...
будьте осторожны с такими заявлениями. всегда есть логическая причина для запуска sleep(). в тестере и даже в индикаторах. верно, для случая использования ОП вы не должны играть с sleep, но вы не можете обобщить это для всех MQL.
когда нам нужно спать в Tester? если, например, я тестирую скрипт, который взаимодействует с тестируемым советником, у меня может возникнуть необходимость синхронизировать состояние. я говорю о мьютексах. чтобы получить мьютекс чистым способом, обе части должны иметь возможность ждать, то есть использовать sleep.
То же самое верно и для индикаторов. неважно, что индикатор работает в потоке UI. если двум потокам нужно синхронизироваться, обоим нужна возможность "спать". а sleep() - единственное чистое решение, если вам нужно ждать заданное количество циклов процессора, конструкции "for" просто демонстрируют недостаток знаний.
Хорошо, давайте приведем практический пример: мои советники могут отображать состояние ордеров (самонарисованные стрелки и т.д.). они делают это, реагируя на внешние команды, "посылаемые" через текстовые описания объектов графика (1-отложенные ордера, 2-открытые позиции, 3-закрытые сделки, 4-все вместе), вот почему я называю это командами графика. Или они могут начинать/останавливать/возобновлять последовательности сделок, реагируя на другие команды ("start", "stop", "resume"). чтобы прочитать команды, им нужно синхронизировать доступ к этим объектам графика (создать объект графика + установить текстовое свойство - это не одна атомарная операция). и, конечно, я хотел бы протестировать это поведение в Тестере, поэтому мне нужен sleep() для ожидания.
То же самое для индикаторов, работающих в Тестере или онлайн. Если они делают что-то подобное, я "должен" остановить поток UI, чтобы получить чистое состояние, 10 милисекунд не имеют значения. btw: чистая реализация мьютекса проверяет время, которое он уже ждет, выходит из цикла и сигнализирует об ошибке, если не может получить блокировку синхронизации, скажем, через несколько секунд.
int seconds; // run until the lock is aquired while (true) { ... // warn every second and cancel after 10 seconds duration = GetTickCount() - startTime; if (duration >= seconds*1000) { if (seconds >= 10) return(_false(catch("AquireLock(5) failed to get lock for mutex \""+ mutexName +"\" after "+ DoubleToStr(duration/1000.0, 3) +" sec., giving up", ERR_RUNTIME_ERROR))); warn(StringConcatenate("AquireLock(6) couldn't get lock for mutex \"", mutexName, "\" after ", DoubleToStr(duration/1000.0, 3), " sec., retrying...")); seconds++; } //debug("AquireLock() couldn't get lock for mutex \""+ mutexName +"\", retrying..."); if (IsTesting() || IsIndicator()) SleepEx(100, true); // expert or indicator under test else Sleep(100); }
Я использую эти команды, написав скрипт и назначив ему горячую клавишу. тогда, если я хочу управлять экспертом/индикатором, мне нужно просто нажать клавишу, например. ALT-O для переключения режима отображения ордеров между всеми возможными значениями. Или у меня есть скрипт "start" и "stop" в фаворитах и я запускаю/останавливаю/возобновляю ea щелчком мыши.
В тестере, например, ea с VisualMode=On на полной скорости почти сразу упадет, если не синхронизирована должным образом.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Здравствуйте, сообщество MQL4,
Я столкнулся с проблемой при запуске советника, включающего функцию Sleep() в тестере стратегий. Очевидно, что тестер не будет запускать советника должным образом с включенной в код функцией Sleep().
Кто-нибудь из присутствующих кодеров обнаружил альтернативный метод, отличный от функции Sleep(), для кодирования советника, чтобы "подождать" определенное время, пока советник будет запущен в тестере?
Спасибо