OnTimer в индикаторах

 

Есть индикатор. В нем есть OnTimer, который прекрасно отрабатывает, если поместить индикатор на чарт.

Есть эксперт. В нем есть OnTimer, который прекрасно отрабатывает, если поместить эксперт на чарт.

Эксперт вызывает индикатор через iCustom. При этом таймер в индикаторе не отрабатывает.

Это баг или так задумано?

 
EventSetMillisecondTimer в индикаторе при этом возвращает false, а GetLastError() возвращает 4051 (ERR_INVALID_FUNCTION_PARAMVALUE)
 
RickD:

Есть индикатор. В нем есть OnTimer, который прекрасно отрабатывает, если поместить индикатор на чарт.

Есть эксперт. В нем есть OnTimer, который прекрасно отрабатывает, если поместить эксперт на чарт.

Эксперт вызывает индикатор через iCustom. При этом таймер в индикаторе не отрабатывает.

Это баг или так задумано?

Это - ограничение архитектуры.

Индикаторы, вызываемые из эксперта, работают в потоке эксперта и не живут собственной жизнью. В отличие от пятёрки.

 

А можно это как-то изменить/улучшить?

Пример: есть индикатор, он через dll отправляет асинхронный запрос на сайт новостей и через какое-то время ожидает ответ, опрашивая приход данных по таймеру или потиково.

Когда индикатор вызывается из эксперта, и долго нет тиков (или выходные), то новости не показываются.

 

Повторяю. Это - ограничение архитектуры. Чтобы изменить поведение индикаторов, надо менять архитектуру клиентского терминала. Мы этого делать не будем.

Накидывайте нужный индикатор непосредственно на график.

 

Подскажите такой момент.

1) Почему когда я в эксперте в OnTimer вызывают индикатор через iCustom, то в индикаторе не срабатывает OnCalculate?

2) Можно ли в таком случае в эксперте вызвать EventChartCustom, а в вызываемом через iCustom индикаторе поймать OnChartEvent?

 

1. Потому что исходные данные у индикатора не изменились. OnCalculate вызывается только при изменении данных (приход новой котировки). Дальнейшие запросы вплоть до прихода следующей котировки не приводят к вызову расчёта

2. Нет. Тут такая же ситуация как и с таймером.

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

 

Или офорляйте индикаторы в виде производных класссов, запихивая их в в советник, как соответствующие экземпляры. Тогда можно будет навсегда забыть про ограничения iCustom, вызывая индикаторы напрямую в советнике со всеми Timer и Event-событиями. При этом еще и экономя на памяти и вычислительных ресурсах.

Надо всего один раз сделать, а дальше пойдет, как по маслу. И будете вспоминать про iCustom, как про страшный сон.

А если захотите визуализировать свои индикаторные классы, то внтури MT4 создаете экземпляр индикатор-класса и прописываете только код: буффер = значение. 

 
stringo:

1. Потому что исходные данные у индикатора не изменились. OnCalculate вызывается только при изменении данных (приход новой котировки). Дальнейшие запросы вплоть до прихода следующей котировки не приводят к вызову расчёта

2. Нет. Тут такая же ситуация как и с таймером.

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

1) Такой обмен данынми уже организован. Чтобы брать данные из индикатора. Но как такой обмен скажет индикатору обновлять значение времени, выводимое на чарт, и сами данные раз в секунду?

2) Кстати - а если значение какого-то параметра индикатора изменилось динамически, то вызов iCustom тоже не приведет к вызову OnCalculate?

3) Если из эксперта послать в чарт PostMessage для эмуляции прихода новой котировки - OnCalculate не вызовется?
 
hrenfx:

Или офорляйте индикаторы в виде производных класссов, запихивая их в в советник, как соответствующие экземпляры. Тогда можно будет навсегда забыть про ограничения iCustom, вызывая индикаторы напрямую в советнике со всеми Timer и Event-событиями. При этом еще и экономя на памяти и вычислительных ресурсах.

Надо всего один раз сделать, а дальше пойдет, как по маслу. И будете вспоминать про iCustom, как про страшный сон.

А если захотите визуализировать свои индикаторные классы, то внтури MT4 создаете экземпляр индикатор-класса и прописываете только код: буффер = значение. 

Да. Это пожалуй выход. Встраивать код индикатора напрямую в советник. Хотя не самый красивый и удобный.

 
Slava:

Это - ограничение архитектуры.

Индикаторы, вызываемые из эксперта, работают в потоке эксперта и не живут собственной жизнью. В отличие от пятёрки.

В Метатрейдер 5 столкнулся с тем, что если из индикатора, в котором есть OnTimer вызвать по iCustom другой индикатор, в котором тоже есть OnTimer, то по логам оба таймера запускаются нормально, проверяю так:

//--- инициализация таймера
   if(EventSetMillisecondTimer(Refresh_msec)) {Print("EventSetMillisecondTimer start well");}
   else {Print("EventSetTimer start fail. Execution error = ",GetLastError()); return(INIT_FAILED);} 

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

Такие вот чудеса, билд 2340.

Пока дошло, в чём причина, пару часов потратил. Пришлось в индикаторе. вызываемом по iCustom убрать OnTimer, только тогда всё заработало.

UPD: Проверил еще один вариант - вызвал индикатор с OnTimer по iCustom на другую валютную пару, не помогло, тоже так не работает.

UPD2: Оказывается даже если в индикаторе, который вызывает другой индикатор  с OnTimer по iCustom, нет OnTimer , OnTimer в вызываемом индикаторе так же не работает. Печаль беда.. Как то совсем Метатрейдер не заточен под  HFT. Не, конечно кое-что может, но не на уровне миллисекунд.

Удивило это - "При работе в режиме реального времени события таймера генерируются не чаще 1 раза в 10-16 миллисекунд, что связано с аппаратными ограничениями." Это какие такие ограничения "аппаратные"? Даже в самом языке есть функция, например 

GetTickCount64()

или еще круче

GetMicrosecondCount()

Если что-то может рассчитываться, значит аппаратно это возможно.