/** * BB-Trend * * Per: * https://www.investopedia.com/ask/answers/121014/what-are-best-indicators-use-conjunction-bollinger-bands.asp * * BBTrend is a relatively new indicator developed by John Bollinger to work with * Bollinger Bands™. It is one of only a few indicators that can signal both strength * and direction, making it a very valuable tool for traders. * * BBTrend is calculated using the following code in the chart: * lower = abs(lowerBB(20) - lowerBB(50)) * upper = abs(upperBB(20) - upperBB(50)) * BBTrend = (lower - upper) / middleBB(20) * * If the BBTrend reads above zero, the signal is a bullish trend, and if the BBTrend * reading is below zero, the signal is a bearish trend. The degree above or below zero * determines the strength or momentum behind the trend. The BBTrend indicator was * still in beta testing in 2012, but it looks to be a great resource for technical * analysts and offers an alternative to the average directional movement index, or ADX, * which gives similar readings. */ #property copyright "2018 Anthony J. Garot" #property link "http://www.garot.com/trading/" #property version "1.0" #property icon "\\Images\\BB-Trend-icon.ico" #property description "BB-Trend" #property description " " #property description "Uses two Bollinger Bands™ to signal both trend and direction." #property description "Formula found here: https://www.investopedia.com/ask/answers/121014/what-are-best-indicators-use-conjunction-bollinger-bands.asp" #property description " " #property description "MQL5 Profile: https://www.mql5.com/en/users/tonegarot" #property description "My Website: http://www.garot.com/trading/" #property strict // indicator settings #property indicator_separate_window //#property indicator_chart_window #property indicator_buffers 10 #property indicator_plots 1 #property indicator_type1 DRAW_COLOR_HISTOGRAM #property indicator_style1 STYLE_SOLID #property indicator_width1 2 #property indicator_color1 Turquoise,SeaGreen,Crimson,Tomato #property indicator_label1 "BB-Trend" const int chartID = 0; // const values const string SHORT_NAME = "BB-Trend"; // input parameters input int InpShorterPeriod = 20; input int InpLongerPeriod = 50; input int InpBollBandsShift = 0; input double InpBollBandsDeviation = 2.000; // indicator buffers/arrays double ExtBBTrendBuffer[]; double ExtBBTrendColors[]; double LowerBuffer[]; double UpperBuffer[]; double BbShorterLowerBuffer[]; // shorter(20) internal double BbShorterMiddleBuffer[]; // shorter(20) internal double BbShorterUpperBuffer[]; // shorter(20) internal double BbLongerLowerBuffer[]; // longer(50) internal double BbLongerMiddleBuffer[]; // longer(50) internal double BbLongerUpperBuffer[]; // longer(50) internal // handles for moving averages int g_shorterHandle; int g_longerHandle; // What's our minimum number of bars to perform a calculation? int g_barsMinimum = -1; void OnInit() { // indicator buffers mapping SetIndexBuffer(0,ExtBBTrendBuffer,INDICATOR_DATA); SetIndexBuffer(1,ExtBBTrendColors,INDICATOR_COLOR_INDEX); SetIndexBuffer(2,UpperBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(3,LowerBuffer,INDICATOR_CALCULATIONS); // Internal SetIndexBuffer(4,BbShorterLowerBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(5,BbShorterMiddleBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(6,BbShorterUpperBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(7,BbLongerLowerBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(8,BbLongerMiddleBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(9,BbLongerUpperBuffer,INDICATOR_CALCULATIONS); // get handles for the indicators used in this indicator g_shorterHandle=iBands(NULL, 0, InpShorterPeriod, InpBollBandsShift, InpBollBandsDeviation, PRICE_CLOSE); g_longerHandle= iBands(NULL, 0, InpLongerPeriod, InpBollBandsShift, InpBollBandsDeviation, PRICE_CLOSE); g_barsMinimum = MathMax(InpLongerPeriod, InpShorterPeriod); IndicatorSetInteger(INDICATOR_DIGITS,_Digits); ChartSetInteger(chartID,CHART_SHIFT,false); ChartSetInteger(chartID,CHART_AUTOSCROLL,true); ChartSetString(chartID,CHART_COMMENT," "); // This sets graphical objects to the foreground, i.e. the grid and // bars will be hidden behind the graphical objects. ChartSetInteger(chartID, CHART_FOREGROUND, false); // sets first bar from what index will be drawn PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpLongerPeriod); // name for DataWindow and indicator subwindow label IndicatorSetString(INDICATOR_SHORTNAME, SHORT_NAME); } 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[]) { // check for rates total if(rates_totalrates_total || prev_calculated<0) { to_copy=rates_total; } else { to_copy=rates_total-prev_calculated; if(prev_calculated>0) to_copy++; } // get buffers // CopyBuffer(handle,buffer,start_pos,count,buffer[]) if(IsStopped()) return(0); //Checking for stop flag if(CopyBuffer(g_longerHandle,0,0,to_copy,BbLongerMiddleBuffer)<=0 || CopyBuffer(g_longerHandle,1,0,to_copy,BbLongerUpperBuffer)<=0 || CopyBuffer(g_longerHandle,2,0,to_copy,BbLongerLowerBuffer)<=0 ) { Print("getting g_longerHandle data has failed! Error",GetLastError()); return(0); } if(IsStopped()) return(0); //Checking for stop flag if(CopyBuffer(g_shorterHandle,0,0,to_copy,BbShorterMiddleBuffer)<=0 || CopyBuffer(g_shorterHandle,1,0,to_copy,BbShorterUpperBuffer)<=0 || CopyBuffer(g_shorterHandle,2,0,to_copy,BbShorterLowerBuffer)<=0 ) { Print("getting g_shorterHandle data has failed! Error",GetLastError()); return(0); } // correct position, when it's first iteration int pos = prev_calculated - 1; if ( pos <= 0 ) { pos = 1; BbLongerMiddleBuffer[0] = 0.; BbLongerUpperBuffer[0] = 0.; BbLongerLowerBuffer[0] = 0.; BbShorterMiddleBuffer[0] = 0.; BbShorterUpperBuffer[0] = 0.; BbShorterLowerBuffer[0] = 0.; } // main cycle for(int i=pos;i 0 ) { if ( ExtBBTrendBuffer[i] > ExtBBTrendBuffer[i-1] ) { ExtBBTrendColors[i] = 0; } else { ExtBBTrendColors[i] = 1; } } else { if ( ExtBBTrendBuffer[i] > ExtBBTrendBuffer[i-1] ) { ExtBBTrendColors[i] = 2; } else { ExtBBTrendColors[i] = 3; } } } // return value of prev_calculated for next call return(rates_total); }