Последовательность выполнение Init() и DeInit() - страница 20

 
Комбинатор:

при смене тф.

если в индикаторах остается муср в буферах со старого тф, может и на таймеры влияет. ну это так, в качестве пятничного бреда.

Это красивее
 
fxsaber:
Это красивее
При разных диджитах там по ходу везде писец наступает, зарекся скрещивать такие счета в одном терминале еще лет 5 назад.
 
fxsaber:
Это красивее

Это для тех кто говорит о правильной последовательности в МТ4.

Смотрите и понимайте что не всё так красиво в МТ4.

 
fxsaber:
Очередность однозначная же.


Ну где же она однозначная.

Поюзайте этот примитивный пример. И поймете "однозначность" при переключения ТФ.

В этом примере в OnInit создается объект и координатами текущего времени и цены. В OnCalculate этот объек движется вместе с ценой.

В OnDeinit он просто ( что логично) удаляется.

При переключении ТФ выясняется, что объект то появляется, то и исчезает. 
Почему так происходит?
Потому, что иногда OnDeinit старого ТФ удаляет то что уже создано в OnInit нового ТФ. Это что не баг! Что должен должен думать программист, который создал этот пример и не читал данной ветки?

Демонстрация неоднозначности очередности OnInit и OnDeinit


#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {

   datetime t = TimeCurrent();
   double pr  = SymbolInfoDouble(Symbol(),SYMBOL_BID);

   ObjectCreate(0,"InitDeinit",OBJ_ARROW_THUMB_UP,0,t,pr);
   ObjectSetInteger(0,"InitDeinit",OBJPROP_WIDTH,15); 

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ObjectDelete(0,"InitDeinit");
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,      // размер массива price[]
                 const int prev_calculated,  // обработано баров на предыдущем вызове
                 const int begin,            // откуда начинаются значимые данные
                 const double& price[])      // массив для расчета
  {

   datetime t = TimeCurrent();
   double pr  = SymbolInfoDouble(Symbol(),SYMBOL_BID);
   ObjectMove(0,"InitDeinit",0,t,pr);
   return(rates_total);
  }
//+------------------------------------------------------------------+
Файлы:
 
Nikolai Semko:

Ну где же она однозначная.

Про таймер шла речь там.
 
fxsaber:
Про таймер шла речь там.

Какая разница. Можете в Юните вместо создания объекта поставить  EventSetTimer, а в Деюните вместо удаления объекта поставить EventKillTimer. И неопределенности от этого не убавиться, т.к. установленный таймер будет убиваться Деюнитом старого ТФ, причем иногда, а иногда нет. Причем будет еще хуще, т.к. объект хоть видно, а таймер не видно - работает он или не работает.
 

Может уже придумали, не читал все. Если индикатор создает панель, можно использовать глобальную переменную терминала, в ините увеличивать ее значение на 1 и использовать как добавку к именам графических объектов.

У меня другая задача была - сохранить параметры панели, для этого создавал глобальные переменные терминала в деините. Решение проблемы простое - создавать глобальные переменные терминала в ините и обновлять каждую по мере изменения параметров в графической панели. В деините удалять переменные, только если причиной деинициализации является удаление индикатора. 

 
Dmitry Fedoseev

Если индикатор создает панель, можно использовать глобальную переменную терминала, в ините увеличивать ее значение на 1 и использовать как добавку к именам графических объектов.
Костыли это все. Надо просто в терминале сделать правильный порядок и все. Сначала деинит претыдущего экземпляра, и только потом инит нового.
Nikolai Semko:


 Что должен должен думать программист, который создал этот пример и не читал данной ветки?

Полностью согласен. Нечитавшие не узнают об этой особенности и будут убивать свое время пытаясь разобраться. Причем это будут сотни людей... особенно жаль начинающих.

Всего-то и надо - один раз устранить баг и все.

 
Nikolai Semko:

Какая разница. Можете в Юните вместо создания объекта поставить  EventSetTimer, а в Деюните вместо удаления объекта поставить EventKillTimer. И неопределенности от этого не убавиться, т.к. установленный таймер будет убиваться Деюнитом старого ТФ, причем иногда, а иногда нет. Причем будет еще хуще, т.к. объект хоть видно, а таймер не видно - работает он или не работает.
Звучит, как глупость. Таймеры копий индикатора никакого отношения друг к другу не имеют.
 
elibrarius:
Костыли это все. Надо просто в терминале сделать правильный порядок и все. Сначала деинит претыдущего экземпляра, и только потом инит нового.

Полностью согласен. Нечитавшие не узнают об этой особенности и будут убивать свое время пытаясь разобраться. Причем это будут сотни людей... особенно жаль начинающих.

Всего-то и надо - один раз устранить баг и все.


О том и речь!
Я лично в шоколаде, т.к. чувствую свое преимущество перед большинством, т.к. знаю как со всем этим справляться не только на словах, но и на деле. Я уже наделал заплаток и наприкручивал костылей к своим программам.

Мне не понятно только почему разработчики упорно не считают данную "особенность" багом. 
Например:

Slawa:

Индикаторы нужно использовать по прямому назначению.

Иными словами, очерёдность выполнения OnInit и OnDeinit индикатора при смене символа-периода графика не должна никого волновать

Но ведь в приведенном мной выше примере с анимированной гифкой явный баг для программера не читавшего данную тему! Что там сделано не по назначению?