//------------------------------------------------------------------ #property copyright "© mladen, 2018" #property link "mladenfx@gmail.com" #property version "1.00" #property description "Choppy market index - smoothed" //------------------------------------------------------------------ #property indicator_separate_window #property indicator_buffers 5 #property indicator_plots 2 #property indicator_label1 "Choppy market index" #property indicator_type1 DRAW_LINE #property indicator_color1 clrDodgerBlue #property indicator_style1 STYLE_SOLID #property indicator_width1 2 #property indicator_label2 "Choppy market index signal line" #property indicator_type2 DRAW_LINE #property indicator_color2 clrCrimson #property indicator_style2 STYLE_DOT // //--- 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 inpChoPeriod = 60; // Choppy index period input int inpSigPeriod = 10; // Signal period input enMaTypes inpSigMethod = ma_sma; // Signal method input int inpSmoothPeriod = 5; // Smoothing period input enMaTypes inpSmoothMethod = ma_sma; // Smoothing method input double inpLevel1 = 40; // Level 1 input double inpLevel2 = 50; // Level 2 input double inpLevel3 = 60; // Level 3 double csi[],sig[],whigh[],wlow[],wclose[]; string _maNames[] = {"SMA","EMA","SMMA","LWMA"}; //------------------------------------------------------------------ // //------------------------------------------------------------------ int OnInit() { SetIndexBuffer(0,csi,INDICATOR_DATA); SetIndexBuffer(1,sig,INDICATOR_DATA); SetIndexBuffer(2,whigh,INDICATOR_CALCULATIONS); SetIndexBuffer(3,wlow,INDICATOR_CALCULATIONS); SetIndexBuffer(4,wclose,INDICATOR_CALCULATIONS); IndicatorSetInteger(INDICATOR_LEVELS,3); IndicatorSetDouble(INDICATOR_LEVELVALUE,0,inpLevel1); IndicatorSetDouble(INDICATOR_LEVELVALUE,1,inpLevel2); IndicatorSetDouble(INDICATOR_LEVELVALUE,2,inpLevel3); IndicatorSetString(INDICATOR_SHORTNAME,"Choppy market index ("+string(inpChoPeriod)+","+string(inpSigPeriod)+", "+_maNames[inpSmoothMethod]+" "+string(inpSmoothPeriod)+" smoothed)"); return(INIT_SUCCEEDED); } // //--- // 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[]) { double _prices[3]; for (int i=(int)MathMax(prev_calculated-1,0); i=inpChoPeriod) ? 100.0*MathAbs(wclose[i]-wclose[i-inpChoPeriod])/(hi-lo) : 0; sig[i] = iCustomMa(inpSigMethod,csi[i],inpSigPeriod,i,rates_total); } return(rates_total); } //+------------------------------------------------------------------+ //| Custom functions | //+------------------------------------------------------------------+ // //--- // #define _maInstances 14 #define _maWorkBufferx1 _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); }