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

 
Vladimir Karputov #:

Шаг 1: Создаём заготовку при помощи 'MQL5 Wizard':


Шаг 2: правильно прописываем 'limit' и ИСПОЛЬЗУЕМ массив close - А НЕ вызов iClose!!!


Результат:

и нет никаких ошибок.

За прямой i++ пример конечно спасибо.
Но то, что у меня обратный цикл, вы не заметили.
И если iClose приведён для примера, значит он нужен чтоб показать, что в дальнейшем используется индекс i в других функциях.

 
Roman #:

Николай я знаю конструкции if и за единичку,

else if

Nikolai Semko #:
Используйте логику:
Если limit = 0,  значит новый тик
Если limit = 1,  значит новый бар (последний элемент буфера rates_total -1, а у Вас rates_total, отсюда и переполнение)
Если limit > 1, то лучше пересчитать весь индикатор

здесь ошибся 
лучше использовать 
если limit != 1

то есть вся логика примерно какая:

limit = rates_total - prev_calculated;
if (limit == 0) {..} // новый тик
else if ( limit == 1) {..} // новый бар
else {..} // полный пересчет всего индикатора
Понимаю, что некоторые будут возмущаться и говорить зачем пересчитывать все, если limit == 2, 
но когда limit не равен 1 и не равен 0, то значит это первая инициализация индикатора, или что-то пошло не так (например сбой соединения или сбой на сервере)
Более того, я не раз нарывался на ситуации, когда prev_calculated было больше rates_total. Возможно это раньше был глюк какой-то и сейчас исправили, но с тех пор использую именно такую конструкцию от греха подальше.
 
Nikolai Semko #:

если limit != 1

А какая разница? он может получиться меньше нуля?
 
Vladimir Karputov #:

Шаг 1: Создаём заготовку при помощи 'MQL5 Wizard':


Шаг 2: правильно прописываем 'limit' и ИСПОЛЬЗУЕМ массив close - А НЕ вызов iClose!!!


Результат:

и нет никаких ошибок.

Кто сказал, что это единственный верный расчёт limit и индикатора?

Обсуждение ведётся насчёт иного расчёта limit и самого индикатора - слева-направо - от начала истории до текущего времени. Это проще и нагляднее.

В рассчитанном таким образом limit (int limit = rates_total - prev_calculated; if(limit>1) limit=rates_total-1;) сразу присутствуют все данные о:

  1. текущий ли это тик,
  2. открытие ли это нового бара,
  3. изменение ли это исторических данных.

Если текущий тик (limit==0), то for(int i=limit; i>=0; i--) { // ... } будет вести расчёт индикатора на каждом новом тике, и только нулевой бар будет пересчитываться.

Если открытие нового бара (limit==1), то for(int i=limit; i>=0; i--) { // ... } будет вести расчёт первого и нулевого бара - предыдущий и вновь открытый

Если это изменение истории (limit>1), то for(int i=limit; i>=0; i--) { // ... } произведёт полный перерасчёт всего индикатора по всей доступной истории (история где-то кем-то была изменена)

 
TheXpert #:
А какая разница? он может получиться меньше нуля?

да, встречал (дописал в предыдущем сообщении)

 
Проблему только Артём понял.
Но видимо эта проблема навсегда.
И теперь только if-ы.
 
Roman #:
Проблему только Артём понял.
Но видимо эта проблема навсегда.
И теперь только if-ы.

Нет, не понял. Уточните что я понял...

 
Vladimir Karputov #:
   int limit=prev_calculated-1;
   if(prev_calculated==0)
      limit=0;
   for(int i=limit; i<rates_total; i++)
     {
      CloseBuffer[i]=close[i];
     }

все же тернарный оператор смотрится более лаконично (ИМХО)

int limit = prev_calculated==0 ? 0: prev_calculated-1;

тем более, как говорил, а если вдруг, что-то пойдет не так и prev_calculated окажется больше rates_total.
Такую ситуацию встречал, когда Макс. баров в окне != unlimited, а например 50000. В этом случает размер массив баров с каждым новым баром увеличивался на 1, но в какой то момент снова становился снова 50000. Логику не уловил. Ловил это пару лет назад. Сейчас нужно проверить. Поставлю распринтовку на своем VPS.

 
Artyom Trishkin #:

Нет, не понял. Уточните что я понял...

Что for теперь не работает как раньше

limit==0
для тиков i>=0
для баров i>0

Выше же вы всё правильно написали,
только для нового бара опечатался for(int i=limit; i>=0; i--)
тут оператор = не нужен, но это в прошлом наверно уже,
если не вернут прежнее поведение.

 
Roman #:

Что for теперь не работает как раньше

limit==0
для тиков i>=0
для баров i>0

Выше же вы всё правильно написали,
только для нового бара опечатался for(int i=limit; i>=0; i--)
тут оператор = не нужен, но это в прошлом наверно уже,
если не вернут прежнее поведение.

Опять ничего не понял. В чём у вас что-то не так? Вроде всё как раньше было.