RangeBoundMA

Download script
RangeBoundMA

This tool is designed to analyze market trends by monitoring the relationships between three different Simple Moving Averages (SMA). In technical analysis, moving averages help smooth out price fluctuations to reveal the underlying direction of the market. By using three distinct timeframes—Fast, Mid, and Slow—this script identifies how much "distance" exists between these different trend speeds.

Core Logic Overview

The primary purpose of this indicator is to detect a "RangeBound" state. It achieves this by measuring the maximum price difference between the three moving averages at any given moment. Instead of simply looking at whether the price is going up or down, it focuses on how much the various trend lines have separated from one another.

How the Calculation Works

The script systematically evaluates the positions of the Fast, Mid, and Slow moving averages to determine which is currently leading, trailing, or sitting in the middle. It follows a comprehensive logic path to ensure it always captures the largest possible gap:

  • Comparative Analysis: The script checks every possible combination of the three averages (e.g., comparing the Fast vs. Mid, Mid vs. Slow, or Fast vs. Slow).
  • Maximum Variance Identification: Regardless of which average is highest or lowest, the logic identifies the two averages that are furthest apart from each other.
  • Distance Measurement: It calculates the numerical difference between those two extreme points. This represents the "spread" of the current market trend.
  • Normalization: Finally, the script scales this distance into a readable format on your chart, providing a clear visual representation of the price gap.

Practical Application

When the resulting value on the indicator remains relatively small or stable, it suggests that the moving averages are clustered closely together. This indicates a "RangeBound" market—a period where the price is moving sideways and lacks a strong, decisive trend. Conversely, a widening gap between these averages would suggest increasing momentum or a significant expansion in the market's trend.

Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1
10 Views
0 Downloads
0 Favorites
RangeBoundMA
//+------------------------------------------------------------------+
//|                                                 RangeBoundMA.mq4 |
//|                               Shenzhen City YuHe E-commerce Ltd. |
//|               find the biggest difference price between the 3 SMA|
//|    when it is still in some range, we say it is in the rangebound|
//+------------------------------------------------------------------+
#property  copyright "Shenzhen City YuHe E-commerce Ltd. Author: He Yigeng"
#property  link      ""
//---- indicator settings
#property  indicator_separate_window
#property  indicator_buffers 1
#property  indicator_color1  Gold
#property  indicator_width1  2
//---- indicator parameters
extern int FastSMA=38;
extern int MidSMA=140;
extern int SlowSMA=210;
extern int SignalSMA=9;
//---- indicator buffers
double     OsmaBuffer[];
double     MacdBuffer[];
double     SignalBuffer[];
double     MacdBufferFS[];
double     MacdBufferFM[];
double     MacdBufferMS[];
double     MAXmaBuffer[];
double     FS[];
double     MS[];
double     FM[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- 2 additional buffers are used for counting.
   IndicatorBuffers(3);
//---- drawing settings
   SetIndexStyle(0,DRAW_LINE);
   SetIndexDrawBegin(0,SignalSMA);
   IndicatorDigits(Digits+2);
//---- 3 indicator buffers mapping
   SetIndexBuffer(0,OsmaBuffer);
   SetIndexBuffer(1,MacdBuffer);
   SetIndexBuffer(2,SignalBuffer);
//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("RangeBoundMA("+FastSMA+","+MidSMA+","+SlowSMA+")");
   SetIndexLabel(0,"RangeBoundMA("+FastSMA+","+MidSMA+","+SlowSMA+")");
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//| Moving Average of Oscillator                                     |
//+------------------------------------------------------------------+
int start()
  {
   int limit;
   int counted_bars=IndicatorCounted();
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
//---- macd counted in the 1-st additional buffer
   for(int i=0; i<limit; i++)
      {
      if(iMA(NULL,0,FastSMA,0,MODE_SMA,PRICE_CLOSE,i)>=iMA(NULL,0,MidSMA,0,MODE_SMA,PRICE_CLOSE,i)
         &&iMA(NULL,0,MidSMA,0,MODE_SMA,PRICE_CLOSE,i)>iMA(NULL,0,SlowSMA,0,MODE_SMA,PRICE_CLOSE,i))
         MacdBuffer[i]=(iMA(NULL,0,FastSMA,0,MODE_SMA,PRICE_CLOSE,i)-iMA(NULL,0,SlowSMA,0,MODE_SMA,PRICE_CLOSE,i));
      if(iMA(NULL,0,FastSMA,0,MODE_SMA,PRICE_CLOSE,i)>=iMA(NULL,0,SlowSMA,0,MODE_SMA,PRICE_CLOSE,i)
         &&iMA(NULL,0,SlowSMA,0,MODE_SMA,PRICE_CLOSE,i)>iMA(NULL,0,MidSMA,0,MODE_SMA,PRICE_CLOSE,i))
         MacdBuffer[i]=(iMA(NULL,0,FastSMA,0,MODE_SMA,PRICE_CLOSE,i)-iMA(NULL,0,MidSMA,0,MODE_SMA,PRICE_CLOSE,i));
      if(iMA(NULL,0,MidSMA,0,MODE_SMA,PRICE_CLOSE,i)>=iMA(NULL,0,FastSMA,0,MODE_SMA,PRICE_CLOSE,i)
         &&iMA(NULL,0,FastSMA,0,MODE_SMA,PRICE_CLOSE,i)>iMA(NULL,0,SlowSMA,0,MODE_SMA,PRICE_CLOSE,i))
         MacdBuffer[i]=(iMA(NULL,0,MidSMA,0,MODE_SMA,PRICE_CLOSE,i)-iMA(NULL,0,SlowSMA,0,MODE_SMA,PRICE_CLOSE,i));
      if(iMA(NULL,0,MidSMA,0,MODE_SMA,PRICE_CLOSE,i)>=iMA(NULL,0,SlowSMA,0,MODE_SMA,PRICE_CLOSE,i)
         &&iMA(NULL,0,SlowSMA,0,MODE_SMA,PRICE_CLOSE,i)>iMA(NULL,0,FastSMA,0,MODE_SMA,PRICE_CLOSE,i))
         MacdBuffer[i]=(iMA(NULL,0,MidSMA,0,MODE_SMA,PRICE_CLOSE,i)-iMA(NULL,0,FastSMA,0,MODE_SMA,PRICE_CLOSE,i));
      if(iMA(NULL,0,SlowSMA,0,MODE_SMA,PRICE_CLOSE,i)>=iMA(NULL,0,FastSMA,0,MODE_SMA,PRICE_CLOSE,i)
         &&iMA(NULL,0,FastSMA,0,MODE_SMA,PRICE_CLOSE,i)>iMA(NULL,0,MidSMA,0,MODE_SMA,PRICE_CLOSE,i))
         MacdBuffer[i]=(iMA(NULL,0,SlowSMA,0,MODE_SMA,PRICE_CLOSE,i)-iMA(NULL,0,MidSMA,0,MODE_SMA,PRICE_CLOSE,i));
      if(iMA(NULL,0,SlowSMA,0,MODE_SMA,PRICE_CLOSE,i)>=iMA(NULL,0,MidSMA,0,MODE_SMA,PRICE_CLOSE,i)
         &&iMA(NULL,0,MidSMA,0,MODE_SMA,PRICE_CLOSE,i)>iMA(NULL,0,FastSMA,0,MODE_SMA,PRICE_CLOSE,i))
         MacdBuffer[i]=(iMA(NULL,0,SlowSMA,0,MODE_SMA,PRICE_CLOSE,i)-iMA(NULL,0,FastSMA,0,MODE_SMA,PRICE_CLOSE,i));
      if(iMA(NULL,0,SlowSMA,0,MODE_SMA,PRICE_CLOSE,i)==iMA(NULL,0,MidSMA,0,MODE_SMA,PRICE_CLOSE,i)
         &&iMA(NULL,0,MidSMA,0,MODE_SMA,PRICE_CLOSE,i)==iMA(NULL,0,FastSMA,0,MODE_SMA,PRICE_CLOSE,i))
         MacdBuffer[i]=(iMA(NULL,0,SlowSMA,0,MODE_SMA,PRICE_CLOSE,i)-iMA(NULL,0,FastSMA,0,MODE_SMA,PRICE_CLOSE,i));
      }
//---- main loop
   for(i=0; i<limit; i++)
     //MacdBuffer[i]=MAXmaBuffer[i];
     OsmaBuffer[i]=MacdBuffer[i]/Point/10;
     //OsmaBuffer[i]=MacdBuffer[i]-SignalBuffer[i];

    
//---- done
   return(0);
}
//+------------------------------------------------------------------+

Comments