//+------------------------------------------------------------------+ //| Choppiness Index.mq4 | //| Copyright © 2009, David Moser | //| dmoser71@gmail.com | //+------------------------------------------------------------------+ #property copyright "Copyright © 2009, David Moser" #property link "dmoser71@gmail.com" // This Indicator is NEVER to be SOLD individually // This Indicator is NEVER to be INCLUDED as part of a collection that is SOLD //---- common control defaults #property indicator_separate_window #property indicator_minimum 0 #property indicator_maximum 100 #property indicator_buffers 3 #property indicator_color1 Yellow #property indicator_width1 2 #property indicator_style1 0 #property indicator_color2 Red #property indicator_width2 1 #property indicator_style2 0 #property indicator_color3 Red #property indicator_width3 1 #property indicator_style3 0 #property indicator_level1 38.2 #property indicator_level2 61.8 #property indicator_levelstyle 2 #property indicator_levelcolor Silver //---- indicator parameters // Main Parameters extern int ChoppinessPeriod=14; // Number of bars to evaluation CI extern int SmoothingPeriod=1; // Number of bars to apply SMA extern int StdDevPeriod=14; // Number of bars to evaluate Standard Deviation of the CI extern bool StdDevFollowPrice=false; // True, StdDev bars follow price, False, StdDev bars centered on 50 extern bool EnableAlertOnHigh=false; // Alert setting for entering time of choppiness extern double AlertHighVal=61.8; // Default value based on fib numbers extern bool EnableAlertOnLow=false; // Alert setting for entering time of trending extern double AlertLowVal=38.2; // Default value based on fib numbers extern int MaxCalcBars=1000; // Limit calculations back this many bars //---- indicator buffers double ExtMapBuffer[]; double StdDevHiBuffer[]; double StdDevLoBuffer[]; double IntMapBuffer[]; double IntStdDevBuffer[]; //---- variables string TimeFrame; datetime LastAlert=0; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { IndicatorBuffers(5); SetIndexStyle(0,DRAW_LINE); SetIndexBuffer(0,ExtMapBuffer); SetIndexStyle(1,DRAW_LINE); SetIndexBuffer(1,StdDevHiBuffer); SetIndexStyle(2,DRAW_LINE); SetIndexBuffer(2,StdDevLoBuffer); SetIndexBuffer(3,IntMapBuffer); SetIndexBuffer(4,IntStdDevBuffer); if (ChoppinessPeriod<2) ChoppinessPeriod = 2; // Any lower and this indicator isn't relevant if (SmoothingPeriod<1) SmoothingPeriod = 1; // Avoid configuration errors if (StdDevPeriod<2) StdDevPeriod = 2; // Any lower and the Standard Deviation isn't relevant if (MaxCalcBars>10000) MaxCalcBars = 10000; // Any higher and may adversely affect performance on multi-chart setups SetIndexDrawBegin(0,ChoppinessPeriod+SmoothingPeriod); SetIndexDrawBegin(1,ChoppinessPeriod+SmoothingPeriod+StdDevPeriod); SetIndexDrawBegin(2,ChoppinessPeriod+SmoothingPeriod+StdDevPeriod); string short_name="Choppiness Index ("+ChoppinessPeriod+","+SmoothingPeriod+","+StdDevPeriod+")"; IndicatorShortName(short_name); switch (Period()) { case 1: TimeFrame = "M1"; break; case 5: TimeFrame = "M5"; break; case 15: TimeFrame = "M15"; break; case 30: TimeFrame = "M30"; break; case 60: TimeFrame = "H1"; break; case 240: TimeFrame = "H4"; break; case 1440: TimeFrame = "D1"; break; case 10080: TimeFrame = "W1"; break; case 43200: TimeFrame = "MN"; break; } //---- initial zero for(int i=0;i<=Bars;i++) ExtMapBuffer[i]=0; // Smoothed & visible main indicator line for(i=0;i<=Bars;i++) StdDevHiBuffer[i]=0; // Upper StdDev band, visible for(i=0;i<=Bars;i++) StdDevLoBuffer[i]=0; // Lower StdDev band, visible for(i=0;i<=Bars;i++) IntMapBuffer[i]=0; // Raw CI, not smoothed, not visible for(i=0;i<=Bars;i++) IntStdDevBuffer[i]=0; // Raw StdDev of Smoothed & visible main indicator line (ExtMapBuffer) return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int start() { int counted_bars=IndicatorCounted(); int z,limit; double bufferTemp1, bufferTemp2; if (counted_bars<0) return(-1); if (counted_bars>0) counted_bars--; limit=Bars-counted_bars; if (limit>MaxCalcBars) limit=MaxCalcBars; for (int i=limit-1; i>=0; i--) { IntMapBuffer[i] = ChoppinessIndex(ChoppinessPeriod,i); bufferTemp1 = 0; for(int j=0; jAlertHighVal) && (ExtMapBuffer[2]AlertLowVal)) { LastAlert = Time[0]; // No more alerts on the current bar Alert(Symbol()+","+TimeFrame+":Choppiness less than "+DoubleToStr(AlertLowVal,1)); } return(0); } double ChoppinessIndex(int period, int bar) { double Low0 = 0, High0 = 0, Close1 = 0; double TrueRangeLow = 0, TrueRangeHigh = 0, TrueRangeSum = 0, Input = 0; double PeriodTrueRangeLow = 999999999, PeriodTrueRangeHigh = 0, PeriodTrueRange = 0; for(int k=bar; kClose1) TrueRangeHigh = High0; else TrueRangeHigh = Close1; if (TrueRangeLow PeriodTrueRangeHigh) PeriodTrueRangeHigh = TrueRangeHigh; // find true high of period TrueRangeSum += TrueRangeHigh; TrueRangeSum -= TrueRangeLow; } PeriodTrueRange = PeriodTrueRangeHigh - PeriodTrueRangeLow; if (PeriodTrueRange==0) PeriodTrueRange = MathPow(10, -12); // avoid possibility of division by zero Input = TrueRangeSum / PeriodTrueRange; return ((logN(Input, 10, MathPow(10, -12)) / logN(period, 10, MathPow(10, -12))) * 100); } double logN(double x, double base, double epsilon) { double integer = 0.0; if ((x < 1) || (base < 1)) return(0); while (x < 1) { integer -= 1; x *= base; } while (x >= base) { integer += 1; x /= base; } double partial = 0.5; x *= x; double decimal = 0.0; while (partial > epsilon) { if (x >= base) { decimal += partial; x = x / base; } partial *= 0.5; x *= x; } return (integer + decimal); } double StdDev(int shift, int samples) { double x0=0, x1=0, x2=0; for (int m=0; m