Quaisquer perguntas de recém-chegados sobre MQL4 e MQL5, ajuda e discussão sobre algoritmos e códigos - página 670

 
Roman Sharanov:
Como criar uma série de instâncias de classe?
Eu fiz ClassName* className[], depois ArrayResize nele, mas isso não me dá acesso a métodos

Sua classe, cujas instâncias você deseja coletar em um array, deve ser herdada de CObject.

E depois é simples: crie uma lista (array) de objetos CArrayObj, e adicione seus objetos a ela.

 
psyman:

Procurando as palavras "modelo indicador" e seu nome não encontra nada, e você já escreveu aqui sobre esse volume de Guerra e Paz.

Qualquer combinação de palavras do correio vem à mente.

Bem, desculpe, sobre o modelo indicador talvez eu o tenha confundido - o modelo de arrasto foi afixado.

Vamos colocar desta forma: criar um modelo de indicador no editor, adicionar o número necessário de variáveis de entrada e buffers a serem desenhados.

Em seguida, separe o que você precisa fazer da tarefa específica.

 
psyman:

Se você diz que é ruim, diga-me como torná-lo bom. Mova os cálculos para o OnInit?

Fair rebuke )) Aqui, uma variante do código que foi publicado aqui:

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);

Tente fazer isso dessa maneira. Você não precisa mover nada para o OnInit.

 
Andrei Novichkov:

Fair rebuke )) Aqui, uma variante do código que foi publicado aqui:

Tente fazer desta maneira. Você não precisa mover nada para o OnInit.

Eu não publiquei tal código aqui - não é o meu estilo :)

Utilizo outras construções - é mais simples e claro.

No OnInit() ela deve ser transferida. Por que você precisa atribuir uma matriz ao buffer indicador em cada carrapato?

 
Artyom Trishkin:

Eu não publiquei tal código aqui - não é o meu estilo :)

Utilizo outras construções - mais simples e claras.

É meu, como poderia ser mais simples? ))) (pelo menos, também tenho em meu modelo olimite de comentários= taxas_total - 1;//--- Primeira chamada de indicador ou mudança de prazo ou carregamento de dados do histórico) e meu estilo de formatação - um colchete próximo a() {

Para aprender a escrever seu próprio indicador, pegue o modelo acima e adicione pelo menos o preço de fechamento e obtenha seu primeiro indicador, depois aprenda a fazer o MAH a partir deste preço de fechamento

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

Eu não publiquei tal código aqui - não é o meu estilo :)

Utilizo construções diferentes - mais simples e mais claras.

Nada precisa ser copiado para o OnInit(). Por que eu deveria atribuir uma matriz ao buffer indicador a cada tick?

Não é o seu código. Foi publicado por alguns de meus colegas, mas não consigo lembrar quem e onde. Foi este código que eu quis dizer quando disse que nada deveria ser movido para o OnInit, mas não o código fonte. Eu não fui muito claro.

E que construção você recomendaria? Isto parece ser muito simples.



Ah, está ali o autor da peça )))) À minha frente. A propósito, também utilizo este estilo de formatação - com uma abertura de parênteses curvos em uma linha.
 
Andrei Novichkov:
Ah, aqui está o autor do trecho )))) À minha frente. A propósito, também utilizo este estilo de formatação - com uma abertura de parênteses enrolados em uma linha.

Você executa o Assistente para criar um indicador, seleciona tipos e cor de linhas e adiciona entradas, se necessário.

e isso é tudo, o indicador está pronto, então copieo corpo daOnCalculate() do modelo e escreva os cálculos ,

você pode escrever seu primeiro indicador em 1 minuto, o código "Olá palavra I indicador! - Eu mostrei :)

ZS: A propósito, os indicadores podem ser transferidos do MT4 para o MT5 nesta forma, o principal é configurar corretamente os buffers de indicadores, no MT5 há uma rasteira na indexação de arrays sob os buffers.... eles são apenas matrizes com a matriz usual )))) indexação .... costumava ser difícil habituar-se à indexação de buffers indicadores no MT4, agora ao contrário, é impossível habituar-se e mudar para o MT5 ))))
 
Andrei Novichkov:

Este não é o seu código. Foi publicado por um de meus colegas, mas não consigo lembrar quem e onde. Era este código que eu queria dizer quando disse que nada deveria ser movido para o OnInit, mas não o código fonte. Eu não fui muito claro.

E que construção você recomendaria? Este aqui parece ser muito simples.



Ah, está ali o autor da peça )))) À minha frente.
//+------------------------------------------------------------------+
//| 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 :

sim, para que serve o código do modelo de indicador? execute o assistente para criar um indicador , escolha os tipos e cores das linhas e, se necessário, adicione entradas

e pronto, o indicador está pronto, então copie o corpo do template OnCalculate() e escreva os cálculos,

você pode escrever seu primeiro indicador em 1 minuto, o código acima é "Olá palavra I indicador!!!" Eu mostrei :)

PS: a propósito, neste formulário, os indicadores podem ser transferidos do MT4 para o MT5, o principal é configurar os buffers do indicador corretamente, no MT5 há um horror que com matrizes de indexação para buffers .... eles são apenas matrizes com a matriz usual)))) indexação .. .. antes era difícil se acostumar com a indexação de buffers de indicadores no MT4, agora, pelo contrário, é impossível se acostumar e mudar para MT5))))

Nada complicado. Um exemplo de indicador de plataforma cruzada (usa uma classe), mas o modelo pode ser retirado - remova a classe e tudo supérfluo que dará erros depois disso - o modelo de plataforma cruzada permanecerá.

Este indicador funcionará da mesma forma em ambas as plataformas sem modificação - apenas compilação com a extensão necessária. Eu tive que dividir o código em duas partes - a classe e o próprio indicador (tudo estava em uma listagem)

Aula:

 //+------------------------------------------------------------------+
//|                                                       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 );
  }  
//+------------------------------------------------------------------+
 

Indicador:

//+------------------------------------------------------------------+
//|                                                       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);
  }
//+------------------------------------------------------------------+
Razão: