Многотаймфреймовый индикатор или Как перебороть психологическую несовместимость с MQL5

 

Раньше всё как-то было просто... делали сдвиг получали кучу данных с других таймфреймов. Сейчас кроме выкапывания этих данных, видимо стоит выкапывать что-то и другое...

int OnCalculate(const int rates_total,const int prev_calculated,const int begin,const double &price[])
  {

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

Как поменять логику не укладывается даже в голове. Может кто-то подскажет, что можно сделать, чтобы поскорее получить результат. Свой индикатор пришлось забросить и вернутся к более простым примерам.

Ставлю задачу:

Нужно получить значение средней для любого таймфрейма несмотря на таймфрейм графика, на который бросили индикатор.

Прикладываю файл стандартной средней.

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
Основы языка / Функции / Функции обработки событий - Документация по MQL5
Файлы:
 
zfs   :

Раньше всё как-то было просто... делали сдвиг получали кучу данных с других таймфреймов. Сейчас кроме выкапывания этих данных, видимо стоит выкапывать что-то и другое...

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

Как поменять логику не укладывается даже в голове. Может кто-то подскажет, что можно сделать, чтобы поскорее получить результат. Свой индикатор пришлось забросить и вернутся к более простым примерам.

Ставлю задачу:

Нужно получить значение средней для любого таймфрейма несмотря на таймфрейм графика, на который бросили индикатор.

Прикладываю файл стандартной средней.

Вопрос, с какой целью. Для построений на графике, или для получения данных в эксперт.

Если для експерта, вызывайте свой индикатор через

int  iCustom(
   string           symbol,     // имя символа
   ENUM_TIMEFRAMES  period,     // период
   string           name        // папка/имя_пользовательского индикатора
   ...                          // список входных параметров индикатора
   );

Впрочем и из индикатора можете также вызвать.

А почему не воспользоватся встроеными средними?

 

int  iMA(
   string               symbol,            // имя символа
   ENUM_TIMEFRAMES      period,            // период
   int                  ma_period,         // период усреднения
   int                  ma_shift,          // смещение индикатора по горизонтали
   ENUM_MA_METHOD       ma_method,         // тип сглаживания
   ENUM_APPLIED_PRICE   applied_price      // тип цены или handle
   );
 
vdv2001   :

Вопрос, с какой целью. Для построений на графике, или для получения данных в эксперт.

Если для експерта, вызывайте свой индикатор через

Впрочем и из индикатора можете также вызвать.

А почему не воспользоватся встроеными средними?

 

 


Вопрос с целью сделать перекинуть индикатор с MQL4. И это не средние. Хочется понять как теперь наиболее алгоритмично получить данные для расчета с другого таймфрейма, отличного от текущего. Индикатор не встроенный, поэтому хотелось бы разобраться... Насчет вызова я тоже думал, неужели это решение самое правильное?
 
zfs :


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


Странный вопрос - вызов индкиатора в МQL5 увеличивается всего на одну строку. - получения данных из буфера.

Пошагово

1. Создали хендл индикатора. - передав в него ЛЮБОЙ ТФ и ВАЛЮТУ

2. Прочитали из буфера данные

3. Анализируем данные.  

Документация по MQL5: Доступ к таймсериям и индикаторам / IndicatorCreate
Документация по MQL5: Доступ к таймсериям и индикаторам / IndicatorCreate
  • www.mql5.com
Доступ к таймсериям и индикаторам / IndicatorCreate - Документация по MQL5
 
sergeev   :


Странный вопрос - вызов индкиатора в МQL5 увеличивается всего на одну строку. - получения данных из буфера.

Пошагово

1. Создали хендл индикатора. - передав в него ЛЮБОЙ ТФ и ВАЛЮТУ

2. Прочитали из буфера данные

3. Анализируем данные.  


Есть еще один этап: что бы работать с данными другого таймфрейма, нужно их конвертировать в текущий.. так как indicator[5] (PERIOD_H1) значит не одно и тоже что indicator[5] (PERIOD_M1) .

А поскольку функицию iBarShift удалили... это настоящая нервотрепка.. с постоянними ошибками 4806, 4014 которые вполне "законны" ... (данные в таймсериях иногда дырявые)

Это медленно и не гарантирован результат (ошибки при запуске МТ5)...

 

 

 я считаю что на данной стадии недостатков с мультитайфреймовыми индикаторами больше чем плюсов по сравнению с МТ4... Надеюсь что в последуючих патчах это исправят...

 
speedyFr   :

А поскольку функицию iBarShift удалили... это настоящая нервотрепка.. с постоянними ошибками 4806, 4014 которые вполне "законны" ... (данные в таймсериях иногда дырявые)

Вот твоя функция, пользуйся ...

В случае дырявых данных должен получить приблезительный + - результат, проверяй сам... 

А вообще алгоритмов (в том числе ипоиска) в интернете валяется достаточно, иногда полезно поискать ...

//+------------------------------------------------------------------+
//|   iBarShift(const datetime &array[], datetime value)
//+------------------------------------------------------------------+
int iBarShift(const datetime &array[], datetime value)
{
   int left,right;
   int n=ArraySize(array);
   int old=-1;
   if(ArrayGetAsSeries(array))//Проверяет направление индексации массива.
   {
      /* проверка позиции за пределами массива */
      if(value > array[0]) return(0);
      if(value <= array[n-1]) return(n-1);
      /*за область поиска принимается весь массив */
      left=0;right=n-1;
      /* ниже алгоритм бинарного поиска требуемого интервала */
      while(left<right-1)
      {
         int node=(left+right)>>1;
         if(value<array[node]) left=node;
         else right=node;
      }

      return(right-1);
   }
   else
   {
      /* проверка позиции за пределами массива */
      if(value < array[0]) return(0);
      if(value >= array[n-1]) return(n-1);
      /*за область поиска принимается весь массив */
      left=0;right=n-1;
      /* ниже алгоритм бинарного поиска требуемого интервала */
      while(left<right-1)
      {
         int node=(left+right)>>1;
         if(value>=array[node]) left=node;
         else right=node;
      }
      /* возвращаем найденную левую границу, 
      обновив старое значение результата */
      return(left);
   }
}
 
vdv2001:

Вот твоя функция, пользуйся ...

В случае дырявых данных должен получить приблезительный + - результат, проверяй сам... 

А вообще алгоритмов (в том числе ипоиска) в интернете валяется достаточно, иногда полезно поискать ...

Спасибо... вот человек чувствуется понимает всю суть вопроса. Попробую внедрить.

Конечно очень тяжело перестраиваться на новое да и времени сейчас нет, сколько раньше было, на изучение, вроде простой язык выдает серьезные ошибки, объяснения которым мне найти, и вроде как простой индикатор становится эпопеей, то мало буферов, хотя используется только один, то с размерностью массива что-то не то, не говоря уже об этих головокружительных переворотах массивов, где надо ещё выучить какой куда повернут и не запутаться.

Документация по MQL5: Операции с массивами / ArrayRange
Документация по MQL5: Операции с массивами / ArrayRange
  • www.mql5.com
Операции с массивами / ArrayRange - Документация по MQL5
 
zfs:

Спасибо... вот человек чувствуется понимает всю суть вопроса. Попробую внедрить.

Конечно очень тяжело перестраиваться на новое да и времени сейчас нет, сколько раньше было, на изучение, вроде простой язык выдает серьезные ошибки, объяснения которым мне найти, и вроде как простой индикатор становится эпопеей, то мало буферов, хотя используется только один, то с размерностью массива что-то не то, не говоря уже об этих головокружительных переворотах массивов, где надо ещё выучить какой куда повернут и не запутаться.

Сам сталкнулся с этой проблемой при переводе с MQL4, а потом просто изменил алгоритм, все даже упростилось. 

Просто, MQL5 заточент под программеров, зато теперь доступ к данным проще, задал диапазон, получил данные и делай с ними все, что хочеш

Мне язык нравится, особенно обработка событий мыши в экспертах и скриптах. Можно свои инструменты создавать. 

 
vdv2001:

Конечно, всё стало лучше... У меня в последнее время проблема в старом терминале сводилась к тому, что не хватало памяти... Но это язык новый и структура у него новая, и ошибки выдает новые и, где теперь искать концы... Пришлось начать всё сначала, разобраться с азами... вот накидал индикатор и опять косяк

      if ((i>2)&&(High[i-1]>=High[i-2])&&
          (Close[i-1]<(High[i-1]-Low[i-1])/2)&&(Low[i]<Low[i-1]))ExtBuffer[i]=1.0;
выражение никогда не выполняется, хотя каждое в отдельности выполняется.
 
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_width1  3
#property indicator_style1  STYLE_SOLID
#property indicator_label1  "ReversalBar"

color  ColorOf[3]={CLR_NONE,Blue,Red};
double ExtBuffer[];

void OnInit()
  {
   SetIndexBuffer(0,ExtBuffer,INDICATOR_COLOR_INDEX); 
   PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,3);
   for(int i=1;i<3;i++)
      PlotIndexSetInteger(0,PLOT_LINE_COLOR,i,ColorOf[i]);
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);   
  }

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 &TickVolume[],
                const long &Volume[],const int &Spread[])
  {
   int i;
   if(prev_calculated==0) i=0;
   else i=prev_calculated-1; 
   while(i<rates_total){  
      ExtBuffer[i]=2.0;
      if ((i>2)&&(High[i-1]>=High[i-2])&&
          (Close[i-1]<(High[i-1]-Low[i-1])/2)&&(Low[i]<Low[i-1]))ExtBuffer[i]=1.0;
      if ((i>2)&&(Low[i-1]<=Low[i-2])&&
          (Close[i-1]>(High[i-1]-Low[i-1])/2)&&(High[i]>High[i-1]))ExtBuffer[i]=0.0;   
      i++;
     }
   return(rates_total);
  }

А вообще вот весь код.... я так полагаю это не единственная ошибка, так как в принципе индюк вообще ничего не рисует, даже свое окно.

Индюк должен в отдельном окне окрашивать свечи исходя из указанных условий.


 

У Вас несоответствие между типом отрисовки и количеством буферов. Для цветных свеч должно быть как минимум 5 буферов (4 буфера для OHLC + 1 буфер для индекса цвета)

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