Новая версия платформы MetaTrader 5 build 2085: Интеграция с Python и массовые улучшения в тестере стратегий - страница 44

 

С какой-то версии (сейчас смотрю на 2093) следующий код, размещенный в эксперте, всегда возвращает признак несинхронизированности (0, false) при нахождении онлайн и поступлении тиков:

void OnTick()
{
  Comment(TimeCurrent() + " Sync=" + SeriesInfoInteger(_Symbol, _Period, SERIES_SYNCHRONIZED));
}

Баг? Как теперь делать проверку?

Файлы:
sync.mq5  1 kb
 
Stanislav Korotky:

С какой-то версии (сейчас смотрю на 2093) следующий код, размещенный в эксперте, всегда возвращает признак несинхронизированности (0, false) при нахождении онлайн и поступлении тиков:

Баг? Как теперь делать проверку?

я не стал изобретать велосипед и взял код из примера MQ, сделал небольшую "косметику" и воткнул в утилитный класс:

/*!
   \brief   Универсальное получению данных
   \param   const string symbol
   \param   const ENUM_TIMEFRAMES period
   \param   const datetime start_date
   \return  код завершения
*/
static int CCheck::CheckLoadHistory(string symbol,ENUM_TIMEFRAMES period,datetime start_date) { 
   datetime first_date = 0;
   datetime times[100];
//--- check symbol & period 
   if(symbol == NULL || symbol == "")
      symbol = Symbol(); 
   if(period == PERIOD_CURRENT)
      period = Period(); 
//--- check if symbol is selected in the MarketWatch 
   if(!SymbolInfoInteger(symbol, SYMBOL_SELECT)) { 
      if(GetLastError() == ERR_MARKET_UNKNOWN_SYMBOL)
         return(-1); 
      SymbolSelect(symbol, true); 
   }
//--- check if data is present 
   SeriesInfoInteger(symbol, period, SERIES_FIRSTDATE, first_date); 
   if(first_date > 0 && first_date <= start_date)
      return(1); 
//--- don't ask for load of its own data if it is an indicator 
   if(MQL5InfoInteger(MQL5_PROGRAM_TYPE) == PROGRAM_INDICATOR && Period() == period && Symbol() == symbol) 
      return(-4); 
//--- second attempt 
   if(SeriesInfoInteger(symbol, PERIOD_M1, SERIES_TERMINAL_FIRSTDATE, first_date)) { 
      //--- there is loaded data to build timeseries 
      if(first_date > 0) {
         //--- force timeseries build 
         CopyTime(symbol, period, first_date + PeriodSeconds(period), 1, times); 
         //--- check date 
         if(SeriesInfoInteger(symbol, period, SERIES_FIRSTDATE, first_date)) 
            if(first_date > 0 && first_date <= start_date)
               return(2); 
      }
   } 
//--- max bars in chart from terminal options 
   int max_bars = TerminalInfoInteger(TERMINAL_MAXBARS); 
//--- load symbol history info 
   datetime first_server_date = 0; 
   while(!SeriesInfoInteger(symbol, PERIOD_M1, SERIES_SERVER_FIRSTDATE, first_server_date) && !IsStopped()) 
      Sleep(5);
//--- fix start date for loading 
   if(first_server_date > start_date) start_date = first_server_date; 
   if(first_date > 0 && first_date < first_server_date) 
      Print("Warning: first server date ", first_server_date, " for ", symbol, " does not match to first series date ", first_date); 
//--- load data step by step 
   int fail_cnt = 0; 
   while(!IsStopped()) {
      //--- wait for timeseries build 
      while(!SeriesInfoInteger(symbol, period, SERIES_SYNCHRONIZED) && !IsStopped()) 
         Sleep(5); 
      //--- ask for built bars 
      int bars = Bars(symbol, period);
      if(bars > 0) {
         if(bars >= max_bars)
            return(-2); 
         //--- ask for first date 
         if(SeriesInfoInteger(symbol, period, SERIES_FIRSTDATE, first_date)) 
            if(first_date > 0 && first_date <= start_date)
               return(0); 
      }
      //--- copying of next part forces data loading 
      int copied = CopyTime(symbol, period, bars, 100, times); 
      if(copied > 0) {
         //--- check for data 
         if(times[0] <= start_date)
            return(0); 
         if(bars + copied >= max_bars)
            return(-2); 
         fail_cnt = 0;
      } else {
         //--- no more than 100 failed attempts 
         fail_cnt++; 
         if(fail_cnt >= 100)
            return(-5);
         Sleep(10);
      }
   }
//--- stopped 
   return (-3);
}
/*!
   \brief   Код завершения
   \param   const string a_sy - символ
   \param   const int a_code - код завершения
*/
static void CCheck::CodeComplete(const string a_sy,const int a_code) {
   switch(a_code) 
     { 
      case -1 : Print("Unknown symbol ", a_sy);                       break; 
      case -2 : Print("Requested bars more than max bars in chart "); break; 
      case -3 : Print("Program was stopped ");                        break; 
      case -4 : Print("Indicator shouldn't load its own data ");      break; 
      case -5 : Print("Load failed ");                                break; 
      case  0 : Print("Loaded OK ");                                  break; 
      case  1 : Print("Loaded previously ");                          break; 
      case  2 : Print("Loaded previously and built ");                break; 
      default : Print("Unknown result "); 
     } 
}

теперь вызываю в нужном классе в конструкторе так:


и проблем не возникает с историей

 
Konstantin:

я не стал изобретать велосипед и взял код из примера MQ, сделал небольшую "косметику" и воткнул в утилитный класс:

теперь вызываю в нужном классе в конструкторе так:


и проблем не возникает с историей

При чем тут велосипед? Был приведен минимальный пример для воспроизведения проблемы.

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

 
Stanislav Korotky:

При чем тут велосипед? Был приведен минимальный пример для воспроизведения проблемы.

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

а я об этом прямо и написал не скрывая, что не стал изобретать велосипед и взял код от MQ, вы прочтите сам код и разберитесь как он работает и почему там вместо одного вызова как у вас

SeriesInfoInteger(_Symbol, _Period, SERIES_SYNCHRONIZED)

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

 
Konstantin:

а я об этом прямо и написал не скрывая, что не стал изобретать велосипед и взял код от MQ, вы прочтите сам код и разберитесь как он работает и почему там вместо одного вызова как у вас

А зачем разбираться в сложном коде, когда есть простое противоречие:

void OnTick()
{
   Comment((bool)SeriesInfoInteger(Symbol(), 0, SERIES_SYNCHRONIZED) + ":"
                                               SymbolIsSynchronized(Symbol()));
}

Результат:    false:true

 
Konstantin:

а я об этом прямо и написал не скрывая, что не стал изобретать велосипед и взял код от MQ, вы прочтите сам код и разберитесь как он работает и почему там вместо одного вызова как у вас

SeriesInfoInteger(_Symbol, _Period, SERIES_SYNCHRONIZED)

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

Вы сами разберитесь - приведенная вами "простыня" использует то же самое API и зациклится из-за того, что выделенная функция всегда возвращает false и вызывается в цикле while. Циклится, по крайней мере, в билде 2093, потому что в билде 1940 все нормально работает.

 

В новом билде часто начинается стремительная утечка памяти в Метаэдиторе. Сжирает всю оперативную память и зависает.  Сначала думал что это на каком-то определённом файле, но оказалось что на разных.

 
Stanislav Korotky:

Вы сами разберитесь - приведенная вами "простыня" использует то же самое API и зациклится из-за того, что выделенная функция всегда возвращает false и вызывается в цикле while. Циклится, по крайней мере, в билде 2093, потому что в билде 1940 все нормально работает.

класс, будем считать, что весь мой код постоянно в зацикленном состоянии, просто поверьте на слово - всегда все стартует без зацикливаний, проблем с историей нет

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

В новых билдах наконец появился namespace - это конечно радует.  Вот только Метаэдитор не видит их. Всплывающие подсказки не появляются ни для самого namespace, ни для его внутренних членов.  Точнее подсказки для членов появляются только если перед ними не указан namespace:


Но такой код естественно не скомпилируется.  Так что что пока пользоваться проблематично.  Особенно при импорте из C#, т.к. там почти всё в namespace. Придётся вслепую набирать все методы и классы.

 
Alexey Navoykov:

В новых билдах наконец появился namespace - это конечно радует.  Вот только Метаэдитор не видит их. Всплывающие подсказки не появляются ни для самого namespace, ни для его внутренних членов.  Точнее подсказки для членов появляются только если перед ними не указан namespace:


Но такой код естественно не скомпилируется.  Так что что пока пользоваться проблематично.  Особенно при импорте из C#, т.к. там почти всё в namespace. Придётся вслепую набирать все методы и классы.

вау, наконец то скоро реализуют о чем просили ))