Utility to view the statistics for a Single Bar of any time frame Indicator For MT5

Utility to view the statistics for a Single Bar of any time frame Indicator For MT5

The Utility to view the statistics for a Single Bar of any time frame Indicator For MT5 displays critical statistics for a single bar. In other words, it shows the critical metrics for the specific time frame and allows the traders to find the perfect trade setups. After processing data, the indicator displays the major details about the anatomy of the candle.

For instance, you can get the exact point of high, low, close and open price. It also gives you the exact number of the bar up and bars down data. Those who are specialized in scalping should definitely try this indicator as it will make the complete trading process much easier and efficient. However, you should be cautious about the order entry point.

Placing the random trades at minor SR levels can cause a huge amount of loss. Be confident about the trade setups and try to find the perfect SR zones by connecting three major swings. Once the key trading spots are determined, use the statistics of the single bar to get your perfect shot in this market.

FREE Utility to view the statistics for a Single Bar of any time frame Indicator

Download the FREE Utility to view the statistics for a Single Bar of any time frame Indicator for MT5.

To receive my email 100% sure: 
Put my email on your whitelist!


Partially Automated Trading Besides Your Day Job

Alerts In Real-Time When Divergences Occur

My Recommended MT4/MT5 Broker


Installing the Utility to view the statistics for a Single Bar of any time frame Indicator For MT5

After you downloaded the indicator via the form above you need to unzip the zip-file. Then you need to copy the file SingleBarValues.mq5 into the folder MQL5\Indicators of your MT5 installation. After that please restart MT5 and then you will be able to see the indicator in the list of indicators.

Parameters of the Utility to view the statistics for a Single Bar of any time frame Indicator For MT5

The Utility to view the statistics for a Single Bar of any time frame Indicator For MT5 has 2 parameters to configure.

input int         Uniquifier       = 3;  // Display Offset and Unique Instance Number
input ENUM_ON_OFF DirectClick         = ON; // select bars with a mouse click

Buffers of the Utility to view the statistics for a Single Bar of any time frame Indicator For MT5

The Utility to view the statistics for a Single Bar of any time frame Indicator For MT5 provides 0 buffers.

Main Parts Of The Code

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( ( rates_total - prev_calculated  gt  0 ) )// new bar
         EventChartCustom(ChartID(),CHARTEVENT_MAKECHART, Uniquifier, NULL, NULL);  // Post an event to refresh the display.
       }else if(barNumBox.displayValue lt 1)  // Redraw for bar zero with every quote
         EventChartCustom(ChartID(),CHARTEVENT_MAKECHART, Uniquifier, NULL, NULL);  // Post an event to refresh the display.
      return rates_total ;
void displayControls(void)
   for(ENUM_CTRL_IDX i=0; i lt endObjIdx; i++)
      string dispText = getPromptTxt(i);
      manageALabel(ctrlObjName[i], dispText, objXPos[i], objYPos[i], objClr[i], 10);
void runDisplay(void)
   static ulong callCount=0; callCount++;
   int barNum = barNumBox.displayValue, catlen;
   string barStr = IntegerToString(barNum);
   static double barClose, barHigh, barLow, barOpen, price[1];
   static MqlRates rates[1];
   datetime theTime=NULL, barTime[1];
   string hdrString, closeString, openString, highString, lowString, timeString;
   switch (workingMechanism)  // enum BAR_INFO_MECH {ARRAYS, IMAS, COPY_FUNCS, RATES};
      case COPY_FUNCS:
         if( CopyClose(_Symbol,workingTF,barNum,COPYONEELEMENT,price) gt -1) { barClose = price[0]; }else{int errCode = GetLastError(); ResetLastError(); PostTerminalError("CopyClose", barNum, workingTF, errCode, callCount);}
         if( CopyHigh(_Symbol,workingTF,barNum,COPYONEELEMENT,price) gt -1) { barHigh = price[0]; }else{int errCode = GetLastError(); ResetLastError(); PostTerminalError("CopyHigh", barNum, workingTF, errCode, callCount);}
         if( CopyLow(_Symbol,workingTF,barNum,COPYONEELEMENT,price) gt -1) { barLow = price[0]; }else{int errCode = GetLastError(); ResetLastError(); PostTerminalError("CopyLow", barNum, workingTF, errCode, callCount);}
         if( CopyOpen(_Symbol,workingTF,barNum,COPYONEELEMENT,price) gt -1) { barOpen = price[0]; }else{int errCode = GetLastError(); ResetLastError(); PostTerminalError("CopyOpen", barNum, workingTF, errCode,callCount);}
         if( CopyTime(_Symbol,workingTF,barNum,COPYONEELEMENT,barTime) gt -1) { theTime = barTime[0]; }else{int errCode = GetLastError(); ResetLastError(); PostTerminalError("CopyTime", barNum, workingTF, errCode,callCount);}
         catlen   = StringConcatenate(hdrString,"Bar: ",IntegerToString(barNum),"; Range: ",DoubleToString(barHigh-barLow,_Digits) );
         catlen   = StringConcatenate(closeString,"CopyClose = ",DoubleToString(barClose,_Digits) );
         catlen   = StringConcatenate(openString,"CopyOpen = ",DoubleToString(barOpen,_Digits) );
         catlen   = StringConcatenate(highString,"CopyHigh = ",DoubleToString(barHigh,_Digits) );
         catlen   = StringConcatenate(lowString,"CopyLow = ",DoubleToString(barLow,_Digits) );
         catlen   = StringConcatenate(timeString,"CopyTime = ",TimeToString(theTime,TIME_DATE|TIME_MINUTES) );
       case DIRECT:
         barClose = iClose(_Symbol,workingTF,barNum);
         if( barClose==0){int errCode = GetLastError(); ResetLastError(); PostTerminalError("iClose", barNum, workingTF, errCode, callCount);}
         barHigh = iHigh(_Symbol,workingTF,barNum);
         if( barHigh==0){int errCode = GetLastError(); ResetLastError(); PostTerminalError("iHigh", barNum, workingTF, errCode, callCount);}
         barLow = iLow(_Symbol,workingTF,barNum);
         if( barLow==0){int errCode = GetLastError(); ResetLastError(); PostTerminalError("iLow", barNum, workingTF, errCode, callCount);}
         barOpen = iOpen(_Symbol,workingTF,barNum);
         if( barOpen==0){int errCode = GetLastError(); ResetLastError(); PostTerminalError("iOpen", barNum, workingTF, errCode,callCount);}
         theTime = iTime(_Symbol,workingTF,barNum);
         if( theTime==NULL){int errCode = GetLastError(); ResetLastError(); PostTerminalError("iTime", barNum, workingTF, errCode,callCount);}
         catlen   = StringConcatenate(hdrString,"Bar: ",IntegerToString(barNum),"; Range: ",DoubleToString(barHigh-barLow,_Digits) );
         catlen   = StringConcatenate(closeString,"iClose = ",DoubleToString(barClose,_Digits) );
         catlen   = StringConcatenate(openString,"iOpen = ",DoubleToString(barOpen,_Digits) );
         catlen   = StringConcatenate(highString,"iHigh = ",DoubleToString(barHigh,_Digits) );
         catlen   = StringConcatenate(lowString,"iLow = ",DoubleToString(barLow,_Digits) );
         catlen   = StringConcatenate(timeString,"iTime = ",TimeToString(theTime,TIME_DATE|TIME_MINUTES) );
      case RATES: // fall thru with RATES as the default
      default:  // Just use RATES as the default
         if( CopyRates(_Symbol,workingTF,barNum,COPYONEELEMENT,rates)  lt  0 ) // get rates.time, rates.open, rates.high, rates.low, rates.close and more
            int errCode = GetLastError(); ResetLastError();
            PostTerminalError("CopyRates", barNum, workingTF, errCode, callCount);
         barClose = rates[0].close;
         barHigh  = rates[0].high;
         barLow   = rates[0].low;
         barOpen  = rates[0].open;
         theTime  = rates[0].time;
         catlen   = StringConcatenate(hdrString,"Bar: ",IntegerToString(barNum),"; Range: ",DoubleToString(barHigh-barLow,_Digits) );
         catlen   = StringConcatenate(closeString,"rates[].close = ",DoubleToString(barClose,_Digits) );
         catlen   = StringConcatenate(openString,"rates[].open  = ",DoubleToString(barOpen,_Digits) );
         catlen   = StringConcatenate(highString,"rates[].high  = ",DoubleToString(barHigh,_Digits) );
         catlen   = StringConcatenate(lowString,"rates[].low   = ",DoubleToString(barLow,_Digits) );
         catlen   = StringConcatenate(timeString,"rates[].time  = ",TimeToString(theTime,TIME_DATE|TIME_MINUTES) );
   manageALabel(infObjName[INFO_HDR], hdrString, infXPos[INFO_HDR], infYPos[INFO_HDR], infClr[INFO_HDR], 11);
   manageALabel(infObjName[INFO_CLOSE], closeString, infXPos[INFO_CLOSE], infYPos[INFO_CLOSE], infClr[INFO_CLOSE], 11);
   manageALabel(infObjName[INFO_OPEN], openString, infXPos[INFO_OPEN], infYPos[INFO_OPEN], infClr[INFO_OPEN], 11);
   manageALabel(infObjName[INFO_HIGH], highString, infXPos[INFO_HIGH], infYPos[INFO_HIGH], infClr[INFO_HIGH], 11);
   manageALabel(infObjName[INFO_LOW], lowString, infXPos[INFO_LOW], infYPos[INFO_LOW], infClr[INFO_LOW], 11);
   manageALabel(infObjName[INFO_TIME], timeString, infXPos[INFO_TIME], infYPos[INFO_TIME], infClr[INFO_TIME], 11);
   barRectangle.topPrice    = barHigh;
   barRectangle.bottomPrice = barLow;
   barRectangle.startTime   = theTime;
   if( CopyTime(_Symbol,_Period,NOSHIFT,COPYONEELEMENT,barTime) gt -1)  // Get the Chart s bar Zero time Succeeded
      if( barTime[0]  lt  (theTime+PeriodSeconds(workingTF)) ) // Not working with statistics of bars inside chart bar zero
         barRectangle.endTime = barTime[0]+PeriodSeconds(PERIOD_CURRENT);
         barRectangle.endTime = theTime+PeriodSeconds(workingTF);
    }else{ // Copytime Failure
      int errCode = GetLastError(); ResetLastError();
      int zeroBar=0;
      PostTerminalError("CopyTime", zeroBar, workingTF, errCode, callCount);

void PostTerminalError( const string operation, const int& barNum, const ENUM_TIMEFRAMES& tf, const int& errCode, const ulong& callCount)
   Print( "Call: ",IntegerToString(callCount)," for ",operation," for bar: ",IntegerToString(barNum)," of Time Frame: ",getPeriodText(tf, PART_TWO)," posted error: "+IntegerToString(errCode)); //+", "+ErrorDescription(errCode));
void displayABox( const BoxStruct& displayBox )
   static long chartID = ChartID();
   string objName = displayBox.editBoxName;
   string displayStr = IntegerToString(displayBox.displayValue);
   int dispWindow = ObjectFind(chartID,objName);
   if ( dispWindow  lt  0 ) // if no such object, make it
      ObjectCreate(chartID,objName,OBJ_EDIT,WINDOW_ZERO,     0, 0);
      ObjectSetInteger(chartID,objName,OBJPROP_FONTSIZE,    10);
      ObjectSetString (chartID,objName,OBJPROP_FONT,        "Arial");
      ObjectSetInteger(chartID,objName,OBJPROP_COLOR,       clrCornflowerBlue);
      ObjectSetInteger(chartID,objName,OBJPROP_BGCOLOR,     clrLightGray);
      ObjectSetInteger(chartID,objName,OBJPROP_XSIZE,       50); 
      ObjectSetInteger(chartID,objName,OBJPROP_YSIZE,       20);
      ObjectSetInteger(chartID,objName,OBJPROP_ALIGN,       ALIGN_CENTER); 
      ObjectSetInteger(chartID,objName,OBJPROP_CORNER,      CORNER_LEFT_UPPER);
      ObjectSetInteger(chartID,objName,OBJPROP_ANCHOR,      ANCHOR_LEFT_UPPER);
      ObjectSetInteger(chartID,objName,OBJPROP_READONLY,    false); 
      ObjectSetInteger(chartID,objName,OBJPROP_BACK,        false); 
      ObjectSetInteger(chartID,objName,OBJPROP_SELECTABLE,  false); 
      ObjectSetInteger(chartID,objName,OBJPROP_SELECTED,    false);
      ObjectSetInteger(chartID,objName,OBJPROP_HIDDEN,      true);
   ObjectSetInteger(chartID,objName,OBJPROP_XDISTANCE,      displayBox.xPos );
   ObjectSetInteger(chartID,objName,OBJPROP_YDISTANCE,      displayBox.yPos );
   ObjectSetString (chartID, objName, OBJPROP_TEXT,         displayStr );
void manageALabel(const string& objName, const string dispStr, const int& xPos, const int& yPos, const color dispClr, const int fontSize = 12)
   static long chartID = ChartID();
   if ( ObjectFind(chartID,objName)  lt  0 )  // if no such object, make it
      ObjectCreate    (chartID, objName, OBJ_LABEL, WINDOW_ZERO,  0, 0);
      ObjectSetInteger(chartID, objName, OBJPROP_FONTSIZE,  fontSize);
      ObjectSetString (chartID, objName, OBJPROP_FONT,      "Arial");
      ObjectSetInteger(chartID, objName, OBJPROP_COLOR,     dispClr);
      ObjectSetInteger(chartID, objName, OBJPROP_CORNER,    CORNER_LEFT_UPPER);
      ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR,    ANCHOR_LEFT_UPPER);
      ObjectSetInteger(chartID, objName, OBJPROP_BACK,      true); 
      ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE,false); 
      ObjectSetInteger(chartID, objName, OBJPROP_SELECTED,  false); 
      ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN,    true);
   ObjectSetInteger(chartID, objName, OBJPROP_XDISTANCE, xPos );
   ObjectSetInteger(chartID, objName, OBJPROP_YDISTANCE, yPos );
   ObjectSetString (chartID, objName, OBJPROP_TEXT,      dispStr );
void makeARectangle(const RectStruct& displayRect) 
   static long chartID = ChartID();
   int windowIndex   = ObjectFind(chartID, displayRect.rectName); // Find which window the object is in (does it exist?)
   if(windowIndex lt 0)                         // No window found with the object in it - Create the object
      if( ObjectCreate(chartID, displayRect.rectName, OBJ_RECTANGLE, CHARTWINDOW, displayRect.startTime, displayRect.topPrice, displayRect.endTime, displayRect.bottomPrice) )
         ObjectSetInteger(chartID,  displayRect.rectName, OBJPROP_COLOR,      displayRect.fillClr);
         ObjectSetInteger(chartID,  displayRect.rectName, OBJPROP_STYLE,      displayRect.lineStyle);
         ObjectSetInteger(chartID,  displayRect.rectName, OBJPROP_WIDTH,      displayRect.lineWidth);
         ObjectSetInteger(chartID,  displayRect.rectName, OBJPROP_BACK,       true);
         ObjectSetInteger(chartID,  displayRect.rectName, OBJPROP_SELECTABLE, false);
         ObjectSetInteger(chartID,  displayRect.rectName, OBJPROP_SELECTED,   false);
         ObjectSetInteger(chartID,  displayRect.rectName, OBJPROP_HIDDEN,     true);
      else  // publish error if the object creation fails.
         int errCode      = GetLastError();
         string errString;
         int catLen = StringConcatenate(errString,__FUNCTION__," Failed to create object ",displayRect.rectName,", Error: ",IntegerToString(errCode)); //,", ",ErrorDescription(errCode));
         Print(errString); Comment(errString);
   else  // Move the Object, it exists already
      ObjectMove(chartID, displayRect.rectName, ANCHOR_POINT_ZERO, displayRect.startTime, displayRect.topPrice );
      ObjectMove(chartID, displayRect.rectName, ANCHOR_POINT_ONE,  displayRect.endTime, displayRect.bottomPrice );
string getInfoMecDescription(BAR_INFO_MECH mechanism)
   string dispString;
   switch (mechanism)
      case COPY_FUNCS: dispString = "COPY_FUNCS"; break;
      case RATES:      dispString = "RATES";     break;
      case DIRECT:     dispString = "DIRECT";     break;
      default:         dispString = "Unknown "+IntegerToString(mechanism); break;
   return( dispString );
   BAR_INFO_MECH nextMech;
   switch (mechanism)
      case RATES:      nextMech = COPY_FUNCS; break;
      case COPY_FUNCS: nextMech = DIRECT;     break;
      case DIRECT:     nextMech = RATES;      break;
      default:         nextMech = RATES;      break;
   return( nextMech );
string getPromptTxt(ENUM_CTRL_IDX idx)
   string dispString;
   switch (idx)
      case BAR_UP:
         dispString = "Bar Up";
      case BAR_DN:
         dispString = "Bar Dn";
      case PERIOD_START:
         dispString = getPeriodText(workingTF,PART_ONE);
      case PERIOD_END:
         dispString = getPeriodText(workingTF,PART_TWO);
      case INFO_MECH:
         dispString = getInfoMecDescription(workingMechanism);
         dispString = "Unknown "+IntegerToString(idx);
string getPeriodText(ENUM_TIMEFRAMES tf, const PERIOD_PARTS partOneTwo)
   string returnString;
   switch (tf)
      case PERIOD_M1:  returnString = (partOneTwo==PART_ONE)?"PERIOD":"_M1";  break;
      case PERIOD_M2:  returnString = (partOneTwo==PART_ONE)?"PERIOD":"_M2";  break;
      case PERIOD_M3:  returnString = (partOneTwo==PART_ONE)?"PERIOD":"_M3";  break;
      case PERIOD_M4:  returnString = (partOneTwo==PART_ONE)?"PERIOD":"_M4";  break;
      case PERIOD_M5:  returnString = (partOneTwo==PART_ONE)?"PERIOD":"_M5";  break;
      case PERIOD_M6:  returnString = (partOneTwo==PART_ONE)?"PERIOD":"_M6";  break;
      case PERIOD_M10: returnString = (partOneTwo==PART_ONE)?"PERIOD":"_M10"; break;
      case PERIOD_M12: returnString = (partOneTwo==PART_ONE)?"PERIOD":"_M12"; break;
      case PERIOD_M15: returnString = (partOneTwo==PART_ONE)?"PERIOD":"_M15"; break;
      case PERIOD_M20: returnString = (partOneTwo==PART_ONE)?"PERIOD":"_M20"; break;
      case PERIOD_M30: returnString = (partOneTwo==PART_ONE)?"PERIOD":"_M30"; break;
      case PERIOD_H1:  returnString = (partOneTwo==PART_ONE)?"PERIOD":"_H1";  break;
      case PERIOD_H2:  returnString = (partOneTwo==PART_ONE)?"PERIOD":"_H2";  break;
      case PERIOD_H3:  returnString = (partOneTwo==PART_ONE)?"PERIOD":"_H3";  break;
      case PERIOD_H4:  returnString = (partOneTwo==PART_ONE)?"PERIOD":"_H4";  break;
      case PERIOD_H6:  returnString = (partOneTwo==PART_ONE)?"PERIOD":"_H6";  break;
      case PERIOD_H8:  returnString = (partOneTwo==PART_ONE)?"PERIOD":"_H8";  break;
      case PERIOD_H12: returnString = (partOneTwo==PART_ONE)?"PERIOD":"_H12"; break;
      case PERIOD_D1:  returnString = (partOneTwo==PART_ONE)?"PERIOD":"_D1";  break;
      case PERIOD_W1:  returnString = (partOneTwo==PART_ONE)?"PERIOD":"_W1";  break;
      case PERIOD_MN1: returnString = (partOneTwo==PART_ONE)?"PERIOD":"_MN1"; break;
      default:  returnString = "Unknown: "+IntegerToString(tf);  break;  // whatcha gonna do?
   switch (tf)
      case PERIOD_M1:  returnTF = PERIOD_M2;   break;
      case PERIOD_M2:  returnTF = PERIOD_M3;   break;
      case PERIOD_M3:  returnTF = PERIOD_M4;   break;
      case PERIOD_M4:  returnTF = PERIOD_M5;   break;
      case PERIOD_M5:  returnTF = PERIOD_M6;  break;
      case PERIOD_M6:  returnTF = PERIOD_M10;  break;
      case PERIOD_M10: returnTF = PERIOD_M12;  break;
      case PERIOD_M12: returnTF = PERIOD_M15;  break;
      case PERIOD_M15: returnTF = PERIOD_M20;  break;
      case PERIOD_M20: returnTF = PERIOD_M30;  break;
      case PERIOD_M30: returnTF = PERIOD_H1;   break;


About Me

I'm Mike Semlitsch the owner of PerfectTrendSystem.com. My trading career started in 2007. Since 2013 I have helped thousands of traders to take their trading to the next level. Many of them are now constantly profitable traders. 

The following performance was achieved by me while trading live in front of hundreds of my clients:

Connect With Me:  

This FREE Indicator Can Transform
Your Trading!

FREE Indicator + Telegram Group

Request the Ultimate Double Top/Bottom Indicator which is used by 10,000+ traders.

Results From 5 Months!
This service starts soon! Be the first who get's notified when it begins!