Author: Copyright � 2010, www.Brooky-Indicators.com.
OBTR

Overview of the On Balance True Range (OBTR) Logic

The On Balance True Range (OBTR) is a technical analysis indicator designed to measure market volatility and trend momentum. Unlike standard oscillators that only look at price direction, this script combines the "True Range" concept (which accounts for the full distance between high and low prices) with an "On Balance" logic similar to how some momentum indicators accumulate gains or losses.

By analyzing these movements, the tool helps traders identify whether the current market volatility is expanding or contracting, and whether the underlying trend is strengthening or weakening.

How the Logic Works

The script processes market data through three distinct stages:

1. Data Foundation (True Range Calculation)

The indicator begins by calculating the "True Range" for every price candle. Instead of just looking at the difference between the current close and the previous close, it captures the actual price movement.

  • If the price moves up, the value of the True Range is added to a running total.
  • If the price moves down, the value is subtracted from that total.
  • If the price remains unchanged, the total stays the same.

This creates a cumulative "Balance" of volatility. It essentially tracks whether the market's significant movements are trending primarily in an upward or downward direction over time.

2. Smoothing and Moving Averages

Once the raw OBTR values are calculated, the script applies two different Moving Averages (Fast and Slow) to that data:

  • Fast Smoothing: Responds quickly to recent price shifts.
  • Slow Smoothing: Provides a broader view of the long-term trend.

By comparing these two lines, the indicator helps filter out "market noise" and highlights the significant flow of volatility.

3. Signal Identification (Visual Outputs)

The script translates the relationship between these averages into several visual signals on your chart:

  • Trend Direction: It tracks whether the Slow Moving Average is sloping upward or downward, indicating the primary direction of the volatility trend.
  • Overbought/Oversold Extremes: By comparing the Fast Smoothing line against the Slow Smoothing line, the script identifies when the current volatility is significantly higher (over-extended) or lower (under-extended) than the average.
  • Stability Zones (Flat Regions): The logic includes specific "Proximity" and "Distance" rules. If the gap between the Fast and Slow lines is very small, or if it exceeds a maximum defined distance, the script identifies these as "flat" or neutral zones. This helps traders recognize periods of consolidation where the market is moving sideways without a clear trend.

Summary for the User

In simple terms, this tool tells you how much the market is moving and in which direction that movement is favoring. It filters out minor price flickers to show you the "true" momentum of volatility, helping you spot when a trend is gaining strength, losing steam, or entering a period of stagnation.

Indicators Used
Indicator of the average true rangeMoving average indicator
Miscellaneous
Implements a curve of type %1
7 Views
0 Downloads
0 Favorites
OBTR
//+------------------------------------------------------------------+
//|                                                         OBTR.mq4 |
//|                     Copyright © 2010, www.Brooky-Indicators.com. |
//|     On Balance True Range   http://www.www.Brooky-Indicators.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, www.Brooky-Indicators.com."
#property link      "http://www.www.Brooky-Indicators.com"
extern string You_Are_Following_Another = "(www.Brooky-Indicators.com) Indicator ";

#property indicator_separate_window
#property indicator_buffers 7
#property indicator_color1 DodgerBlue
#property indicator_color2 Orange
#property indicator_color3 C'93,93,93'
#property indicator_color4 Blue
#property indicator_color5 C'93,93,93'
#property indicator_color6 Lime
#property indicator_color7 Red


#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 3
#property indicator_width4 3
#property indicator_width5 3
#property indicator_width6 3
#property indicator_width7 3
//---- input parameters
extern string OBTR_Concept_By = "Tom Bierovic";
extern string Basic_Codebase  = "Metaquotes";
extern string This_Indi_Coder = "www.Brooky-Indicators.com";
extern string Ma_Modes        = "0=sma, 1=ema, 2=smma, 3=lwma";
extern string Price_Modes     = "0=Cl, 1=Op, 2=Hi, 3=Lo";
extern string Price_Modes2    = "4=Med, 5=Typ, 6=Weight";
extern string Div1            = "--------------------------------------------";
extern string Fast_Ma         = "  Smoothing ";
extern int    Fast_MA_Period  = 1;
extern int    Fast_Mode       = 0;
extern int    Fast_Shift      = 0;
extern int    Slow_MA_Period  = 26;
extern int    Slow_Mode       = 0;
extern int    Slow_Shift      = 0;
extern string Div2            = "--------------------------------------------";
extern string Holding         = "  Ma OBTR Distance Settings ";
extern int    Proximity       = 11;
extern int    Distance_Max    = 126;
extern string OBTR_Price      = "Set Price for Calculations";
extern int    OBTR_Price_Mode =0;
//---- buffers
double         OBTRBuffer[];
double         OBTRFast_Buffer[];
double         OBTRSlow_Buffer[];
double         OBTRover_Buffer[];
double         OBTRunder_Buffer[];
double         OBTRflat_Buffer[];
double         OBTRSlowup_Buffer[];
double         OBTRSlowdn_Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string sShortName;
//---- indicator buffer mapping
   IndicatorBuffers(8);
   SetIndexBuffer(0,OBTRover_Buffer);SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer(1,OBTRunder_Buffer);SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexBuffer(2,OBTRflat_Buffer);SetIndexStyle(2,DRAW_HISTOGRAM);
   SetIndexBuffer(3,OBTRFast_Buffer);SetIndexStyle(3,DRAW_LINE);SetIndexDrawBegin(3,Fast_Shift);
   SetIndexBuffer(4,OBTRSlow_Buffer);SetIndexStyle(4,DRAW_LINE);SetIndexDrawBegin(4,Slow_Shift); 
   SetIndexBuffer(5,OBTRSlowup_Buffer);SetIndexStyle(5,DRAW_LINE);SetIndexDrawBegin(5,Slow_Shift);
   SetIndexBuffer(6,OBTRSlowdn_Buffer);SetIndexStyle(6,DRAW_LINE);SetIndexDrawBegin(6,Slow_Shift);  
   SetIndexBuffer(7,OBTRBuffer);
   
//---- sets default precision format for indicators visualization
   IndicatorDigits(0);     
//---- name for DataWindow and indicator subwindow label
   sShortName="Brooky_OBTR";
   IndicatorShortName(sShortName);
   SetIndexLabel(0,sShortName);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| On Balance True Range    Concept by Tom Bierovic                                            |
//+------------------------------------------------------------------+
int start()
  {
   int    i,nLimit,nCountedBars;
//---- bars count that does not changed after last indicator launch.
   nCountedBars=IndicatorCounted();
//---- last counted bar will be recounted
   if(nCountedBars>0) nCountedBars--;
   nLimit=Bars-nCountedBars-1;


   for(i=nLimit; i>=0; i--)

       
     {
     double use_point;
     if (Point==0.0001)use_point=0.0001;
     if (Point==0.00001)use_point=0.0001;
     if (Point==0.01)use_point=0.01;
     if (Point==0.001)use_point=0.01;
     
     int multiplier; 
     multiplier = 1 / use_point;

     OBTRFast_Buffer[i]=EMPTY_VALUE;
     OBTRSlow_Buffer[i]=EMPTY_VALUE;
     OBTRover_Buffer[i]=EMPTY_VALUE;
     OBTRunder_Buffer[i]=EMPTY_VALUE;
     OBTRflat_Buffer[i]=EMPTY_VALUE;

     if(i==Bars-1)
        OBTRBuffer[i]=iATR(NULL,0,1,i)*multiplier;
      else
        {
         double dCurrentPrice=GetAppliedPrice(OBTR_Price_Mode, i);
         double dPreviousPrice=GetAppliedPrice(OBTR_Price_Mode, i+1);
         if(dCurrentPrice==dPreviousPrice)
            OBTRBuffer[i]=OBTRBuffer[i+1];
         else
           {
            if(dCurrentPrice<dPreviousPrice)
               OBTRBuffer[i]=OBTRBuffer[i+1]-iATR(NULL,0,1,i)*multiplier;  
            else
               OBTRBuffer[i]=OBTRBuffer[i+1]+iATR(NULL,0,1,i)*multiplier;
           }
        }
     }
     for(i=nLimit; i>=0; i--)
     {
     
      OBTRFast_Buffer[i]=iMAOnArray(OBTRBuffer,0,Fast_MA_Period,Fast_Shift,Fast_Mode,i);
      OBTRSlow_Buffer[i]=iMAOnArray(OBTRBuffer,0,Slow_MA_Period,Slow_Shift,Slow_Mode,i);
     }
     
     for(i=nLimit; i>=0; i--)
     {
     if(OBTRSlow_Buffer[i]>OBTRSlow_Buffer[i+1])OBTRSlowup_Buffer[i]=OBTRSlow_Buffer[i];
     if(OBTRSlow_Buffer[i]<OBTRSlow_Buffer[i+1])OBTRSlowdn_Buffer[i]=OBTRSlow_Buffer[i];
     
     if(OBTRFast_Buffer[i]>OBTRSlow_Buffer[i])OBTRover_Buffer[i]=OBTRBuffer[i];
     if(OBTRFast_Buffer[i]<OBTRSlow_Buffer[i])OBTRunder_Buffer[i]=OBTRBuffer[i];
     
     
     if(OBTRFast_Buffer[i]==OBTRSlow_Buffer[i])OBTRflat_Buffer[i]=OBTRBuffer[i];
     if(MathAbs(OBTRFast_Buffer[i]-OBTRSlow_Buffer[i])<Proximity)
         OBTRflat_Buffer[i]=OBTRBuffer[i];
     if(MathAbs(OBTRFast_Buffer[i]-OBTRSlow_Buffer[i])>Distance_Max)
         OBTRflat_Buffer[i]=OBTRBuffer[i];   
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
   double GetAppliedPrice(int nAppliedPrice, int nIndex)
    {
      double dPrice;
//----
      switch(nAppliedPrice)
       {
         case 0:  dPrice=Close[nIndex];                                  break;
         case 1:  dPrice=Open[nIndex];                                   break;
         case 2:  dPrice=High[nIndex];                                   break;
         case 3:  dPrice=Low[nIndex];                                    break;
         case 4:  dPrice=(High[nIndex]+Low[nIndex])/2.0;                 break;
         case 5:  dPrice=(High[nIndex]+Low[nIndex]+Close[nIndex])/3.0;   break;
         case 6:  dPrice=(High[nIndex]+Low[nIndex]+2*Close[nIndex])/4.0; break;
         default: dPrice=0.0;
       }
//----
   return(dPrice);
  }
//+------------------------------------------------------------------+

Comments