Побаровый обход индикатора

 

Задача: в советнике нужно сравнивать значения индикатора на баре n и баре n+1 до тех пор, пока выполняется условие: значения индикатора на баре n > значения индикатора на баре n+1. При этом глубина прохода вглубь истории заранее неизвестна:

глубина шесть баров 

или так

глубина четырнадцать баров


самый простой и примитивный метод: цикл от "0" до "100"

вариант с циклом от "0" до BarsCalculated

...

 

"iMAGet Depths Of History" version   "1.000".

- самый простой и примитивный метод: цикл от "0" до "100"

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   for(int i=0;i<100;i++)
     {
      if(iMAGet(i)<iMAGet(i+1))
        {
         Comment("bar# ",i);
         return;
        }
     }
  }

 и в каждом заходе цикла два раза вызывается функция iMAGet:

//+------------------------------------------------------------------+
//| Get value of buffers for the iMA                                 |
//+------------------------------------------------------------------+
double iMAGet(const int index)
  {
   double MA[1];
//--- reset error code 
   ResetLastError();
//--- fill a part of the iMABuffer array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(handle_iMA,0,index,1,MA)<0)
     {
      //--- if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated 
      return(0.0);
     }
   return(MA[0]);
  }

Недостатки такого способа: 

  1. Цикл до "100" - а кто сказал, что индикатор посчитал 100 и более баров? В общем нет проверки на кол-во баров
  2. В одном заходе цикла ДВА обращения к функции iMAGet
...

Файлы:
 

"iMAGet Depths Of History" version   "1.001".

- вариант с циклом от "0" до BarsCalculated

Внесённые изменения: сначала узнаем количество рассчитанных баров в индикаторе и затем делаем цикл от "0" до этого BarsCalculated:

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   int limit=BarsCalculated(handle_iMA);
   if(limit>0)
      limit--;
   for(int i=0;i<limit;i++)
     {
      if(iMAGet(i)<iMAGet(i+1))
        {
         Comment("limit: ",limit,"\n",
                 "bar# ",i);
         return;
        }
     }
  }

"limit--" - для того, чтобы не выйти за пределы посчитанных баров, когда будет вызов "iMAGet(i+1)"

Недостатки такого способа: 

  1. В одном заходе цикла ДВА обращения к функции iMAGet
...
Файлы:
 

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

 
Dmitry Fedoseev:

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


Да, вариант с двумя статическими переменными позволит в каждом заходе обращаться к iMAGet только один раз.

 
Vladimir Karputov:

Да, вариант с двумя статическими переменными позволит в каждом заходе обращаться к iMAGet только один раз.


Да не об этом было. 

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