Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 2496

 
Aleksandr Slavskii #:

Если таймер уже прибит значит индикатор уже рассчитан и его не надо рассчитывать по новой.

В индикаторе есть условие, что при prev_calculate == 0 нужно инициализировать буферы?

 
Artyom Trishkin #:

В индикаторе есть условие, что при prev_calculate == 0 нужно инициализировать буферы?

Да какая разница?

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

К тому же индикатор не советник, в нём OnInit срабатывает при каждом чихе, а значит будет по новой включаться таймер.

 
Aleksandr Slavskii #:

Да какая разница?

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

К тому же индикатор не советник, в нём OnInit срабатывает при каждом чихе, а значит будет по новой включаться таймер.

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

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

UPD. Опять таки, если индикатору для расчёта необходимы данные с иного периода графика, то все нужные таймсерии необходимо удерживать - обращаться к ним не реже одного раза в две минуты. Тут тоже нужен таймер.
 
Artyom Trishkin #:

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

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

Хорошо. Спасибо. Статью перечитывать некогда, хоть там наверняка есть красивое решение.

Для себя с учётом вами сказанного, исправил код так, перенёс запуск таймера из OnInit() в OnCalculate()

int priv = 0;
//+------------------------------------------------------------------+
int OnInit()
  {
// код
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
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[])
  {
   priv = prev_calculated;

   if(prev_calculated <= 0)
     {
      EventSetTimer(1);
     }
     
   if(iBarShift(_Symbol, PERIOD_CURRENT, time[rates_total - 18]) < 0)
     {
      Print("iBarShift < 0");
      return prev_calculated;
     }

   return(rates_total);
  }
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(priv <= 0)//если выходные и нет новых тиков
     {
      Print(__FUNCTION__, " Set");
      ChartSetSymbolPeriod(0, _Symbol, PERIOD_CURRENT);
     }
   else
     {
      EventKillTimer();
      Print(__FUNCTION__, " KillTimer");
     }
  }
//+------------------------------------------------------------------+

При переключении таймфреймов получаю вот

HO      0       14:25:24.206    ChartSetSymbolPeriod (GBPUSD,H4)        OnTimer KillTimer
MH      0       14:25:26.315    ChartSetSymbolPeriod (GBPUSD,M15)       iBarShift < 0
HM      0       14:25:27.316    ChartSetSymbolPeriod (GBPUSD,M15)       OnTimer KillTimer

Ну оно и понятно, сегодня не выходные)))

ЗЫ. Отключил сетевуху и увидел недостатки этого решения. Получается хрень какая то если нет интернета при запуске индикатора.
 

Если кому то интересно, то вот так работает вроде норм)

И с выключенным инетом и с включенным и в моменты включения/выключения.

int priv = 0;
//+------------------------------------------------------------------+
int OnInit()
  {
// код
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
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[])
  {
   if(prev_calculated <= 0)
     {
      EventSetTimer(1);
      priv = 0;
      Print("prev_calculated <= 0");
     }

   if(iBarShift(_Symbol, PERIOD_CURRENT, time[rates_total - 18]) < 0)
     {
      Print("iBarShift < 0");
      return prev_calculated;
     }

   priv = rates_total;

   return(rates_total);
  }
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(priv <= 0)//если выходные и нет новых тиков
     {
      Print(__FUNCTION__, " Set");
      ChartSetSymbolPeriod(0, _Symbol, PERIOD_CURRENT);
     }
   else
     {
      EventKillTimer();
      Print(__FUNCTION__, " KillTimer");
     }
  }
//+------------------------------------------------------------------+
 
Aleksandr Slavskii #:
Хорошо. Спасибо. Статью перечитывать некогда, хоть там наверняка есть красивое решение.

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

 
Aleksandr Slavskii #:

Если кому то интересно, то вот так работает вроде норм)

И с выключенным инетом и с включенным и в моменты включения/выключения.

Для чего вот это?

   if(iBarShift(_Symbol, PERIOD_CURRENT, time[rates_total - 18]) < 0)
     {
      Print("iBarShift < 0");
      return prev_calculated;
     }
 
Artyom Trishkin #:

Для чего вот это?

Да просто проверял как работает.

Когда инета нет и переключаешь между таймфреймами, то iBarShift может выдать -1, вот в этом случае принты показывают как работает весь этот код.

 
Artyom Trishkin #:

Вы делаете репорт об ошибке?

Или Вы пишете программу, где просите указать как обойти ошибки в iBarShift максимально просто без "костылей"?

По-моему, и судя по Вашим постам - второе.

Из полученных ответов думаю есть смысл сделать репорт об ошибке. Куда его нести?

 
Andrei Sokolov #:

Из полученных ответов думаю есть смысл сделать репорт об ошибке. Куда его нести?

В ветку по последней бете терминала.

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

Для примера, поглядите как делает репорты fxsaber

Бета-версия платформы MetaTrader 5 build 4695: расширение поддержки OpenBLAS и общая оптимизация работы - В пятницу 22 ноября будет выпущена обновленная версия платформы MetaTrader 5 в бета-режиме.
Бета-версия платформы MetaTrader 5 build 4695: расширение поддержки OpenBLAS и общая оптимизация работы - В пятницу 22 ноября будет выпущена обновленная версия платформы MetaTrader 5 в бета-режиме.
  • 2024.11.22
  • MetaQuotes
  • www.mql5.com
Для обновления на новый билд платформы MetaTrader 5 достаточно нажать После окончания данного этапа бета-тестирования будет выпущен финальный билд новой платформы MetaTrader 5. автоматическим торговым системам и тестированию торговых стратегий