IndicatorCounted() постоянно равен нулю =(

 

Приветствую! :)

Имеется примерно такой код индикатора:

bool busy=false;

int start()
{
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   limit=Bars-counted_bars+1;
   limit=MathMin(bBars-1, limit);
   if(IndicatorCounted()>0) limit=1;
   
   FileWrite(han, TimeToStr(TimeCurrent(), TIME_MINUTES|TIME_SECONDS), Bars, IndicatorCounted());
   FileFlush(han);
   //if(busy=false) return(0);
   for (i=0; i<limit; i++)
   { 
      busy=true;
      FileWrite(han, TimeToStr(TimeCurrent(), TIME_MINUTES|TIME_SECONDS), DoubleToStr(i, 0), DoubleToStr(IndicatorCounted(), 0));
      FileFlush(han);
      Здесь идут сложные вычисления которые занимают минуты 3
   }

   busy=false;
}

Бросаю на М1 график. Индикатор виснет вместе с терминалом, якобы выполняя расчеты.
Минут через 15 принудительно его закрываю, открываю лог и вижу:

Pic1

Получается, что индикатор не реагирует на вновь приходящие тики (логично) пока не просчитает первый раз. НО! При просчете забывает сообщить терминалу что IndicatorConted() надо уже присвоить значение отличное от 0.
То есть выходит, что вновь приходящие тики, встающие в очередь на просчет запоминают текущее значение IndicatorCounted()???

Пытался контролировать через переменную busy (закомментированная строка - результат тот же).

Пытался и так:

int start()
{
   FileWrite(han, TimeToStr(TimeCurrent(), TIME_MINUTES|TIME_SECONDS), Bars, IndicatorCounted());
   FileFlush(han);
   return(0);
   .
   .
   .
}

Естественно на этот раз все работало правильно:

Pic2

Что же получается? Система не успевает записать в IndicatorCounted() новое значение? То есть надо делать типа sleep() что-то? Знаю что в индикаторе нельзя )
Или по приходу нового тика, так как старый еще не закончил расчеты он запоминает что IndicatorCounte() все еще равен нулю и когда приходит его время начинает считать, исходя из старого значения IndicatourCounted()=0?

В общем как быть? )

 

Попробуйте проверить этот вариант

bool busy=false;

int start()
{
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   limit=Bars-counted_bars+1;
   limit=MathMin(bBars-1, limit);
   if(counted_bars>0) limit=1;
   
   FileWrite(han, TimeToStr(TimeCurrent(), TIME_MINUTES|TIME_SECONDS), Bars, counted_bars);
   FileFlush(han);
   //if(busy=false) return(0);
   for (i=0; i<limit; i++)
   { 
      busy=true;
      FileWrite(han, TimeToStr(TimeCurrent(), TIME_MINUTES|TIME_SECONDS), DoubleToStr(i, 0), DoubleToStr(counted_bars, 0));
      FileFlush(han);
      Здесь идут сложные вычисления которые занимают минуты 3
   }

   busy=false;
}
 
Expert:

Приветствую! :)

Имеется примерно такой код индикатора:

bool busy=false;

int start()
{
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   limit=Bars-counted_bars+1;
   limit=MathMin(bBars-1, limit);
   if(IndicatorCounted()>0) limit=1;
   
   FileWrite(han, TimeToStr(TimeCurrent(), TIME_MINUTES|TIME_SECONDS), Bars, IndicatorCounted());
   FileFlush(han);
   //if(busy=false) return(0);
   for (i=0; i<limit; i++)
   { 
      busy=true;
      FileWrite(han, TimeToStr(TimeCurrent(), TIME_MINUTES|TIME_SECONDS), DoubleToStr(i, 0), DoubleToStr(IndicatorCounted(), 0));
      FileFlush(han);
      Здесь идут сложные вычисления которые занимают минуты 3
   }

   busy=false;
}

Бросаю на М1 график. Индикатор виснет вместе с терминалом, якобы выполняя расчеты.
Минут через 15 принудительно его закрываю, открываю лог и вижу:

Получается, что индикатор не реагирует на вновь приходящие тики (логично) пока не просчитает первый раз. НО! При просчете забывает сообщить терминалу что IndicatorConted() надо уже присвоить значение отличное от 0.
То есть выходит, что вновь приходящие тики, встающие в очередь на просчет запоминают текущее значение IndicatorCounted()???

Пытался контролировать через переменную busy (закомментированная строка - результат тот же).

Пытался и так:

Естественно на этот раз все работало правильно:


Что же получается? Система не успевает записать в IndicatorCounted() новое значение? То есть надо делать типа sleep() что-то? Знаю что в индикаторе нельзя )
Или по приходу нового тика, так как старый еще не закончил расчеты он запоминает что IndicatorCounte() все еще равен нулю и когда приходит его время начинает считать, исходя из старого значения IndicatourCounted()=0?

В общем как быть? )


Как минимум не вешать на минутный график то, что считается 3 минуты
 
VladislavVG:

Как минимум не вешать на минутный график то, что считается 3 минуты


Не получится. Надо получить значения всех минутных барах.

И почему-то мне кажется что дело тут не в барах.

 
Vinin:

Попробуйте проверить этот вариант


Сделал по Вашему совету - результат не изменился.
 

Что за переменная bBars?

Весьма вероятно, что ее значение меньше единицы, поэтому нет модификации буферов индикатора,- значение IndicatorCounted() не изменяется.

 
tara:

Что за переменная bBars?

Весьма вероятно, что ее значение меньше единицы, поэтому нет модификации буферов индикатора,- значение IndicatorCounted() не изменяется.

Нет, проблема не в ней. Воспроизвести ситуацию не удается. Судя по логу, мы никогда не попадаем внутрь цикла: for (i=0; i<limit; i++) . А это возможно только, если IndicatorCounted() = 0. Как автор этого добился, непонятно.

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

//+------------------------------------------------------------------+
//|                                                          111.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window/
bool busy=false;
int bBars = 0;
// файл отладочной печати
   string tst = "tst";
   int    han;  
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   han = FileOpen( tst, FILE_WRITE | FILE_SHARE_READ | FILE_CSV, ";" );     
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
//---
{
   int counted_bars=IndicatorCounted();
   int i, limit;
   if(counted_bars<0) return(-1);
   limit=Bars-counted_bars+1;
   limit=MathMin(bBars-1, limit);
   if(IndicatorCounted()>0) limit=1;
   
   FileWrite(han, TimeToStr(TimeCurrent(), TIME_MINUTES|TIME_SECONDS), Bars, IndicatorCounted());
   FileFlush(han);
   //if(busy=false) return(0);
   for (i=0; i<limit; i++)
   { 
      busy=true;
      FileWrite(han, TimeToStr(TimeCurrent(), TIME_MINUTES|TIME_SECONDS), DoubleToStr(i, 0), DoubleToStr(IndicatorCounted(), 0));
      FileFlush(han);
//      Здесь идут сложные вычисления которые занимают минуты 3
   }

   busy=false;
  
//--- return value of prev_calculated for next call
   return(0);
}
//+------------------------------------------------------------------+
 
tara:

Не попадем в цикл никогда, если bBars всегда меньше 1.

Вот лог приведенного мной индюка. Там bBars = 0

if(IndicatorCounted()>0) limit=1;

22:39:23;5004;0
22:39:27;5004;5003
22:39:27;0;5003
22:39:30;5004;5003
22:39:30;0;5003
22:39:44;5004;5003
22:39:44;0;5003

 
Mislaid:

Вот лог приведенного мной индюка. Там bBars = 0

if(IndicatorCounted()>0) limit=1;

22:39:23;5004;0
22:39:27;5004;5003
22:39:27;0;5003
22:39:30;5004;5003
22:39:30;0;5003
22:39:44;5004;5003
22:39:44;0;5003


Да, я уже въехал. Интересненько :)
 

В соседней ветке обсуждали с человеком.

Чтобы симитировать ситуацию сделал такой индикатор:

#property indicator_separate_window
#property indicator_buffers 1

double Buffer_1[];

bool busy=false;
int han;

int init()
{
   han=FileOpen("bug log.csv", FILE_CSV|FILE_WRITE);
   SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,1);       
   SetIndexBuffer(0,Buffer_1); 
   return(0);
}

int deinit()
{
   FileClose(han);
   return(0);
}

int start()
{
   //if(busy) return(0);
   int limit=3000;
   if(IndicatorCounted()>0) limit=1;
   
   for (int i=0; i<limit; i++)
   { 
      busy=true;
      FileWrite(han, TimeToStr(TimeCurrent(), TIME_MINUTES|TIME_SECONDS), DoubleToStr(i, 0), DoubleToStr(IndicatorCounted(), 0));
      FileFlush(han);
      
      for(int j=1; j<7000; j++)
        for(int k=1; k<7000; k++)
          double var=2*0.34*MathArccos(0.5)+1.33*MathArcsin(0.23)+1.53*MathArctan(0.11)+2.33*MathCos(0.23)+1.22*MathLog(12)+1.22;
      
      Buffer_1[i]=var;
   }
   
   busy=false;
   return(777);
}

В общем, пока что, иначе как багом МТ4 я это назвать не могу )

Файлы:
bugztest.mq4  2 kb
 
Expert:

В соседней ветке обсуждали с человеком.

Чтобы симитировать ситуацию сделал такой индикатор:

В общем, пока что, иначе как багом МТ4 я это назвать не могу )

Багом можно называть то, что можно повторить на других компьютерах. А твой код, переделанный под новый МЕ у меня работает и ты это видел здесь и код и файл записанный этим кодом. Повторять эксперимент переписывая код под старый стандарт с использованием IndicatorCounted() не имею желания, лучше ты перепиши весь код с учётом требований нового МЕ. Единственное что мне не понравилось, это по 7000 итераций 2 вложенных цикла и я убавил один из них до 700. Тебе лучше подойти к этому вопросу более реально, что ты с барами хочешь сделать? сколько времени должно занимать вычисление одного бара? Функция GetTickCount() поможет определить это время.
Причина обращения: