Обсуждение статьи "Как перенести расчетную часть любого индикатора в код эксперта" - страница 4

 
Aleksey Vyazmikin #:
Из статьи я не понял, есть ли у класса-индикатора защита от пропущенных баров? К примеру произошел разрыв связи на 5 баров, а потом дальше история загрузилась, класс-индикатор перезаполнит только последнее значение в буере или сделает полный перерасчет?

Если посмотреть в стандартный класс-индикатора, то при обновлении данных он использует функцию CopyBuffer. Т.е. заполняет весь буфер из истории терминала, а не какую-то часть.

bool CIndicatorBuffer::Refresh(const int handle,const int num)
  {
//--- check
   if(handle==INVALID_HANDLE)
     {
      SetUserError(ERR_USER_INVALID_HANDLE);
      return(false);
     }
//---
   m_data_total=CopyBuffer(handle,num,-m_offset,m_size,m_data);
//---
   return(m_data_total>0);
  }
 
Dmitriy Gizlyk #:

Если посмотреть в стандартный класс-индикатора, то при обновлении данных он использует функцию CopyBuffer. Т.е. заполняет весь буфер из истории терминала, а не какую-то часть.

И перерасчет всей истории на каждом новом баре?

Не слишком ли это тогда затратно? Почему не определить дату последнего расчета и скопировать данные именно для этого кусочка времени?

 
Aleksey Vyazmikin #:

И перерасчет всей истории на каждом новом баре?

Не слишком ли это тогда затратно? Почему не определить дату последнего расчета и скопировать данные именно для этого кусочка времени?

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

  • cur_date - текущее время;
  • m_last_calculate - время последнего пересчета.

bool CMA::Calculate(void)
  {
   datetime cur_date=(datetime)SeriesInfoInteger(m_Symbol,m_Timeframe,SERIES_LASTBAR_DATE);
   if(m_last_calculate==cur_date && ArraySize(m_source_data)==m_history_len)
      return true;
//---
   if(!LoadHistory())
      return false;
//---
   int shift=Bars(m_Symbol,m_Timeframe,m_last_calculate,cur_date)-1;
 
Dmitriy Gizlyk #:

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

  • cur_date - текущее время;
  • m_last_calculate - время последнего пересчета.

Спасибо за уточнение!

 

большое спасибо

Очень хорошая концепция, но если я хочу написать индикатор price action с несколькими ценами (high,low,close,open), который вычисляет значение индикатора на основе разницы high и low, то возникает проблема наличия только одного массива данных (m_source_data в классе CIndicator), есть ли способ обойти это или вы предлагаете модифицировать класс CIndicator и сделать m_source_data массивом (mqlRates или CArrayBuffer,...)?

 
Mehrdad Sarrafi вычисляет значение индикатора на основе разницы high и low, то возникает проблема наличия только одного массива данных (m_source_data в классе CIndicator), есть ли способ обойти это или вы предлагаете модифицировать класс CIndicator и сделать m_source_data массивом (mqlRates или CArrayBuffer,...)?

Да, вы можете модифицировать CIndicator, чтобы создать m_source_data как массив MqlRates. Я рекомендую MqlRates, потому что в других случаях вам понадобятся некоторые действия для синхронизации данных в разных массивах.