ROC_Smoothed

Download script
ROC_Smoothed

This tool is designed to measure and visualize the momentum of a financial instrument by calculating the "Rate of Change" (the speed at which a price is moving) while applying sophisticated smoothing techniques to reduce market noise.

Core Logic Overview

At its heart, the script determines how much an asset's price has changed over a specific period. However, rather than looking at raw, jagged price movements—which can often be misleading due to sudden spikes—it processes the data through various mathematical filters to provide a clearer picture of the underlying trend.

Key Components of the Calculation

The script operates using three distinct layers of logic:

1. The Rate of Change (ROC) Engine The primary objective is to find the difference between the current smoothed price and a past smoothed price. By subtracting a previous value from the current one, the tool reveals whether the market is accelerating, decelerating, or moving sideways.

2. Customizable Smoothing Methods To ensure the data is readable and professional, the script offers several different "Moving Average" types to smooth out the price fluctuations. Depending on your preference, it can calculate the trend using:

  • Simple & Exponential Averages: Standard methods for balancing current and past data.
  • Linear & Smoothed Moving Averages: Methods that weight data differently to prioritize specific trends.
  • Non-Lagging Moving Average: A specialized calculation designed to identify trends more quickly by minimizing the "delay" often found in standard indicators.

3. Price Source Flexibility The logic allows for different types of "price inputs." Instead of just looking at the final closing price of a candle, you can configure the script to look at:

  • The opening price.
  • The highest and lowest points reached during a period.
  • Calculated averages (such as the "Typical" or "Weighted" price).

Final Output Processing

Once the smoothed prices are calculated for both the present and the past, the script performs the final calculation:

  • Absolute Difference: It calculates the raw difference between the two points and normalizes it to make it easy to read on a chart.
  • Percentage Growth: Optionally, it can convert this difference into a percentage, allowing you to see the relative growth of an asset regardless of its total price value.

By combining these elements, the tool provides a refined visual representation of market velocity, helping to distinguish between temporary "noise" and significant directional shifts in price.

Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1
13 Views
0 Downloads
0 Favorites
ROC_Smoothed
//+------------------------------------------------------------------+
//|                                                 ROC_Smoothed.mq4 |
//|                                    Copyright © 2006, Robert Hill |
//|                                                                  |
//| Modified ROC to use EMA                                          |
//+------------------------------------------------------------------+
#property  copyright "Copyright © 2006, Robert Hill"
//---- indicator settings
#property  indicator_separate_window
#property  indicator_buffers 1
#property  indicator_color1  Red
//---- indicator parameters
extern string  strROC = "ROC Period for lookback";
extern int     RPeriod = 10;
extern string  sep0 = "----------------------------------";
extern string  strMA = "MA input parameters";
extern int     MAPeriod=14;
extern string  sep1 = "----------------------------------";
extern string  strType = "Moving Average Types" ;
extern string  str0 = "0 = SMA, 1 = EMA, 2 = SMMA";
extern string  str1 = "3 = LWMA, 4 = LSMA, 5 = NLMA";
extern int     MAType = 1;
extern string  sep2 = "----------------------------------";
extern string  strAP = "Applied Price Types";
extern string  str2 = "0=close, 1=open, 2=high";
extern string  str3 = "3=low, 4=median(high+low)/2";
extern string  str4 = " 5=typical(high+low+close)/3";
extern string  str5 = "6=weighted(high+low+close+close)/4";
extern int     MAAppliedPrice = 0;
extern string  sep3 = "----------------------------------";
extern string  str6 = "NonLagMA Deviation";
extern double  Deviation      = 0;         
extern bool    UsePercent = false;

//---- indicator buffers
double     RateOfChange[];

//---- variables

int    MAMode;
string strMAType;

// Variables for NonLag
int Phase;
double Len;  
double Cycle =  4;
double pi = 3.1415926535;    
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- drawing settings
   SetIndexStyle(0,DRAW_LINE);
   SetIndexDrawBegin(0,RPeriod);
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+1);
//---- indicator buffers mapping
   if(!SetIndexBuffer(0,RateOfChange))
      Print("cannot set indicator buffers!");
switch (MAType)
   {
      case 1: strMAType="EMA"; MAMode=MODE_EMA; break;
      case 2: strMAType="SMMA"; MAMode=MODE_SMMA; break;
      case 3: strMAType="LWMA"; MAMode=MODE_LWMA; break;
      case 4: strMAType="LSMA"; break;
      case 5: strMAType="NLMA";break;
      default: strMAType="SMA"; MAMode=MODE_SMA; break;
   }
   IndicatorShortName( "ROC (" + RPeriod + ")_Smoothed_" + strMAType+ " (" +MAPeriod + ") ");
//---- name for DataWindow and indicator subwindow label
   SetIndexLabel(0,"ROC_Smoothed");

// Variables for NonLag
   Phase = MAPeriod-1;
   Len = MAPeriod*Cycle + Phase;  

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

//+------------------------------------------------------------------+
//| LSMA with PriceMode                                              |
//| PrMode  0=close, 1=open, 2=high, 3=low, 4=median(high+low)/2,    |
//| 5=typical(high+low+close)/3, 6=weighted(high+low+close+close)/4  |
//+------------------------------------------------------------------+

double LSMA(int Rperiod, int prMode, int shift)
{
   int i;
   double sum, pr;
   int length;
   double lengthvar;
   double tmp;
   double wt;

   length = Rperiod;
 
   sum = 0;
   for(i = length; i >= 1  ; i--)
   {
     lengthvar = length + 1;
     lengthvar /= 3;
     tmp = 0;
     switch (prMode)
     {
     case 0: pr = Close[length-i+shift];break;
     case 1: pr = Open[length-i+shift];break;
     case 2: pr = High[length-i+shift];break;
     case 3: pr = Low[length-i+shift];break;
     case 4: pr = (High[length-i+shift] + Low[length-i+shift])/2;break;
     case 5: pr = (High[length-i+shift] + Low[length-i+shift] + Close[length-i+shift])/3;break;
     case 6: pr = (High[length-i+shift] + Low[length-i+shift] + Close[length-i+shift] + Close[length-i+shift])/4;break;
     }
     tmp = ( i - lengthvar)*pr;
     sum+=tmp;
    }
    
    wt = MathFloor(sum*6/(length*(length+1))/Point)*Point; 
    
    return(wt);
}

double NonLag(int RPeriod, int myLen, double myPhase, int myShift)
{

   int i;
   double alfa, beta, t, Sum, Weight,g;
   double myPrice;
   double Coeff =  3*pi;
   
      Weight=0; Sum=0; t=0;
       
      for (i=0;i<=myLen-1;i++)
	   { 
        g = 1.0/(Coeff*t+1);   
        if (t <= 0.5 ) g = 1;
        beta = MathCos(pi*t);
        alfa = g * beta;
        myPrice = iMA(NULL,0,1,0,MODE_SMA,MAAppliedPrice,myShift+i); 
        Sum += alfa*myPrice;
        Weight += alfa;
        if ( t < 1 ) t += 1.0/(myPhase-1); 
        else if ( t < myLen-1 )  t += (2*Cycle-1)/(Cycle*RPeriod-1);
      }
	   if (Weight > 0) Weight = (1.0+Deviation/100)*Sum/Weight;
      Weight = MathFloor(Weight/Point)*Point;
      return (Weight);

}

//+------------------------------------------------------------------+
//| Rate of Change Smoothed                                          |
//+------------------------------------------------------------------+
int start()
  {
   int limit;
   double ROC, MA_Cur, MA_Prev;
   int counted_bars=IndicatorCounted();
//---- check for possible errors
   if(counted_bars<0) return(-1);
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
//---- ROC calculation
   for(int i=0; i<limit; i++)
   {
      if (MAType == 4)
      {
        MA_Cur = LSMA(MAPeriod, MAAppliedPrice,i);
        MA_Prev = LSMA(MAPeriod, MAAppliedPrice,i+RPeriod);
      }
      else if (MAType == 5)
      {
        MA_Cur = NonLag(MAPeriod, Len, Phase, i);
        MA_Prev = NonLag(MAPeriod, Len, Phase, i+RPeriod);
      }
      else
      {
        MA_Cur = iMA(NULL,0,MAPeriod,0,MAMode, MAAppliedPrice,i);
        MA_Prev = iMA(NULL,0,MAPeriod,0,MAMode, MAAppliedPrice,i+RPeriod);
      }
      ROC=MA_Cur-MA_Prev;
      if (UsePercent)
      {
        RateOfChange[i] = 100 * ROC / MA_Prev; 
      }
      else
      {
        RateOfChange[i] = NormalizeDouble(ROC/Point,1);
      }
   }
      
//---- done
   return(0);
  }

Comments