Init() выполняется не дождавшись данных - страница 3

 
TheXpert >>:
Гениальностью не страдаю, в отличие от некоторых :) .

Сам дурак!!!)))

Все? Закончили? (Извинений за ваш тон в наезде "не по делу" об init() не требую - проехали)

 
Svinozavr >>:

Послал бы я тебя на х@й, да воспитание не позволяет :).

alsu >>:

остальные 10% включают вариант

по-моему тоже работает:)

Нет. Собсно, по делу. Реализуем простенький советник.

//+------------------------------------------------------------------+
//|                                                    InitCheck.mq4 |
//+------------------------------------------------------------------+

extern bool InitInInit = false;

bool FirstRun = true;

int init()
{
   if (InitInInit)
   {
      FirstRun = true;
   }
      
   return(0);
}

int start()
{
   Print ("FirstRun = ", FirstRun, " InitInInit = ", InitInInit);
   FirstRun = false;
   
   return(0);
}

Запускаем. Смотреть снизу вверх.

2009.09.03 16:32:29 InitCheck EURUSD,M1: FirstRun = 0 InitInInit = 0
2009.09.03 16:32:28 InitCheck EURUSD,M1: FirstRun = 0 InitInInit = 0 (вот она, засада)
2009.09.03 16:32:25 InitCheck EURUSD,M1: initialized
2009.09.03 16:32:25 InitCheck EURUSD,M5: uninit reason 3
2009.09.03 16:32:24 InitCheck EURUSD,M5: FirstRun = 0 InitInInit = 0
2009.09.03 16:32:21 InitCheck EURUSD,M5: FirstRun = 1 InitInInit = 0
2009.09.03 16:32:18 InitCheck EURUSD,M5 inputs: InitInInit=false;
2009.09.03 16:32:18 InitCheck EURUSD,M5: initialized
2009.09.03 16:32:18 InitCheck EURUSD,M5: loaded successfully
2009.09.03 16:32:18 InitCheck EURUSD,M5: uninit reason 2
2009.09.03 16:32:17 InitCheck EURUSD,M5: FirstRun = 0 InitInInit = 1
2009.09.03 16:32:17 Compiling 'InitCheck'
2009.09.03 16:32:16 InitCheck EURUSD,M5: FirstRun = 0 InitInInit = 1
2009.09.03 16:32:05 InitCheck EURUSD,M5: FirstRun = 0 InitInInit = 1
2009.09.03 16:32:00 InitCheck EURUSD,M5: FirstRun = 1 InitInInit = 1 (тут все классно)
2009.09.03 16:32:00 InitCheck EURUSD,M5: initialized
2009.09.03 16:31:59 InitCheck EURUSD,M1: uninit reason 3
2009.09.03 16:31:57 InitCheck EURUSD,M1: FirstRun = 0 InitInInit = 1
2009.09.03 16:31:51 InitCheck EURUSD,M1: FirstRun = 0 InitInInit = 1
2009.09.03 16:31:50 InitCheck EURUSD,M1: FirstRun = 1 InitInInit = 1
2009.09.03 16:31:47 InitCheck EURUSD,M1 inputs: InitInInit=true;
2009.09.03 16:31:47 InitCheck EURUSD,M1: initialized

 
TheXpert >>:

Послал бы я тебя на х@й, да воспитание не позволяет :).

Извинения приняты...)))

 

Проблема "старых" данных решаема. Об этом я как-то писал на примере функции . В случае функции Bars достаточно воспользоваться ее "старшей сестрой" - функцией iBars, и использовать такую вот конструкцию:

   Comment("Подождите, идет сбор данных...");
   int P = 0;
   while (P < 120)
     {
      NowDay = iBars(Symbol(), 0);
      if (GetLastError() != 4066) break;
      P++;
      Sleep(1000);
     } 
   if (P == 120)
     {
      Comment("Не удалось получить данные по количеству баров. Советник отключен!");
      Print("Не удалось получить данные по количеству баров. Советник отключен!");
      return(0);
     }
   Comment("");   
 
TheXpert >>:

Послал бы я тебя на х@й, да воспитание не позволяет :).

Нет. Собсно, по делу. Реализуем простенький советник.

Запускаем. Смотреть снизу вверх.


Спасибо ребята, что начали обсуждение этого вопроса, но давайте ка я на правах топикстартера призову вас к уважению друг друга! Это первое.

Второе. Решение которое предложил Svinozavr рабочее и приходило мне в голову. Однако хочется более элегантного решения, а не изворачиваться как можем. Это камень в огород разработчиков MQL4

Третье. В последнем коде, представленным TheXpert единственное присвоение значения переменной InitInInit происходит только при ее инициализации. И значение ей присваивается ЛОЖЬ. И НИГДЕ более по коду нет присвоения ей другого значения! Следовательно, в листинге логов строка "2009.09.03 16:31:47 InitCheck EURUSD,M1 inputs: InitInInit=true;" не могла появиться! TheXpert либо предоставил нам не тот код, что хотел, либо пытается нас ввести в заблуждение. Дополнительно хочу сказать, что отсутствие данных проявляется только в определенном случае, описанном в первом посте.

Четвертое. Scriptong предложил ожидать 2 минуты, а почему не 5 или 10? Я ждал 1 минуту и данные не пришли. Далее вопрос Scriptong: чем принципиально отличается получение данных через переменную Bars и функцию iBars()? Ведь и там и там одни и те же данные в одно и тоже время получаются от терминала. Так же решение, предложенное Scriptong, не приведет к желаемому результату. Мы лишь сможем узнать об ошибке исполнения, но не сможем обойти ее. Нужно каким-то образом получить правильные данные в случае ошибки. А ведь они эти данные приходят с функцией START(). Таким образом отсутствие данных имеет место только при инициализации, и из-за этого останавливать программу?

 
KI-trader >>:

Четвертое. Scriptong предложил ожидать 2 минуты, а почему не 5 или 10? Я ждал 1 минуту и данные не пришли. Далее вопрос Scriptong: чем принципиально отличается получение данных через переменную Bars и функцию iBars()? Ведь и там и там одни и те же данные в одно и тоже время получаются от терминала. Так же решение, предложенное Scriptong, не приведет к желаемому результату. Мы лишь сможем узнать об ошибке исполнения, но не сможем обойти ее. Нужно каким-то образом получить правильные данные в случае ошибки. А ведь они эти данные приходят с функцией START(). Таким образом отсутствие данных имеет место только при инициализации, и из-за этого останавливать программу?

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

Две минуты выбраны эмпирически. Этого времени хватает практически на любом медленном канале для обновления данных.

Отличие Bars от iBars точно такое же, как MarketInfo(Symbol(), MODE_BID) от Bid. Знаете, чем они отличаются? Ведь отличие есть и существенное.

 
KI-trader >>:

Проблема в том, что функция INIT() выполняется, не получив данные.


Внимание вопрос: Как программно это обойти?


Init и deinit выполняются всегда, когда меняется таймфрейм или меняются параметры индикатора. Это не проблема, это так было задумано.

Если Вы хотите дождаться загрузки данных, а уже потом начинать работать, то нужно в функции start дождаться момента, когда IndicatorCounted перестанет меняться:



int bar_count;


//+------------------------------------------------------------------+
int init(){
    bar_count = 0;
    //----
    return(0);
    }


//+------------------------------------------------------------------+
int start(){
    int counted_bars;

    //----
    counted_bars = IndicatorCounted();
    if(counted_bars <= 0)
        return(0);
    else if(counted_bars != bar_count){
        bar_count = counted_bars;
        return(0);
        }
    else{
        // здесь все данные уже загружены
        ....
        }

    //----
    return(0);
    }


 

TheXpert!

Т.е. получается, что при смене тайм-фрейма в эксперте операции присвоения объявленных в голове переменных не происходит! Я проверил. Это - бредовая реальность. Из значения запоминаются и не сбрасываются по uninit=3! Именно запоминаются, а не обнуляются - я инвертировал логику first. Но если объявить эту переменную как extern, то все канает. Вот проверочный код эксперта:

// советник
extern bool EnableMyInit=1;
extern bool first=1;

first=1;

int init() {
   if(EnableMyInit) return(0);
   Print("init()!!! Bars=",Bars," Period=",Period());
   return(0);
  }

int my_init() {
   if(!first || !EnableMyInit) return(0);
   first=0;
   Print("my_init()!!! Bars=",Bars," Period=",Period());
   return(0);
  }

int start()
  {
   my_init();
   return(0);
  }

А может, так и было задумано? Ну, типа, стат. переменные при смене тайм-фрейма не переинициализируются спецом. Хотя зачем?

==========

З.Ы. В индикаторах такого не происходит.

Кстати. Бары совершенно корректно определяются в init() эксперта при смене тайм-фрейма.

А вообще, кто забыл, речь шла изначально про индикаторы.)))

 
Scriptong >>:

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

Две минуты выбраны эмпирически. Этого времени хватает практически на любом медленном канале для обновления данных.

Отличие Bars от iBars точно такое же, как MarketInfo(Symbol(), MODE_BID) от Bid. Знаете, чем они отличаются? Ведь отличие есть и существенное.


Bars содержит данные ТЕКУЩЕГО инструмента на ТЕКУЩЕМ тайм-фрейме, в отличии от iBars(), которая вернет данные ЛЮБОГО инструмента на ЛЮБОМ тайм-фрейме. Вот и все разница! А мне надо что бы функция INIT() выполнилась после получения данных терминалом! Если данных нет, то и Bars и iBars() вернут НОЛЬ!


piterpen >>:

Init и deinit выполняются всегда, когда меняется таймфрейм или меняются параметры индикатора. Это не проблема, это так было задумано.

Если Вы хотите дождаться загрузки данных, а уже потом начинать работать, то нужно в функции start дождаться момента, когда IndicatorCounted перестанет меняться:

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

Вы предложили решение при котором ОПЯТЬ выполнение кода, предназначенного для функции INIT() происходит в функции START().

Я уже писал:

Второе. Решение которое предложил Svinozavr рабочее и приходило мне в голову. Однако хочется более элегантного решения, а не изворачиваться как можем. Это камень в огород разработчиков MQL4

Говоря Вашими словами хочется, что бы IndicatorCounted перестал меняться еще в функции INIT().

 
KI-trader >>:


Говоря Вашими словами хочется, что бы IndicatorCounted перестал меняться еще в функции INIT().

Странный подход к жизни. Есть некая данность. Вам хочется, чтобы было по-другому. И что? Вы в силах создать свой торговый терминал и свой язык типа MQL?

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