Нужна ли ф-я IndicatorCounted() ?

 

По идее, такая ф-я нужна (и так написано в "Учебнике" и "Справочнике") для определения кол-ва посчитанных индикатором баров, но это вранье.

Я-то думал (прочтя описание), что после восстановления связи будут просчитаны только пропущенные бары. Щаз! IndicatorCounted() сбрасывается в ноль, и со всей дури все считается заново.

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

Из полезных свойств IndicatorCounted() :

- значение ноль при подключении индюка;

- определение первого тика нового бара, для повторного пересчета предыдущего. (Кста, еще большой вопрос: нужно ли это при реальной торговле.)

Из вредных:

- нелогичный сброс в ноль.


Так нах IndicatorCounted() нужна???

Понять, что индюк первый раз подключен, можно и без нее. Ф-я init() на что? Да даже не init(), а просто объявление переменной статичной или в головной части индюка.

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

"Не создавай лишних сущностей без крайней на то необходимости." Дополню "бритву Оккама": особенно, если это сущность ведет себя как последняя сво.


Т.е., известная конструкция:

   int counted_bars=IndicatorCounted();
   int limit=Bars-counted_bars-1;
   for(int i=limit; i>=0; i--)
     {
      // тело цикла
     }

Заменяется на:

   static int BarsOld;
   int limit=Bars-BarsOld-(BarsOld==0);
   if(Bars!=BarsOld) BarsOld=Bars;
   for(int i=limit; i>=0; i--)
     {
      // тело цикла
     }

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


---------------------------

Я просмотрел форум - вопросы эти поднимались, но как-то разрозненно (м.б. чего-то пропустил - тогда пардон).


Может, я чего-то не понимаю, и IndicatorCounted() - супер полезная ф-я, и мой отказ от нее - роковая ошибка?

Кто чего думает?

 
Svinozavr писал(а) >>

По идее, такая ф-я нужна (и так написано в "Учебнике" и "Справочнике") для определения кол-ва посчитанных индикатором баров, но это вранье.

Я-то думал (прочтя описание), что после восстановления связи будут просчитаны только пропущенные бары. Щаз! IndicatorCounted() сбрасывается в ноль, и со всей дури все считается заново.

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

Из полезных свойств IndicatorCounted() :

- значение ноль при подключении индюка;

- определение первого тика нового бара, для повторного пересчета предыдущего. (Кста, еще большой вопрос: нужно ли это при реальной торговле.)

Из вредных:

- нелогичный сброс в ноль.

Так нах IndicatorCounted() нужна???

Понять, что индюк первый раз подключен, можно и без нее. Ф-я init() на что? Да даже не init(), а просто объявление переменной статичной или в головной части индюка.

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

"Не создавай лишних сущностей без крайней на то необходимости." Дополню "бритву Оккама": особенно, если это сущность ведет себя как последняя сво.

Т.е., известная конструкция:

Заменяется на:

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


---------------------------

Я просмотрел форум - вопросы эти поднимались, но как-то разрозненно (м.б. чего-то пропустил - тогда пардон).

Может, я чего-то не понимаю, и IndicatorCounted() - супер полезная ф-я, и мой отказ от нее - роковая ошибка?

Кто чего думает?

Кажется апокалипсис настал...

Первое сообщение на форуме и сразу с "нах".

Или не апокалипсис, а "цирк уехал, клоуны приехали".

 
Integer >>:

Кажется апокалипсис настал...

Первое сообщение на форуме и сразу с "нах".

Или не апокалипсис, а "цирк уехал, клоуны приехали".

Спасибо за ответ. Оперативно, и, что главное, по существу.

(И появился всадник на коне бледном. И имя этому всаднику - клоун.)

Ну, здравствуйте, клоун. Еще раз спасибо за ответ.

 

Любопытная конструкция

int limit=Bars-BarsOld-(BarsOld==0);

Ранее с таким не сталкивался, а потому не понял два момента.

1. Зачем вычитать выражение (BarsOld==0)?

2. Почему конструкция (BarsOld==0) используется в вычислении, ведь == это оператор сравнения?

Поясните пожалуйста.

 
drknn >>:

Любопытная конструкция

Ранее с таким не сталкивался, а потому не понял два момента.

1. Зачем вычитать выражение (BarsOld==0)?

2. Почему конструкция (BarsOld==0) используется в вычислении, ведь == это оператор сравнения?

Поясните пожалуйста.


1. Потому что (наверное...) иногда из числа требуется вычитать\прибавлять 1

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

2. Это логические выражение. Поэтому. С возвращаемым результатом 0 или 1.

//--- скрипт
int start()
{
int hyp=3;
Alert(10+24-(hyp==4)  );
//---
return(0);
}
в одном случае получим 33 в другом 34 из этого выражения при равенстве или нет.
 

Спасибо за ответ. Тогда возникает другой вопрос. При использовании кода

static int BarsOld;
   int limit=Bars-BarsOld-(BarsOld==0);
   if(Bars!=BarsOld) BarsOld=Bars;
   for(int i=limit; i>=0; i--)
     {
      // тело цикла
     }

Что произойдёт если я не отсоединяя индикатор от графика просто щёлкну мышью по другому таймфрейму?

По-идее (исходя из логикки автора), у меня должны сохраниться значения в индикаторных буферах. Попробовал. Сделал индикатор, который окрашивает бары. Кинул на график с только что указанной конструкцией организации цикла. Переключился на другой таймфрейм и получил кашу на графике. Организовал цикл через 

 int counted_bars=IndicatorCounted();
   int limit=Bars-counted_bars-1;
   for(int i=limit; i>=0; i--)
     {
      // тело цикла
     }
И каша исчезла... Всё теперь работает как положено.
 

Я ее вообще не использую. "определение первого тика нового бара" можно сделать и без нее...

 

Согласен с автором темы. Функция спорная. Во всяком случае, логика ее работы весьма туманна...

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

Например, вы загрузили терминал в выходные. Он выдал вам все, известные ему - последние котировки. Что же нам говорит функция IndicatorCounted() ? Она говорит нам "0". Получается что все бары неактуальны и нуждаются в пересчете. Ну да Бог с ним, с офф-лайном... Отнесем это на счет реализации работы функции start() - нет приходящих котировок и start вызывается единожды, при запуске индюка, и видимо расчет значений IndicatorCounted() производится после вызова start().

Давайте поднимем другой момент. Допустим вы рисуете стрелки разворота на исторических данных. Программист, котороый только что начал писать под МТ4 будет наивно пологать, что раз IndicatorCounted() вернул значение, равное Bars-1 или близкое к тому, то значит все бары загружены в индикаторные буфера и отрисованы, но это СОВСЕМ не так. И если вы думаете, что обсчитываете нулевой бар, то это может быть БОЛЬШИМ заблуждением, и на самом деле, если в конструкции типа:

 int counted_bars=IndicatorCounted();
   int limit=Bars-counted_bars-1;
   for(int i=limit; i>=0; i--)
     {
      // тело цикла
     }
limit вам вернул вам ноль - это лишь значит что МТ дошел до последнего ИМЕЮЩЕГОСЯ В НАЛИЧИИ бара, а это запросто могут быть исторические данные, загруженные ранее.
Для того, чтобы избежать подобных вещей, я пробовал обложиться множеством условий, типа:
void start() 
{
...
   if (first_stat) {                                              // Определяем, заполнено ли окно графика
      vbars_count=WindowBarsPerChart();                           // Кол-во Баров на видимой части графика
      fvbar=WindowFirstVisibleBar();                              // номер первого видимого бара в окне текущего графика
      if( vbars_count > (fvbar+2) ) {return;}                     
   }   
...
   if (limit < 4) 
    if (first_stat) {                          // поскольку в init() не гарантируется наличие актуальных данных, считаем статистику 
      
       DiffTime = TimeLocal() - (iTime(NULL,0,0)+(5*3600));                             // -5 часов (18000 сек) - разность поясов
       DiffTime1 = TimeCurrent() - Time[0];                                             // разница между последней котировкой и текущим баром
       Print(" Time difference DiffTime Stat (sec): ", DiffTime, " DiffTime1: ",DiffTime1," limit ",limit);    // для отладки и понимания 
       if ((TFPeriod > DiffTime) && (DiffTime > 0) && (DiffTime1 < TFPeriod)) {         // где TFPeriod - величина расхождения времени
         InitFiles();
         OptimizationDHP(0);
         StatInit(Bars_for_Stats, 0, 3);                                            
         first_stat = false; }
...
но даже эти условия не гарантируют вам факта актуальности данных. А самой надежной конструкцией, в данном случае, оказалась банальная задержка:
   if (First_Run == 0) { 
       First_Run = TimeLocal();  
   } else {
       Delay_run = TimeLocal() - First_Run;
       if (Delay_run < 10) {return;}                            // Задержка в 10 сек
Вероятно значения временных функцих и переменных (типа TimeCurrent(), Time[0] и пр.) присваиваются раньше, чем это происходит фактически. IndicatorCounted() не исключение...

Так что из полезных свойств:

Из полезных свойств IndicatorCounted() :
- значение ноль при подключении индюка;
- определение первого тика нового бара, для повторного пересчета предыдущего.
последнее можно смело убирать ))). Если котировки приходят нормально, без задержек и пропусков - это будет работать. А вот если нет, могут быть множественные варианты событий )). Лично я, проведя серию исследований и экспериментов, теперь использую конструкцию типа: 
if( LastBar != Time[0]) {
   ...
   LastBar = Time[0];}

Наверно код МТ тестировался на медленных машинах ))) или вопросами синхронизации процессов никто не грел голову...

 
Сказывается особенность подгрузки исторических данных. В это время текущие уже загружены обычно, точнее, они загружаются раньше. Потом загружаются недалекое прошлое. В это время функция IndicatorCounted() работает некорректно. После загрузки функция возвращает не всегда корректное значение. Но на следующем тике обычно все исправляется.
 

Я пришел к использованию конструкции, где выполнение условия Bars-IndicatorCounted() > 2 (кроме первого вызова start(), разумеется), ведет к переинициализации индикатора и пересчету истории заново. Т.е., если Bars-IndicatorCounted() >2, это означает, что есть пропущенные бары (или бар). Причем хрен знает где и определенно сказать, что было (почему ф-я вышла за рамки штатной задержки за Bars), не представляется возможным. Потому лучше переинициализиоровать и пересчитать индикатор. Конструкция такова:

bool first=1;

int start()
  {
   int ic=IndicatorCounted();
   if(!first && Bars-ic>2) ic=reinit(); // если есть пропущенные бары не на момент присоединения инд-ра
   
   int limit=Bars-ic-1;
   for(int i=limit; i>=0; i--) {
      //----
      // цикл пересчета
      //----
     }
   first=0;
   return(0);
  }
//+------------------------------------------------------------------+
int reinit() { // дополнительная инициализация
   // то, что необходимо переинициализировать при пересчете:
   // индикаторные массивы, общие и стат. переменные (последние нужно передавать в ф-ю)
   // удаление граф. объектов, обнуление их счетчика
   // и т.д.
   return(0);
  }
 

))) Вообще, эта тема была мной открыта, когда я только познакомился с MQL4. Перепробовал много конструкций, в т.ч. и без IndicatorCounted(), но варианты с отслеживанием Bars и его предыдущего состояния (или по времени) хоть и давали возможность пересчитать только необходимое кол-во последних пропущенных баров, но нисколько не гарантировали от ошибок работы индикатора, если история была изменена по другому.

Нигде (я искал!) мне не удалось найти четкое и однозначное описание логики работы IndicatorCounted(). Преположение, что =0, когда или история отсутсвует (собсвенно, не преположение, а это так написано), или когда пропущено более чем ??? последних баров, или когда есть изменения истории не на последних барах, выглядит правдоподобно. Во всяком случае, конструкция выше работает без сбоев. А вот есть ли какие-то промежуточные значения в случях кроме указанных, я даже выяснять не стал. Не вижу практического смысла. Т.е. значения, не равные 0 и Bars-IndicatorCounted() > 2, я никак не интерпретирую и не использую.

Интерпретирую! В том смысле, что если такие значения появились, то я все пересчитываю заново.

Такие дела...

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