Camilo Mora: . I am struggling with the last part of it, which collects the highest and lowest prior values.
Your loop is wrong. You already used ArrayMaximum before. Use it again on your buffer.
I believe that high level primitive functions such as ArrayMaximum should not be used. It's easier and faster to write your own function than to dig through the documentation and try to make ArrayMaximum work without knowing what's under the hood. Find the values you need in the loop yourself. Writing your own loop/function for this is not at all difficult or time-consuming. But in return you will be in control of everything.
I corrected the error in the loop...
//+------------------------------------------------------------------ #property copyright "mladen" #property link "mladenfx@gmail.com" #property link "https://www.mql5.com" #property description "Chandelier exit" //+------------------------------------------------------------------ #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 4 #property indicator_type1 DRAW_LINE #property indicator_color1 clrDeepSkyBlue #property indicator_type2 DRAW_LINE #property indicator_color2 clrPaleVioletRed //--- input parameters input int AtrPeriod = 10; // Atr period input double AtrMultiplier1 = 3.0; // Atr multiplier input int LookBackPeriod = 20; // Look-back period double UplBuffer1[],UpdBuffer1[],DnlBuffer1[],DndBuffer1[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,UplBuffer1,INDICATOR_DATA); SetIndexBuffer(1,DnlBuffer1,INDICATOR_DATA); SetIndexBuffer(2,UpdBuffer1,INDICATOR_DATA); SetIndexBuffer(3,DndBuffer1,INDICATOR_DATA); return (INIT_SUCCEEDED); } // // // void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| 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(Bars(_Symbol,_Period)<rates_total) return(prev_calculated); if(ArrayRange(work,0)!=rates_total) ArrayResize(work,rates_total); int i=(int)MathMax(prev_calculated-1,1); for(; i<rates_total && !_StopFlag; i++) { int _start = MathMax(i-LookBackPeriod,0); double _atr = 0; for(int k=1; k<=AtrPeriod && (i-k-1)>=0; k++) _atr += MathMax(high[i-k],close[MathMax(i-k-1,0)])- MathMin(low[i-k],close[MathMax(i-k-1,0)]); _atr/=(double)AtrPeriod; double _max = high[ArrayMaximum(high,_start,LookBackPeriod)]; double _min = low [ArrayMinimum(low ,_start,LookBackPeriod)]; UplBuffer1[i] = _max-AtrMultiplier1*_atr; DnlBuffer1[i] = _min+AtrMultiplier1*_atr; } return (i); } //+------------------------------------------------------------------+

You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Hi,
I am trying to convert an indicator from MQL4 to MQL5. I am struggling with the last part of it, which collects the highest and lowest prior values.
This indicator is suppose to add and subtract the ATR to the high and low of each bar, and from a given lookback period select the largest or smallest, and display both lines This indicator is a variant of the Chandelier exit, called Chande-Kroll exit...
An MQL5 version exist, but it fails to do it correctly, as it does not select the prior highest and lowest values.
#property indicator_chart_window #property indicator_buffers 2 #property indicator_plots 2 #property indicator_type1 DRAW_LINE #property indicator_color1 clrBlue #property indicator_type2 DRAW_LINE #property indicator_color2 clrRed //--- labels #property indicator_label1 "Upper Donchian" #property indicator_label2 "Lower Donchian" //--- input parameter input int InpDonchianPeriod=20; // period of the channel input int AtrPeriod=10; // atr period input double AtrMultiplier = 3.0; // Atr multiplier //--- indicator buffers double ExtUpBuffer[]; double ExtDnBuffer[]; double UpperLine[]; double LowerLine[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- define buffers SetIndexBuffer(0, UpperLine); SetIndexBuffer(1, LowerLine); 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 the indicator has previously been calculated, start from the bar preceding the last one int start=prev_calculated-1; //--- if this is the first calculation of the indicator, then move by InpDonchianPeriod bars form the beginning if(prev_calculated==0) start=InpDonchianPeriod+1; //--- calculate levels for all bars in a loop for(int i=start; i<rates_total; i++) { if(i-2-InpDonchianPeriod <0 ) continue; // bypass start of indicator double _atr = 0; for(int k=1; k<=AtrPeriod && (i-k-1)>=0; k++) _atr += MathMax(high[i-k],close[MathMax(i-k-1,0)])- MathMin(low[i-k],close[MathMax(i-k-1,0)]); _atr/=(double)AtrPeriod; double highest = high[ArrayMaximum(high,i-InpDonchianPeriod,InpDonchianPeriod)]; double lowest = low [ArrayMinimum(low ,i-InpDonchianPeriod,InpDonchianPeriod)]; ExtUpBuffer[i]=highest-AtrMultiplier*_atr ; ExtDnBuffer[i]=lowest+AtrMultiplier*_atr ; /* UpperLine[i]=-10000000; LowerLine[i]= 10000000; //---- for(int ii=prev_calculated-InpDonchianPeriod-1;ii<rates_total;ii++) { UpperLine[i]=MathMax( UpperLine[i], ExtDnBuffer[ii+i]); LowerLine[i]=MathMin( LowerLine[i], ExtUpBuffer[ii+i]); } */ } //--- succesfully calculated return(rates_total); }