Как начать работу с MQL5 - страница 7

 

Пример получения значений из индикатора iRSI

Код: iRSI get value.mq5

Не забывайте о правилах:создавайте хэндл индикатора ОДИН раз в OnInit,

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iRSI
   handle_iRSI=iRSI(Symbol(),Period(),Inp_RSI_ma_period,Inp_RSI_applied_price);
//--- if the handle is not created
   if(handle_iRSI==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iRSI indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }


использовать CopyBuffer для получения данных:

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double rsi[];
   ArraySetAsSeries(rsi,true);
   int start_pos=0,count=2;
   if(!iGetArray(handle_iRSI,0,start_pos,count,rsi))
      return;
//---
   string text="";
   int limit=(count>2)?2:count;
   for(int i=0; i<limit; i++)
     {
      text=text+
           " bar #"+IntegerToString(i)+": "+
           " rsi "+DoubleToString(rsi[i],2)+"\n";
     }
   Comment(text);
  }


Результат:

iRSI получить значение

Рис. 1. iRSI get value


Файлы:
 

Пример получения значений из индикатора iBands

Код (Эксперт): Значения iBands на графике.mq5

Не забывайте о правилах:создавайте хэндл индикатора ОДИН раз в OnInit,

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iBands
   handle_iBands=iBands(Symbol(),Period(),Inp_Bands_bands_period,
                        Inp_Bands_bands_shift,Inp_Bands_deviation,Inp_Bands_applied_price);
//--- if the handle is not created
   if(handle_iBands==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iBands indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }


использовать CopyBuffer для получения данных:

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   string text="";
   double upper[],lower[],middle[];
   ArraySetAsSeries(upper,true);
   ArraySetAsSeries(lower,true);
   ArraySetAsSeries(middle,true);
   int start_pos=0,count=3;
   if(!iGetArray(handle_iBands,UPPER_BAND,start_pos,count,upper) ||
      !iGetArray(handle_iBands,LOWER_BAND,start_pos,count,lower) ||
      !iGetArray(handle_iBands,BASE_LINE,start_pos,count,middle))
     {
      return;
     }
   string text_upper="",text_lower="",text_middle="";
   for(int i=count-1; i>=0; i--)
     {
      text_upper  = text_upper   + "Upper" + "["+IntegerToString(i) + "]" +" " + DoubleToString(upper[i],Digits()+1)  +" | ";
      text_lower  = text_lower   + "Lower" + "["+IntegerToString(i) + "]" +" " + DoubleToString(lower[i],Digits()+1)  +" | ";
      text_middle = text_middle  + "Middle"+ "["+IntegerToString(i) + "]" +" " + DoubleToString(middle[i],Digits()+1) +" | ";
     }
   Comment(text_upper+"\n"+text_lower+"\n"+text_middle);
  }


Результат:

Значения iBands на графике

Рис. 1. Значения iBands на графике

 

Пример создания индикатора на основе iATR

Код: xSuperTrend.mq5


Шаг 1: В редакторе MetaEditor перейдите в папку с индикаторами (в моем примере это папка "MyInd"). Далее нажмите правую кнопку мыши:

Шаг 1

Рис. 1. Шаг 1


Шаг 2: Выберите тип программы: Пользовательский индикатор

Шаг 2

Рис. 2. Шаг 2


Шаг 3: Введите название индикатора

Шаг 3

Рис. 3. Шаг 3


Шаг 4. Подключаем полную форму для OnCalculate

Шаг 4

Рис. 4. Шаг 4


Шаг 5. Мы добавляем к индикатору три графические конструкции. Мы даем им имена и цвета.

Шаг 5

Рис. 5. Шаг 5


В результате мы получаем пустой индикатор. Обозначим эту версию числом '1.000'.


Продолжение следует ...

Файлы:
 

Пример создания индикатора на основе iATR. Часть 2.

Код: xSuperTrend.mq5


Приступаем к наполнению нашего индикатора: добавляем входные параметры, добавляем переменную"handle_iATR" - в ней будет храниться хэндл индикатора iATR.

#property indicator_width3  1
//--- input parameters
input int      Inp_ma_period           = 10;    // Super Trend: averaging period 
input double   Inp_multiplier          = 3.0;   // Super Trend: multiplier
//--- indicator buffers
double   UpTrendBuffer[];
double   SuperTrendBuffer[];
double   DownTrendBuffer[];
//---
int      handle_iATR;                          // variable for storing the handle of the iATR indicator
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()


Примечание: переменная "handle_iATR" объявляется на глобальном уровне программы (в "заголовке" программы).

Сохраните номер версии 1.001


Продолжение следует ...

Файлы:
 

Пример создания индикатора на основе iATR. Часть 3.

Код: xSuperTrend.mq5

Работает с помощью ( iATR )

Наш индикатор ('xSuperTrend') оснащен iATR - а это значит, что нам нужен еще один буфер. Добавьте буфер.

Было:

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   3

*** 
//--- indicator buffers
double   UpTrendBuffer[];
double   SuperTrendBuffer[];
double   DownTrendBuffer[];
//---
int      handle_iATR;                          // variable for storing the handle of the iATR indicator

Стало:

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   3

*** 
//--- indicator buffers
double   UpTrendBuffer[];
double   SuperTrendBuffer[];
double   DownTrendBuffer[];
double   iATRBuffer[];
//---
int      handle_iATR;                          // variable for storing the handle of the iATR indicator


Получаем хэндл индикатора (не забывайте: хэндл должен быть получен ОДИН раз в OnInit)

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,UpTrendBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SuperTrendBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,DownTrendBuffer,INDICATOR_DATA);
   SetIndexBuffer(3,iATRBuffer,INDICATOR_CALCULATIONS);
   //--- create handle of the indicator iATR
   handle_iATR=iATR(Symbol(),Period(),Inp_ma_period);
//--- if the handle is not created
   if(handle_iATR==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iATR indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }

Сохраняем номер версии 1.002


Продолжение следует ...

Documentation on MQL5: Technical Indicators / iATR
Documentation on MQL5: Technical Indicators / iATR
  • www.mql5.com
//|                                                    Demo_iATR.mq5 | //|                        Copyright 2011, MetaQuotes Software Corp. | //|                                              https://www.mql5.com | "The method of creation of the handle is set through the 'type' parameter (function type...
Файлы:
 

Пример создания индикатора на основе iATR. Часть 4.

Код: xSuperTrend.mq5

Работает с помощью (iATR ) - копируйте-вставляйте :)

Сначала в "верхней части программы" добавляем переменную'bars_calculated' - в ней хранится количество баров, которые посчитал индикатор iATR.

int      handle_iATR;                           // variable for storing the handle of the iATR indicator
int      bars_calculated=0;                     // we will keep the number of values in the Average True Range indicator
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()

Практически полностью вставляем код из справки (В вставленном коде замените 'handle' на 'handle_iATR')

//+------------------------------------------------------------------+
//| 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[])
  {
//---
   int values_to_copy;
//--- determine the number of values calculated in the indicator
   int calculated=BarsCalculated(handle_iATR);
   if(calculated<=0)
     {
      PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
      return(0);
     }
//--- if it is the first start of calculation of the indicator or if the number of values in the iATR indicator changed
//---or if it is necessary to calculated the indicator for two or more bars (it means something has changed in the price history)
   if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
     {
      //--- if the iATRBuffer array is greater than the number of values in the iATR indicator for symbol/period, then we don't copy everything
      //--- otherwise, we copy less than the size of indicator buffers
      if(calculated>rates_total)
         values_to_copy=rates_total;
      else
         values_to_copy=calculated;
     }
   else
     {
      //--- it means that it's not the first time of the indicator calculation, and since the last call of OnCalculate()
      //--- for calculation not more than one bar is added
      values_to_copy=(rates_total-prev_calculated)+1;
     }
//--- fill the iATRBuffer array with values of the Average True Range indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operation
   if(!FillArrayFromBuffer(iATRBuffer,handle_iATR,values_to_copy))
      return(0);
//--- memorize the number of values in the Average True Range indicator
   bars_calculated=calculated;
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iATR indicator                |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[],  // indicator buffer for ATR values
                         int ind_handle,    // handle of the iATR indicator
                         int amount         // number of copied values
                        )
  {
//--- reset error code
   ResetLastError();
//--- fill a part of the iATRBuffer array with values from the indicator buffer that has 0 index
   if(CopyBuffer(ind_handle,0,0,amount,values)<0)
     {
      //--- if the copying fails, tell the error code
      PrintFormat("Failed to copy data from the iATR indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
//--- everything is fine
   return(true);
  }
//+------------------------------------------------------------------+
//| Indicator deinitialization function                              |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(handle_iATR!=INVALID_HANDLE)
      IndicatorRelease(handle_iATR);
   Comment("");
  }
//+------------------------------------------------------------------+

Сохраняем номер версии 1.003


Продолжение следует ...

Documentation on MQL5: Technical Indicators / iATR
Documentation on MQL5: Technical Indicators / iATR
  • www.mql5.com
//|                                                    Demo_iATR.mq5 | //|                        Copyright 2011, MetaQuotes Software Corp. | //|                                              https://www.mql5.com | "The method of creation of the handle is set through the 'type' parameter (function type...
Файлы:
 

Пример создания индикатора на основе iATR. Часть 5.

Код: xSuperTrend.mq5

До этого момента мы выполняли подготовительные операции. Теперь пришло время написать логику индикатора.

Чтобы избежать лишних вычислений, мы всегда работаем в переменной'prev_calculated'.

//--- memorize the number of values in the Average True Range indicator
   bars_calculated=calculated;
//--- main loop
   int limit=prev_calculated-1;
   if(prev_calculated==0)
      limit=1;
   for(int i=limit; i<rates_total; i++)
     {

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


Помните, что в индикаторе уже есть все массивы по текущему символу (ope, high, low, close и другие) - они передаются через OnCalculate.

   bars_calculated=calculated;
//--- main loop
   int limit=prev_calculated-1;
   if(prev_calculated==0)
      limit=1;
   for(int i=limit; i<rates_total; i++)
     {
      //--- сalculate SuperTrend
      UpTrendBuffer[i]  = (high[i-1]+low[i-1])/2.0+Inp_multiplier*iATRBuffer[i];
      DownTrendBuffer[i]= (high[i-1]+low[i-1])/2.0-Inp_multiplier*iATRBuffer[i];
      SuperTrendBuffer[i]=SuperTrendBuffer[i-1];
      //--- set SuperTrend levels
      if(close[i]>SuperTrendBuffer[i-1] && close[i-1]<=SuperTrendBuffer[i-1])
        {
         SuperTrendBuffer[i]=DownTrendBuffer[i];
        }
      else
         if(close[i]<SuperTrendBuffer[i-1] && close[i-1]>=SuperTrendBuffer[i-1])
           {
            SuperTrendBuffer[i]=UpTrendBuffer[i];
           }
         else
            if(SuperTrendBuffer[i-1]<DownTrendBuffer[i])
               SuperTrendBuffer[i]=DownTrendBuffer[i];
            else
               if(SuperTrendBuffer[i-1]>UpTrendBuffer[i])
                  SuperTrendBuffer[i]=UpTrendBuffer[i];
               else
                  SuperTrendBuffer[i]=SuperTrendBuffer[i-1];
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }


Сохраните номер версии 1.005


Конец.

Файлы:
xSuperTrend.mq5  16 kb
 

Пошаговая инструкция: индикатор отображает два iCCI в одном окне.

Таким образом, шаг за шагом:

Шаг 1

Рис. 1. Шаг первый

  1. Дайте имя индикатору
  2. Добавьте входной параметр (затем замените его)
  3. Нажмите кнопку " Далее ".


Полный текст и код: CCI Dual:

 

Простой пример Одна позиция

Код: Простой пример Одна позиция.mq5

//+------------------------------------------------------------------+
//|                                  Simple example One position.mq5 |
//|                              Copyright © 2020, Vladimir Karputov |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020, Vladimir Karputov"
#property version   "1.000"
/*
   barabashkakvn Trading engine 3.137
*/
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
//---
CPositionInfo  m_position;                   // object of CPositionInfo class
CTrade         m_trade;                      // object of CTrade class
CSymbolInfo    m_symbol;                     // object of CSymbolInfo class
//--- input parameters
input group             "Trading settings"
input ENUM_POSITION_TYPE   InpPosType           = POSITION_TYPE_BUY; // Open position
input group             "Additional features"
input ulong                InpDeviation         = 10;                // Deviation
input ulong                InpMagic             = 200;               // Magic number
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(!m_symbol.Name(Symbol())) // sets symbol name
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");
      return(INIT_FAILED);
     }
//---
   m_trade.SetExpertMagicNumber(InpMagic);
   m_trade.SetMarginMode();
   m_trade.SetTypeFillingBySymbol(m_symbol.Name());
   m_trade.SetDeviationInPoints(InpDeviation);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(!IsPositionExists())
     {
      if(InpPosType==POSITION_TYPE_BUY)
         m_trade.Buy(m_symbol.LotsMin());
      else
         m_trade.Sell(m_symbol.LotsMin());
     }
  }
//+------------------------------------------------------------------+
//| Is position exists                                               |
//+------------------------------------------------------------------+
bool IsPositionExists(void)
  {
   for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
            return(true);
//---
   return(false);
  }
//+------------------------------------------------------------------+


Советник удерживает одну позицию на рынке (заданного типа) - как только вы закроете эту позицию, советник снова откроет одну позицию.

Файлы:
 

Пример получения значения MultiTimeFrame iRSI

Код: Пример MultiTimeFrame iRSI get value.mq5

Следует помнить, что в MQL5 хэндл индикатора должен быть получен один раз (в OnInit). Задача: для индикаторов RSI есть три таймфрейма и свои параметры. Необходимо получить значения от этих индикаторов.

Алгоритм действий: на глобальном уровне программы (в "шапке" эксперта) объявляем массив'arr_handle_iRSI' - в этом массиве будут храниться хэндлы индикаторов RSI с разных таймфреймов.

Код:

//+------------------------------------------------------------------+
//|                        Example MultiTimeFrame iRSI get value.mq5 |
//|                              Copyright © 2020, Vladimir Karputov |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020, Vladimir Karputov"
#property version   "1.000"
/*
   barabashkakvn Trading engine 3.138
*/
//--- input parameters
input group             "RSI 0"
input bool                 Inp_RSI_0_Use           = true;        // RSI 0: Use
input ENUM_TIMEFRAMES      Inp_RSI_0_period        = PERIOD_M5;   // RSI 0: timeframe
input int                  Inp_RSI_0_ma_period     = 14;          // RSI 0: averaging period
input ENUM_APPLIED_PRICE   Inp_RSI_0_applied_price = PRICE_CLOSE; // RSI 0: type of price
input group             "RSI 1"
input bool                 Inp_RSI_1_Use           = true;        // RSI 1: Use
input ENUM_TIMEFRAMES      Inp_RSI_1_period        = PERIOD_H1;   // RSI 1: timeframe
input int                  Inp_RSI_1_ma_period     = 14;          // RSI 1: averaging period
input ENUM_APPLIED_PRICE   Inp_RSI_1_applied_price = PRICE_CLOSE; // RSI 1: type of price
input group             "RSI 2"
input bool                 Inp_RSI_2_Use           = true;        // RSI 2: Use
input ENUM_TIMEFRAMES      Inp_RSI_2_period        = PERIOD_D1;   // RSI 2: timeframe
input int                  Inp_RSI_2_ma_period     = 14;          // RSI 2: averaging period
input ENUM_APPLIED_PRICE   Inp_RSI_2_applied_price = PRICE_CLOSE; // RSI 2: type of price
input group             "Additional features"
input bool     InpPrintLog          = false;       // Print log
//---
int               arr_handle_iRSI[];                     // array for storing the handle of the iRSI indicator
ENUM_TIMEFRAMES   arr_timeframe_iRSI[];                  // array for storing the timeframe of the iRSI indicator
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(Inp_RSI_0_Use)
     {
      //--- create handle of the indicator iRSI
      int handle_iRSI=iRSI(Symbol(),Inp_RSI_0_period,Inp_RSI_0_ma_period,Inp_RSI_0_applied_price);
      //--- if the handle is not created
      if(handle_iRSI==INVALID_HANDLE)
        {
         //--- tell about the failure and output the error code
         PrintFormat("Failed to create handle of the iRSI indicator for the symbol %s/%s, error code %d",
                     Symbol(),
                     EnumToString(Inp_RSI_0_period),
                     GetLastError());
         //--- the indicator is stopped early
         return(INIT_FAILED);
        }
      int size=ArraySize(arr_handle_iRSI);
      ArrayResize(arr_handle_iRSI,size+1,3);
      ArrayResize(arr_timeframe_iRSI,size+1,3);
      arr_handle_iRSI[size]=handle_iRSI;
      arr_timeframe_iRSI[size]=Inp_RSI_0_period;
     }
//---
   if(Inp_RSI_1_Use)
     {
      //--- create handle of the indicator iRSI
      int handle_iRSI=iRSI(Symbol(),Inp_RSI_1_period,Inp_RSI_1_ma_period,Inp_RSI_1_applied_price);
      //--- if the handle is not created
      if(handle_iRSI==INVALID_HANDLE)
        {
         //--- tell about the failure and output the error code
         PrintFormat("Failed to create handle of the iRSI indicator for the symbol %s/%s, error code %d",
                     Symbol(),
                     EnumToString(Inp_RSI_1_period),
                     GetLastError());
         //--- the indicator is stopped early
         return(INIT_FAILED);
        }
      int size=ArraySize(arr_handle_iRSI);
      ArrayResize(arr_handle_iRSI,size+1,3);
      ArrayResize(arr_timeframe_iRSI,size+1,3);
      arr_handle_iRSI[size]=handle_iRSI;
      arr_timeframe_iRSI[size]=Inp_RSI_1_period;
     }
//---
   if(Inp_RSI_2_Use)
     {
      //--- create handle of the indicator iRSI
      int handle_iRSI=iRSI(Symbol(),Inp_RSI_2_period,Inp_RSI_2_ma_period,Inp_RSI_2_applied_price);
      //--- if the handle is not created
      if(handle_iRSI==INVALID_HANDLE)
        {
         //--- tell about the failure and output the error code
         PrintFormat("Failed to create handle of the iRSI indicator for the symbol %s/%s, error code %d",
                     Symbol(),
                     EnumToString(Inp_RSI_2_period),
                     GetLastError());
         //--- the indicator is stopped early
         return(INIT_FAILED);
        }
      int size=ArraySize(arr_handle_iRSI);
      ArrayResize(arr_handle_iRSI,size+1,3);
      ArrayResize(arr_timeframe_iRSI,size+1,3);
      arr_handle_iRSI[size]=handle_iRSI;
      arr_timeframe_iRSI[size]=Inp_RSI_2_period;
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int size=ArraySize(arr_handle_iRSI);
   if(size==0)
      return;
//---
   string text="";
   for(int i=0; i<size; i++)
     {
      double rsi[];
      ArraySetAsSeries(rsi,true);
      int start_pos=0,count=3;
      if(!iGetArray(arr_handle_iRSI[i],0,start_pos,count,rsi))
         return;
      //---
      text=text+EnumToString(arr_timeframe_iRSI[i]);
      int limit=(count>3)?3:count;
      for(int j=0; j<limit; j++)
        {
         text=text+
              " bar#"+IntegerToString(j)+": "+
              " rsi "+DoubleToString(rsi[j],2);
        }
      text=text+"\n";
     }
   Comment(text);
  }
//+------------------------------------------------------------------+
//| Get value of buffers                                             |
//+------------------------------------------------------------------+
bool iGetArray(const int handle,const int buffer,const int start_pos,
               const int count,double &arr_buffer[])
  {
   bool result=true;
   if(!ArrayIsDynamic(arr_buffer))
     {
      if(InpPrintLog)
         PrintFormat("ERROR! EA: %s, FUNCTION: %s, this a no dynamic array!",__FILE__,__FUNCTION__);
      return(false);
     }
   ArrayFree(arr_buffer);
//--- reset error code
   ResetLastError();
//--- fill a part of the iBands array with values from the indicator buffer
   int copied=CopyBuffer(handle,buffer,start_pos,count,arr_buffer);
   if(copied!=count)
     {
      //--- if the copying fails, tell the error code
      if(InpPrintLog)
         PrintFormat("ERROR! EA: %s, FUNCTION: %s, amount to copy: %d, copied: %d, error code %d",
                     __FILE__,__FUNCTION__,count,copied,GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
   return(result);
  }
//+------------------------------------------------------------------+


Результат работы:

Пример получения значения MultiTimeFrame iRSI

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