Индикаторы: Обработчик события "новый бар" для индикаторов

 

Обработчик события "новый бар" для индикаторов:

В отличии от OnCalculate() расчет индикатора производится только при появлении нового бара на графике.

В статье "Обработчик события "новый бар" описаны все идеи, на которых основан данный обработчик. В самой статье приводится пример обработчика для советников. Здесь я выкладываю вариант для индикаторов.  Суть такая же: все расчеты происходят только при появлении нового бара. Это удобная альтернатива прямому использованию OnCalculate().

Автор: Константин

 
datetime new_time=TimeCurrent()/period_seconds*period_seconds; // Время открытия бара на текущем графике

Здесь ошибка. Если период неделя или месяц.

Если период неделя, то началом недели считается среда, поскольку 1970.01.01 - это четверг.

Если период месяц, и в текущем месяце не 30 дней, то считает тоже неправильно, поскольку period_seconds соответствует 30 дням.

 
Maratori:

Здесь ошибка. Если период неделя или месяц.

Если период неделя, то началом недели считается среда, поскольку 1970.01.01 - это четверг.

Если период месяц, и в текущем месяце не 30 дней, то считает тоже неправильно, поскольку period_seconds соответствует 30 дням. 

Согласен. Для этих периодов в OnNewBarCalculate.mqh можно использовать это:

//+------------------------------------------------------------------+
//| 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[])
  {
//---
   // При появлении нового бара запускаем обработчик события NewBar
   if(current_chart.isNewBar()>0) 
      OnNewBarCalculate(rates_total,prev_calculated,time,open,high,low,close,tick_volume,volume,spread);
   return(rates_total);
  }

 

 

Немного для других целей, но я пока что использую такую функцию:

datetime getHTFTime(datetime time, ENUM_TIMEFRAMES highTimeFrame) {
  int periodSeconds = PeriodSeconds(highTimeFrame);
  if(periodSeconds <= 60*60*24) return datetime(time/periodSeconds*periodSeconds);
  
  MqlDateTime sTime;
  TimeToStruct(time, sTime);
  
  if(highTimeFrame == PERIOD_W1) {
    TimeToStruct(time - datetime(sTime.day_of_week * 24 * 60 * 60), sTime);
    sTime.hour = 0;
    sTime.min = 0;
    sTime.sec = 0;
  } else if(highTimeFrame == PERIOD_MN1) {
      sTime.day = 1;
      sTime.hour = 0;
      sTime.min = 0;
      sTime.sec = 0;
    }
  return StructToTime(sTime);
}

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

Если есть предложения по оптимизации кода, буду рад выслушать.

Конечно можно сделать так:

datetime timeOut[1];
CopyTime(_Symbol, highTimeFrame, timeIn, 1, timeOut);

Но в этом случае у меня возникала проблема синхронизации. Т.е. приходится ждать пока история прогрузится.