Как советнику перезагрузить себя?

 

Именно перезагрузить, с чтением терминалом ex4-файла, как происходит при новом запуске или при вызове команды "Обновить" из контекстного меню навигатора терминала.

ChartSetSymbolPeriod( NULL, 0 ) не работает.

ChartApplyTemplate работает, но иногда приводит к зависанию старой копии советника и, соответственно, не нормальной загрузке новой (он даже не инициализируется, хотя на график подгружается, это видно по версии файла):

2018.05.21 02:16:57.170 EA EURUSD,Weekly: Trying to apply template...
2018.05.21 02:16:58.328 EA EURUSD,Weekly: ExpertRemove function called
2018.05.21 02:16:58.328 EA EURUSD,Weekly: Done!
2018.05.21 02:17:07.501 EA EURUSD,Weekly: shutdown by timeout
2018.05.21 02:17:16.016 Expert EA EURUSD,Weekly: removed
2018.05.21 02:17:16.032 Expert EA EURUSD,Weekly: loaded successfully


Код такой:

bool Restart()
{
        Print( "Trying to apply template..." );
        if ( !ChartSaveTemplate( ChartID(), "EA" ) )
        {
                Print( "ChartSaveTemplate failed with error #", GetLastError(), "!" );
                return(false);
        }
        Sleep(1000); // Даем время на выполнение асинхронного сохранения шаблона
        if ( !ChartApplyTemplate( ChartID(), "EA" ) )
        {
                Print( "ChartSaveTemplate failed with error #", GetLastError(), "!" );
                return(false);
        }
        ExpertRemove();

        Print( "Done!" );
        return(true);
}


Кроме "Обновления" окна навигатора с помощью ВинАпи идеи есть?

 

Сама идея верна. Проблема лишь в реализации.

Здесь лишнее - ExpertRemove. Да и вообще после ChartApplyTemplate нужно поскорее отдать управление терминалу. Именно из-за этого и возникает аварийная выгрузка советника. 

 
Ihor Herasko:

Сама идея верна. Проблема лишь в реализации.

Здесь лишнее - ExpertRemove. Да и вообще после ChartApplyTemplate нужно поскорее отдать управление терминалу. Именно из-за этого и возникает аварийная выгрузка советника. 

Супер, попробую без Ремува.

 
Andrey Khatimlianskii:

Именно перезагрузить, с чтением терминалом ex4-файла, как происходит при новом запуске или при вызове команды "Обновить" из контекстного меню навигатора терминала.

ChartSetSymbolPeriod( NULL, 0 ) не работает.

А почему не работает ChartSetSymbolPeriod ?

Вот например пример советника с двумя вариантами 

Нажать Ctrl: перезагрузка через ChartSetSymbolPeriod 

Нажать Shift: перезагрузка через ChartApplyTemplate


В первом варианте выполняется OnInit, но не переинициализируются глобальные переменные

А во втором варианте все переинициализируется 

Поэтому можно выбирать, какой вариант нужен.

//+------------------------------------------------------------------+
//|                                                       Reboot.mq4 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int start=0;
int tf;
bool reboot=false;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   if (!reboot) tf=_Period; 
   if(tf!=_Period) ChartSetSymbolPeriod(0,NULL,tf);
   reboot=false;
   Print("Hello "+(string)start);
   start++;
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Print("OnDeinit "+(string)start);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(id==CHARTEVENT_KEYDOWN) 
   {
    if (lparam==17) Reboot();  //ctrl
    if (lparam==16) Restart();  //shift
   }
  }
//+------------------------------------------------------------------+
bool Restart()
  {
   Print("Trying to apply template...");
   if(!ChartSaveTemplate(ChartID(),"EA"))
     {
      Print("ChartSaveTemplate failed with error #",GetLastError(),"!");
      return(false);
     }
   Sleep(1000); // Даем время на выполнение асинхронное сохранение шаблона
   if(!ChartApplyTemplate(ChartID(),"EA"))
     {
      Print("ChartSaveTemplate failed with error #",GetLastError(),"!");
      return(false);
     }
//    ExpertRemove();

   Print("Done!");
   return(true);
  }
//+------------------------------------------------------------------+
void Reboot()
  {
   reboot=true;
   int TF=PERIOD_M5;
   if(tf==TF) TF=PERIOD_M1;
   ChartSetSymbolPeriod(0,NULL,TF);
  }
//+------------------------------------------------------------------+
 
Nikolai Semko:

А почему не работает ChartSetSymbolPeriod ?

... 

В первом варианте выполняется OnInit, но не переинициализируются глобальные переменные

Потому что нужно именно перечитать файл советника с диска, а ChartSetSymbolPeriod этого не делает. 
 
Andrey Khatimlianskii:
Потому что нужно именно перечитать файл советника с диска, а ChartSetSymbolPeriod этого не делает. 

понятно

 
Ihor Herasko:

Сама идея верна. Проблема лишь в реализации.

Здесь лишнее - ExpertRemove. Да и вообще после ChartApplyTemplate нужно поскорее отдать управление терминалу. Именно из-за этого и возникает аварийная выгрузка советника. 

Мысль про ExpertRemove оказалась неверной.

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

EventKillTimer тоже не помог, но сработала связка ExpertRemove с проверкой _StopFlag в начале OnTimer.

 
Для воспроизведения зависания, видимо, достаточно запустить частый таймер. Но я чистовых экспериментов не проводил. Оставлю для энтузиастов.
 

Когда потребуется перезапуститься, нужно вызвать OnInit() и не париться

Это равнозначно перезагрузке и оч.надежно

т.е. просто:

OnInit();


 
Renat Akhtyamov:

Когда потребуется перезапуститься, нужно вызвать OnInit() и не париться

Это равнозначно перезагрузке и оч.надежно

т.е. просто:

OnInit();


Не подойдет, т. к. речь о том, чтобы считать файл ex4 с диска. Такой подход требуется при обновлении программы. Старая копия должна быть выгружена из памяти, а новая загружена. Это как бы две разных программы.

 
Renat Akhtyamov:

Когда потребуется перезапуститься, нужно вызвать OnInit() и не париться

Это равнозначно перезагрузке и оч.надежно

т.е. просто:

OnInit();


Кроме того, что сказал Игорь (а сказал он правильно), вызов ОнИнит отличается от перезапуска советника отсутствием пересоздания глобальных объектов и переменных.

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