Скачать MetaTrader 5

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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Denis Lysenko
5563
Denis Lysenko  

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

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

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?

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

Victor Nikolaev
Модератор
14972
Victor Nikolaev  

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

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;
}
Vladyslav Goshkov
2148
Vladyslav Goshkov  
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 минуты
Denis Lysenko
5563
Denis Lysenko  
VladislavVG:

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


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

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

Denis Lysenko
5563
Denis Lysenko  
Vinin:

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


Сделал по Вашему совету - результат не изменился.
Алексей Тарабанов
7328
Алексей Тарабанов  

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

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

Mislaid
609
Mislaid  
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);
}
//+------------------------------------------------------------------+
Mislaid
609
Mislaid  
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

Алексей Тарабанов
7328
Алексей Тарабанов  
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


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

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

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

#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
Alexey Viktorov
10405
Alexey Viktorov  
Expert:

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

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

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

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