Редко, но бывают ситуации, когда котировки по одному инструменту замирают и надолго (видел такое в йеной). И если советник висит на этой паре то ты попал, если не перевел весь код в OnTime().
Если работать на ООП, или использовать определенные алгоритмы то и перевода кода непонадобится. Но согласитесь что удобней получать тики в реальном времени по всем парам находящимся в обзоре (причем не придумывать что-то свое при этом)...
Lizar:
Такое событие можно получить при помощи TimeCuurent(), а вот что с ним дальше делать, как синронизировать - вопрос.
В обработчике OnTick() данная функция вернет время пришедшего обрабатываемого тика. В других случаях (например, вызов в обработчиках OnInit(), OnDeinit(), OnTimer() и так далее) это – время прихода последней котировкипо любому символу, доступного в окне "Обзор рынка", то самое время, которое показано в заголовке этого окна.
В обработчике OnTick() данная функция вернет время пришедшего обрабатываемого тика. В других случаях (например, вызов в обработчиках OnInit(), OnDeinit(), OnTimer() и так далее) это – время прихода последней котировкипо любому символу, доступного в окне "Обзор рынка", то самое время, которое показано в заголовке этого окна.
Да это понятно. только если поместить ее в OnTime мы сможем обновлять время не чаще раза в минуту, а если в текущую OnTick() то рискуем пропустить тики по какой-то из пар (в мультах).
А что делать в блоке обработки это понятно (для мультов) - Получаем новое значение, сравниваем с имеющимся и делаем выводы был новый тик или нет.
Событие NewTick генерируется только для экспертов при поступлении нового тика по символу, к графику которого прикреплен эксперт.
Еще раз. Мы говорим про советник который висит на каком-то символе. Он запускается по событию
void OnTick() {}
если находиться внутри этой функции, а тиков по этой паре уже более часа нет, то и ничего сделать в течении часа нельзя. Пока единственный выход, это делать в таймере, он запускается независимо от прихода тиков по инструменту.
Да это понятно. только если поместить ее в OnTime мы сможем обновлять время не чаще раза в минуту, а если в текущую OnTick() то рискуем пропустить тики по какой-то из пар (в мультах).
В этом то и дело, что событие мы получить можем, а использовать толком нет.
Еще раз. Мы говорим про советник который висит на каком-то символе. Он запускается по событию
void OnTick() {}
если находиться внутри этой функции, а тиков по этой паре уже более часа нет, то и ничего сделать в течении часа нельзя. Пока единственный выход, это делать в таймере, он запускается независимо от прихода тиков по инструменту.
Да, если действовать в рамках этого https://www.mql5.com/ru/docs/basis/function/events, то согласен, что наилучший вариант, как сейчас видится, это OnTime. Но это нас только спасет от зависимости поступления тиков. И не спасет от однопоточности: пока обрабатываем сигнал по одному инструменту, рискуем пропустить или запаздать с обработкой других. Особенно это актуально становится при условии "время обработки торговых заявок от 2 до 7 секунд" + реквоты.
А про TimeCuurent() вспомнил, потому что Interesting заговорил про тики в реальном времени по всем парам находящимся в обзоре рынка.
If you call this prototype function from one place, then we have what we need. But if we want to use this function, for example, again in another place in the same calculation loop, it will always return false, which means that there is no bar. And this will not always be true. Static variable in this case imposes an artificial limit on the number of prototype function calls.
Вы правы. Но вызывать несколько раз функцию типа isnewbar() в течение 1 тика - плохая практика. Вызовите ее только один раз и сохраните результат в переменной.
Проблема в том, что предложенное вами решение - использование класса без статической переменной - не решает того, что вы подчеркнули. И даже ситуация стала еще хуже. Вы должны объявить экземпляр вашего класса как глобальную переменную (объект), а также инициализировать его в OnInit(). Тот, кто будетиспользовать ваш класс, должен знать обэтой операции:
Всегда использоватьглобальнуюпеременную
Всегдаинициализировать , даже еслисимвол и периодзаданы по умолчанию (для временного графика).
И наконец, "если мы хотим использовать эту функцию, например, еще раз в другом месте в том же цикле вычислений". Все равно она ВСЕГДА возвращает FALSE.
Вы заменили статическую локальную переменную на глобальную, что одно и то же, и не решили свою проблему.
Тем не менее, вашастатьязаставляетзадуматься ипредлагаетинтересные идеи.
Хорошая статья, спасибо, что поделились! Все это было очень полезно!
В общем, я взял вашу функцию isNewBar, и при компиляции она выдает следующее сообщение:"возможна потеря данных из-за преобразования типов".
Поэтому я изменил типы var с datetime на long таким образом:
//+------------------------------------------------------------------+//| Возвращает true, если для пары символ/период появился новый бар |//+------------------------------------------------------------------+bool isNewBar()
{
//--- запомните время открытия последнего бара в статической переменнойstaticlong last_time=0;
//--- текущее времяlong lastbar_time=SeriesInfoInteger(CurrencyPair,Period01,SERIES_LASTBAR_DATE);
//--- если это первый вызов функцииif(last_time==0)
{
//--- установите время и выйдите
last_time=lastbar_time;
return(false);
}
//--- если время отличаетсяif(last_time!=lastbar_time)
{
//--- запомните время и верните true
last_time=lastbar_time;
return(true);
}
//--- если мы дошли до этой строки, то бар не новый; return falsereturn(false);
}
Теперь она компилируется без каких-либо замечаний и, кажется, работает нормально. Спасибо!
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
Prival:
Редко, но бывают ситуации, когда котировки по одному инструменту замирают и надолго (видел такое в йеной). И если советник висит на этой паре то ты попал, если не перевел весь код в OnTime().
Lizar:
Такое событие можно получить при помощи TimeCuurent(), а вот что с ним дальше делать, как синронизировать - вопрос.
А причем тут TimeCuurent()?
Справка гласит:
В обработчике OnTick() данная функция вернет время пришедшего обрабатываемого тика. В других случаях (например, вызов в обработчиках OnInit(), OnDeinit(), OnTimer() и так далее) это – время прихода последней котировки по любому символу, доступного в окне "Обзор рынка", то самое время, которое показано в заголовке этого окна.
Справка гласит:
В обработчике OnTick() данная функция вернет время пришедшего обрабатываемого тика. В других случаях (например, вызов в обработчиках OnInit(), OnDeinit(), OnTimer() и так далее) это – время прихода последней котировки по любому символу, доступного в окне "Обзор рынка", то самое время, которое показано в заголовке этого окна.
Да это понятно. только если поместить ее в OnTime мы сможем обновлять время не чаще раза в минуту, а если в текущую OnTick() то рискуем пропустить тики по какой-то из пар (в мультах).
А что делать в блоке обработки это понятно (для мультов) - Получаем новое значение, сравниваем с имеющимся и делаем выводы был новый тик или нет.
Но вот скажите мне, нафига это делать в эксперте?
Справка гласит:
ошибка. вот что гласит справка https://www.mql5.com/ru/docs/basis/function/events
Событие NewTick генерируется только для экспертов при поступлении нового тика по символу, к графику которого прикреплен эксперт.
Еще раз. Мы говорим про советник который висит на каком-то символе. Он запускается по событию
void OnTick() {}
если находиться внутри этой функции, а тиков по этой паре уже более часа нет, то и ничего сделать в течении часа нельзя. Пока единственный выход, это делать в таймере, он запускается независимо от прихода тиков по инструменту.
Да это понятно. только если поместить ее в OnTime мы сможем обновлять время не чаще раза в минуту, а если в текущую OnTick() то рискуем пропустить тики по какой-то из пар (в мультах).
ошибка. вот что гласит справка https://www.mql5.com/ru/docs/basis/function/events
Еще раз. Мы говорим про советник который висит на каком-то символе. Он запускается по событию
void OnTick() {}
если находиться внутри этой функции, а тиков по этой паре уже более часа нет, то и ничего сделать в течении часа нельзя. Пока единственный выход, это делать в таймере, он запускается независимо от прихода тиков по инструменту.
Да, если действовать в рамках этого https://www.mql5.com/ru/docs/basis/function/events, то согласен, что наилучший вариант, как сейчас видится, это OnTime. Но это нас только спасет от зависимости поступления тиков. И не спасет от однопоточности: пока обрабатываем сигнал по одному инструменту, рискуем пропустить или запаздать с обработкой других. Особенно это актуально становится при условии "время обработки торговых заявок от 2 до 7 секунд" + реквоты.
А про TimeCuurent() вспомнил, потому что Interesting заговорил про тики в реальном времени по всем парам находящимся в обзоре рынка.
Очень интересная статья. Спасибо, что поделились всем этим.
Однако есть несколько замечаний:
Говоря об этой функции, вы говорите:
If you call this prototype function from one place, then we have what we need. But if we want to use this function, for example, again in another place in the same calculation loop, it will always return false, which means that there is no bar. And this will not always be true. Static variable in this case imposes an artificial limit on the number of prototype function calls.
Вы заменили статическую локальную переменную на глобальную, что одно и то же, и не решили свою проблему.
Тем не менее, ваша статья заставляет задуматься и предлагает интересные идеи.
Хорошая статья, спасибо, что поделились! Все это было очень полезно!
В общем, я взял вашу функцию isNewBar, и при компиляции она выдает следующее сообщение:"возможна потеря данных из-за преобразования типов".
Поэтому я изменил типы var с datetime на long таким образом:
Теперь она компилируется без каких-либо замечаний и, кажется, работает нормально. Спасибо!