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

 
Artyom Trishkin #:

Всегда была проверка: if(limit>1) limit=rates_total-1. Это для случаев, если нет в расчётах i+сколько_то. Если есть, то эти "сколько-то" нужно включать в конструкцию: limit=rates_total-1-сколько_то.

Без неё всегда был выход за пределы массива. Ведь rates_total - это ни что иное как Bars(). Соответственно, если баров 5000, и мы обращаемся к индексу 5000, то выходим за пределы массива (подсчёт-то баров с нуля начинается).

В вашем примере не правильный расчёт limit:

Должен быть таким:

А после него проверка на limit>1

и если limit таки больше единицы, то limit = rates_total-1

Спасибо Артём! И сорян за кипишь.
Точно, должна быть проверка, о ней как раз я запамятовал.
В коде у меня комментарий ещё остался 
//Проверка и расчёт количества просчитываемых баров.
Видимо копипаста дала о себе знать, и пошло недопонимание у меня.
С проверкой всё как надо работает. Спасибо.

 
Roman #:

Спасибо Артём!
Точно, должна быть проверка, о ней как раз я запамятовал.
С проверкой всё как надо работает. Спасибо.

Пожалуйста. Расчёт limit исправьте. Он у вас не правильный - я выше акцентировал внимание на этом.

int limit = rates_total-1-prev_calculated;

-1 здесь быть не должно.

Если rates_total равен 5000, и просчитанных на прошлом вызове OnCalculate() баров тоже 5000 (prev_calculated), то limit будет равен -1. Соответственно, цикл выполняться не будет вообще.

Если же хотите сделать выбор как считать индикатор (по тикам на нулевом баре, либо только на открытии нового), то введите переменную, указывающую как считать:

int end = (каждый тик ? WRONG_VALUE : 0);

тогда цикл будет таким: for(int i=limit; i>end; i--) { //... }

и расчёт limit будет верным, и цикл таким, какой хотите.

 

Правильный код.

i>=0 для каждого  тика

i>0 для нового бара

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,       
                 const int prev_calculated,   
                 const int begin,             
                 const double& price[])      
{
   ArraySetAsSeries(price, true);
   ArraySetAsSeries(IndBuff, true);
   
   //-------------------------------------------------------------------------
   //Расчёт и проверка количества просчитываемых баров
   int limit = rates_total-prev_calculated;
   
   if(limit>1) 
      limit = rates_total-1;
   

   //-------------------------------------------------------------------------
   //Расчёт индикатора
   for(int i=limit; i>=0; i--)
   {

      IndBuff[i] = price[i]; 

   }
   

   return(rates_total);
}
 
Nikolai Semko #:
Или

Ты даже не спросил чем заняться... Телепаты из отпуска вернулись? ;)

 
Roman #:

Правильный код.

i>=0 для каждого  тика

i>0 для нового бара

ArraySetAsSeries(IndBuff, true);

Это лучше в OnInit() перенести

 
Artyom Trishkin #:

Ты даже не спросил чем заняться... Телепаты из отпуска вернулись? ;)

:)
Артем, не нужно быть телепатом, чтобы увидеть, что чел зарегистрировался несколько минут назад и первым делом увидел "Ошибки, баги, вопросы"
Ясень пень, что спрашивает про то, можно ли на халяву капусты срубить, причем чтоб особо не напрягаться...

 
Nikolai Semko #:

:)
Артем, не нужно быть телепатом, чтобы увидеть, что чел зарегистрировался несколько минут назад и первым делом увидел "Ошибки, баги, вопросы"
Ясень пень, что спрашивает про то, можно ли на халяву капусты срубить, причем чтоб особо не напрягаться...

Может он решил тяжким трудом программиста срубить себе средств на Бентли, вложившись в репетитора? :)

 
Artyom Trishkin #:

Может он решил тяжким трудом программиста срубить себе средств на Бентли, вложившись в репетитора? :)

Вряд ли, Артем.
Если бы в нем был потенциал программиста, он бы не допустил двусмысленности и неопределенности.
:)
 
Roman #:

Знаешь, что больше всего неприятно? Что любые поведения изменяют молча, без предупреждений.
А люди потом мучаются. Надоел этот метатрейдер.

просто оформление индикаторного цикла тащат из дремучих времён методом копи-пасты (и кривых автозаполнений), не думая. 

всё-же просто c нынешним интерфейсом:

for(int bar=prev_calculated>0?prev_calculates-1:0 ; bar<rates_total; bar++) {

   int i=rates_total-1; // i используем если обращения как ArraySetSeries(x,true), иначе bar

   ....

}

return rates_total;

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

 
Maxim Kuznetsov #:

просто оформление индикаторного цикла тащат из дремучих времён методом копи-пасты (и кривых автозаполнений), не думая. 

всё-же просто c нынешним интерфейсом:

for(int bar=prev_calculated>0?prev_calculates-1:0 ; bar<rates_total; bar++) {

   int i=rates_total-1; // i используем если обращения как ArraySetSeries(x,true), иначе bar

   ....

}

return rates_total;

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

Да, погорячился с высказыванием.
Просто когда что-то раньше работало, а теперь нет, начинаются нервные тики ))
И начинаешь всё перепроверять, и необоснованно грешить на то что сломали, забывая о какой нибудь особенности которую конечно не помнишь.
А виной всему копипаста. Думаю многие с этим сталкивались.

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

m

В некоторых C/C++ редакторах такая фишка есть.
Очень удобно, наклепал основных заготовок с которыми в основном работаешь, и потом просто в мастере их подгружаешь.
Стандартные шаблоны MQL, ну не то совсем.
Понятно, что можно сказать, что и так можно написать шаблоны и потом копипастить их.
И снова возвращаемся к коварному слову копипаста. А то что можно автоматизировать, и облегчить участь программиста, как то не рассматривается.

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