Ошибки, баги, вопросы - страница 3032

 
Andrey Dik:

Спасибо, Андрей. Ты единственный кто полностью вник в вопрос.


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


итоговый код второго индикатора, будет полезно кому-то надеюсь:

Вот начало того от чего вам надо было задуматься

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

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

Alexey Viktorov, 2021.05.28 08:36

А зачем такая проверка

//проверка готовности данных и индикатора на другом TF
if (SeriesInfoInteger (Symbol (), tf, SERIES_SYNCHRONIZED))
{
  if (iBars (Symbol (), tf) != BarsCalculated (handleFr)) return 0;
}
else return 0;

Проще будет без условия написать return 0; и все дела…

На каждом новом баре условие будет выполнено и независимо от синхронизации будет пересчёт всех баров. Вы написали необдуманный код и выдаёте это за баг терминала…


А  Igor Makanu ещё раньше говорил об этом…
 

Хочу напомнить.

1. Для каждого символа, для которого открыт хоть один график, работает отдельный поток для обработки пришедших тиков. Может быть открыто несколько графиков по какому-то символу, но поток будет всё равно один.

2. Поток символа обрабатывает не графики, а таймсерии. То есть, те самые массивы данных, которые отдаются на запрос CopyRates

3. Бесполезно спрашивать у своего символа в OnTick или OnCalculate, синхронизирован ли он. Конечно, да!

4. Все таймсерии обрабатываются по порядку, от младшей к старшей. Сначала применение тика, потом расчёт всех индикаторов, созданных на данной таймсерии. Если вы из индикатора, работающего на M1, спрашиваете данные для этого же символа H1, то вы никогда не получите данных с применённым тиком. Данные всегда будут на один тик назад, какие бы ухищрения вы не применяли. Потому что один поток на символ с последовательной обработкой таймфреймов.

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

 
Slava:

Хочу напомнить.

1. Для каждого символа, для которого открыт хоть один график, работает отдельный поток для обработки пришедших тиков. Может быть открыто несколько графиков по какому-то символу, но поток будет всё равно один.

2. Поток символа обрабатывает не графики, а таймсерии. То есть, те самые массивы данных, которые отдаются на запрос CopyRates

3. Бесполезно спрашивать у своего символа в OnTick или OnCalculate, синхронизирован ли он. Конечно, да!

4. Все таймсерии обрабатываются по порядку, от младшей к старшей. Сначала применение тика, потом расчёт всех индикаторов, созданных на данной таймсерии. Если вы из индикатора, работающего на M1, спрашиваете данные для этого же символа H1, то вы никогда не получите данных с применённым тиком. Данные всегда будут на один тик назад, какие бы ухищрения вы не применяли. Потому что один поток на символ с последовательной обработкой таймфреймов.

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

Побольше пожалуйста таких развернутых напоминаний! Спасибо!

 
Slava:

Хочу напомнить.

4. Все таймсерии обрабатываются по порядку, от младшей к старшей. Сначала применение тика, потом расчёт всех индикаторов, созданных на данной таймсерии. Если вы из индикатора, работающего на M1, спрашиваете данные для этого же символа H1, то вы никогда не получите данных с применённым тиком. Данные всегда будут на один тик назад, какие бы ухищрения вы не применяли. Потому что один поток на символ с последовательной обработкой таймфреймов.

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

Я правильно понимаю, что если советник, работающий на M1, использует индикатор на M1(или любом ином ТФ?), который берет данные с верхнего ТФ, то на первом тике нового бара он не сможет вернуть актуальное значение в любом случае, так как очередь до расчета верхнего ТФ дойдет через n тиков?

Просто столкнулся с таким поведением и искал проблему в индикаторе, а теперь выясняется что так и должно быть. Но если это так, то это сильно мешает при тестировании, так как приходится пропускать несколько тиков, что при тестировании в режиме OHLC критично.

 
Slava:

2. Поток символа обрабатывает не графики, а таймсерии. То есть, те самые массивы данных, которые отдаются на запрос CopyRates

....

4. Все таймсерии обрабатываются по порядку, от младшей к старшей. Сначала применение тика, потом расчёт всех индикаторов, созданных на данной таймсерии. Если вы из индикатора, работающего на M1, спрашиваете данные для этого же символа H1, то вы никогда не получите данных с применённым тиком. Данные всегда будут на один тик назад, какие бы ухищрения вы не применяли. Потому что один поток на символ с последовательной обработкой таймфреймов.

почему появляются черные экраны "Обновление" при переключении ТФ?

открыл чарт которым пользовался ранее (Н1 на EURUSD), бросил индикатор, минуты 2-3 ничего не делал, затем переключаешь по очереди к младшему чарту (М30...М1), может появляться секунд на 10 "черный экран обновление"

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


поэтому и вопрос: как часто из индикатора вызывающего индикатор на другом ТФ нужно обращаться к другому ТФ, т.е. если индикатор запущен на М5 и один раз в 30 минут будет вызывать индикатор на Н1 - CopyBuffer() всегда будет получать корректные данные с Н1 ?

или же не факт, поэтому "дергайте индикатор" на Н1 каждый тик  (варианты с обрывами связи пока не рассматриваем)

 

как работать с переменными из одного цикла/функции в другой функции?

можно сделать видимость более глобальной?

 
Igor Makanu:

почему появляются черные экраны "Обновление" при переключении ТФ?

открыл чарт которым пользовался ранее (Н1 на EURUSD), бросил индикатор, минуты 2-3 ничего не делал, затем переключаешь по очереди к младшему чарту (М30...М1), может появляться секунд на 10 "черный экран обновление"

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


поэтому и вопрос: как часто из индикатора вызывающего индикатор на другом ТФ нужно обращаться к другому ТФ, т.е. если индикатор запущен на М5 и один раз в 30 минут будет вызывать индикатор на Н1 - CopyBuffer() всегда будет получать корректные данные с Н1 ?

или же не факт, поэтому "дергайте индикатор" на Н1 каждый тик  (варианты с обрывами связи пока не рассматриваем)

полагаю, исходя из слов Славы,что не факт.

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

но есть очень интересные непонятки, ответы на которые я не нашёл в документации.

как быть, когда тики не идут (выходные к примеру)? если накинуть индикатор работающий на текущем ТФ, то он отрисуется без проблем, причем что интересно - прихода тика для этого не требуется! но если индикатор запрашивает данные с другого ТФ, то он ничего не сможет сделать пока не придет новый тик, а тики то не идут, выходные!

ок, в онтаймере будем вызывать ChartRedraw (ChartID ())и что бы совсем уже наверняка Comment (cnt);, где cnt увеличивается на 1, видим, что на экаране cnt исправно тикает, но индикатор так и не отрисовывается.

но, стоит лишь обновить экран кнопой Обновить из контекстного меню, то индикатор благополучно отрисовывается просчитавшись от начала до конца.

выясняется, что  ChartRedraw () и Обновить по кнопе совсем не одно и тоже, хотя на ум приходит обратное.


ЗЫ Ваш пример кода второго индикатора рабочий, но код Эксперта шустрее.

 
Andrey Dik:

как быть, когда тики не идут (выходные к примеру)? если накинуть индикатор работающий на текущем ТФ, то он отрисуется без проблем, причем что интересно - прихода тика для этого не требуется! 

не требуется

когда набрасываете индикатор на чарт, то там строго определенная последовательность вызовов: OnInit() и сразу OnCalculated() , т.е. первый  OnCalculated() вызывается до прихода тика, поэтому и нужно prev_calc сравнивать с 0 , т.к. по приходу тика или соединением с сервером будет опять вызван OnCalculated() и вот этот  prev_calc станет равен нулю

Andrey Dik:

выясняется, что  ChartRedraw () и Обновить по кнопе совсем не одно и тоже, хотя на ум приходит обратное.

скорее всего нужно использовать ChartSetSymbolPeriod() с параметрами NULL и текущий период, должно помочь

 
Igor Makanu:

скорее всего нужно использовать ChartSetSymbolPeriod() с параметрами NULL и текущий период, должно помочь

ChartSetSymbolPeriod

Вызов ChartSetSymbolPeriod с тем же символом и таймфреймом можно использовать для обновления графика (аналогично команде Refresh в терминале). Обновление графика в свою очередь запускает перерасчет индикаторов, прикрепленных к нему. Таким образом, вы можете рассчитать индикатор на графике даже при отсутствии тиков (например, в выходные дни).

помогло. ещё, как сейчас помню, Ac Пушкин говаривал:

О, сколько нам открытий чудных
Готовят просвещенья дух
И опыт, сын ошибок трудных,
И гений, парадоксов друг,
И случай, бог изобретатель.

 
Andrey Dik:


как быть, когда тики не идут (выходные к примеру)? если накинуть индикатор работающий на текущем ТФ, то он отрисуется без проблем, причем что интересно - прихода тика для этого не требуется! но если индикатор запрашивает данные с другого ТФ, то он ничего не сможет сделать пока не придет новый тик, а тики то не идут, выходные!


С другого таймфрейма возьмутся те данные, которые готовы на данный момент. То есть, в выходной все данные будут прекрасно синхронизированы

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