//+------------------------------------------------------------------ #property copyright "mladen" #property link "mladenfx@gmail.com" #property link "https://www.mql5.com" #property description "Rsi(var)" //+------------------------------------------------------------------ #property indicator_separate_window #property indicator_buffers 5 #property indicator_plots 3 #property indicator_type1 DRAW_COLOR_LINE #property indicator_color1 clrSilver,clrDarkGray #property indicator_width1 2 #property indicator_type2 DRAW_LINE #property indicator_color2 clrOrange #property indicator_width2 1 #property indicator_type3 DRAW_LINE #property indicator_color3 clrRed #property indicator_width3 1 //--- input parameters enum enMaTypes { ma_sma, // Simple moving average ma_ema, // Exponential moving average ma_smma, // Smoothed MA ma_lwma // Linear weighted MA }; input int inpPeriod = 14; // RSI period input ENUM_APPLIED_PRICE inpPrice = PRICE_CLOSE; // Price input enMaTypes inpMaMethod = ma_smma; // RSI average method input int inpFastMa = 2; // Fast MA period (<=0 - no average) input enMaTypes inpFastMaMethod = ma_smma; // Fast MA method input int inpSlowMa = 8; // Slow MA period (<=0 - no average) input enMaTypes inpSlowMaMethod = ma_smma; // Slow MA method //--- buffers and global variables declarations double val[],valc[],avg1[],avg2[],prices[]; string _avgNames[]={"SMA","EMA","SMMA","LWMA"}; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,val,INDICATOR_DATA); SetIndexBuffer(1,valc,INDICATOR_COLOR_INDEX); SetIndexBuffer(2,avg1,INDICATOR_DATA); SetIndexBuffer(3,avg2,INDICATOR_DATA); SetIndexBuffer(4,prices,INDICATOR_CALCULATIONS); //--- IndicatorSetString(INDICATOR_SHORTNAME,"Rsi(var) ("+_avgNames[inpMaMethod]+") ("+(string)inpPeriod+")"); return (INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator de-initialization function | //+------------------------------------------------------------------+ 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)0) ? prices[i-1] : prices[i]; double _bulls = 0.5*(MathAbs(_price1-_price2)+(_price1-_price2)); double _bears = 0.5*(MathAbs(_price1-_price2)-(_price1-_price2)); double _avgBulls = iCustomMa(inpMaMethod,_bulls,inpPeriod,i,rates_total,0); double _avgBears = iCustomMa(inpMaMethod,_bears,inpPeriod,i,rates_total,1); val[i] = (_avgBulls!=0) ? 100.0/(1+_avgBears/_avgBulls) : 0; valc[i]=(i>0) ?(val[i]>val[i-1]) ? 0 :(val[i]0) ? iCustomMa(inpFastMaMethod,val[i],inpFastMa,i,rates_total,2) : EMPTY_VALUE; avg2[i] = (inpSlowMa>0) ? iCustomMa(inpSlowMaMethod,val[i],inpSlowMa,i,rates_total,3) : EMPTY_VALUE; } return (i); } //+------------------------------------------------------------------+ //| Custom functions | //+------------------------------------------------------------------+ #define _maInstances 4 #define _maWorkBufferx1 1*_maInstances //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double iCustomMa(int mode,double price,double length,int r,int bars,int instanceNo=0) { 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)); default : return(price); } } // // // // // double workSma[][_maWorkBufferx1]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double iSma(double price,int period,int r,int _bars,int instanceNo=0) { if(ArrayRange(workSma,0)!=_bars) ArrayResize(workSma,_bars); workSma[r][instanceNo]=price; double avg=price; int k=1; for(; k=0; k++) avg+=workSma[r-k][instanceNo]; return(avg/(double)k); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ 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 getPrice(ENUM_APPLIED_PRICE tprice,const double &open[],const double &close[],const double &high[],const double &low[],int i,int _bars) { switch(tprice) { case PRICE_CLOSE: return(close[i]); case PRICE_OPEN: return(open[i]); case PRICE_HIGH: return(high[i]); case PRICE_LOW: return(low[i]); case PRICE_MEDIAN: return((high[i]+low[i])/2.0); case PRICE_TYPICAL: return((high[i]+low[i]+close[i])/3.0); case PRICE_WEIGHTED: return((high[i]+low[i]+close[i]+close[i])/4.0); } return(0); } //+------------------------------------------------------------------+