Как в индикаторе получить значение другого индикатора с младшего таймфрейма

 

Здравствуйте! хочу получить значение средней с минутного тайма находясь на любом другом таймфрейме - но мне выдает ошибку! Подскажите что делаю не так. Спасибо!

//+------------------------------------------------------------------+
//|                                                          IMA.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window

//--- MA handles
int                      ExtFastMaHandle;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   ExtFastMaHandle=iMA(NULL,PERIOD_M1,12,0,MODE_EMA,PRICE_CLOSE);
//---
   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[])
  {
//---
   //--- not all data may be calculated
   int calculated=BarsCalculated(ExtFastMaHandle);
   if(calculated<rates_total)
     {
      Print("Not all data of ExtFastMaHandle is calculated (",calculated,"bars ). Error",GetLastError());
      return(0);
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 

Справка:

BarsCalculated

Возвращает количество рассчитанных данных для запрашиваемого индикатора.

int  BarsCalculated( 
   int       indicator_handle,     // handle индикатора 
   );

Параметры

indicator_handle

[in]  Хэндл индикатора, полученный соответствующей индикаторной функцией.

Возвращаемое значение

Возвращает количество рассчитанных данных в индикаторном буфере или -1 в случае ошибки (данные еще не рассчитаны).


То есть нужно проверить BarsCalculated на ошибку (на "-1"). Не зачем сравнивать количество посчитанных баров на индикаторе с rates_total Вашего индикатора. 

 
Vladimir Karputov:

Справка:

BarsCalculated

Возвращает количество рассчитанных данных для запрашиваемого индикатора.

int  BarsCalculated( 
   int       indicator_handle,     // handle индикатора 
   );

Параметры

indicator_handle

[in]  Хэндл индикатора, полученный соответствующей индикаторной функцией.

Возвращаемое значение

Возвращает количество рассчитанных данных в индикаторном буфере или -1 в случае ошибки (данные еще не рассчитаны).


То есть нужно проверить BarsCalculated на ошибку (на "-1"). Не зачем сравнивать количество посчитанных баров на индикаторе с rates_total Вашего индикатора. 

Сделал как Вы написали, но ничего не изменилось

//+------------------------------------------------------------------+
//|                                                          IMA.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window

//--- MA handles
int                      ExtFastMaHandle;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   ExtFastMaHandle=iMA(NULL,PERIOD_M1,12,0,MODE_EMA,PRICE_CLOSE);
//---
   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[])
  {
//---
   //--- not all data may be calculated
   int calculated=BarsCalculated(ExtFastMaHandle);
   if(calculated<0)
     {
      Print("Not all data of ExtFastMaHandle is calculated (",calculated,"bars ). Error",GetLastError());
      return(0);
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Надо обновить график и тогда все работает... просто наверное выходные..
 
Tango_X:
Надо обновить график и тогда все работает... просто наверное выходные..

Есть решение без обновления?

 

Получение данных с чужого таймфрейма при первом запуске редко когда отдаст сразу количество посчитанных баров - и это правильно. Вот пример: получение данных с индикаторов на текущем таймфрейме и с двух чужих:

//+------------------------------------------------------------------+
//|                                          MA Three Timeframes.mq5 |
//|                              Copyright © 2017, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0
//--- input parameters
//--- MA
input int                  Inp_MA_0_ma_period      = 12;             // MA 0: averaging period
input int                  Inp_MA_0_ma_shift       = 0;              // MA 0: horizontal shift
input ENUM_MA_METHOD       Inp_MA_0_ma_method      = MODE_SMA;       // MA 0: smoothing type
input ENUM_APPLIED_PRICE   Inp_MA_0_applied_price  = PRICE_CLOSE;    // MA 0: type of price

input ENUM_TIMEFRAMES      Inp_MA_1_period         = PERIOD_M1;      // MA 1: timeframe
input int                  Inp_MA_1_ma_period      = 12;             // MA 1: averaging period
input int                  Inp_MA_1_ma_shift       = 0;              // MA 1: horizontal shift
input ENUM_MA_METHOD       Inp_MA_1_ma_method      = MODE_SMA;       // MA 1: smoothing type
input ENUM_APPLIED_PRICE   Inp_MA_1_applied_price  = PRICE_CLOSE;    // MA 1: type of price

input ENUM_TIMEFRAMES      Inp_MA_2_period         = PERIOD_D1;      // MA 2: timeframe
input int                  Inp_MA_2_ma_period      = 12;             // MA 2: averaging period
input int                  Inp_MA_2_ma_shift       = 0;              // MA 2: horizontal shift
input ENUM_MA_METHOD       Inp_MA_2_ma_method      = MODE_SMA;       // MA 2: smoothing type
input ENUM_APPLIED_PRICE   Inp_MA_2_applied_price  = PRICE_CLOSE;    // MA 2: type of price
//---
int    handle_iMA_0;                         // variable for storing the handle of the iMA indicator
int    handle_iMA_1;                         // variable for storing the handle of the iMA indicator
int    handle_iMA_2;                         // variable for storing the handle of the iMA indicator
//---
ulong  ExtCounter=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iMA 
   handle_iMA_0=iMA(Symbol(),Period(),Inp_MA_0_ma_period,Inp_MA_0_ma_shift,
                    Inp_MA_0_ma_method,Inp_MA_0_applied_price);
//--- if the handle is not created 
   if(handle_iMA_0==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code 
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early 
      return(INIT_FAILED);
     }
//--- create handle of the indicator iMA 
   handle_iMA_1=iMA(Symbol(),Inp_MA_1_period,Inp_MA_1_ma_period,Inp_MA_1_ma_shift,
                    Inp_MA_1_ma_method,Inp_MA_1_applied_price);
//--- if the handle is not created 
   if(handle_iMA_1==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code 
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Inp_MA_1_period),
                  GetLastError());
      //--- the indicator is stopped early 
      return(INIT_FAILED);
     }
//--- create handle of the indicator iMA 
   handle_iMA_2=iMA(Symbol(),Inp_MA_2_period,Inp_MA_2_ma_period,Inp_MA_2_ma_shift,
                    Inp_MA_2_ma_method,Inp_MA_2_applied_price);
//--- if the handle is not created 
   if(handle_iMA_2==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code 
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Inp_MA_2_period),
                  GetLastError());
      //--- the indicator is stopped early 
      return(INIT_FAILED);
     }
//---
   ExtCounter=0;
//---
   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[])
  {
//---
   int calculated_1=BarsCalculated(handle_iMA_1);
   int calculated_2=BarsCalculated(handle_iMA_2);
   Print(IntegerToString(ExtCounter)+"\n"+
         EnumToString(PERIOD_CURRENT)+": "+IntegerToString(prev_calculated)+"\n"+
         EnumToString(Inp_MA_1_period)+": "+IntegerToString(calculated_1)+"\n"+
         EnumToString(Inp_MA_2_period)+": "+IntegerToString(calculated_2));
   ExtCounter++;
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

и результат (ВНИМАНИЕ: специально вывел данные через Print. Когда рынок откроется - такой Print может сильно засорить лог-файл!). Как видите даже менял символы - и все данные подтянулись и индикаторы рассчитались:

MA Three Timeframes (EURUSD,M15)        0
MA Three Timeframes (EURUSD,M15)        PERIOD_CURRENT: 0
MA Three Timeframes (EURUSD,M15)        PERIOD_M1: -1
MA Three Timeframes (EURUSD,M15)        PERIOD_D1: -1
MA Three Timeframes (EURUSD,M15)        1
MA Three Timeframes (EURUSD,M15)        PERIOD_CURRENT: 501052
MA Three Timeframes (EURUSD,M15)        PERIOD_M1: 500000
MA Three Timeframes (EURUSD,M15)        PERIOD_D1: 12394
MA Three Timeframes (USDCHF,M15)        0
MA Three Timeframes (USDCHF,M15)        PERIOD_CURRENT: 0
MA Three Timeframes (USDCHF,M15)        PERIOD_M1: -1
MA Three Timeframes (USDCHF,M15)        PERIOD_D1: -1
MA Three Timeframes (USDCHF,M15)        1
MA Three Timeframes (USDCHF,M15)        PERIOD_CURRENT: 0
MA Three Timeframes (USDCHF,M15)        PERIOD_M1: -1
MA Three Timeframes (USDCHF,M15)        PERIOD_D1: 12351
MA Three Timeframes (USDCHF,M15)        2
MA Three Timeframes (USDCHF,M15)        PERIOD_CURRENT: 500076
MA Three Timeframes (USDCHF,M15)        PERIOD_M1: -1
MA Three Timeframes (USDCHF,M15)        PERIOD_D1: 12351
MA Three Timeframes (USDCHF,M15)        3
MA Three Timeframes (USDCHF,M15)        PERIOD_CURRENT: 0
MA Three Timeframes (USDCHF,M15)        PERIOD_M1: -1
MA Three Timeframes (USDCHF,M15)        PERIOD_D1: 12351
MA Three Timeframes (USDCHF,M15)        4
MA Three Timeframes (USDCHF,M15)        PERIOD_CURRENT: 0
MA Three Timeframes (USDCHF,M15)        PERIOD_M1: 342961
MA Three Timeframes (USDCHF,M15)        PERIOD_D1: 12352
MA Three Timeframes (NZDCAD,M15)        0
MA Three Timeframes (NZDCAD,M15)        PERIOD_CURRENT: 0
MA Three Timeframes (NZDCAD,M15)        PERIOD_M1: -1
MA Three Timeframes (NZDCAD,M15)        PERIOD_D1: -1
MA Three Timeframes (NZDCAD,M15)        1
MA Three Timeframes (NZDCAD,M15)        PERIOD_CURRENT: 109467
MA Three Timeframes (NZDCAD,M15)        PERIOD_M1: 500000
MA Three Timeframes (NZDCAD,M15)        PERIOD_D1: 1146
MA Three Timeframes (NZDCAD,M15)        2
MA Three Timeframes (NZDCAD,M15)        PERIOD_CURRENT: 0
MA Three Timeframes (NZDCAD,M15)        PERIOD_M1: 500000
MA Three Timeframes (NZDCAD,M15)        PERIOD_D1: 1147
Файлы:
 

Владимир спасибо за советы! Хочу продолжить тему.

Теперь мы выводим показания МА младшего ТФ на текущего ТФ и сразу возникает вопрос - как правильно считывать показания МА младшего ТФ (М1) на текущем ТФ(к примеру на  Н1) внутри бара? т.е нужно в режиме онлайн видеть изменения МА внутри свечи Н1. В приведенном ниже коде мы видим показания МА только на начало нового бара старшего ТФ. Есть кое какие идеи по этому поводу - но получается очень громоздкий код). Интересует как это правильно делается? Спасибо!

//+------------------------------------------------------------------+
//|                                                          Ma.mq5  |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Ma
#property indicator_label1  "Ma minute"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- indicator buffers
double         MaBuffer[];
//--- MA handles
int                      MaHandle;

double Ma[1];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MaBuffer,INDICATOR_DATA);
   MaHandle=iMA(NULL,PERIOD_M1,12,0,MODE_EMA,PRICE_CLOSE);
   if(MaHandle==INVALID_HANDLE)
     {
      Print("Invalid handle of Ma indicator");
      return(-1);
     }
//---
   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[])
  {
//---
   int calculated=BarsCalculated(MaHandle);
   if(calculated<0)
     {
      Print("Not all data of MaHandle is calculated (",calculated,"bars ). Error",GetLastError());
      return(0);
     }
   
   int limit;
   if(prev_calculated==0)
      limit=0;
   else limit=prev_calculated-1;
//--- calculate Ma
   for(int i=limit;i<rates_total && !IsStopped();i++)
     {
      CopyBuffer(MaHandle,0,time[i],1,Ma);
      MaBuffer[i]=Ma[0];
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Tango_X:

Владимир спасибо за советы! Хочу продолжить тему.

Теперь мы выводим показания МА младшего ТФ на текущего ТФ и сразу возникает вопрос - как правильно считывать показания МА младшего ТФ (М1) на текущем ТФ(к примеру на  Н1) внутри бара? т.е нужно в режиме онлайн видеть изменения МА внутри свечи Н1. В приведенном ниже коде мы видим показания МА только на начало нового бара старшего ТФ. Есть кое какие идеи по этому поводу - но получается очень громоздкий код). Интересует как это правильно делается? Спасибо!

Код неверный: Вы смешиваете зелёное и квадратное (создаёте цикл от limit до rates_total - это зеленое) и пытаетесь копировать данные из чужого Зендов - это квадратное).

 
Vladimir Karputov:

Код неверный: Вы смешиваете зелёное и квадратное (создаёте цикл от limit до rates_total - это зеленое) и пытаетесь копировать данные из чужого Зендов - это квадратное).

Вот вроде получилось, хотел бы услышать Ваших комментарий, может чего не учел... Спасибо!!!


//+------------------------------------------------------------------+
//|                                                          Ma.mq5  |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Ma
#property indicator_label1  "Ma minute"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  4
//--- indicator buffers
double         MaBuffer[];
//--- MA handles
int                      MaHandle;

double Ma[1];
datetime       gdt_BarOpenTime=0,gdt_BarOpenTime_m=0;
int kk;
datetime time_m[1];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MaBuffer,INDICATOR_DATA);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   MaHandle=iMA(NULL,PERIOD_M1,12,0,MODE_EMA,PRICE_CLOSE);
   if(MaHandle==INVALID_HANDLE)
     {
      Print("Invalid handle of Ma indicator");
      return(-1);
     }
//---
   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[])
  {
//---
   int calculated=BarsCalculated(MaHandle);
   if(calculated<0)
     {
      Print("Not all data of ExtFastMaHandle is calculated (",calculated,"bars ). Error",GetLastError());
      return(0);
     }

   int limit;
   if(prev_calculated==0)
     {
      limit=0;
      ArrayInitialize(MaBuffer,EMPTY_VALUE);
     }
   else limit=prev_calculated-1;
//--- calculate Ma

   for(int i=limit;i<rates_total && !IsStopped();i++)
     {
      // --- НОВЫЙ БАР
      if(gdt_BarOpenTime!=time[i])
        {
         CopyBuffer(MaHandle,0,time[i],1,Ma);
         MaBuffer[i]=Ma[0];
         kk=iBarShift(NULL,PERIOD_M1,time[i],false);// номер бара в массиве МА ТФ=М1
         kk++;
         gdt_BarOpenTime=time[i];
        }
      // ---   
      else
        {
         CopyTime(NULL,PERIOD_M1,kk,1,time_m);
         if(gdt_BarOpenTime_m!=time_m[0])
           {
            CopyBuffer(MaHandle,0,time_m[0],1,Ma);
            MaBuffer[i]=Ma[0];
            gdt_BarOpenTime_m=time_m[0];
            Print("Новый бар младшего ТФ ",time_m[0]," текущее время ",TimeCurrent(),"     ",NormalizeDouble(Ma[0],6));
           }
        }

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

Внимательно посмотрите:

//+------------------------------------------------------------------+
//| 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 calculated=BarsCalculated(MaHandle);


Это переменные rates_total и prev_calculated относятся к текущему графику и текущему таймфрейму.

А эта переменная calculated относится к чужому таймфрейму.

Количество баров текущего таймфрейма не равно количеству баров чужого таймрфема.

 
Vladimir Karputov:

Внимательно посмотрите:


Это переменные rates_total и prev_calculated относятся к текущему графику и текущему таймфрейму.

А эта переменная calculated относится к чужому таймфрейму.

Количество баров текущего таймфрейма не равно количеству баров чужого таймрфема.

Все верно, я это учел. Внутри цикла текущего ТФ я перебираю бары младшего ТФ. Все работает как надо... Или что то не так я сделал?