альтернатива функциональному сну

 

Здравствуйте, сообщество MQL4,

Я столкнулся с проблемой при запуске советника, включающего функцию Sleep() в тестере стратегий. Очевидно, что тестер не будет запускать советника должным образом с включенной в код функцией Sleep().

Кто-нибудь из присутствующих кодеров обнаружил альтернативный метод, отличный от функции Sleep(), для кодирования советника, чтобы "подождать" определенное время, пока советник будет запущен в тестере?


Спасибо

 
WhooDoo22:

Здравствуйте, сообщество MQL4,

Я столкнулся с проблемой при запуске советника, включающего функцию Sleep() в тестере стратегий. Очевидно, что тестер не будет запускать советника должным образом с включенной в код функцией Sleep().

Кто-нибудь из присутствующих обнаружил альтернативный метод, отличный от функции Sleep(), для кодирования советника, чтобы "подождать" определенное количество времени, пока советник будет запущен в тестере?

Нет никакой логической причины для работы функции Sleep() в тестере стратегий... что вы пытаетесь сделать? Если вы пытаетесь определить время события, то используйте время и не пытайтесь просто сделать паузу на необходимое время, это не то, для чего предназначена функция Sleep().
 

Саймон,

Я решил использовать функцию 'Sleep()' потому, что Seconds() возвращает значения из последнего известного времени сервера (получение данных из последнего известного времени сервера приводит к пропуску секунд и/или паузе). Мне нужна надежность, а не универсальность.

Что вы скажете по этому поводу?


Спасибо

 
WhooDoo22:

Саймон,

Причина, по которой я решил использовать функцию 'Sleep()', заключается в том, что Seconds() возвращает значения из последнего известного времени сервера (получение данных из последнего известного времени сервера приводит к пропуску секунд и/или паузе).

Что вы можете сказать по этому поводу? Вы можете "видеть" время только для времени, которое имеет тики, если нет тиков в течение 30 секунд, то вы увидите пропуск 30 секунд ... Вы ничего не можете с этим поделать, так оно и есть. Время для тиков в тестере стратегий должно быть разумно равномерным, поскольку тики не реальные, а синтезированные.
 

Саймон,

Итак, вы пишете: причина, по которой я могу называть эти "пропуски" и/или "паузы" в секундах, заключается в том, что между [секундами x] и [секундами y] не создаются тики. Говоря простым языком, создается тик, теперь сохраняется "секунда x". В течение трех секунд тик не создается, затем создается тик. Теперь сохраняются "секунды y". ('секунды y' = (секунды x + три секунды)) как ('секунды x' = (секунды y - три секунды)).

Что вы скажете по этому поводу?


Пока что я буду рассматривать свои варианты.

Большое спасибо за ваши ответы.

 
  1. Пока вы не вернетесь со старта. В тестере НИКОГДА не создаются тики. Сохраните TimeCurrent() в статической/общей(глобальной) переменной. Следующий тик int deltaSec = TimeCurrent() - предыдущий.
  2. https://www.mql5.com/en/forum/127483 сообщил, что DayOfWeek() всегда возвращает 5 в тестере (определенно не то же самое в индикаторах, как и Ask и Bid). Я никогда не использую ЛЮБЫЕ Seconds(), DayOfWeek() и т.д., потому что вам не нужно текущее время сервера, вам нужно время тика тестера. now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ....
 
WhooDoo22:

Саймон,

Итак, вы пишете: причина, по которой я могу называть эти "пропуски" и/или "паузы" в секундах, заключается в том, что между [секундами x] и [секундами y] не создаются тики. Говоря простым языком, создается тик, теперь сохраняется "секунда x". В течение трех секунд тик не создается, затем создается тик. Теперь сохраняются "секунды y". ('секунды y' = (секунды x + три секунды)) как ('секунды x' = (секунды y - три секунды)).

Что вы скажете на это?

Да, между тиками легко может быть 3 секунды, как и в реальном мире, посмотрите на любую валютную пару в полночь по Гринвичу, вы увидите множество больших многосекундных промежутков между тиками ... вы даже можете получить отсутствие тиков в течение более минуты и пропущенные бары M1 ... это не редкость.
 

Уильям,

Большое спасибо за ваш ответ.

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());

Что вы скажете на это?


Спасибо
 
WhooDoo22:

now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ...

Другими словами...

sec = TimeSeconds(TimeCurrent()); и DOW = TimeDayOfWeek(TimeCurrent());

Посмотрите, что дает TimeSeconds(), затем подумайте, что дает TimeCurrent(). . какой из них вам нужен и почему?
 
WhooDoo22:

Я не понимаю, что вы имеете в виду, говоря: "Пока вы не вернетесь с начала". Не могли бы вы пояснить?"

В тестере никогда не создаются клещи" Не имеете ли вы в виду, что в тестере никогда не создаются настоящие клещи. Разве вы не согласны с тем, что в тестере создаются искусственные клещи?

  1. int start(){
       // do something
       return; // Return from start.
    }
    int start(){
       // do something
       // Fall off the end is a Return from start.
    }

  2. Никакие тики не создаются, пока вы не вернетесь, и он не создаст следующий и не вызовет ваш start(). Если вы вычисляете в течение 5 минут и возвращаетесь, объем (количество тиков) при следующем вызове будет +1. На живом графике, если вы рассчитываете на 5 минут, то вы пропустите 5 минут тиков, а на M1 сформируется несколько новых баров.
 
RaptorUK:
Нет никакой логической причины для того, чтобы 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 на полной скорости почти сразу упадет, если не синхронизирована должным образом.

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