Join our fan page
- Views:
- 75
- Published:
-
Need a robot or indicator based on this code? Order it on Freelance Go to Freelance
I have repeatedly seen traders clamoring for an indicator that counts consecutive up and down candles (bars) in the Forum. Clearly, many traders use, or want to use, that indicator. Although I've seen various options for MT4, options for MT5 appear to be limited. The consecutive bar counting indicators that I found merely show the current count of consecutive bars that print in the current price direction. Therefore, I coded this Consecutive_Bars indicator for MT5.
The main benefit of this indicator is that you can set a level at the most frequently appearing "false swing" count─thereby filtering those false swings out of your trading. The blue line study shows up bars, and the red line study show down bars. Upon 1 bar printing in the opposite direction of the count, the line studies respectively return to the 0 level.
The only input setting is MaxBars which sets the maximum lookback/drawing period of the entire indicator.
The code (framed below) is heavily commented as a detailed explanation, especially for aspiring coders.
//+------------------------------------------------------------------+ //| Consecutive_Bars.mq5 | //| Copyright 2026, Ryan Lawrence Johnson | //| https://www.mql5.com/en/users/rjo | //+------------------------------------------------------------------+ //--- store price, time, and volume data for access as in MQL4 #define SERIES(name,type) \ class C##name \ { \ public: \ type operator[](const int i){return i##name(NULL,0,i);} \ }name; SERIES(Open,double) SERIES(Low,double) SERIES(High,double) SERIES(Close,double) SERIES(Time,datetime) SERIES(Volume,long) SERIES(TickVolume,long) //--- properties #property copyright "© 2026, Ryan Lawrence Johnson" #property link "https://www.mql5.com/en/users/rjo" #property version "1.00" #property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 2 #property indicator_type1 DRAW_SECTION #property indicator_style1 STYLE_SOLID #property indicator_color1 clrDodgerBlue #property indicator_width1 1 #property indicator_type2 DRAW_SECTION #property indicator_style2 STYLE_SOLID #property indicator_color2 clrRed #property indicator_width2 1 //--- settings input int MaxBars = 200; //--- variables on global scope int countUp; int countDn; //--- arrays for indicator data buffers double consecUpBars[]; double consecDnBars[]; //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0, consecUpBars, INDICATOR_DATA); // set index buffer 0 to store up bars PlotIndexSetString(0, PLOT_LABEL, "Consec Up Bars"); // set on-screen label (for mouse cursor rollover) for up bars PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, Bars(NULL, 0) - MaxBars); // PLOT_DRAW_BEGIN defines undrawn bars ==> so skip all bars except MaxBars // (this indicator loops thruogh bars in reverse chronological order) SetIndexBuffer(1, consecDnBars, INDICATOR_DATA); // set index buffer 1 to store down bars PlotIndexSetString(1, PLOT_LABEL, "Consec Dn Bars"); // set on-screen label (for mouse cursor rollover) for down bars PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, Bars(NULL, 0) - MaxBars); // PLOT_DRAW_BEGIN defines undrawn bars ==> so skip all bars except MaxBars // (this indicator loops thruogh bars in reverse chronological order) //--- indicator short name IndicatorSetString(INDICATOR_SHORTNAME, "Consec Bars"); // set the indicator short name // (required if you use ChartIndicatorDelete() in an EA) //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 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[]) { //--- align indicator data direction with price data direction ArraySetAsSeries(consecUpBars, true); // set the up bars indicator buffer (array) to align with the time series of price data ArraySetAsSeries(consecDnBars, true); // set the down bars indicator buffer (array) to align with the time series of price data int limit; // declare a variable of the integer type to store the main loop starting bar index int bar; // declare a variable of the integer type to store the current bar index //--- calculation of the starting bar index limit = rates_total + (MaxBars - rates_total) - 1; // starting index for the calculation of all of the bars // use rates_total - 1 for reverse chronological loop // avoids the need to use prev_calculated // skip all bars except MaxBars ==> a negative integer is added to rates_total - 1 //--- main loop for(bar = limit; bar >= 0; bar--) // loop iterates in reverse chronological order starting at current bar 0 // adding 1, 2, 3, an so on for previous/older bars // every call to a specific bar number inside the loop must reference the variable, bar { // consecutive up bars if(Close[bar] > Open[bar] // current close is higher than current open ==> a curent up bar && Close[bar + 1] < Open[bar + 1]) // previous close is lower than previous open ==> a previous down bar { countUp = 1; // set the up bar count to 1 ==> to prepare for a potential consecutive up bars swing } if(Close[bar] > Open[bar] // current close is higher than current open ==> a current up bar && Close[bar + 1] > Open[bar + 1]) // previous close is higher than previous open ==> a previous up bar { countUp++; // add, and keep adding, to the up bar count ==> while additional up bars continue to form } consecUpBars[bar] = countUp; // set the up bars indicator buffer to the up bars count if(Close[bar] < Open[bar]) // current close is lower than current open ==> a current down bar { consecUpBars[bar] = 0; // set the up bars indicator buffer to 0 ==> the consecutive up bars swing has ended } // consecutive down bars if(Close[bar] < Open[bar] // current close is lower than current open ==> a current down bar && Close[bar + 1] > Open[bar + 1]) // previous close is higher than previous open ==> a previous up bar { countDn = 1; // set down bar count to 1 ==> to prepare for a potential consecutive down bars swing } if(Close[bar] < Open[bar] // current close is lower than current open ==> a current down bar && Close[bar + 1] < Open[bar + 1]) // previous close is lower than previous open ==> a previous down bar { countDn++; // add, and keep adding, to the down bar count ==> while additional down bars continue to form } consecDnBars[bar] = countDn; // set the down bars indicator buffer to the down bars count if(Close[bar] > Open[bar]) // current close is higher than previous open ==> a current up bar { consecDnBars[bar] = 0; // set the down bars indicator buffer to 0 ==> the consecutive down bars swing has ended } } //--- return value of prev_calculated for next call return(rates_total + (MaxBars - rates_total) - 1); // again, rates_total is edited to reference MaxBars and - 1 // this aligns with the definition of the variable, limit } //+------------------------------------------------------------------+
Multi-Timeframe Candle Map
An educational MT5 panel that maps the live price vertically inside four developing candles and summarizes location alignment, dispersion, candle direction and time remaining.
SR Zone Scanner
Multi-timeframe Support & Resistance zone scanner with strength rating and instant alerts — M15, H1, H4, D1.
Accelerator Oscillator (AC)
The Acceleration/Deceleration Indicator (AC) measures acceleration and deceleration of the current driving force.
MACD Signals
Indicator edition for new platform.
