Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 990

 
kopeyka2:

Как раз это  проверял. Но ПРОБЛЕМА в том, что установив  хендэл  на один постоянный период,   в 

CopyBuffer значение на  других таймфреймах НЕ ПЕРЕДАЕТСЯ. На установленном хендлэ периоде  значение было, а на меньших таймфремах 0.0 (ноль). Подвигал в поисках по буферу... ноль. Почему не передается в  CopyBuffer  ?

У меня копируется...

//--- Подготовка данных
   int count=(limit>1 ? rates_total : 2),copied=0;
      ResetLastError();
   if(CopyBuffer(handle_ma,0,0,1,BufferPrice)<0)
     {
      PrintFormat("Failed to copy data from the handle_ma indicator, error code %d",GetLastError());
      return(0.0);
     }
//   copied=CopyBuffer(handle_ma,0,0,count,BufferPrice);
Print(BufferPrice[0]);

другой вопрос что копируется :) Вероятней всего Вы запрашиваете больше число баров для копирования, чем есть на том TF, принтаните

Print("count=",count," Bars=",Bars(Symbol(),Timeframes));
 
Artyom Trishkin:

Если хэндл создан успешно, то создан он с теми параметрами, которые вы ему передали при создании. И уж отдавать данные индикатора он будет на любом таймфрейме. Вот только данные он будет отдавать того таймфрейма, который ему задали при создании. И чтобы их корректно отобразить на рабочем таймфрейме, нужно преобразовать полученные данные от хэндла индикатора к тому тф, на котором работает ваш индикатор.

Верно ли я провел эксперемент.?

1)Я создал хэндэл по периоду D1.
2)Далее в CopyBuffer закладываем значения согласно инструкции (от куда и до куда).
Написал от нуля до N-ого бара.
В рамках этого интервала , по идее , должны записаться значения хэндэла. Даже при переходе на другой таймфрейм значения должны быть от установленного D1. А вот как раз этого я не наблюдаю. Или что-то не так? Что-то ещё надо дописать при установке хэндэла? Поскольку нет передачи в буфер.
 
kopeyka2:
Верно ли я провел эксперемент.?

1)Я создал хэндэл по периоду D1.
2)Далее в CopyBuffer закладываем значения согласно инструкции (от куда и до куда).
Написал от нуля до N-ого бара.
В рамках этого интервала , по идее , должны записаться значения хэндэла. Даже при переходе на другой таймфрейм значения должны быть от установленного D1. А вот как раз этого я не наблюдаю. Или что-то не так? Что-то ещё надо дописать при установке хэндэла? Поскольку нет передачи в буфер.

Я ж вам дал направление...

Изучайте:


//+------------------------------------------------------------------+
//|                                                     MTF_LRMA.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                                 https://mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com"
#property version   "1.00"
#property description "Multi Timeframe Linear Regression Moving Average with signal line"
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots   2
//--- plot LWMA
#property indicator_label1  "LRMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrLimeGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot Signal
#property indicator_label2  "Signal"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- enums
enum ENUM_DRAW_MODE
  {
   DRAW_MODE_STEPS,  // Steps
   DRAW_MODE_SLOPE   // Slope
  };
//--- input parameters
input uint              InpPeriod      =  34;               // LRMA period
input uint              InpSignal      =  5;                // Signal period
input ENUM_TIMEFRAMES   InpTimeframe   =  PERIOD_H1;        // LRMA timeframe
input ENUM_DRAW_MODE    InpDrawMode    =  DRAW_MODE_STEPS;  // Drawing mode
//--- indicator buffers
double         BufferLRMA[];
double         BufferSignal[];
double         BufferLRMATmp[];
double         BufferSignalTmp[];
double         BufferLWMA[];
double         BufferSMA[];
//--- global variables
ENUM_TIMEFRAMES   timeframe1;
int               period_lrma;
int               signal;
int               handle_lwma;
int               handle_sma;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- timer
   EventSetTimer(90);
//--- set global variables
   period_lrma=int(InpPeriod<1 ? 1 : InpPeriod);
   signal=int(InpSignal<1 ? 1 : InpSignal);
   timeframe1=(InpTimeframe>Period() ? InpTimeframe : Period());
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferLRMA,INDICATOR_DATA);
   SetIndexBuffer(1,BufferSignal,INDICATOR_DATA);
   SetIndexBuffer(2,BufferLRMATmp,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,BufferSignalTmp,INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,BufferLWMA,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,BufferSMA,INDICATOR_CALCULATIONS);
//--- setting indicator parameters
   string label=TimeframeToString(timeframe1)+" LRMA("+(string)period_lrma+","+(string)signal+")";
   IndicatorSetString(INDICATOR_SHORTNAME,label);
   IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--- setting plot buffer parameters
   PlotIndexSetString(0,PLOT_LABEL,TimeframeToString(timeframe1)+" LRMA("+(string)period_lrma+")");
   PlotIndexSetString(1,PLOT_LABEL,TimeframeToString(timeframe1)+" Signal("+(string)signal+")");
//--- setting buffer arrays as timeseries
   ArraySetAsSeries(BufferLRMA,true);
   ArraySetAsSeries(BufferSignal,true);
   ArraySetAsSeries(BufferLRMATmp,true);
   ArraySetAsSeries(BufferSignalTmp,true);
   ArraySetAsSeries(BufferLWMA,true);
   ArraySetAsSeries(BufferSMA,true);
//--- create handles
   ResetLastError();
   handle_lwma=iMA(NULL,timeframe1,period_lrma,0,MODE_LWMA,PRICE_CLOSE);
   if(handle_lwma==INVALID_HANDLE)
     {
      Print(__LINE__,": The ",TimeframeToString(timeframe1)," iMA(",(string)period_lrma,") object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
   handle_sma=iMA(NULL,timeframe1,period_lrma,0,MODE_SMA,PRICE_CLOSE);
   if(handle_sma==INVALID_HANDLE)
     {
      Print(__LINE__,": The ",TimeframeToString(timeframe1)," iMA(",(string)period_lrma,") object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
//--- get timeframe
   Time(NULL,timeframe1,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[])
  {
//--- Проверка количества доступных баров
   if(rates_total<fmax(signal,4)) return 0;
//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-signal-2;
      ArrayInitialize(BufferLRMA,0);
      ArrayInitialize(BufferSignal,0);
      ArrayInitialize(BufferLRMATmp,0);
      ArrayInitialize(BufferSignalTmp,0);
      ArrayInitialize(BufferLWMA,0);
      ArrayInitialize(BufferSMA,0);
     }
//--- Подготовка данных
   if(Time(NULL,timeframe1,1)==0)
      return 0;
   int bars=(timeframe1==Period() ? rates_total : Bars(NULL,timeframe1));
   int count=(limit>1 ? fmin(bars,rates_total) : 1),copied=0;
   copied=CopyBuffer(handle_lwma,0,0,count,BufferLWMA);
   if(copied!=count) return 0;
   copied=CopyBuffer(handle_sma,0,0,count,BufferSMA);
   if(copied!=count) return 0;
      
//--- Расчёт индикатора
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      BufferLRMATmp[i]=3.0*BufferLWMA[i]-2.0*BufferSMA[i];
      BufferSignalTmp[i]=GetSMA(bars,i,signal,BufferLRMATmp);
     }
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      DataConversion(rates_total,NULL,timeframe1,i,BufferLRMATmp,BufferLRMA,InpDrawMode);
      DataConversion(rates_total,NULL,timeframe1,i,BufferSignalTmp,BufferSignal,InpDrawMode);
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Custom indicator timer function                                  |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Time(NULL,timeframe1,1);
  }
//+------------------------------------------------------------------+
//| Transfering data from the source timeframe to current timeframe  |
//+------------------------------------------------------------------+
void DataConversion(const int rates_total,
                    const string symbol_name,
                    const ENUM_TIMEFRAMES timeframe_src,
                    const int shift,
                    const double &buffer_src[],
                    double &buffer_dest[],
                    ENUM_DRAW_MODE mode=DRAW_MODE_STEPS
                   )
  {
   if(timeframe_src==Period())
     {
      buffer_dest[shift]=buffer_src[shift];
      return;
     }
   int bar_curr=BarToCurrent(symbol_name,timeframe_src,shift);
   if(bar_curr>rates_total-1)
      return;
   int bar_prev=BarToCurrent(symbol_name,timeframe_src,shift+1);
   int bar_next=(shift>0 ? BarToCurrent(symbol_name,timeframe_src,shift-1) : 0);
   if(bar_prev==WRONG_VALUE || bar_curr==WRONG_VALUE || bar_next==WRONG_VALUE)
      return;
   buffer_dest[bar_curr]=buffer_src[shift];
   if(mode==DRAW_MODE_STEPS)
      for(int j=bar_curr; j>=bar_next; j--)
         buffer_dest[j]=buffer_dest[bar_curr];
   else
     {
      if(bar_prev>rates_total-1) return;
      for(int j=bar_prev; j>=bar_curr; j--)
         buffer_dest[j]=EquationDirect(bar_prev,buffer_dest[bar_prev],bar_curr,buffer_dest[bar_curr],j);
      if(shift==0)
         for(int j=bar_curr; j>=0; j--)
            buffer_dest[j]=buffer_dest[bar_curr];
     }
  }
//+------------------------------------------------------------------+
//| Возвращает бар заданного таймфрейма как бар текущего таймфрейма  |
//+------------------------------------------------------------------+
int BarToCurrent(const string symbol_name,const ENUM_TIMEFRAMES timeframe_src,const int shift,bool exact=false)
  {
   datetime time=Time(symbol_name,timeframe_src,shift);
   return(time!=0 ? BarShift(symbol_name,Period(),time,exact) : WRONG_VALUE);
  }
//+------------------------------------------------------------------+
//| Возвращает смещение бара по времени                              |
//| https://www.mql5.com/ru/forum/743/page11#comment_7010041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |
//+------------------------------------------------------------------+
int BarShift(const string symbol_name,const ENUM_TIMEFRAMES timeframe,const datetime time,bool exact=false)
  {
   int res=Bars(symbol_name,timeframe,time+1,UINT_MAX);
   if(exact) if((timeframe!=PERIOD_MN1 || time>TimeCurrent()) && res==Bars(symbol_name,timeframe,time-PeriodSeconds(timeframe)+1,UINT_MAX)) return(WRONG_VALUE);
   return res;
  }
//+------------------------------------------------------------------+
//| Возвращает Time                                                  |
//+------------------------------------------------------------------+
datetime Time(const string symbol_name,const ENUM_TIMEFRAMES timeframe,const int shift)
  {
   datetime array[];
   ArraySetAsSeries(array,true);
   return(CopyTime(symbol_name,timeframe,shift,1,array)==1 ? array[0] : 0);
  }
//+------------------------------------------------------------------+
//| Уравнение прямой                                                 |
//+------------------------------------------------------------------+
double EquationDirect(const int left_bar,const double left_price,const int right_bar,const double right_price,const int bar_to_search)
  {
   return(right_bar==left_bar ? left_price : (right_price-left_price)/(right_bar-left_bar)*(bar_to_search-left_bar)+left_price);
  }
//+------------------------------------------------------------------+
//| Timeframe to string                                              |
//+------------------------------------------------------------------+
string TimeframeToString(const ENUM_TIMEFRAMES timeframe)
  {
   return StringSubstr(EnumToString(timeframe),7);
  }
//+------------------------------------------------------------------+
//| Simple Moving Average                                            |
//+------------------------------------------------------------------+
double GetSMA(const int rates_total,const int index,const int period,const double &price[],const bool as_series=true)
  {
//---
   double result=0.0;
//--- check position
   bool check_index=(as_series ? index<=rates_total-period-1 : index>=period-1);
   if(period<1 || !check_index)
      return 0;
//--- calculate value
   for(int i=0; i<period; i++)
      result+=(as_series ? price[index+i]: price[index-i]);
//---
   return(result/period);
  }
//+------------------------------------------------------------------+
 
Aleksey Vyazmikin:

У меня копируется...

другой вопрос что копируется :) Вероятней всего Вы запрашиваете больше число баров для копирования, чем есть на том TF, принтаните

Все скромнее. Кучу не закладывают. Всего 1-2 бара на D1. Точнее так int lm=IBarShift(NULL,PERIOD_D1, iTime(NULL, PERIOD_CURRENT, limit));
int bars=PeriodSeconds(PERIOD_D1/PeriodSecond(_Period);

int startbar=lm-(lm-bars);

count в CopyBuffer  попробовал делать без limit и rate_total.

Проще говоря эксперемент руб с CopyByffer что в него класть, то и должно быть. Но там нет.
 

kopeyka2:
Верно ли я провел эксперемент.?

...

... Даже при переходе на другой таймфрейм значения должны быть от установленного D1. А вот как раз этого я не наблюдаю. Или что-то не так? Что-то ещё надо дописать при установке хэндэла? Поскольку нет передачи в буфер.

Проще говоря эксперемент руб с CopyByffer что в него класть, то и должно быть. Но там нет.

Вы не проверили доступность данных, но пытаетесь копировать. Гляньте в код выше - там в секундном таймере раз в полторы минуты идёт обращение к неродному таймфрейму - для постоянного поддержания данных в актуальном состоянии. И в коде первым делом проверяется доступность запрашиваемых данных. Если они ещё не готовы, то возврат нуля для следующего тика и полного расчёта индикатора. А вот когда уже все данные получены и рассчитаны, и отображены, то в конце возвращается количество рассчитанных данных - чтобы на следующем тике не делать полный перерасчёт.

 
Спасибо. Все прочитал. Буду искать.
 
kopeyka2:
Спасибо. Все прочитал. Буду искать.

Чего искать-то? Выше полностью рабочий код. Можете препарировать как хотите. Вашу ошибку я указал - вы не проверяете доступность данных.

Даже вот в этой строчке:

int lm=IBarShift(NULL,PERIOD_D1, iTime(NULL, PERIOD_CURRENT, limit));

где проверка того, что вернул iTime() ? Нету проверки. Но вы неизвестный результат сразу пихаете в iBarShift(). А уверены, что даёте функции то, что ожидаете?

 
Artyom Trishkin:

Если хэндл создан успешно, то создан он с теми параметрами, которые вы ему передали при создании. И уж отдавать данные индикатора он будет на любом таймфрейме. Вот только данные он будет отдавать того таймфрейма, который ему задали при создании. И чтобы их корректно отобразить на рабочем таймфрейме, нужно преобразовать полученные данные от хэндла индикатора к тому тф, на котором работает ваш индикатор.

Именно я так и думал. Вопрос непонимания в словах "параметры". И я начал смотреть ВСЕ переменные которые участвуют в хэндл --> CopyBuffer

1) Мой вопрос с самого начала был в том, что бы переключив ЭКРАН таймфрейна сохранить данные  хэндла. Ну как это в МТ4.

А на деле получается так: 

handle_ma=iMA(NULL,PERIOD_H1,period,0,MODE_SMA,PRICE_CLOSE); 

 Comment(handle_ma);  // ВСЕГДА 10

ВСЕГДА и на ВСЕХ таймфреймах дает одно и тоже значение 10

Ничего не получив тут я двинулся дальше.

2)  Цитирую: "Получает в массив buffer данные указанного буфера указанного индикатора в указанном количестве".

CopyBuffer(handle_ma,0,0,count,BufferPrice);  //

То есть, установив count от руки мы должны иметь ИНТЕРВАЛ со значениями. И они есть! НО!!!!!! Только когда период хэндла соответствует

таймфрейму на экране монитора PERIOD_H1. Все значения передаются четко. Но перейдя на другой таймфрейм на экране данных НЕТ.

Они НЕ ПЕРЕДАЮТСЯ НИКАК!!!! А мой вопрос был именно в этом. И количество баров для count тут не так важно, если их там НЕТ!!!


Я посмотрел предложенный индикатор MTF_LRMA.mq5 Но в нем тоже самое . Переключаемся на другой таймфрейм на экране и данные идут по таймфрейму экрана. А мне надо по хэндэлу.

Напррмер: iClose(NULL, PERIOD_H1, 5); на всех таймфреймах будут давать одно и тоже значение : Закрытие на 5 баре по Н1. 

Пока что все примеры были по корректировке count буфера CopyBuffer. НО массив то ПУСТОЙ


 
kopeyka2:

Именно я так и думал. Вопрос непонимания в словах "параметры". И я начал смотреть ВСЕ переменные которые участвуют в хэндл --> CopyBuffer

1) Мой вопрос с самого начала был в том, что бы переключив ЭКРАН таймфрейна сохранить данные  хэндла. Ну как это в МТ4.

А на деле получается так: 

ВСЕГДА и на ВСЕХ таймфреймах дает одно и тоже значение 10

Ничего не получив тут я двинулся дальше.

2)  Цитирую: "Получает в массив buffer данные указанного буфера указанного индикатора в указанном количестве".

То есть, установив count от руки мы должны иметь ИНТЕРВАЛ со значениями. И они есть! НО!!!!!! Только когда период хэндла соответствует

таймфрейму на экране монитора PERIOD_H1. Все значения передаются четко. Но перейдя на другой таймфрейм на экране данных НЕТ.

Они НЕ ПЕРЕДАЮТСЯ НИКАК!!!! А мой вопрос был именно в этом. И количество баров для count тут не так важно, если их там НЕТ!!!


Я посмотрел предложенный индикатор MTF_LRMA.mq5 Но в нем тоже самое . Переключаемся на другой таймфрейм на экране и данные идут по таймфрейму экрана. А мне надо по хэндэлу.

Напррмер: iClose(NULL, PERIOD_H1, 5); на всех таймфреймах будут давать одно и тоже значение : 10 баров по Н1. 

Пока что все примеры были по корректировке count буфера CopyBuffer. НО массив то ПУСТОЙ


Вы не правы. Хэндл отдает данные на любом таймфрейме. Часов через 10 дам пример. С мобилы не смогу
 
Artyom Trishkin:
Вы не правы. Хэндл отдает данные на любом таймфрейме. Часов через 10 дам пример. С мобилы не смогу

Ок. Спасибо за ответ 


Исправил сам себя 

Напррмер: iClose(NULL, PERIOD_H1, 5); на всех таймфреймах будут давать одно и тоже значение : Закрытие на 5 баре по Н1. 

Думал может так

MqlParam params[]; 
//--- create iMA("EURUSD",PERIOD_M15,8,0,MODE_EMA,PRICE_CLOSE); 
   ArrayResize(params,4); 
//--- set ma_period 
   params[0].type         =TYPE_INT; 
   params[0].integer_value=0; 
//--- set ma_shift 
   params[1].type         =TYPE_INT; 
   params[1].integer_value=0; 
//--- set ma_method 
   params[2].type         =TYPE_INT; 
   params[2].integer_value=MODE_EMA; 
//--- set applied_price 
   params[3].type         =TYPE_INT; 
   params[3].integer_value=PRICE_CLOSE; 
//--- create MA 
   h_MA=IndicatorCreate("EURUSD",PERIOD_M15,IND_MA,4,params); 
//--- release indicators (first h_MACD) 
   
  if(h_MA==INVALID_HANDLE)
     {
      Print("The iMA (",string(PERIOD_M15),") object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
//---
   return(INIT_SUCCEEDED);

Но если Вы меня переубедите, что можно по первому способу получить значение технического индикатора (iMA) , подожду. Но пока непонимаю…