Как правильно использовать встроенные индикаторы типа iMA iBands и тп на кастомном массиве внутри эксперта?

 

Ищу уже долго ответ по всему инету но там и не нашёл чего-то вразумительного с рабочим примером.

Если встроенный индикатор на хэндле другого использовать - то всё работает.

А как наложить такую машку на обычный массив чисел?

Как вообще этот хэндл работает? Как мой массив превратить в хэндл для индикатора и нужно ли это делать?

 

в четвёрке есть такое:

https://docs.mql4.com/ru/indicators/imaonarray

в пятёрке есть аналог, здесь:

https://www.mql5.com/ru/articles/81

double iMAOnArrayMQL4(double &array[],
                      int total,
                      int period,
                      int ma_shift,
                      int ma_method,
                      int shift)
  {
   double buf[],arr[];
   if(total==0) total=ArraySize(array);
   if(total>0 && total<=period) return(0);
   if(shift>total-period-ma_shift) return(0);
   switch(ma_method)
     {
      case MODE_SMA :
        {
         total=ArrayCopy(arr,array,0,shift+ma_shift,period);
         if(ArrayResize(buf,total)<0) return(0);
         double sum=0;
         int    i,pos=total-1;
         for(i=1;i<period;i++,pos--)
            sum+=arr[pos];
         while(pos>=0)
           {
            sum+=arr[pos];
            buf[pos]=sum/period;
            sum-=arr[pos+period-1];
            pos--;
           }
         return(buf[0]);
        }
      case MODE_EMA :
        {
         if(ArrayResize(buf,total)<0) return(0);
         double pr=2.0/(period+1);
         int    pos=total-2;
         while(pos>=0)
           {
            if(pos==total-2) buf[pos+1]=array[pos+1];
            buf[pos]=array[pos]*pr+buf[pos+1]*(1-pr);
            pos--;
           }
         return(buf[shift+ma_shift]);
        }
      case MODE_SMMA :
        {
         if(ArrayResize(buf,total)<0) return(0);
         double sum=0;
         int    i,k,pos;
         pos=total-period;
         while(pos>=0)
           {
            if(pos==total-period)
              {
               for(i=0,k=pos;i<period;i++,k++)
                 {
                  sum+=array[k];
                  buf[k]=0;
                 }
              }
            else sum=buf[pos+1]*(period-1)+array[pos];
            buf[pos]=sum/period;
            pos--;
           }
         return(buf[shift+ma_shift]);
        }
      case MODE_LWMA :
        {
         if(ArrayResize(buf,total)<0) return(0);
         double sum=0.0,lsum=0.0;
         double price;
         int    i,weight=0,pos=total-1;
         for(i=1;i<=period;i++,pos--)
           {
            price=array[pos];
            sum+=price*i;
            lsum+=price;
            weight+=i;
           }
         pos++;
         i=pos+period;
         while(pos>=0)
           {
            buf[pos]=sum/weight;
            if(pos==0) break;
            pos--;
            i--;
            price=array[pos];
            sum=sum-lsum+price*period;
            lsum-=array[i];
            lsum+=price;
           }
         return(buf[shift+ma_shift]);
        }
      default: return(0);
     }
   return(0);
  }
iMAOnArray - Технические индикаторы - Справочник MQL4
iMAOnArray - Технические индикаторы - Справочник MQL4
  • docs.mql4.com
В отличие от iMA(...), функция iMAOnArray не выбирает данные на основе названия инструмента, таймфрейма и используемой цены - ценовые данные должны быть подготовлены заранее...
 

Спасибо за пример, но это выглядит как костыль...

Мне нужно будет кучу стандарных индюков юзать на своих данных. Не все же их в виде кода переписывать?

 
В наше время использовать стандартные индикаторы не модно :)
 
При вызове функции индикатора, последним параметром указать хэндл другого индикатора. Но что делать, если нужные данные не в нулевом буфере - не знаю.
 
Dmitry Fedoseev:
При вызове функции индикатора, последним параметром указать хэндл другого индикатора. Но что делать, если нужные данные не в нулевом буфере - не знаю.

Просто указать handle индикатора недостаточно. После этого надо скопировать буфер, и тут как раз указывается какой буфер копировать.

int  CopyBuffer( 
   int       indicator_handle,     // handle индикатора 
   int       buffer_num,           // номер буфера индикатора 
   int       start_pos,            // откуда начнем  
   int       count,                // сколько копируем 
   double    buffer[]              // массив, куда будут скопированы данные 
   );
 
Alexey Viktorov:

Просто указать handle индикатора недостаточно. После этого надо скопировать буфер, и тут как раз указывается какой буфер копировать.

Знакомые слова встретились: хэндл и буфер? Имеется ввиду буфер, который обрабатывается вторым индикатором.

 
Dmitry Fedoseev:

Знакомые слова встретились: хэндл и буфер? Имеется ввиду буфер, который обрабатывается вторым индикатором.

А я ещё удивился, как это Федосеев такое не знает……… может кто взломал аккаунт и издевается……… А оказалось, что я просто не понял сути. Да и сейчас не въехал до конца.

На вскидку, если правильно теперь понял, можно подключить библиотеку индикатора и там всё рассчитать.

 
Второй индикатор (тот, которому последним параметром передается хэндл первого индикатора), применяется к нулевому буферу. А вот как второй индикатор применить к другому буферу первого индикатора?
 
Dmitry Fedoseev:
Второй индикатор (тот, которому последним параметром передается хэндл первого индикатора), применяется к нулевому буферу. А вот как второй индикатор применить к другому буферу первого индикатора?

Сейчас — никак.