//------------------------------------------------------------------ #property copyright "mladen" #property link "www.forex-station.com" //------------------------------------------------------------------ #property indicator_separate_window #property indicator_buffers 9 #property indicator_minimum -5 #property indicator_maximum 105 #property indicator_color1 clrSilver #property indicator_color2 clrOrange #property indicator_color3 clrOrange #property indicator_color4 clrLimeGreen #property indicator_color5 clrLimeGreen #property indicator_color6 clrRed #property indicator_color7 clrDarkSlateGray #property indicator_color8 clrDarkSlateGray #property indicator_color9 clrDarkSlateGray #property indicator_style6 STYLE_DOT #property indicator_style7 STYLE_DOT #property indicator_style8 STYLE_DOT #property indicator_style9 STYLE_DOT #property strict // // // // // 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_highlow, // High/low 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 pr_hahighlow // Heiken ashi high/low }; enum enRsiTypes { rsi_rsi, // Regular Rsi rsi_wil, // Slow Rsi rsi_rap, // Rapid Rsi rsi_har, // Harris Rsi rsi_rsx, // Rsx rsi_cut // Cuttlers Rsi }; enum enMaTypes { ma_sma, // Simple moving average ma_ema, // Exponential moving average ma_smma, // Smoothed MA ma_lwma, // Linear weighted MA ma_tema // Triple exponential moving average - TEMA }; enum colorOn { clrOnSlope, // Color change on slope change clrOnMid, // Color change on mid level cross clrOnOuter // Color change on outer levels cross }; extern ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT; // Time frame extern int RsiPeriod = 10; // Rsi period extern enRsiTypes RsiMethod = rsi_rsx; // Rsi type extern enPrices RsiPrice = pr_close; // Rsi price to use extern int RsiSmoothing = 20; // Super smoothing period extern int StochPeriod = 32; // Stoch period extern int SlowingPeriod = 3; // Stoch slowing period extern int SignalPeriod = 5; // Stoch signal period extern enMaTypes StochMaMode = ma_sma; // Stoch Average type extern double OverSold = 10; // Oversold floating level extern double OverBought = 90; // Overbought floating level extern int MinMaxPeriod = 15; // Floating levels min max period extern int linesWidth = 3; // Stoch Rsi line width extern colorOn ColorChangeOn = clrOnSlope; // Color change on: extern bool Interpolate = true; // Interpolate in multi time frame mode? // // // // // double sk[]; double sd[]; double skda[]; double skdb[]; double skua[]; double skub[]; double lvup[]; double lvmi[]; double lvdn[]; double storsi[]; double rsi[]; double value[]; double count[]; string indicatorFileName; #define _mtfCall(_buff,_ind) iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,RsiPeriod,RsiMethod,RsiPrice,RsiSmoothing,StochPeriod,SlowingPeriod,SignalPeriod,StochMaMode,OverSold,OverBought,MinMaxPeriod,linesWidth,ColorChangeOn,_buff,_ind) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // // // // // int init() { IndicatorBuffers(13); SetIndexBuffer(0, sk); SetIndexStyle(0,EMPTY,EMPTY,linesWidth); SetIndexBuffer(1, skda); SetIndexStyle(1,EMPTY,EMPTY,linesWidth); SetIndexBuffer(2, skdb); SetIndexStyle(2,EMPTY,EMPTY,linesWidth); SetIndexBuffer(3, skua); SetIndexStyle(3,EMPTY,EMPTY,linesWidth); SetIndexBuffer(4, skub); SetIndexStyle(4,EMPTY,EMPTY,linesWidth); SetIndexBuffer(5, sd); SetIndexBuffer(6, lvup); SetIndexBuffer(7, lvmi); SetIndexBuffer(8, lvdn); SetIndexBuffer(9, storsi); SetIndexBuffer(10,rsi); SetIndexBuffer(11,value); SetIndexBuffer(12,count); indicatorFileName = WindowExpertName(); TimeFrame = fmax(TimeFrame,_Period); IndicatorShortName(timeFrameToString(TimeFrame)+" Stochastic "+getRsiName((int)RsiMethod)+" super smoother ("+(string)RsiPeriod+","+(string)StochPeriod+","+(string)SlowingPeriod+","+(string)SignalPeriod+")"); return(0); } int deinit() { return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // // // // // int start() { int i,counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; int limit = fmin(Bars-counted_bars,Bars-1); count[0]=limit; if (TimeFrame!=_Period) { limit = (int)fmax(limit,fmin(Bars-1,_mtfCall(12,0)*TimeFrame/_Period)); if (value[limit]==-1) CleanPoint(limit,skda,skdb); if (value[limit]== 1) CleanPoint(limit,skua,skub); for (i=limit;i>=0 && !_StopFlag; i--) { int y = iBarShift(NULL,TimeFrame,Time[i]); sk[i] = _mtfCall(0,y); skda[i] = EMPTY_VALUE; skdb[i] = EMPTY_VALUE; skua[i] = EMPTY_VALUE; skub[i] = EMPTY_VALUE; sd[i] = _mtfCall(5,y); lvup[i] = _mtfCall(6,y); lvmi[i] = _mtfCall(7,y); lvdn[i] = _mtfCall(8,y); value[i] = _mtfCall(11,y); // // // // // if (!Interpolate || (i>0 && y==iBarShift(NULL,TimeFrame,Time[i-1]))) continue; #define _interpolate(buff) buff[i+k] = buff[i]+(buff[i+n]-buff[i])*k/n int n,k; datetime time = iTime(NULL,TimeFrame,y); for(n = 1; (i+n)= time; n++) continue; for(k = 1; k=0; i--) { if (value[i] == -1) PlotPoint(i,skda,skdb,sk); if (value[i] == 1) PlotPoint(i,skua,skub,sk); } return(0); } // // // // // if (value[limit]==-1) CleanPoint(limit,skda,skdb); if (value[limit]== 1) CleanPoint(limit,skua,skub); for(i=limit; i>=0; i--) { rsi[i] = iRsi(RsiMethod,iSsm(getPrice(RsiPrice,Open,Close,High,Low,i),RsiSmoothing,i,0),RsiPeriod,i); double llv = rsi[ArrayMinimum(rsi,StochPeriod,i)]; double hhv = rsi[ArrayMaximum(rsi,StochPeriod,i)]; if ((hhv-llv)!=0) storsi[i] = 100.0*((rsi[i] - llv)/(hhv - llv)); else storsi[i] = 0; sk[i] = iCustomMa(StochMaMode,storsi[i],SlowingPeriod,i,0); sd[i] = iCustomMa(StochMaMode,sk[i], SignalPeriod, i,1); // // // // // double hi = sk[ArrayMaximum(sk,MinMaxPeriod,i)]; double lo = sk[ArrayMinimum(sk,MinMaxPeriod,i)]; double rn = hi-lo; lvup[i] = lo+rn*OverBought/100.0; lvdn[i] = lo+rn*OverSold /100.0; lvmi[i] = (lvup[i]+lvdn[i])*0.5; skda[i] = EMPTY_VALUE; skdb[i] = EMPTY_VALUE; skua[i] = EMPTY_VALUE; skub[i] = EMPTY_VALUE; switch(ColorChangeOn) { case clrOnOuter : value[i] = (sk[i]>lvup[i]) ? 1 : (sk[i]lvmi[i]) ? 1 : (sk[i]sk[i+1]) ? 1 : (sk[i]1) { workSsm[i][s+_ssm] = workSsmCoeffs[instanceNo][_sc1]*(workSsm[i][s+_tprice]+workSsm[i-1][s+_tprice])/2.0 + workSsmCoeffs[instanceNo][_sc2]*workSsm[i-1][s+_ssm] + workSsmCoeffs[instanceNo][_sc3]*workSsm[i-2][s+_ssm]; } return(workSsm[i][s+_ssm]); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // // string rsiMethodNames[] = {"Rsi","Slow Rsi","Rapid Rsi","Harris Rsi","Rsx","Cuttler Rsi"}; string getRsiName(int method) { int max = ArraySize(rsiMethodNames)-1; method=fmax(fmin(method,max),0); return(rsiMethodNames[method]); } // // // // // #define rsiInstances 1 double workRsi[][rsiInstances*13]; #define _price 0 #define _change 1 #define _changa 2 #define _rsival 1 #define _rsval 1 double iRsi(int rsiMode, double price, double period, int i, int instanceNo=0) { if (ArrayRange(workRsi,0)!=Bars) ArrayResize(workRsi,Bars); int z = instanceNo*13; int r = Bars-i-1; // // // // // workRsi[r][z+_price] = price; switch (rsiMode) { case rsi_rsi: { double alpha = 1.0/fmax(period,1); if (r=0; k++) sum += fabs(workRsi[r-k][z+_price]-workRsi[r-k-1][z+_price]); workRsi[r][z+_change] = (workRsi[r][z+_price]-workRsi[0][z+_price])/fmax(k,1); workRsi[r][z+_changa] = sum/fmax(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*(fabs(change) - workRsi[r-1][z+_changa]); } if (workRsi[r][z+_changa] != 0) return(50.0*(workRsi[r][z+_change]/workRsi[r][z+_changa]+1)); else return(50.0); } // // // // // case rsi_wil : { double up = 0; double 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 if(up + dn == 0) workRsi[r][z+_rsival] = workRsi[r-1][z+_rsival]+(1/fmax(period,1))*(50 -workRsi[r-1][z+_rsival]); else workRsi[r][z+_rsival] = workRsi[r-1][z+_rsival]+(1/fmax(period,1))*(100*up/(up+dn)-workRsi[r-1][z+_rsival]); return(workRsi[r][z+_rsival]); } // // // // // case rsi_rap : { double up = 0; double 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(up + dn == 0) return(50); else return(100 * up / (up + dn)); } // // // // // case rsi_har : { double avgUp=0,avgDn=0; double up=0; double 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; double rs = 1; if (avgDn!=0) rs = avgUp/avgDn; return(100-100/(1.0+rs)); } // // // // // case rsi_rsx : { double Kg = (3.0)/(2.0+period), Hg = 1.0-Kg; if (r=0; k++) { double diff = workRsi[r-k][z+_price]-workRsi[r-k-1][z+_price]; if (diff > 0) sump += diff; if (diff < 0) sumn -= diff; } if (sumn > 0) return(100.0-100.0/(1.0+sump/sumn)); else return(50); } } return(0); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // #define _maInstances 2 #define _maWorkBufferx1 1*_maInstances #define _maWorkBufferx2 2*_maInstances #define _maWorkBufferx3 3*_maInstances double iCustomMa(int mode, double price, double length, int r, int instanceNo=0) { int bars = Bars; r = bars-r-1; switch (mode) { case ma_sma : return(iSma(price,(int)length,r,bars,instanceNo)); case ma_ema : return(iEma(price,length,r,bars,instanceNo)); case ma_smma : return(iSmma(price,(int)length,r,bars,instanceNo)); case ma_lwma : return(iLwma(price,(int)length,r,bars,instanceNo)); case ma_tema : return(iTema(price,(int)length,r,bars,instanceNo)); default : return(price); } } // // // // // double workSma[][_maWorkBufferx2]; double iSma(double price, int period, int r, int _bars, int instanceNo=0) { if (ArrayRange(workSma,0)!= _bars) ArrayResize(workSma,_bars); instanceNo *= 2; int k; workSma[r][instanceNo+0] = price; workSma[r][instanceNo+1] = price; for(k=1; k=0; k++) workSma[r][instanceNo+1] += workSma[r-k][instanceNo+0]; workSma[r][instanceNo+1] /= 1.0*k; return(workSma[r][instanceNo+1]); } // // // // // double workEma[][_maWorkBufferx1]; double iEma(double price, double period, int r, int _bars, int instanceNo=0) { if (ArrayRange(workEma,0)!= _bars) ArrayResize(workEma,_bars); workEma[r][instanceNo] = price; if (r>0 && period>1) workEma[r][instanceNo] = workEma[r-1][instanceNo]+(2.0/(1.0+period))*(price-workEma[r-1][instanceNo]); return(workEma[r][instanceNo]); } // // // // // double workSmma[][_maWorkBufferx1]; double iSmma(double price, double period, int r, int _bars, int instanceNo=0) { if (ArrayRange(workSmma,0)!= _bars) ArrayResize(workSmma,_bars); workSmma[r][instanceNo] = price; if (r>1 && period>1) workSmma[r][instanceNo] = workSmma[r-1][instanceNo]+(price-workSmma[r-1][instanceNo])/period; return(workSmma[r][instanceNo]); } // // // // // double workLwma[][_maWorkBufferx1]; double iLwma(double price, double period, int r, int _bars, int instanceNo=0) { if (ArrayRange(workLwma,0)!= _bars) ArrayResize(workLwma,_bars); workLwma[r][instanceNo] = price; if (period<=1) return(price); double sumw = period; double sum = period*price; for(int k=1; k=0; k++) { double weight = period-k; sumw += weight; sum += weight*workLwma[r-k][instanceNo]; } return(sum/sumw); } double workTema[][_maWorkBufferx3]; #define _tema1 0 #define _tema2 1 #define _tema3 2 double iTema(double price, double period, int r, int bars, int instanceNo=0) { if (period<=1) return(price); if (ArrayRange(workTema,0)!= bars) ArrayResize(workTema,bars); instanceNo*=3; // // // // // workTema[r][_tema1+instanceNo] = price; workTema[r][_tema2+instanceNo] = price; workTema[r][_tema3+instanceNo] = price; double alpha = 2.0 / (1.0+period); if (r>0) { workTema[r][_tema1+instanceNo] = workTema[r-1][_tema1+instanceNo]+alpha*(price -workTema[r-1][_tema1+instanceNo]); workTema[r][_tema2+instanceNo] = workTema[r-1][_tema2+instanceNo]+alpha*(workTema[r][_tema1+instanceNo]-workTema[r-1][_tema2+instanceNo]); workTema[r][_tema3+instanceNo] = workTema[r-1][_tema3+instanceNo]+alpha*(workTema[r][_tema2+instanceNo]-workTema[r-1][_tema3+instanceNo]); } return(workTema[r][_tema3+instanceNo]+3.0*(workTema[r][_tema1+instanceNo]-workTema[r][_tema2+instanceNo])); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // // #define priceInstances 1 double workHa[][priceInstances*4]; double getPrice(int tprice, const double& open[], const double& close[], const double& high[], const double& low[], int i, int instanceNo=0) { if (tprice>=pr_haclose) { if (ArrayRange(workHa,0)!= Bars) ArrayResize(workHa,Bars); instanceNo*=4; int r = Bars-i-1; // // // // // double haOpen; if (r>0) haOpen = (workHa[r-1][instanceNo+2] + workHa[r-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 = fmax(high[i],fmax(haOpen,haClose)); double haLow = fmin(low[i] ,fmin(haOpen,haClose)); if(haOpenhaOpen) 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]=0; i--) if (tf==iTfTable[i]) return(sTfTable[i]); return(""); } //------------------------------------------------------------------- // //------------------------------------------------------------------- // // // // // void CleanPoint(int i,double& first[],double& second[]) { if (i>=Bars-3) return; if ((second[i] != EMPTY_VALUE) && (second[i+1] != EMPTY_VALUE)) second[i+1] = EMPTY_VALUE; else if ((first[i] != EMPTY_VALUE) && (first[i+1] != EMPTY_VALUE) && (first[i+2] == EMPTY_VALUE)) first[i+1] = EMPTY_VALUE; } void PlotPoint(int i,double& first[],double& second[],double& from[]) { if (i>=Bars-2) return; if (first[i+1] == EMPTY_VALUE) if (first[i+2] == EMPTY_VALUE) { first[i] = from[i]; first[i+1] = from[i+1]; second[i] = EMPTY_VALUE; } else { second[i] = from[i]; second[i+1] = from[i+1]; first[i] = EMPTY_VALUE; } else { first[i] = from[i]; second[i] = EMPTY_VALUE; } }