Новая версия платформы MetaTrader 4 build 1350 - страница 12

 
Maxim Kuznetsov #:

Ради отстрела пятки сделали венигрет - таймфрейм меняется из индикатора, символ из советника. Ещё поди ресурсы и имена имеются общие. Что вы ожидаете ???

Максим. Все ждут кода, в котором Вы решите проблему. Не нравятся три кнопки, что я дал, далее были примеры с другими продуктами.

Было бы всё просто, не было бы такой глобальной проблемы в сотнях дэшбордах и торговых панелях.

 
Vladislav Andruschenko #:

к сожалению Вы не разобрались в примерах выше. 

Посмотрите их и напишите еще раз, но с полными данными, которые выкладывали не один раз... 

Естественно всё "сделано" как "нужно" 


В примере выше видно, что советник Mooving - стандартный. Без объектов! но в него добавляем ObjectDeleteALL 

В втором индикаторе только 1 объект - кнопка. 

Никаких одинаковых названий. 

Или как тогда объяснить поведение, что OnDeinit - удаляет один объект - и весь терминал зависает наглухо. 

Ну я бы еще поверил, если бы там было +_100500 объектов.

Но пример выше показывает, что это явно "ненормальное поведение терминала"  

Читаем справку,

что физически происходит при переключении таймфрейма ? 1.сохраняется шаблон 2. начинает удалятся советник 3. Удаляются индикаторы (2,3 порядок неопределён, зависит от билда)...загружается шаблон, по нему загружаются индикаторы и советник.
Где-то у вас происходит race - добавляете ObjectsDelete в OnDeinit "стандартного" индикатора, а советник не "отпускает"(или спамит) график, и ждёте пока он освободит ресурс. Что-то вот такое происходит. Возможно в советнике неверно отработана причина reason в OnDeinit или циклы не реагирует на IsStopped 

 
Maxim Kuznetsov #:

Где-то у вас происходит race - добавляете ObjectsDelete в OnDeinit "стандартного" индикатора, а советник не "отпускает"(или спамит) график, и ждёте пока он освободит ресурс. Что-то вот такое происходит. Возможно в советнике неверно отработана причина reason в OnDeinit или циклы не реагирует на IsStopped 

я выше привел пример с Комментом, советник просто очищает комментарий в деините и всё зависает, без удаления объектов и без канвасов и без ресурсов-объектов внутри ЕА.
Стандартный советник из поставки, просто добавьте Коммент и всё, приплыли.

 
Maxim Kuznetsov #:

Читаем справку,

что физически происходит при переключении таймфрейма ? 1.сохраняется шаблон 2. начинает удалятся советник 3. Удаляются индикаторы (2,3 порядок неопределён, зависит от билда)...загружается шаблон, по нему загружаются индикаторы и советник.
Где-то у вас происходит race - добавляете ObjectsDelete в OnDeinit "стандартного" индикатора, а советник не "отпускает"(или спамит) график, и ждёте пока он освободит ресурс. Что-то вот такое происходит. Возможно в советнике неверно отработана причина reason в OnDeinit или циклы не реагирует на IsStopped 


Я прекрасно понимаю, что "объем" данных "может" повлиять на лаги. 

Но в данном случае: всего лишь 1 объект. И зависание постоянное = 100% раз при использовании сразу и эксперта и индикатора. 

Т.е. если бы это было случайно - то и ладно, можно списать на огромное количество объектов.

Но объект всего лишь 1 и зависание 100% всегда. 

И если дело в своих разработках, то передать контрол управления не проблема. 

Но реалии диктуют, что разработки от сотни тысяч авторов, не совмещаются на МТ4 100% при использовании этой функции. 

Возникает конфликт.

И Если с эксперта эта функция вызывается нормально - без глюков! То с индикатора происходит зависание! 

 
Taras Slobodyanik #:

Нашел ошибку, это из-за строки Comment(""); при деините.

Можно проверить на стандартном эксперте Moving Average.mq4, просто добавляем:

и всё, подвисание гарантировано.
если убираем, то всё работает ок.

Это было бы очень странно...

Проверил на всякий случай именно с Moving Average. Ничего не виснет. Видимо, есть что-то еще. Уточните, все шаги для воспроизведения, пожалуйста.

 
Ihor Herasko #:

Это было бы очень странно...

Проверил на всякий случай именно с Moving Average. Ничего не виснет. Видимо, есть что-то еще. Уточните, все шаги для воспроизведения, пожалуйста.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Новая версия платформы MetaTrader 4 build 1350

Vladislav Andruschenko, 2021.11.15 17:07

Теперь как минимум нас 3, которые видят этот явный баг, который возник примерно год назад... 

Сейчас еще кто-нибудь "поймет" 


Например у меня в эксперте, если отключить все удаление объектов и обращение к ChartSet/Get..... то зависания нет ))))

т.е. проблема явная в ChartSetSymbolPeriod в индикаторах, при ее использовании - эксперт деинициализируется и снова не инициализируется (Если в нем есть Работа с чартом и объектами.)

Для воспроизведения:

Индикатор PrototypeCanvasMulti_IND_dn.mq4 Нанести на график

В стандартный советник (любой) добвить:

void OnDeinit(const int reason)
       {
        ObjectsDeleteAll(0,"");
       }

При нажатии на кнопку DN - происходит зависание. 


Это повторяется с любыми парами : Эксперт + индикатор (С функций переключения графика ТФ/Символа )

Уважаемая Администрация @MetaQuotes Пожалуйста, обратите на это внимание. 


 
Ihor Herasko #:

Это было бы очень странно...

Проверил на всякий случай именно с Moving Average. Ничего не виснет. Видимо, есть что-то еще. Уточните, все шаги для воспроизведения, пожалуйста.

что мы все здесь обсуждаем?)

Как я писал выше:

возьмите индикаторы которые выложил Vitaliy Kuznetsov, и стандартный эксперт, добавьте в него строку и вы все сами увидите.
без "коммента" всё переключается отлично

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

 

Увы, понять проблему могут только те, кто постоянно с этим работает. 

Для всех остальных надо что-то доказывать, показывать, рисовать, разъяснять.... 

А времени то не хватает :-) 

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

Боюсь, что она также утонет в сотнях сообщениях - попытках что-то доказать.... 

 
Vladislav Andruschenko #:

Проверил. Да, зависает. Но пример слишком неочевиден. Лучше сделать вот такую тестовую подборку.

Советник Test_Expert:

#property strict

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() 
{
   Print(__FUNCTION__);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) 
{
   Print(__FUNCTION__, ", Enter");
   ObjectsDeleteAll(0);   
   Print(__FUNCTION__, ", Exit");
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() 
{
}
//+------------------------------------------------------------------+

Индикатор Test:

#property strict
#property indicator_chart_window
#property indicator_plots 0

#define MY_RECT                  "TEST_RECT"

string   g_arrSymbols[] = {"GBPUSD", "EURUSD"};

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{   
   Print(__FUNCTION__);
   ShowRectangle(MY_RECT, Time[1], High[1], Time[10], Low[10], "Click here", clrRed);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{        
   ObjectDelete(0, MY_RECT);
   Print(__FUNCTION__);   
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   return(rates_total);
}

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   if (id == CHARTEVENT_OBJECT_CLICK && sparam == MY_RECT)
      ChartSetSymbolPeriod(0, (Symbol() != g_arrSymbols[0])? g_arrSymbols[0] : g_arrSymbols[1], PERIOD_CURRENT);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Отображение прямоугольника                                                                                                                                                                        |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowRectangle(string sName, datetime dtTime1, double fPrice1, datetime dtTime2, double fPrice2, string sTooltip, color clrColor, bool bIsBack = true, int nWidth = 0, ENUM_LINE_STYLE eStyle = STYLE_SOLID)
{
   if (ObjectFind(0, sName) < 0)
   {
      ObjectCreate(0, sName, OBJ_RECTANGLE, 0, dtTime1, fPrice1, dtTime2, fPrice2);
      ObjectSetInteger(0, sName, OBJPROP_BACK, bIsBack);
      ObjectSetInteger(0, sName, OBJPROP_WIDTH, nWidth);
      ObjectSetInteger(0, sName, OBJPROP_STYLE, eStyle);
      ObjectSetInteger(0, sName, OBJPROP_HIDDEN, true);
      ObjectSetInteger(0, sName, OBJPROP_SELECTABLE, false);
   }
   
   ObjectMove(0, sName, 0, dtTime1, fPrice1);
   ObjectMove(0, sName, 1, dtTime2, fPrice2);
   ObjectSetInteger(0, sName, OBJPROP_COLOR, clrColor);
   ObjectSetString(0, sName, OBJPROP_TOOLTIP, sTooltip);
}

//+------------------------------------------------------------------+

Для воспроизведения:

  1. Запустить советник и индикатор на одном графике. 
  2. Произвести клик левой клавишей мыши на красном прямоугольнике (на одной из пяти его опорных точек). 
Получится, хоть и недолгое, но зависание. В журнале видно следующее:

2021.11.16 09:30:49.006 Test_Expert EURUSD,H1: OnDeinit, Exit
2021.11.16 09:30:39.368 Test_Expert EURUSD,H1: OnDeinit, Enter
2021.11.16 09:30:39.368 Test_Expert EURUSD,H1: uninit reason 3

Эксперт выполнял удаление объектов почти 10 секунд. Таким образом, проблема имеется. Возникает вопрос: что при этом произошло с индикатором? Ведь о его действиях в журнале ничего нет. Его объект бесследно исчез. Новые попытки запустить индикатор, не выгружая, ни к чему не приводят. Нужно только удалить индикатор с графика и присоединить заново.

Думаю, тут проблема в синхронизации потоков: эксперт (отдельный поток) получает сообщение о переключении графика и начинает выполнять удаление единственного объекта, но ему каким-то образом мешает поток индикатора (он же - GUI терминала). К чести терминала, получившийся dead lock (если это действительно он), со временем раскрывается, что и позволяет терминалу продолжить работу, хоть и с небольшим подвисанием.

 
Taras Slobodyanik #:

что мы все здесь обсуждаем?)

Как я писал выше:

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

Для описания проблемы, если Вы действительно заинтересованы в ее решении, лучше приводить выхолощенные коды. В коде больше 100 строк никто разбираться не будет.

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