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

 
Кто-нибудь встречался с такой проблемой: индикатор в тестере стратегий рисует в главном окне графика одно значение, а в советник с помощью функции iCustom() на том же самом баре индикатор возвращает другое значение. Значения очень сильно разнятся, т.е. это явно не ошибка округления. В качестве пользовательского индикатора используется одна из версий технического индикатора «KAMA™» (Kaufman Adaptive Moving Average).

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

 
Eugene Myzrov:
Кто-нибудь встречался с такой проблемой: индикатор рисует в главном окне графика одно значение, а при вызове из советника с помощью функции iCustom() на том же самом баре индикатор показывает другое значение. Значения очень сильно разнятся, т.е. это явно не ошибка округления.

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

Какой номер бара сравнивается?

Если нулевой (еще не закрывшийся бар) то значения индикатора на этом баре будут постоянно меняться пока бар не закроется.

 
Vitalii Ananev: Какой номер бара сравнивается? Если нулевой (еще не закрывшийся бар) то значения индикатора на этом баре будут постоянно меняться пока бар не закроется.
Нет, не нулевой, используется значение последнего закрытого бара (советник работает по ценам открытия - просыпается один раз в бар).
 
Eugene Myzrov:
Нет, не нулевой, используется значение последнего закрытого бара (советник работает по ценам открытия - просыпается один раз в бар).
Тогда, думаю, что индикатор пересчитывает не только нулевой бар, но и уже закрытые бары.
 


Вот исходный код индикатора на MQL4. Что в нем не так?

//+------------------------------------------------------------------+
//| «KAMA™ Color»
//+------------------------------------------------------------------+
#property copyright  "Copyright © 2016, «Scriptolog®» [ myzrov@mail.ru ]" // ©€®±µ™ «»
#property link       "mailto:myzrov@mail.ru"
#property version    "1.0"
#property strict

#property description "Технический индикатор «KAMA™ Color» (Kaufman Adaptive Moving Average) используется"
#property description "для построения скользящей средней с малой чувствительностью к шумам в"
#property description "ценовых сериях и характеризуется минимальным запаздыванием для определения тренда."
#property description "Его разработал и описал Перри Кауфман (Perry Kaufman) в своей книге «Smarter Trading».\n"

#property description "Предупреждение. Торговля с кредитным плечом несёт в себе большие финансовые риски."
//#property icon        "\\Images\\Constructor.ico" // путь к файлу заставки

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2

#property indicator_label1  "KAMA Up"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  5

#property indicator_label2  "KAMA Down"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  5

   input int   KAMA_PERIOD          =10;           // KAMA. Период усреднения
   input int   KAMA_PERIOD_EMA_FAST = 2;           // KAMA. Период экспоненциальной MA быстрой   
   input int   KAMA_PERIOD_EMA_SLOW =30;           // KAMA. Период экспоненциальной MA медленной

// indicator buffers
   double   aKamaUp[], aKamaDn[];

// global variables
   double   SSC_FAST; // SSC(i) - текущее значение изменяющейся сглаживающей константы.
   double   SSC_SLOW;
   double   SSC_DELTA;

   int      MAX_PERIOD;

   double   nKAMA, nKAMA1;
   
   bool     last_trend_up;
   double   nNoise, nER, nSSC, nPriceCurrent, nPrice, nPrice1;
 
//+------------------------------------------------------------------+
//| KAMA initialization function                                      |
//+------------------------------------------------------------------+
int OnInit()
{
   nKAMA1=0; last_trend_up=false;

// check for input values
   bool ok=true;
   if (KAMA_PERIOD         <=0) {Alert("Input parameter KAMA_PERIOD has incorrect value: ",          KAMA_PERIOD         ); ok=false;}
   if (KAMA_PERIOD_EMA_SLOW<=0) {Alert("Input parameter KAMA_PERIOD_EMA_SLOW has incorrect value: ", KAMA_PERIOD_EMA_SLOW); ok=false;}
   if (KAMA_PERIOD_EMA_FAST<=0) {Alert("Input parameter KAMA_PERIOD_EMA_FAST has incorrect value: ", KAMA_PERIOD_EMA_FAST); ok=false;}

   if (!ok) return(INIT_PARAMETERS_INCORRECT);

   SSC_FAST=2.0/(1.0+KAMA_PERIOD_EMA_FAST);
   SSC_SLOW=2.0/(1.0+KAMA_PERIOD_EMA_SLOW); SSC_DELTA=SSC_FAST-SSC_SLOW;

   ArraySetAsSeries(aKamaUp, true);
   ArraySetAsSeries(aKamaDn, true);

   SetIndexBuffer(0, aKamaUp, INDICATOR_DATA); SetIndexEmptyValue(0, EMPTY_VALUE);
   SetIndexBuffer(1, aKamaDn, INDICATOR_DATA); SetIndexEmptyValue(1, EMPTY_VALUE);

   MAX_PERIOD=(int)MathMax(KAMA_PERIOD_EMA_SLOW, KAMA_PERIOD_EMA_FAST);
   MAX_PERIOD=(int)MathMax(MAX_PERIOD,           KAMA_PERIOD)+2;

   SetIndexDrawBegin(0, MAX_PERIOD);
   SetIndexDrawBegin(1, MAX_PERIOD);

   IndicatorSetInteger(INDICATOR_DIGITS, _Digits);

   string short_name=StringConcatenate("KAMA(", KAMA_PERIOD, ",", KAMA_PERIOD_EMA_FAST, ",", KAMA_PERIOD_EMA_SLOW, ")");
   IndicatorSetString(INDICATOR_SHORTNAME, short_name);

   return(0);
}
//+------------------------------------------------------------------+
//| KAMA 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       &real_volume[],
                const int        &spread[])
{
   int N=rates_total-prev_calculated; if (N==0) return(rates_total); if (N>MAX_PERIOD) {N-=MAX_PERIOD; nKAMA1=close[N];}

   ArraySetAsSeries(close, true);

   for (int i=N; i>=0 && !IsStopped(); i--) {

      aKamaUp[i]=EMPTY_VALUE;
      aKamaDn[i]=EMPTY_VALUE; 

      nPriceCurrent=close[i];

   // Calculate ER value
      nNoise=0.0; nPrice1=nPriceCurrent; 
      for (int k=1; k<=KAMA_PERIOD; k++) {
         nPrice=nPrice1; nPrice1=close[i+k]; nNoise+=MathAbs(nPrice1-nPrice);
      }
      nER=(nNoise>0 ? MathAbs(nPriceCurrent-nPrice1)/nNoise : 0.0);
      nSSC=nER*SSC_DELTA+SSC_SLOW; // calculate SSC

      nKAMA =nKAMA1+MathPow(nSSC, 2)*(nPriceCurrent-nKAMA1); // calculate KAMA

      nKAMA = NormalizeDouble(nKAMA, _Digits);

      if (close[i]>nKAMA) {aKamaUp[i]=nKAMA; last_trend_up=true; } else
                          {aKamaDn[i]=nKAMA; last_trend_up=false;}

      nKAMA1=nKAMA; // запомнить последнее значение
   }
   return(rates_total);
}
 

Так сразу то и не разглядишь, что там не так. Погоняйте в тестере понаблюдайте. Через функцию Print() попробуйте выводить каждый тик значение буферов индикатора на 1 баре. Если они меняются, значит точно пересчитывается. Можно еще попробовать изменит порядок прохода по барам в цикле.

 for (int i=N; i>=0 && !IsStopped(); i--) {

изменить на

 for (int i=0; i<=N && !IsStopped(); i++) {
 
Vitalii Ananev: Так сразу то и не разглядишь, что там не так. Погоняйте в тестере понаблюдайте. Через функцию Print() попробуйте выводить каждый тик значение буферов индикатора на 1 баре. Если они меняются, значит точно пересчитывается. Можно еще попробовать изменить порядок прохода по барам в цикле...

Нет, индикатор точно не пересчитывается, я проверял. Обратный порядок не подходит, т.к. индикатор использует предыдущее значение для построения следующего значения.

 
comp:
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Чтение буферов индикатора, установленного на чарт

comp, 2016.03.17 00:07

В Сервисдеске дали решение для MT5. Для MT4 вопрос открыт.

Support Team 2016.03.17 06:44

Для MT4 это к сожалению невозможно.

Спасибо, но это немного не то. Мне достаточно увидеть индикатор на графике в тестере стратегий в режиме визуализации, и вот как раз в тестере я вижу правильно нарисованный индикатор, а в советник поступают непонятные значения.
 
Eugene Myzrov:

Нет, индикатор точно не пересчитывается, я проверял. Обратный порядок не подходит, т.к. индикатор использует предыдущее значение для построения следующего значения.

Может вы в советнике берете не тот буфер. На графике отображается значение одного буфера, а в советнике вы получаете значение другого буфера индикатора. 

Больше уже ни знаю что  и предположить, если проверка показала, что пересчета нет, значит остаются вариант разных буферов. 

....

Уточните еще, какие непонятные значения? 

В начале цикла буфера индикатора инициализируются значением EMPTY_VALUE, а это значение не всегда равно нулю.

aKamaUp[i]=EMPTY_VALUE;
aKamaDn[i]=EMPTY_VALUE;  

 Попробуйте еще в OnInit() добавить

...
   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
...

   

 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Чтение буферов индикатора, установленного на чарт

comp, 2016.03.13 22:05

Запускаете индикатор, затем - советник

Наблюдаете, что значения буфера индикатора (CTRL+D) не совпадают со значениями iCustom (выводятся в комментарий чарта советником).

В вашем случае полное совпадение на живых чартах. В тестере не смотрел.