Обсуждение статьи "Индикатор от индикатора в MQL5"

 

Опубликована статья Индикатор от индикатора в MQL5:

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

Автор:  MetaQuotes

 

Спасибо  за очередную хорошую статью. Для меня уже по традиции статьи MQL Community стали способом получения высшего образования после среднего (имеется ввиду встроенный MQL справочник редактора)

Если по делу, то заметил в коде маленький изъян. По задумке автора

//--- флаг для однократного вывода значений price[]

 переменную

   bool printed=false;

 необходимо вынести за пределы функции OnCalculate(), иначе распечатка массива будет на каждом событии.

 

Еще допущена опечатка здесь

Правило передачи PLOT_DRAW_BEGIN в параметр begin: Значение входного параметра begin в OnCalculate(), при расчетах пользовательского индикатора A на данных другого (базового) индикатора B, всегда равно значению свойства PLOT_DRAW_BEGIN нулевого графического построения базового индикатора B.

Таким образом, если мы создали на графике индикатор RSI (индикатор A) с периодом 14 и затем на данных индикатора RSI(14) построили наш пользовательский индикатор True Strength Index (индикатор B), то: 

Судя по правилу и логике индикатор А - это пользовательский TSI, а индикатор B(базовый) - RSI.

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

А есть какая-нибудь возможность при программном (через iCustom, например) создании индикатора сообщить ему, что нужно брать на вход данные от другого индикатора? Или, еще лучше, дать ему прямо массив данных, на которых он должен построиться.

 
ds2:

А есть какая-нибудь возможность при программном (через iCustom, например) создании индикатора сообщить ему, что нужно брать на вход данные от другого индикатора? Или, еще лучше, дать ему прямо массив данных, на которых он должен построиться.

Смотрите функцию iCustom:

Если в индикаторе используется первая форма вызова, то при запуске пользовательского индикатора на вкладке "Parameters" можно дополнительно указать на каких данных он будет рассчитываться. Если параметр "Apply to" не выбран явно, то по умолчанию расчет производится по значениям "Close".

При вызове пользовательского индикатора из mql5-программы параметр Applied_Price или хэндл другого индикатора должен передаваться последним после всех предусмотренных пользовательским индикатором входных переменных.

 
Rosh:

Решил построить индикатор от индикатора и наткнулся на непонятку.

оба индикатора строятся на базе

int OnCalculate (const int rates_total,      // размер массива price[]
                 const int prev_calculated,  // обработано баров на предыдущем вызове
                 const int begin,            // индекс с которого начинаются значимые данные в массиве price[]
                 const double& price[]       // массив для расчета
   );

соответственно пользователь имеет возможность задать поле applied_price в параметрах.

Вот моя трудность состоит в том как передать внутреннему индикатору (от которого строится внешний) поле applied_price ???

Самое простое решение сделать инпут и предупредить пользователя что инпут applied_price и параметр applied_price должны быть одинаковы, но это как то криво.

 

Пример для OnCalculate() смотрели?

Для получения значений пользовательского индикатора из других mql5-программ используется функция iCustom(), возвращающая хэндл индикатора для последующих операций. При этом также можно указать необходимый массив  price[] или хэндл другого индикатора. Этот параметр должен передаваться последним в списке  входных переменных пользовательского индикатора.
 
Пример:

void OnStart()
  {
//---
   string terminal_path=StatusInfoString(STATUS_TERMINAL_PATH);
   int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL);
   if(handle_customMA>0)
      Print("handle_customMA = ",handle_customMA);
   else
      Print("Cannot open or not EX5 file '"+terminal_path+"\\MQL5\\Indicators\\"+"Custom Moving Average.ex5'");
  }

В данном примере последним параметром передано значение PRICE_TYPICAL (из перечисления ENUM_APPLIED_PRICE ), которое указывает, что пользовательский индикатор будет построен по типическим ценам, полученным как (High+Low+Close)/3. Если параметр не указывается, то индикатор строится по значениям PRICE_CLOSE, то есть по ценам закрытия каждого бара.


 
Rosh:

Пример для OnCalculate() смотрели?


Да смотрел,

int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL);

applied_price при вызове iCustom указывается явно, но в индикаторе из которого вызывается iCustom где его взять?

ведь пользователь его задаёт в параметрах а не в инпутах.

int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   hndl=iCustom(_Symbol,_Period,"MyInd",param_ind,???? вот тут нужно указать аплиед_прайс который будет задавать пользователь);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
 //...
 return(rates_total);
}

PS фишка в том чтоб пользователь задав один раз параметр applied_price и больше не парился, чтоб это значение пошло по всей пирамиде вызовов.

 

Может я неправильно понимаю вопрос, но попытаюсь подбросить еще одну идею

indicator_applied_price

int

задает значение по умолчанию для поля "Apply to". Можно задавать одно из значений перечисления ENUM_APPLIED_PRICE. Если свойство не задано, то по умолчанию применяется значение PRICE_CLOSE

 
Rosh:

Может я неправильно понимаю вопрос, но попытаюсь подбросить еще одну идею

indicator_applied_price

int

задает значение по умолчанию для поля "Apply to". Можно задавать одно из значений перечисления ENUM_APPLIED_PRICE. Если свойство не задано, то по умолчанию применяется значение PRICE_CLOSE

Идея хорошая но в сторону (как прыжки в ширину:)

Нужно именно передать значение параметра applied_price которое выбрал пользователь во внешнем индикаторе во внутренний.

Например есть МА которая строится на выбранных данных (это внутренний индикатор), и значение этого МА нужно отнять от прайса.

Соответственно если выбран PRICE_CLOSE то на основе этого прайса должна быть построена МА и этот же прайс должен быть использован в формуле расчёта индикатора.

1 инд
МА(app_price)
2 инд
МА(app_price)-price(app_price)
 

Из вышеописанного видно что app_price просто напрашивается объявить как input, но тогда пользователю придётся дважды указывать нужный параметр.

Один раз в Inputs другой раз в Parametrs. Что сами понимаете не есть гуд.

возможны случаи когда это нужно, но есть случаи когда это как раз плохо.


 

Я думаю, это не смертельно. Как часто такая проблема встает в повседневной жизни? Один раз можно и указать при запуске.
Причина обращения: