Индикатор возвращает в советник значения, отличные от тех, что рисует на графике - страница 2

 
Vitalii Ananev: Может вы в советнике берете не тот буфер. На графике отображается значение одного буфера, а в советнике вы получаете значение другого буфера индикатора. Больше уже ни знаю что  и предположить, если проверка показала, что пересчета нет, значит остаются вариант разных буферов. Уточните еще, какие непонятные значения? В начале цикла буфера индикатора инициализируются значением EMPTY_VALUE, а это значение не всегда равно нулю.

Тоже не вариант, нумерация буферов [0..1] в советнике сохраняется такая же как и в индикаторе.
Специально подготовил урезанный вариант советника, который только и делает, что обращается за данными к индикатору KAMA и выводит их на печать.

#property copyright   "Copyright© 2015, Scriptolog® [ myzrov@mail.ru ] " //©€®±µ™«»
#property link        "mailto:myzrov@mail.ru"
#property version     "1.0" // версия советника
#property strict

#property description "Торговый советник использует индикатор «KAMA»...\n"
#property description "Предупреждение. Торговля с кредитным плечом несёт в себе большие финансовые риски."

#define INDEX_UP 0
#define INDEX_DN 1

//Работа с пользовательскими индикаторами, подключенными в качестве ресурсов
//#resource                         "\\Indicators\\SIMPLE\\KAMA.ex4"
//#define     KAMA_INDICATOR_NAME   "::Indicators\\SIMPLE\\KAMA.ex4"
  #define     KAMA_INDICATOR_NAME               "\\SIMPLE\\KAMA.ex4"

  sinput string  KAMA_            = "ИНДИКАТОР «KAMA»"; // .
   input int     KAMA_PERIOD      =  70;                // KAMA. Период усреднения
   input int     KAMA_PERIOD_FAST =   2;                // KAMA. Период усреднения EMA быстрой
   input int     KAMA_PERIOD_SLOW =  30;                // KAMA. Период усреднения EMA медленной 

//+------------------------------------------------------------------+
//| expert initialization function
//+------------------------------------------------------------------+
int OnInit()
{
// сбросим значение ошибки
   ResetLastError();
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   return;
}
//+------------------------------------------------------------------+
//| expert start function (с приходом каждого тика...)
//+------------------------------------------------------------------+
void OnTick()
{
// Определить появление нового тика или нового бара на текущем ТФ
   if (IsNewBar()) {

   // Получить значение индикатора "KAMA"
      double   kama_up=getKAMA(INDEX_UP, 1); // KAMA_UP на закрытом баре #1
      double   kama_dn=getKAMA(INDEX_DN, 1); // KAMA_DN на закрытом баре #1

      double   kama = (kama_up!=EMPTY_VALUE ? kama_up : kama_dn); kama = NormalizeDouble(kama, _Digits);

      Print("*** KAMA: ", dts(kama_up)," / ",dts(kama_dn), " => ", kama);
   }
   return;
}
//+------------------------------------------------------------------+
//| Возвращает значение индикатора «KAMA» на k-том баре
//+------------------------------------------------------------------+
double getKAMA(int index, int k)
{
// Получить значение указанного пользовательского индикатора
   double nKAMA=iCustom(_Symbol       , // ПАРАМЕТРЫ ИНДИКАТОРА «KAMA»
                  PERIOD_CURRENT      , // KAMA. Таймфрейм. Период графика
                  KAMA_INDICATOR_NAME , // KAMA. Имя индикатора 
                  KAMA_PERIOD         , // KAMA. Период усреднения
                  KAMA_PERIOD_FAST    , // KAMA. Период усреднения EMA быстрой
                  KAMA_PERIOD_SLOW    , // KAMA. Период усреднения EMA медленной 
                  index               , // Индекс линии индикатора [0..1]
                  k);                   // Номер бара
   return(nKAMA);
}
//+------------------------------------------------------------------+
//| Определить появление нового бара на текущем ТФ
//+------------------------------------------------------------------+
bool IsNewBar()
{
   bool ok=false;
   static datetime dLastTime=0; // последнее известное время открытия бара
   datetime dNewTime=Time[0]; // время открытия текущего бара
   if      (dNewTime>dLastTime) {dLastTime=dNewTime; ok=true;}
   return(ok);
}
//+-----------------------------------------------------
//| Преобразовать числовое значение в текстовую строку
//+-----------------------------------------------------
string dts(double x) {return(x==EMPTY_VALUE ? "EMPTY_VALUE" : DoubleToString(x, _Digits));}
 
comp:
В вашем случае полное совпадение на живых чартах. В тестере не смотрел.

Вот так код должен быть написан! Иначе индикатор будет глючным:

if(i) nKAMA1=nKAMA; // запомнить последнее значение
 
Vitalii Ananev: Попробуйте еще в OnInit() добавить. 
Но в OnInit() уже установлены значения по умолчанию EMPTY_VALUE.
   SetIndexEmptyValue(0, EMPTY_VALUE);
   SetIndexEmptyValue(1, EMPTY_VALUE);

 
Eugene Myzrov:
Но в OnInit() уже установлены значения по умолчанию EMPTY_VALUE.
А да точно есть, не внимательно посмотрел, я обычно с новой строки пишу. 
 
Nikolay Kositsin: Вот так код должен быть написан!
if(i) nKAMA1=nKAMA; // запомнить последнее значение
Иначе индикатор будет глючным
Точно! Спасибо, Николай, причина действительно в этом!

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

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

   for (int i=N; i>0 && !IsStopped(); i--) {
      ...      
      nKAMA1=nKAMA;
   }

Позже, когда было принято решение добавить в советник тиковый режим обработки, я чисто механически добавил в индикатор обработку нулевого бара (i>=0), а про то, что сохранять предыдущее значение индикатора теперь надо не на каждом тике, а лишь при поступлении нового бара - просто забыл.

Исправил на:
   for (int i=N; i>=0 && !IsStopped(); i--) {
      ...      
      if (i>0) nKAMA1=nKAMA;
   }

Теперь все работает как часы - данные в советник поступают те же самые, что отображаются на графике.

Всем откликнувшимся - спасибо.

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