Thanks for another good article. Traditionally, MQL Community articles have become a way for me to get a post-secondary education (meaning the inbuilt MQL editor's guide)
On the point, I noticed a small flaw in the code. According to the author's idea
//--- flag for one-time output of price[] values
variable
bool printed=false;
variable should be moved outside the OnCalculate() function, otherwise the array printing will occur at every event.
There is also a misprint here
Правило передачи PLOT_DRAW_BEGIN в параметр begin: Значение входного параметра begin в OnCalculate(), при расчетах пользовательского индикатора A на данных другого (базового) индикатора B, всегда равно значению свойства PLOT_DRAW_BEGIN нулевого графического построения базового индикатора B.
Thus, if we created an RSI indicator (indicator A) with a period of 14 and then built our custom indicator True Strength Index (indicator B) on the RSI(14) indicator data, then:
Judging by the rule and logic, indicator A is custom TSI and indicator B(basic) is RSI.

- www.mql5.com
This article contains the detailed knowledge.
Thanks.
Hi,
This article is really interesting and open new opportunities to manage indicators.
Since I'm a beginner in MQL5, I've tried to implement the possibility to apply an indicator to another. I've written a little code which only duplicate
an adaptative moving average hoping to use it on any indicator of the chart.
Unfortunately, in the list of parameters which appears when you launch the indicator I don't have the case "apply to : previuos indicator's data".
How the code should be organised to have the possibility to apply it to another indicator ?
Here is my code:
#property indicator_separate_window #property indicator_minimum 1.3 #property indicator_maximum 1.35 //#property indicator_chart_window #property indicator_buffers 2 #property indicator_plots 1 //--- plot dMA #property indicator_label1 "dAMA" #property indicator_type1 DRAW_LINE #property indicator_color1 Red #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- input parameters input int AMAPeriod=9; input int FastEMA=2; input int SlowEMA=20; //--- indicator buffers double AMABuffer[]; double dAMABuffer[]; int h_dAMA; int h_AMA; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,dAMABuffer,INDICATOR_DATA); SetIndexBuffer(1,AMABuffer,INDICATOR_CALCULATIONS); //PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MAPeriod+1); h_AMA=iAMA(_Symbol,PERIOD_CURRENT,AMAPeriod,FastEMA,SlowEMA,0,PRICE_CLOSE); if(h_AMA == INVALID_HANDLE) { Print("AMA indicator initialization error, Code = ", GetLastError()); return(-1); } ArraySetAsSeries(AMABuffer,true); ArraySetAsSeries(dAMABuffer,true); PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MathMax(AMAPeriod,SlowEMA)); //--- return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, // size of the price[] array const int prev_calculated,// number of bars processed at the previous call const int begin, // where the significant data start from const double &price[] // array for calculation ) { if(BarsCalculated(h_AMA)<rates_total) return(0); //--- we can copy not all data int to_copy; if(prev_calculated>rates_total || prev_calculated<=0) { to_copy=rates_total; if(CopyBuffer(h_AMA,0,0,to_copy,AMABuffer)<=0) return(0); for (int i=0;i<to_copy-MathMax(AMAPeriod,SlowEMA);i++) { dAMABuffer[i]=AMABuffer[i]; } } else { to_copy=rates_total-prev_calculated+MathMax(AMAPeriod,SlowEMA)-1; //--- last value is always copied to_copy++; if(CopyBuffer(h_AMA,0,0,to_copy,AMABuffer)<=0) return(0); for (int i=0;i<to_copy;i++) { dAMABuffer[i]=AMABuffer[i]; } } //--- try to copy Print(dAMABuffer[0]); //to see if we go till the end //--- return value of prev_calculated for next call //--- //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+
Hi,
I've understood the problem: you are only able to apply one indicator to another which is in the same window.
Do you have an idea on how to apply one indicator (and to display it in a separate window) to another which is in the main window?
thanks
Bests
Is there any possibility to create an indicator programmatically (via iCustom, for example) and tell it to take data from another indicator as input? Or, even better, to give it directly an array of data on which it should be built.
Is there any possibility to create an indicator programmatically (via iCustom, for example) and tell it to take data from another indicator as input? Or, even better, to give it directly an array of data on which it should be built.
See the iCustom function:
If the first form of call is used in the indicator, then when launching a custom indicator on the "Parameters" tab you can additionally specify on what data it will be calculated. If the "Apply to" parameter is not selected explicitly, then by default the calculation is performed by "Close" values.
When calling a custom indicator from an mql5-program, the Applied_Price parameter or the handle of another indicator should be passed last after all input variables provided by the custom indicator.
Hi,
This is a very good article but I have some questions.
1. Only the indicators that uses the short form of the OnCalculate() function call, can be applaied to another indicator or the indicators that use the long form of the OnCalculate() function call can be applied too? If so , haw can be applied one indicator with long form of the OnCalculate() function call, to another indicator???
2. Applying one indicator to another (TSI over RSI) generates some display problems (see attached image). While RSI is plotted from 0 to 100 the second indicator (TSI) have values below 0 too , values wich are not visibile on the chart. Wich is the problem and why the chart don't properly adjust to display correctly both indicators. Can we solve this problem or it's a MetaTrader bug???
I decided to build an indicator from an indicator and came across a confusion.
Both indicators are built on the base
int OnCalculate (const int rates_total, // price[] array size const int prev_calculated, // bars processed on the previous call const int begin, // index from which the significant data starts в массиве price[] const double& price[] // array for calculation );
Accordingly, the user has the ability to set the applied_price field in the parameters.
My difficulty is how to pass the applied_price field to the internal indicator (from which the external indicator is built)?
The simplest solution is to make an input and warn the user that the applied_price input and the applied_price parameter should be the same, but this is kind of crooked.
Have you looked at the example for 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'"); }
In this example, the last parameter passed is the PRICE_TYPICAL value (from the ENUM_APPLIED_PRICE enumeration), which indicates that the custom indicator will be built by typical prices obtained as (High+Low+Close)/3. If the parameter is not specified, the indicator is built by PRICE_CLOSE values, i.e. by closing prices of each bar.
Yes, I did,
int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL);
applied_price is specified explicitly when iCustom is called, but in the indicator from which iCustom is called, where to get it?
Because the user sets it in the parameters, not in the inputs.
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 the trick is that the user having once set the applied_price parameter and no more did not bother, that this value went through the whole pyramid of calls.

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
New article Applying One Indicator to Another is published:
Do you want to improve an indicator for its correct application to the other indicator's data? In this article we'll review all the steps required for such modification.
Author: MetaQuotes