Любой вопрос новичка, чтоб не захламлять форум. Профи, не проходите мимо. Без вас никуда - 6. - страница 600

 

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

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

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?

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

 
Expert:

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

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


Этим всё сказано. На примерно такой код, примерно такой ответ... писать?
 
peace1984:
Это мой первый опыт, строго не судите:)
Честно говоря, мне кажется, что в тестере запоминается прошлое значение переменной - с прошлого теста. Каким образом - ХЗ, времени мало на разборы полётов. Может баг терминала. Просто вставил в код комментарий и вывод значений в журнал. Выходит так, что при каждом новом запуске теста в переменной sys сохраняется значение из предыдущего теста. Фигня какая-то. Мож кто ещё увидит, мож глаз замылился у меня...
Файлы:
11_1.mq4  8 kb
 
AlexeyVik:
Этим всё сказано. На примерно такой код, примерно такой ответ... писать?


Дело в том, что остальной код не имеет значения. Суть ошибки описана в этом куске.
Вообще боялся отпугнуть людей большим постом. И так раздул его.

Если коротко, то можно так сформулировать: Если расчет индикатор рассчитывается продолжительное время (больше минуты), то IndicatorCounted() постоянно возвращает 0.

 
artmedia70:
Честно говоря, мне кажется, что в тестере запоминается прошлое значение переменной - с прошлого теста. Каким образом - ХЗ, времени мало на разборы полётов. Может баг терминала. Просто вставил в код комментарий и вывод значений в журнал. Выходит так, что при каждом новом запуске теста в переменной sys сохраняется значение из предыдущего теста. Фигня какая-то. Мож кто ещё увидит, мож глаз замылился у меня...

Просто ты забыл о том, что строка

int       sys=(Sys<0)?0:Sys;

при перевызове свойств индикатора выполняться не будет.

Досконально не вникал, но может так будет достигнут желаемый результат?

extern int Sys=0;
int       sys;    // изменено
double    opb;
double    ops;
double    cb;
double    cs;
double    lot;
double    next_order;
int       i=0;
int       x;
double    max;
double    min;
int       ticket;
int       tip;
int       count;
bool      res;
double    bal;
double    sl;
datetime  d;
double    N;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
   sys=(Sys<0)?0:Sys;  // добавлено
   bal=AccountBalance();
   return(0);
  }
 
AlexeyVik:

Просто ты забыл о том, что строка

при перевызове свойств индикатора выполняться не будет.

Досконально не вникал, но может так будет достигнут желаемый результат?



Вообще - советник. Но ХЗ, нет времени на эксперименты. У меня все советники так, как я написал, работают. Надо будет отследить в тестере эту хрень. Когда время будет.
 
Expert:


Дело в том, что остальной код не имеет значения. Суть ошибки описана в этом куске.
Вообще боялся отпугнуть людей большим постом. И так раздул его.

Если коротко, то можно так сформулировать: Если расчет индикатор рассчитывается продолжительное время (больше минуты), то IndicatorCounted() постоянно возвращает 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(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;
}

когда ты заремил выделенную строку??? Телепаты не помогут, а простые смертные и тем-более...

Потом вот эта часть

   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;

я не знаю от какого программиста это пошло, но что-то тут совсем неадекватно написано... Не в твой адрес камень. Ты как многие просто взял код и пытаешься его править...

Если переменная counted_bars равна количеству баров, не измененных после последнего вызова индикатора (первая строка)

То как она может стать меньше нуля что её проверяют if(counted_bars < 0) я никогда не смогу понять...

Дальше тоже чушь но мне уже лениво это разбирать...

 
AlexeyVik:

Просто ты забыл о том, что строка

при перевызове свойств индикатора выполняться не будет.

Досконально не вникал, но может так будет достигнут желаемый результат?




я пробовал так.. не работает..
 
artmedia70:
Вообще - советник. Но ХЗ, нет времени на эксперименты. У меня все советники так, как я написал, работают. Надо будет отследить в тестере эту хрень. Когда время будет.

Ну да, конечно советник. Тогда возникает другой вопрос, а почему советник встал на график в виде подвального индикатора? Но сути не меняет, при перезапуске как индикатора так и советника переменные глобального уровня не переинициализируются и строка int sys=(Sys<0)?0:Sys; не выполняется.
 
peace1984:

я пробовал так.. не работает..
Наверное не совсем так пробовал.
Я только-что перекомпилировал код в советниках и запустил. При изменении параметра Sys в комментарии это значение меняется.
Причина обращения: