MQL4 ve MQL5 ile ilgili herhangi bir acemi sorusu, algoritmalar ve kodlar hakkında yardım ve tartışma - sayfa 670

 
Roman Sharanov :
Bir dizi sınıf örneği nasıl oluşturulur?
ClassName* className[] yapıldı, ardından ArrayResize yapıldı, ancak geçersiz işaretçi erişim yöntemlerine erişim vermiyor

Örneklerini bir dizide toplamak istediğiniz sınıfınız CObject'den miras alınmalıdır.

Ve sonra her şey basit: CArrayObj nesnelerinin bir listesini (dizisini) oluşturun ve nesnelerinizi buna ekleyin.

 
psyman :

"Gösterge şablonu" ve adınıza göre, arama hiçbir şey bulamıyor, ancak burada Savaş ve Barış cildine zaten yazmışlar.

Gönderideki herhangi bir kelime kombinasyonunu hatırlayın.

Üzgünüm, belki gösterge şablonu hakkında yanılttım - Trol şablonunu yayınladım.

Şunu yapalım: düzenleyicide bir gösterge şablonu oluşturun, oluştururken gerekli sayıda giriş değişkeni ve çizilebilir arabellek ekleyin.

Ardından, belirli bir görevden ne yapılması gerektiğini analiz edeceğiz.

 
psyman :

Kötü diyorsan, nasıl iyi yapacağımı söyle. Hesaplamalar OnInit'e taşınsın mı?

Adil azarlama)) İşte burada yayınlanan kodun bir versiyonu:

 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[])
{
   int i,limit;
   if (prev_calculated == 0 ) {
      limit = rates_total - 1 ;     //--- Первый вызов индикатора или смена таймфрейма или подгрузка данных из истории
   }
   else limit = rates_total - prev_calculated + 1 ;

   for (i = limit; i >= 0 ; i--) { //--- В этом цикле основные вычисления. Таким образом обрабатываться будет только "свежая" информация                       
   }
   return (rates_total);

Bunu yapmaya çalışın. Ve OnInit'te herhangi bir şey aktarmak gerekli değildir.

 
Andrei Novichkov :

Adil azarlama)) İşte burada yayınlanan kodun bir versiyonu:

Bunu yapmaya çalışın. Ve OnInit'te herhangi bir şey aktarmak gerekli değildir.

Burada böyle bir kod yayınlamadım - benim değil :)

Diğer yapıları kullanıyorum - daha basit ve daha net.

OnInit'te () aktarmak gerekir. Neden her işarette gösterge arabelleğine bir dizi atamalısınız ?

 
Artyom Trishkin :

Burada böyle bir kod yayınlamadım - benim değil :)

Diğer yapıları kullanıyorum - daha basit ve daha net.

bu benim, nerede daha kolay? ))) (en azından şablonda limit = rate_total - 1 yorumum var ; //--- Göstergenin ilk çağrısı veya zaman çerçevesini değiştirme veya geçmişten veri yükleme ) ve biçimlendirme stilim bir küme ayracı for() {

peki konuya göre kendi indikatörünüzü nasıl yazacağınızı öğrenmek için yukarıdaki şablonu alıp en azından kapanış fiyatını ekleyip ilk indikatörümüzü alıyoruz sonra bu kapanış fiyatından mashka yapmayı öğreniyoruz

 for (i = limit; i >= 0 ; i--) { //--- В этом цикле основные вычисления. Таким образом обрабатываться будет только "свежая" информация                       
Buffer[i] = close[i];   
}
 
Artyom Trishkin :

Burada böyle bir kod yayınlamadım - benim değil :)

Diğer yapıları kullanıyorum - daha basit ve daha net.

OnInit'te () aktarmak gerekir. Neden her işarette gösterge arabelleğine bir dizi atamalısınız ?

Bu senin kodun değil. Bazı meslektaşlarım yayınladı ama kim ve nerede olduğunu hatırlayamıyorum. Orijinal koda değil, OnInit'e hiçbir şeyin aktarılması gerekmediğini yazarken aklımda bu kod vardı. Tam olarak ifade edilmedi.

Hangi tasarımı önerirsiniz? Bu son derece basit görünüyor.



Ve işte parçanın yazarı)))) önümde. Bu arada, ben de bu biçimlendirme stilini kullanıyorum - satır başına bir küme ayracı ile.
 
Andrei Novichkov :
Ve işte parçanın yazarı)))) önümde. Bu arada, ben de bu biçimlendirme stilini kullanıyorum - satır başına bir küme ayracı ile.

evet, gösterge şablon kodu ne işe yarar? bir gösterge oluşturmak için sihirbazı çalıştırın, çizgilerin türlerini ve rengini seçin ve gerekirse girdileri ekleyin

ve bu kadar, gösterge hazır, ardından gövdeyi OnCalculate() şablonundan kopyalayın ve hesaplamaları yazın,

1 dakika içinde ilk indikatörünüzü yazabilirsiniz, yukarıdaki kod "Merhaba kelime ben göstergesi!!!" Gösterdim :)

Not: Bu arada, bu formda, göstergeler MT4'ten MT5'e aktarılabilir, asıl şey gösterge arabelleklerini doğru bir şekilde ayarlamaktır, MT5'te arabellek dizilerini indeksleme ile bir korku vardır .... onlar sadece dizilerdir normal dizi ile)))) indeksleme .. .. daha önce MT4'te gösterge tamponlarının indekslenmesine alışmak zordu, şimdi tam tersine buna alışmak ve MT5)'e geçmek imkansız)))
 
Andrei Novichkov :

Bu senin kodun değil. Bazı meslektaşlarım yayınladı ama kim ve nerede olduğunu hatırlayamıyorum. Orijinal koda değil, OnInit'e hiçbir şeyin aktarılması gerekmediğini yazarken aklımda bu kod vardı. Tam olarak ifade edilmedi.

Hangi tasarımı önerirsiniz? Bu son derece basit görünüyor.



Ve işte parçanın yazarı)))) önümde.
 //+------------------------------------------------------------------+
//| Custom indicator 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 &volume[],
                 const int &spread[])
  {
//--- Проверка количества доступных баров (1 - минимально, 4 - оптимально для большинства расчётов. Но всё "по месту"...)
   if (rates_total< 4 ) return 0 ;
//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated; // 0 - пришел новый тик, новый бар формироваться не начал. 1 - пришел новый тик и начал формироваться новый бар.
   if (limit> 1 ) 
               // если вписать "limit>0", то на нулевом баре будет расчёт только нулевого бара, на каждом новом баре будет полный перерасчёт всей истории
               // если вписать "limit>1", то на нулевом баре будет расчёт только нулевого бара, на открытии нового бара - пересчёт первого и нулевого,
               // при подгрузке истории и на первом запуске - перерасчёт всей истории
     {
      limit=rates_total- 1 ;
       // здесь должна быть инициализация всех используемых буферов индикатора необходимыми значениями (обычно EMPTY_VALUE и 0)
     }
//--- Расчёт индикатора
   for ( int i=limit; i>= 0 && ! IsStopped (); i--)
     {
       // необходимые действия по расчёту индикатора
     }

//--- return value of prev_calculated for next call
   return (rates_total);
  }
//+------------------------------------------------------------------+
 
Igor Makanu :

evet, gösterge şablon kodu ne işe yarar? bir gösterge oluşturmak için sihirbazı çalıştırın, çizgilerin türlerini ve rengini seçin ve gerekirse girdileri ekleyin

ve bu kadar, gösterge hazır, ardından gövdeyi OnCalculate() şablonundan kopyalayın ve hesaplamaları yazın,

1 dakika içinde ilk indikatörünüzü yazabilirsiniz, yukarıdaki kod "Merhaba kelime ben göstergesi!!!" Gösterdim :)

Not: Bu arada, bu formda, göstergeler MT4'ten MT5'e aktarılabilir, asıl şey gösterge arabelleklerini doğru bir şekilde ayarlamaktır, MT5'te arabellek dizilerini indeksleme ile bir korku vardır .... onlar sadece dizilerdir normal dizi ile)))) indeksleme .. .. daha önce MT4'te gösterge tamponlarının indekslenmesine alışmak zordu, şimdi tam tersine buna alışmak ve MT5)'e geçmek imkansız)))

Karmaşık bir şey yok. Bir çapraz platform göstergesi örneği (bir sınıf kullanır), ancak şablon çıkarılabilir - sınıfı ve bundan sonra hata verecek gereksiz her şeyi kaldırın - platformlar arası şablon kalacaktır.

Bu gösterge, değişiklik yapılmadan her iki platformda da aynı şekilde çalışacaktır - yalnızca gerekli uzantıyla derleme. Kodu iki bölüme ayırmam gerekti - sınıf ve göstergenin kendisi (her şey tek bir listedeydi)

Sınıf:

 //+------------------------------------------------------------------+
//|                                                       TestMA.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                             https://mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link        "https://mql5.com/ru/users/artmedia70"
#property version    "1.00"
//+------------------------------------------------------------------+
//| Класс скользящих средних                                         |
//+------------------------------------------------------------------+
#include <Arrays\ArrayObj.mqh>
class CAvg : public CObject
  {
protected :
   ENUM_TIMEFRAMES       m_timeframe;
   string                m_symbol;
   int                   m_period;
   ENUM_MA_METHOD        m_method;
   ENUM_APPLIED_PRICE    m_price;
   int                   m_rates_total;
   double                m_prev_value;
   //---
   bool                  CheckPosition( const int rates_total, const int period, const int index)   const { return (period>= 1 && index<=rates_total-period- 1 );   }
   double                Open ( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index)       const ;
   double                High ( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index)       const ;
   double                Low ( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index)       const ;
   double                Close ( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index)     const ;
   double                Median( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index)     const ;
   double                Typical( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index)   const ;
   double                Weighted( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index)   const ;
public :
   void                  Timeframe( const ENUM_TIMEFRAMES timeframe)            { this .m_timeframe=timeframe;       }
   void                  Method( const ENUM_MA_METHOD method)                   { this .m_method=method;             }
   void                  AppliedPrice( ENUM_APPLIED_PRICE price)                { this .m_price=price;               }
   void                  Symbol ( const string symbol_name)                      { this .m_symbol=symbol_name;        }
   void                  Period ( const int period)                              { this .m_period=period;             }
   ENUM_TIMEFRAMES       Timeframe( void )                                 const { return this .m_timeframe;          }
   ENUM_MA_METHOD        Method( void )                                     const { return this .m_method;             }
   ENUM_APPLIED_PRICE    AppliedPrice( void )                               const { return this .m_price;              }
   string                Symbol ( void )                                     const { return this .m_symbol;             }
   int                    Period ( void )                                     const { return this .m_period;             }
   int                   RatesTotal( void )                                 const { return this .m_rates_total;        }
   double                AppliedPrice( const ENUM_APPLIED_PRICE applied_price, const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index) const ;
   double                AppliedPrice( const int index)                   const ;
   double                SMA( const int rates_total, const int period, const int index, const double &price[]);
   double                EMA( const int rates_total, const int period, const int index, const double &price[]);
   double                SMMA( const int rates_total, const int period, const int index, const double &price[]);
   double                LWMA( const int rates_total, const int period, const int index, const double &price[]);
   double                GetMA( const int rates_total, const ENUM_MA_METHOD method, const int period, const int index, const double &price[]);
   double                GetMA( const int rates_total, const int index, const double &price[]);
   string                MethodToString( const ENUM_MA_METHOD method)     const { return :: StringSubstr (:: EnumToString (method), 5 );       }
   string                MethodToString( void )                             const { return :: StringSubstr (:: EnumToString ( this .m_method), 5 );}
   string                PriceToString( const ENUM_APPLIED_PRICE price)   const { return :: StringSubstr (:: EnumToString (price), 6 );        }
   string                PriceToString( void )                             const { return :: StringSubstr (:: EnumToString ( this .m_price), 6 ); }
                        CAvg( const int rates_total, const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int period);
                        CAvg( void ) : m_prev_value( 0 ){;}
                       ~CAvg( void ){;}
  };
//+------------------------------------------------------------------+
//| CAvg Конструктор                                                 |
//+------------------------------------------------------------------+
CAvg::CAvg( const int rates_total, const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int period) : m_prev_value( 0 )
  {
   this .m_symbol=symbol_name;
   this .m_timeframe=timeframe;
   this .m_period=period;
   this .m_rates_total=rates_total;
  }
//+------------------------------------------------------------------+
//| CAvg возвращает значение MA                                      |
//+------------------------------------------------------------------+
double CAvg::GetMA( const int rates_total, const int index, const double &price[])
  {
   this .m_rates_total=rates_total;
   switch ( this .m_method)
     {
       case MODE_EMA   :   return this .EMA( this .m_rates_total, this .m_period,index,price);
       case MODE_SMMA :   return this .SMMA( this .m_rates_total, this .m_period,index,price);
       case MODE_LWMA :   return this .LWMA( this .m_rates_total, this .m_period,index,price);
       //---MODE_SMA
       default         :   return this .SMA( this .m_rates_total, this .m_period,index,price);
     }
  }
//+------------------------------------------------------------------+
//| CAvg возвращает значение MA                                      |
//+------------------------------------------------------------------+
double CAvg::GetMA( const int rates_total, const ENUM_MA_METHOD method, const int period, const int index, const double &price[])
  {
   switch (method)
     {
       case MODE_EMA   :   return this .EMA(rates_total,period,index,price);
       case MODE_SMMA :   return this .SMMA(rates_total,period,index,price);
       case MODE_LWMA :   return this .LWMA(rates_total,period,index,price);
       //---MODE_SMA
       default         :   return this .SMA(rates_total,period,index,price);
     }
  }
//+------------------------------------------------------------------+
//| CAvg Simple Moving Average                                       |
//+------------------------------------------------------------------+
double CAvg::SMA( const int rates_total, const int period, const int index, const double &price[])
  {
//---
   double result= 0.0 ;
//--- check position
   if (! this .CheckPosition(rates_total,period,index))
       return 0 ;
//--- calculate value
   for ( int i= 0 ; i<period; i++)
     result=result+price[index+i];
   result/=period;
//---
   return result;
  }
//+------------------------------------------------------------------+
//| CAvg Exponential Moving Average                                  |
//+------------------------------------------------------------------+
double CAvg::EMA( const int rates_total, const int period, const int index, const double &price[])
  {
//---
   //static double prev_value=0;
   double result= 0.0 ;
//--- check position
   if (! this .CheckPosition(rates_total,period,index))
       return 0 ;
   double pr= 2.0 /(period+ 1.0 );
//--- SMA for first data
   if (index==rates_total-period- 1 || this .m_prev_value== 0 )
       this .m_prev_value=result= this .SMA(rates_total,period,index,price);
//--- EMA
   else
     {
      result= this .m_prev_value+pr*(price[index]- this .m_prev_value);
       //--- new bar
       if (index!= 0 )
         this .m_prev_value=result;
     }
//---
   return result;
  }
//+------------------------------------------------------------------+
//| CAvg Smoothed Moving Average                                     |
//+------------------------------------------------------------------+
double CAvg::SMMA( const int rates_total, const int period, const int index, const double &price[])
  {
//---
   //static double prev_value=0;
   double result= 0.0 ;
//--- check position
   if (! this .CheckPosition(rates_total,period,index))
       return 0 ;
//--- SMA for first data
   if (index==rates_total-period- 1 || this .m_prev_value== 0 )
       this .m_prev_value=result= this .SMA(rates_total,period,index,price);
//--- SMMA
   else
     {
      result=( this .m_prev_value*(period- 1 )+price[index])/period;
       //--- new bar
       if (index!= 0 )
         this .m_prev_value=result;
     }
//---
   return result;
  }
//+------------------------------------------------------------------+
//| CAvg Linear Weighted Moving Average                              |
//+------------------------------------------------------------------+
double CAvg::LWMA( const int rates_total, const int period, const int index, const double &price[])
  {
//---
   double result= 0.0 ,count= 0 ,total= 0 ,k= 0 ;
//--- check position
   if (! this .CheckPosition(rates_total,period,index))
       return 0 ;
//--- calculate value
   for ( int j=index+period- 1 ; j>=index; j--)
     {
      count++;
      k+=count;
      total+=price[j]*count;
     }
   result=total/k;
//---
   return (result);
  }
//+------------------------------------------------------------------+
//| CAvg Возвращает цену по индексу                                  |
//+------------------------------------------------------------------+
double CAvg::AppliedPrice( const int index) const
  {
   switch ( this .m_price)
     {
       case PRICE_OPEN       :   return this . Open ( this .m_symbol, this .m_timeframe,index);
       case PRICE_HIGH       :   return this . High ( this .m_symbol, this .m_timeframe,index);
       case PRICE_LOW        :   return this . Low ( this .m_symbol, this .m_timeframe,index);
       case PRICE_CLOSE      :   return this . Close ( this .m_symbol, this .m_timeframe,index);
       case PRICE_MEDIAN     :   return this .Median( this .m_symbol, this .m_timeframe,index);
       case PRICE_TYPICAL    :   return this .Typical( this .m_symbol, this .m_timeframe,index);
       //---PRICE_WEIGHTED
       default               :   return this .Weighted( this .m_symbol, this .m_timeframe,index);
     }
  }
//+------------------------------------------------------------------+
//| CAvg Возвращает цену по индексу                                  |
//+------------------------------------------------------------------+
double CAvg::AppliedPrice( const ENUM_APPLIED_PRICE applied_price, const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index) const
  {
   switch (applied_price)
     {
       case PRICE_OPEN       :   return this . Open (symbol_name,timeframe,index);
       case PRICE_HIGH       :   return this . High (symbol_name,timeframe,index);
       case PRICE_LOW        :   return this . Low (symbol_name,timeframe,index);
       case PRICE_CLOSE      :   return this . Close (symbol_name,timeframe,index);
       case PRICE_MEDIAN     :   return this .Median(symbol_name,timeframe,index);
       case PRICE_TYPICAL    :   return this .Typical(symbol_name,timeframe,index);
       //---PRICE_WEIGHTED
       default               :   return this .Weighted(symbol_name,timeframe,index);
     }
  }
//+------------------------------------------------------------------+
//| CAvg Возвращает цену Open по индексу                             |
//+------------------------------------------------------------------+
double CAvg:: Open ( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index) const
  {
   double array[];
   return (:: CopyOpen (symbol_name,timeframe,index, 1 ,array)== 1 ? array[ 0 ] : 0 );
  }  
//+------------------------------------------------------------------+
//| CAvg Возвращает цену High по индексу                             |
//+------------------------------------------------------------------+
double CAvg:: High ( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index) const
  {
   double array[];
   return (:: CopyHigh (symbol_name,timeframe,index, 1 ,array)== 1 ? array[ 0 ] : 0 );
  }  
//+------------------------------------------------------------------+
//| CAvg Возвращает цену Low по индексу                              |
//+------------------------------------------------------------------+
double CAvg:: Low ( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index) const
  {
   double array[];
   return (:: CopyLow (symbol_name,timeframe,index, 1 ,array)== 1 ? array[ 0 ] : 0 );
  }  
//+------------------------------------------------------------------+
//| CAvg Возвращает цену Close по индексу                            |
//+------------------------------------------------------------------+
double CAvg:: Close ( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index) const
  {
   double array[];
   return (:: CopyClose (symbol_name,timeframe,index, 1 ,array)== 1 ? array[ 0 ] : 0 );
  }  
//+------------------------------------------------------------------+
//| CAvg Возвращает медианную цену по индексу                        |
//+------------------------------------------------------------------+
double CAvg::Median( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index) const
  {
   double array[];
   double high= this . High (symbol_name,timeframe,index);
   double low= this . Low (symbol_name,timeframe,index);
   return (high> 0 && low> 0 ? (high+low)/ 2.0 : 0 );
  }  
//+------------------------------------------------------------------+
//| CAvg Возвращает типичную цену по индексу                         |
//+------------------------------------------------------------------+
double CAvg::Typical( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index) const
  {
   double array[];
   double high= this . High (symbol_name,timeframe,index);
   double low= this . Low (symbol_name,timeframe,index);
   double close= this . Close (symbol_name,timeframe,index);
   return (high> 0 && low> 0 && close> 0 ? (high+low+close)/ 3.0 : 0 );
  }  
//+------------------------------------------------------------------+
//| CAvg Возвращает взвешенную цену по индексу                       |
//+------------------------------------------------------------------+
double CAvg::Weighted( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const int index) const
  {
   double array[];
   double high= this . High (symbol_name,timeframe,index);
   double low= this . Low (symbol_name,timeframe,index);
   double close= this . Close (symbol_name,timeframe,index);
   return (high> 0 && low> 0 && close> 0 ? (high+low+close+close)/ 4.0 : 0 );
  }  
//+------------------------------------------------------------------+
 

Gösterge:

 //+------------------------------------------------------------------+
//|                                                       TestMA.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                             https://mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link        "https://mql5.com/ru/users/artmedia70"
#property version    "1.00"
#property indicator_chart_window
#ifdef __MQL4__
#property strict
#property indicator_buffers 2
#else 
#property indicator_buffers 3
#property indicator_plots    2
#endif 
//--- plot MAstd
#property indicator_label1    "Calculation MA"
#property indicator_type1    DRAW_LINE
#property indicator_color1    clrBlue
#property indicator_style1    STYLE_SOLID
#property indicator_width1    4
//--- plot MAcalc
#property indicator_label2    "Standart MA"
#property indicator_type2    DRAW_LINE
#property indicator_color2    clrDarkOrange
#property indicator_style2    STYLE_DOT
#property indicator_width2    2
//--- input parameters
input int       InpPeriod                     =   10 ;             // Period
input ENUM_MA_METHOD        InpMethod         =   MODE_EMA ;       // Method
input ENUM_APPLIED_PRICE    InpAppliedPrice   =   PRICE_CLOSE ;   // Applied price  
//--- indicator buffers
double          BufferMAcalc[];
double          BufferMAstd[];
double          BufferPrice[];
//---
int             digits;
int             period_ma;
int             handle_ma;
CAvg           avg();
//--- includes

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
  {
//---
#ifdef __MQL4__
   IndicatorBuffers ( 3 );
#endif 
   period_ma=(InpPeriod< 1 ? 1 : InpPeriod);
   digits= Digits ()+ 1 ;
//--- indicator buffers mapping
   SetIndexBuffer ( 0 ,BufferMAcalc, INDICATOR_DATA );
   SetIndexBuffer ( 1 ,BufferMAstd, INDICATOR_DATA );
   SetIndexBuffer ( 2 ,BufferPrice, INDICATOR_CALCULATIONS );
//---
   ArraySetAsSeries (BufferMAcalc, true );
   ArraySetAsSeries (BufferMAstd, true );
   ArraySetAsSeries (BufferPrice, true );
//---
#ifdef __MQL5__
   ResetLastError ();
   handle_ma= iMA ( NULL , PERIOD_CURRENT ,period_ma, 0 ,InpMethod,InpAppliedPrice);
   if (handle_ma== INVALID_HANDLE )
     {
       Print ( "Error creation iMA(" ,( string )period_ma, "): " , GetLastError ());
       return INIT_FAILED ;
     }
#endif 
//---
   Comment ( "\nMA type: " ,avg.MethodToString(InpMethod), ", price: " ,avg.PriceToString(InpAppliedPrice), ", period: " ,( string )period_ma);
//---
   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Custom indicator 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 &volume[],
                 const int &spread[])
  {
//--- Установка массивов буферов как таймсерий
#ifdef __MQL5__
   ArraySetAsSeries (open, true );
   ArraySetAsSeries (high, true );
   ArraySetAsSeries (low, true );
   ArraySetAsSeries (close, true );
#endif 
//--- Проверка количества доступных баров
   if (rates_total< fmax (period_ma, 4 )) return 0 ;
//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if (limit> 1 )
     {
      limit=rates_total- 1 ;
       ArrayInitialize (BufferMAcalc, EMPTY_VALUE );
       ArrayInitialize (BufferMAstd, EMPTY_VALUE );
       ArrayInitialize (BufferPrice,0);
     }
//--- Подготовка данных
#ifdef __MQL5__
   int count=(limit> 1 ? rates_total : 1 ),copied= 0 ;
   copied= CopyBuffer (handle_ma, 0 , 0 ,count,BufferMAstd);
   if (copied!=count) return 0 ;
#endif 
//--- Расчёт индикатора
   for ( int i=limit; i>= 0 && ! IsStopped (); i--)
     {
       #ifdef __MQL4__ BufferMAstd[i]= iMA ( NULL , PERIOD_CURRENT ,period_ma, 0 ,InpMethod,InpAppliedPrice,i); #endif 
       BufferPrice[i]=avg.AppliedPrice(InpAppliedPrice, NULL , PERIOD_CURRENT ,i);
      BufferMAcalc[i]=avg.GetMA(rates_total,InpMethod,period_ma,i,BufferPrice);
     }

//--- return value of prev_calculated for next call
   return (rates_total);
  }
//+------------------------------------------------------------------+