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

 
Konstantin Nikitin:
Ну вот и задача поменялась. Смотрим ваше первое сообщение

имелось ввиду средней МА

 
Tango_X:

имелось ввиду средней МА

Насколько я понял. Вам проще будет отследить появление нового бара на старшем TF и запросить предыдущий бар с младшего TF.

 
Konstantin Nikitin:

Насколько я понял. Вам проще будет отследить появление нового бара на старшем TF и запросить предыдущий бар с младшего TF.

Так будет на истории, а в режиме реального времени нужно отследить все значения МА на каждом баре М1 внутри свечи Н1

 
Tango_X:

Так будет на истории, а в режиме реального времени нужно отследить все значения МА на каждом баре М1 внутри свечи Н1

Немного другой вариант к реализации:

  1. Отслеживаете на старшем тф datetime минуты(newdatetime)
  2. Наступила новая минута (oldatetime!=newdatetime).
  3. Если время 0-го бара m1 совпадает c newdatetime, то скопировали массив(ы) open(или другие) необходимой размерности с 0-го(1-го индекса) с тф m1.
  4. Если время 0-го бара m1 не совпадает c newdatetime, на следующем вызове индикатора повторяем п.3
  5. Посчитали на этом массиве необходимые индикаторы, olddatetime=newdatetime.

А с непосредственным вызовом стандартных индикаторов много чего проверять и гадать как оно сработает в случае чего.

Еще для справки:

https://www.mql5.com/ru/docs/series/iopen https://www.mql5.com/ru/docs/series/itime

Документация по MQL5: Доступ к таймсериям и индикаторам / iOpen
Документация по MQL5: Доступ к таймсериям и индикаторам / iOpen
  • www.mql5.com
Значение цены открытия бара (указанного параметром shift) соответствующего графика или 0 в случае ошибки. Для получения дополнительной информации об ошибке необходимо вызвать функцию GetLastError(). Функция всегда возвращает актуальные данные, для этого она при каждом вызове делает запрос к таймсерии по указанным символу/периоду. Это означает...
 
Tango_X:

Так будет на истории, а в режиме реального времени нужно отследить все значения МА на каждом баре М1 внутри свечи Н1

Зачем отслеживать? Ведь отобразить сможете только одно значение. Значит нужно запрашивать всегда одно значение и его отображать.


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


Вот набросок - без проверок:

//+------------------------------------------------------------------+
//|                                      MA on current timeframe.mq5 |
//|                              Copyright © 2019, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2019, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//---
#property indicator_label1  "iMA" 
#property indicator_type1   DRAW_LINE 
#property indicator_color1  clrThistle 
#property indicator_style1  STYLE_SOLID 
#property indicator_width1  1 
//--- input parameters
input ENUM_TIMEFRAMES      Inp_MA_period        = PERIOD_M1;   // MA: timeframe
input int                  Inp_MA_ma_period     = 12;          // MA: averaging period
input int                  Inp_MA_ma_shift      = 0;           // MA: horizontal shift
input ENUM_MA_METHOD       Inp_MA_ma_method     = MODE_SMA;    // MA: smoothing type
input ENUM_APPLIED_PRICE   Inp_MA_applied_price = PRICE_CLOSE; // MA: type of price

double iMABuffer[];                       // indicator buffer 
int    handle_iMA;                        // variable for storing the handle of the iMA indicator
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Binding an array and an indicator buffer 
   SetIndexBuffer(0,iMABuffer,INDICATOR_DATA);
//--- The 0 (empty) value will mot participate in drawing 
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//--- create handle of the indicator iMA 
   handle_iMA=iMA(Symbol(),Inp_MA_period,Inp_MA_ma_period,Inp_MA_ma_shift,
                  Inp_MA_ma_method,Inp_MA_applied_price);
//--- if the handle is not created 
   if(handle_iMA==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);
     }
//---
   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[])
  {
//---
   if(prev_calculated==0)
      ArrayInitialize(iMABuffer,0.0);

   double   buffer[];
   int      buffer_num=0;           // indicator buffer number
   int      start_pos=0;            // start position
   int      count=1;                // amount to copy
   if(!iGetArray(handle_iMA,buffer_num,start_pos,count,buffer))
      return(0);

   iMABuffer[rates_total-1]=buffer[0];
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Get value of buffers                                             |
//+------------------------------------------------------------------+
double iGetArray(const int handle,const int buffer,const int start_pos,const int count,double &arr_buffer[])
  {
   bool result=true;
   if(!ArrayIsDynamic(arr_buffer))
     {
      Print("This a no dynamic array!");
      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 
      PrintFormat("Failed to copy data from the indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated 
      return(false);
     }
   return(result);
  }
//+------------------------------------------------------------------+
Файлы:
 

Хотя мой пример плохой - пока после запуска не нарисует два бара - линия не может отобразится.

А вот версия 1.001 уже решает эту проблему:

//+------------------------------------------------------------------+
//| 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[])
  {
//---
   double   buffer[];
   int      buffer_num=0;           // indicator buffer number
   int      start_pos=0;            // start position
   int      count=1;                // amount to copy
   if(!iGetArray(handle_iMA,buffer_num,start_pos,count,buffer))
      return(0);

   if(prev_calculated==0)
     {
      ArrayInitialize(iMABuffer,0.0);
      iMABuffer[rates_total-2]=buffer[0];
     }

   iMABuffer[rates_total-1]=buffer[0];
//--- return value of prev_calculated for next call
   return(rates_total);
  }

При первом старте или при подкачке истории заполняем бар #rates_total-2 и линия сразу рисуется.

Файлы:
 
Vladimir Karputov:

Хотя мой пример плохой - пока после запуска не нарисует два бара - линия не может отобразится.

А вот версия 1.001 уже решает эту проблему:

При первом старте или при подкачке истории заполняем бар #rates_total-2 и линия сразу рисуется.

Можно попробовать так это дело отображать.

 
Vladimir Karputov:

Зачем отслеживать? Ведь отобразить сможете только одно значение. Значит нужно запрашивать всегда одно значение и его отображать.


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


Вот набросок - без проверок:

Спасибо!!! Добавил историю

for(int i=0; i<rates_total;i++)
        {
         if(!iGetArray(handle_iMA,buffer_num,iBarShift(NULL,PERIOD_M1,time[i],false),count,buffer))
            return(0);
         iMABuffer[i]=buffer[0];
        }