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

 
Alexey Viktorov:

Я …кодеру не товарищ. Это не подтверждение, а подсказка, не надо возвращать 0. От этого все ваши проблемы. Вы сами вызываете полный пересчёт индикатора.

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

 
Andrei Trukhanovich:

замени

на

и протестируй.

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

2021.05.28 21:22:54.394 LitTF (EURUSD,M2) Индикатор на периоде 3 ещё не рассчитан

2021.05.28 21:22:54.396 LitTF (EURUSD,M2) Индикатор на периоде 3 ещё не рассчитан

2021.05.28 21:22:54.397 OldTF (EURUSD,M3) 0.000262 sec, расcчитано 50046 баров, всего баров 50046

2021.05.28 21:22:55.796 LitTF (EURUSD,M2) 0.007693 sec, расcчитано 50000 баров, всего баров 50000

2021.05.28 21:24:02.286 LitTF (EURUSD,M2) Индикатор на периоде 3 ещё не рассчитан

2021.05.28 21:24:02.286 OldTF (EURUSD,M3) 0.000000 sec, расcчитано 1 баров, всего баров 50047

2021.05.28 21:24:03.017 LitTF (EURUSD,M2) 0.000015 sec, расcчитано 1 баров, всего баров 50001

2021.05.28 21:26:03.898 LitTF (EURUSD,M2) 0.000007 sec, расcчитано 1 баров, всего баров 50002

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


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

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   ulong t = GetMicrosecondCount ();
   if (rates_total == prev_calculated) return rates_total;

   
   if (SeriesInfoInteger (Symbol (), OldTF, SERIES_SYNCHRONIZED))
   {
      if (iBars (Symbol (), OldTF) != BarsCalculated (Handle))
      {
        Print ("Индикатор на периоде ", OldTF, " ещё не рассчитан");
        return prev_calculated;
      }
   }
   else 
   {
     Print ("Период ", OldTF, " не синхронизирован.");
     return prev_calculated;
   }

   ArraySetAsSeries (high, true);
   ArraySetAsSeries (time, true);

   int limit = rates_total - prev_calculated - 1;

   double buff [];
   int ind = 0;
   for (int i = limit; i >= 0; i--)
   {
      ind = iBarShift (Symbol (), OldTF, time [i], false);
      if (CopyBuffer (Handle, 0, ind, 1, buff) != -1)
      {
        IBuffer [i] = buff [0];
      }
      else
      {
        Print ("Ошибка копирования буфера ", GetLastError ());
        return 0;
      }
   }

   //----------------------------------------------------------------
   double e = (GetMicrosecondCount () - t) / 1000000.0;
   Print (DoubleToString (e, 6), " sec, расcчитано ", rates_total - prev_calculated, " баров, всего баров ", rates_total);
   return(rates_total);
}
 
Andrey Dik:

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

Посчитайте сколько дураков вам подсказывают… только один умник не слышит никого и упёрся……………

Куда ещё разворачивать совет от Andrei Trukhanovich там и дураку всё понятно… Сам себе создали проблему и пытаетесь выставить свой …код как баг mql.

 
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 () и Обновить по кнопе совсем не одно и тоже, хотя на ум приходит обратное.


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