Попробуйте проверить этот вариант
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; }
Приветствую! :)
Имеется примерно такой код индикатора:
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 минуты
Как минимум не вешать на минутный график то, что считается 3 минуты
Не получится. Надо получить значения всех минутных барах.
И почему-то мне кажется что дело тут не в барах.
Попробуйте проверить этот вариант
Сделал по Вашему совету - результат не изменился.
Что за переменная bBars?
Весьма вероятно, что ее значение меньше единицы, поэтому нет модификации буферов индикатора,- значение IndicatorCounted() не изменяется.
Что за переменная 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); } //+------------------------------------------------------------------+
Не попадем в цикл никогда, если 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
Вот лог приведенного мной индюка. Там 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 я это назвать не могу )
В соседней ветке обсуждали с человеком.
Чтобы симитировать ситуацию сделал такой индикатор:
В общем, пока что, иначе как багом МТ4 я это назвать не могу )
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Приветствую! :)
Имеется примерно такой код индикатора:
Бросаю на М1 график. Индикатор виснет вместе с терминалом, якобы выполняя расчеты.
Минут через 15 принудительно его закрываю, открываю лог и вижу:
Получается, что индикатор не реагирует на вновь приходящие тики (логично) пока не просчитает первый раз. НО! При просчете забывает сообщить терминалу что IndicatorConted() надо уже присвоить значение отличное от 0.
То есть выходит, что вновь приходящие тики, встающие в очередь на просчет запоминают текущее значение IndicatorCounted()???
Пытался контролировать через переменную busy (закомментированная строка - результат тот же).
Пытался и так:
Естественно на этот раз все работало правильно:
Что же получается? Система не успевает записать в IndicatorCounted() новое значение? То есть надо делать типа sleep() что-то? Знаю что в индикаторе нельзя )
Или по приходу нового тика, так как старый еще не закончил расчеты он запоминает что IndicatorCounte() все еще равен нулю и когда приходит его время начинает считать, исходя из старого значения IndicatourCounted()=0?
В общем как быть? )