iMAOnArray - помогите, пожалуйста!

 

Не стал бы обращаться на форум, дабы таким простым вопросом не утруждать, но я уже три дня ломаю голову. Ну не пойму, где ошибка.

Сначала об ошибке:

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

В чем проблема: При вызове из советника нулевого значения второго буфера, значения какие-то неверные и с каждым баров становятся всё меньше и меньше и где-то через 20-30 баров становятся 2.67294е-18 и всё.

Ну в чем же может быть проблема?

Сам индикатор:

#property copyright   "2005-2014, MetaQuotes Software Corp."

#property link        "http://www.mql4.com"

#property strict


#property indicator_separate_window

#property indicator_buffers 2

#property indicator_color1 Silver

#property indicator_color2 Red


input int TotalBars=20;

input int MA_per=20;


double ExtBuffer[];

double MA[];

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

void OnInit(void)

  {

   IndicatorBuffers(2);

   IndicatorDigits(Digits);


   SetIndexStyle(0,DRAW_LINE);

   SetIndexStyle(1,DRAW_LINE);


   SetIndexBuffer(0,ExtBuffer);

   SetIndexBuffer(1,MA);


   SetIndexLabel(0,"Name");

   SetIndexLabel(1,"MA");

  }


double white_4H=0,black_4H=0;

double koeff=0;

//+------------------------------------------------------------------+

//|                                                                  |

//+------------------------------------------------------------------+

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[])

  {


   if(rates_total<=TotalBars)

      return(0);


   int limit=rates_total-prev_calculated;


   if(prev_calculated>0)

      limit++;


   for(int k=0;k<limit;k++)

     {

      white_4H=0;black_4H=0;

      for(int i=k-TotalBars;i<k;i++)

        {

         if(iClose(NULL,PERIOD_H4,i)>iOpen(NULL,PERIOD_H4,i))white_4H+=iClose(NULL,PERIOD_H4,i)-iOpen(NULL,PERIOD_H4,i);

         if(iClose(NULL,PERIOD_H4,i)<iOpen(NULL,PERIOD_H4,i))black_4H-=iOpen(NULL,PERIOD_H4,i)-iClose(NULL,PERIOD_H4,i);

        }


      ExtBuffer[k]=white_4H+black_4H;


     }


   for(int n=0;n<limit;n++)

     {

      MA[n]=iMAOnArray(ExtBuffer,0,MA_per,0,MODE_SMA,n);

     }


   return(rates_total);

  }

//+------------------------------------------------------------------+


Из советника вызывается следующим образом:

MA=iCustom(Symbol(),TF,"indicator_name",20,20,1,0);


Заранее признателен за помощь!


UPD. Самое главное, что сам индикатор отрисовывается отлично, как нужно!!! А с советника вызываются неверные значения. Вот в этом-то и загвоздка!



MQL4: automated forex trading, strategy tester and custom indicators with MetaTrader
MQL4: automated forex trading, strategy tester and custom indicators with MetaTrader
  • www.mql4.com
MQL4: automated forex trading, strategy tester and custom indicators with MetaTrader
 
Сделай обнуление буферов в ините.
 
Igor Kryuchkov:
Сделай обнуление буферов в ините.

Сделал... Не помогает (((


   ArrayInitialize(ExtBuffer,EMPTY_VALUE);

   ArrayInitialize(MA,EMPTY_VALUE);


 
33valeta.ru:


UPD. Самое главное, что сам индикатор отрисовывается отлично, как нужно!!! А с советника вызываются неверные значения. Вот в этом-то и загвоздка!

Нужно брать значения со сформированного бара. Значение, взятое с нулевого бара, не видно на истории, оно "внутри" бара. Сами то значения правильные. Просто получается детализация, которая вовсе не нужна.

 
Ihor Herasko:

Нужно брать значения со сформированного бара. Значение, взятое с нулевого бара, не видно на истории, оно "внутри" бара. Сами то значения правильные. Просто получается детализация, которая вовсе не нужна.

Я в отчаянии.

Поменял в советнике на MA=iCustom(Symbol(),TF,"indicator_name",20,20,1,1);

Ничего не изменилось...

Смотрите, что я добавил в этом же цикле

(for(int n=0;n<limit;n++)

     {

      MA[n]=iMAOnArray(ExtBuffer,0,MA_per,0,MODE_SMA,n);

     }

в индикаторе:

MyTime[n]=iTime(NULL,0,n);

А в советнике соответственно вызов значений этой функции:

datetime time=iCustom(Symbol(),TF,"indicator_name",20,20,2,0);

Так и всё прекрасно работает, выводит в Comment(time); время именно нулевого бара...


Видимо, что-то всё-таки во взаимодействии двух буфферов не так работает... (((

 
33valeta.ru:

datetime time=iCustom(Symbol(),TF,"indicator_name",20,20,2,0);

Какое значение имеет переменная TF в данном случае?

Сейчас только обратил внимание на тот факт, что в индикаторе жестко задан ТФ - PERIOD_H4, а вот при расчете индекса бара берутся данные с текущего ТФ. Если текущий ТФ отличается от Н4, то получим кашу.
 
Ihor Herasko:

Какое значение имеет переменная TF в данном случае?

TF это всего лишь таймфрейм. Определяется в советнике.

 
33valeta.ru:

TF это всего лишь таймфрейм. Определяется в советнике.

Читайте дальше, добавил.

 
Ihor Herasko:

Какое значение имеет переменная TF в данном случае?

Сейчас только обратил внимание на тот факт, что в индикаторе жестко задан ТФ - PERIOD_H4, а вот при расчете индекса бара берутся данные с текущего ТФ. Если текущий ТФ отличается от Н4, то получим кашу.
Конечно же используется таймфрейм 4 часа! Я просто упростил код для форума.
 

У вас индикатор считается от самого свежего бара в сторону истории. Подозреваю, что рисуется он не так, как должен, хоть вам и кажется, что всё нормально.

Далее, чему будут равны значения i в этом цикле: for(int i = k - TotalBars; i < k; i++), если k меньше TotalBars? вот.

 

Проанализируйте, что будет рассчитано вот в этом цикле, если значение k равно 0, а значение TotalBars более нуля:

 for(int i=k-TotalBars;i<k;i++)
        {
         if(iClose(NULL,PERIOD_H4,i)>iOpen(NULL,PERIOD_H4,i))white_4H+=iClose(NULL,PERIOD_H4,i)-iOpen(NULL,PERIOD_H4,i);
         if(iClose(NULL,PERIOD_H4,i)<iOpen(NULL,PERIOD_H4,i))black_4H-=iOpen(NULL,PERIOD_H4,i)-iClose(NULL,PERIOD_H4,i);
        }

Чтобы понять, в чем дело, запустите индикатор в тестере на всех тиках, а потом сравните полученный результат с индикатором, наброшенным на график после окончания тестирования:


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