//------------------------------------------------------------------ #property copyright "© mladen, 2016, MetaQuotes Software Corp." #property link "www.forex-tsd.com, www.mql5.com" #property version "1.00" //------------------------------------------------------------------ #property indicator_separate_window #property indicator_buffers 9 #property indicator_plots 6 #property indicator_label1 "corrected rsi levels" #property indicator_type1 DRAW_FILLING #property indicator_color1 clrLimeGreen,clrOrange #property indicator_label2 "corrected rsi up level" #property indicator_type2 DRAW_LINE #property indicator_color2 clrLimeGreen #property indicator_style2 STYLE_DOT #property indicator_label3 "corrected rsi middle level" #property indicator_type3 DRAW_LINE #property indicator_color3 clrSilver #property indicator_style3 STYLE_DOT #property indicator_label4 "corrected rsi down level" #property indicator_type4 DRAW_LINE #property indicator_color4 clrOrange #property indicator_style4 STYLE_DOT #property indicator_label5 "Rsi" #property indicator_type5 DRAW_COLOR_LINE #property indicator_color5 clrDarkGray,clrLimeGreen,clrSandyBrown #property indicator_style5 STYLE_DOT #property indicator_label6 "corrected rsi" #property indicator_type6 DRAW_COLOR_LINE #property indicator_color6 clrDarkGray,clrLimeGreen,clrSandyBrown #property indicator_width6 2 // // // // // enum enPrices { pr_close, // Close pr_open, // Open pr_high, // High pr_low, // Low pr_median, // Median pr_typical, // Typical pr_weighted, // Weighted pr_average, // Average (high+low+open+close)/4 pr_medianb, // Average median body (open+close)/2 pr_tbiased, // Trend biased price pr_tbiased2, // Trend biased (extreme) price pr_haclose, // Heiken ashi close pr_haopen , // Heiken ashi open pr_hahigh, // Heiken ashi high pr_halow, // Heiken ashi low pr_hamedian, // Heiken ashi median pr_hatypical, // Heiken ashi typical pr_haweighted, // Heiken ashi weighted pr_haaverage, // Heiken ashi average pr_hamedianb, // Heiken ashi median body pr_hatbiased, // Heiken ashi trend biased price pr_hatbiased2 // Heiken ashi trend biased (extreme) price }; enum enRsiTypes { rsi_cut, // Cuttler's RSI rsi_ehl, // Ehlers' smoothed RSI rsi_har, // Harris' RSI rsi_rap, // Rapid RSI rsi_rsi, // RSI rsi_rsx, // RSX rsi_slo // Slow RSI }; enum enColorOn { chg_onSlope, // change color on slope change chg_onLevel, // Change color on outer levels cross chg_onMiddle, // Change color on middle level cross chg_onOrig // Change color on rsi value cross }; input int RsiPeriod = 32; // Rsi period input enRsiTypes RsiType = rsi_rsx; // Rsi type input int CorrectionPeriod = 0; // Correction period (<0 no correction =0 same as rsi period) input enPrices Price = pr_close; // Price input enColorOn ColorOn = chg_onLevel; // Color change on : input int LevelsPeriod = 50; // Floating levels period input double LevelsUp = 90; // Upper level % input double LevelsDown = 10; // Lower level % double val[],valc[],fill1[],fill2[],levelUp[],levelMi[],levelDn[],cor[],corc[]; //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // void OnInit() { SetIndexBuffer(0,fill1 ,INDICATOR_DATA); SetIndexBuffer(1,fill2 ,INDICATOR_DATA); SetIndexBuffer(2,levelUp,INDICATOR_DATA); SetIndexBuffer(3,levelMi,INDICATOR_DATA); SetIndexBuffer(4,levelDn,INDICATOR_DATA); SetIndexBuffer(5,val ,INDICATOR_DATA); SetIndexBuffer(6,valc ,INDICATOR_COLOR_INDEX); SetIndexBuffer(7,cor ,INDICATOR_DATA); SetIndexBuffer(8,corc ,INDICATOR_COLOR_INDEX); IndicatorSetString(INDICATOR_SHORTNAME,"\"Corrected\" "+getRsiName(RsiType)+" ("+(string)RsiPeriod+","+(string)CorrectionPeriod+","+(string)LevelsPeriod+")"); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // 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)0) ? CorrectionPeriod : (CorrectionPeriod<0) ? 0 : (int)RsiPeriod ; int colorOn = (deviationsPeriod>0) ? ColorOn : (ColorOn!=chg_onOrig) ? ColorOn : chg_onSlope; int levelPeriod = (LevelsPeriod>1) ? LevelsPeriod : RsiPeriod; int i=(int)MathMax(prev_calculated-1,0); for (; i0) ? MathPow(cor[i-1]-val[i],2) : 0; double c = (v20) ? cor[i-1]+c*(val[i]-cor[i-1]) : val[i]; // // // // // int start = MathMax(i-levelPeriod+1,0); double min = cor[ArrayMinimum(cor,start,levelPeriod)]; double max = cor[ArrayMaximum(cor,start,levelPeriod)]; double range = max-min; levelUp[i] = min+LevelsUp *range/100.0; levelDn[i] = min+LevelsDown*range/100.0; levelMi[i] = (levelUp[i]+levelDn[i])*0.5; valc[i] = (i>0) ? (val[i]>val[i-1]) ? 1 : (val[i]val[i]) ? 2 : (i>0) ? corc[i-1]: 0; break; case chg_onMiddle : corc[i] = (cor[i]>levelMi[i]) ? 1 : (cor[i]0) ? corc[i-1]: 0; break; case chg_onLevel: corc[i] = (cor[i]>levelUp[i]) ? 1 : (cor[i]0) ? (cor[i]==cor[i-1]) ? corc[i-1]: 0 : 0; break; default : corc[i] = (i>0) ? (cor[i]>cor[i-1]) ? 1 : (cor[i]levelUp[i]) ? levelUp[i] : (cor[i]=0; k++) { newMean = (workDev[i-k]-oldMean)/(k+1)+oldMean; squares += (workDev[i-k]-oldMean)*(workDev[i-k]-newMean); oldMean = newMean; } return(MathSqrt(squares/MathMax(k-isSample,1))); } // // // // // //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // // string getRsiName(int method) { switch (method) { case rsi_rsi: return("RSI"); case rsi_rsx: return("RSX"); case rsi_cut: return("Cuttler's RSI"); case rsi_har: return("Haris' RSI"); case rsi_rap: return("Rapid RSI"); case rsi_slo: return("Slow RSI"); case rsi_ehl: return("Ehlers' smoothed RSI"); default: return(""); } } // // // // // #define rsiInstances 3 double workRsi[][rsiInstances*13]; #define _price 0 #define _prices 3 #define _change 1 #define _changa 2 #define _rsival 1 #define _rsval 1 double iRsi(int rsiMode, double price, double period, int r, int bars, int instanceNo=0) { if (ArrayRange(workRsi,0)!=bars) ArrayResize(workRsi,bars); int z = instanceNo*13; // // // // // workRsi[r][z+_price] = price; switch (rsiMode) { case rsi_rsi: { double alpha = 1.0/MathMax(period,1); if (r=0; k++) sum += MathAbs(workRsi[r-k][z+_price]-workRsi[r-k-1][z+_price]); workRsi[r][z+_change] = (workRsi[r][z+_price]-workRsi[0][z+_price])/MathMax(k,1); workRsi[r][z+_changa] = sum/MathMax(k,1); } else { double change = workRsi[r][z+_price]-workRsi[r-1][z+_price]; workRsi[r][z+_change] = workRsi[r-1][z+_change] + alpha*( change - workRsi[r-1][z+_change]); workRsi[r][z+_changa] = workRsi[r-1][z+_changa] + alpha*(MathAbs(change) - workRsi[r-1][z+_changa]); } return(50.0*(workRsi[r][z+_change]/MathMax(workRsi[r][z+_changa],DBL_MIN)+1)); } // // // // // case rsi_slo : { double up = 0, dn = 0; for(int k=0; k<(int)period && (r-k-1)>=0; k++) { double diff = workRsi[r-k][z+_price]- workRsi[r-k-1][z+_price]; if(diff>0) up += diff; else dn -= diff; } if (r<1) workRsi[r][z+_rsival] = 50; else workRsi[r][z+_rsival] = workRsi[r-1][z+_rsival]+(1/MathMax(period,1))*(100*up/MathMax(up+dn,DBL_MIN)-workRsi[r-1][z+_rsival]); return(workRsi[r][z+_rsival]); } // // // // // case rsi_rap : { double up = 0, dn = 0; for(int k=0; k<(int)period && (r-k-1)>=0; k++) { double diff = workRsi[r-k][z+_price]- workRsi[r-k-1][z+_price]; if(diff>0) up += diff; else dn -= diff; } return(100 * up /MathMax(up + dn,DBL_MIN)); } // // // // // case rsi_ehl : { double up = 0, dn = 0; workRsi[r][z+_prices] = (r>2) ? (workRsi[r][z+_price]+2.*workRsi[r-1][z+_price]+workRsi[r-2][z+_price])/4.0 : price; for(int k=0; k<(int)period && (r-k-1)>=0; k++) { double diff = workRsi[r-k][z+_prices]- workRsi[r-k-1][z+_prices]; if(diff>0) up += diff; else dn -= diff; } return(50*(up-dn)/MathMax(up+dn,DBL_MIN)+50); } // // // // // case rsi_cut : { double sump = 0; double sumn = 0; for (int k=0; k<(int)period && (r-k-1)>=0; k++) { double diff = workRsi[r-k][z+_price]-workRsi[r-k-1][z+_price]; if (diff > 0) sump += diff; else sumn -= diff; } workRsi[r][instanceNo+_rsival] = 100.0-100.0/(1.0+sump/MathMax(sumn,DBL_MIN)); return(workRsi[r][instanceNo+_rsival]); } // // // // // case rsi_har : { double avgUp=0,avgDn=0,up=0,dn=0; for(int k=0; k<(int)period && (r-k-1)>=0; k++) { double diff = workRsi[r-k][instanceNo+_price]- workRsi[r-k-1][instanceNo+_price]; if(diff>0) { avgUp += diff; up++; } else { avgDn -= diff; dn++; } } if (up!=0) avgUp /= up; if (dn!=0) avgDn /= dn; workRsi[r][instanceNo+_rsival] = 100-100/(1.0+(avgUp/MathMax(avgDn,DBL_MIN))); return(workRsi[r][instanceNo+_rsival]); } // // // // // case rsi_rsx : { double Kg = (3.0)/(2.0+period), Hg = 1.0-Kg; if (r=pr_haclose) { if (ArrayRange(workHa,0)!= _bars) ArrayResize(workHa,_bars); instanceNo*=_pricesSize; // // // // // double haOpen; if (i>0) haOpen = (workHa[i-1][instanceNo+2] + workHa[i-1][instanceNo+3])/2.0; else haOpen = (open[i]+close[i])/2; double haClose = (open[i] + high[i] + low[i] + close[i]) / 4.0; double haHigh = MathMax(high[i], MathMax(haOpen,haClose)); double haLow = MathMin(low[i] , MathMin(haOpen,haClose)); if(haOpen haOpen) return((haHigh+haClose)/2.0); else return((haLow+haClose)/2.0); case pr_hatbiased2: if (haClose>haOpen) return(haHigh); if (haCloseopen[i]) return((high[i]+close[i])/2.0); else return((low[i]+close[i])/2.0); case pr_tbiased2: if (close[i]>open[i]) return(high[i]); if (close[i]