HMA_Color_v02b

Download script
Author: Ron Thompson
HMA_Color_v02b

This script implements the Hull Moving Average (HMA), a sophisticated technical analysis tool designed to track market trends with high responsiveness. Unlike standard moving averages, which often suffer from significant "lag" (the delay between a price change and the indicator's reaction), the HMA uses a unique mathematical approach to smooth out price data while keeping the line closely aligned with current market movements.

How the Logic Works

The script processes market data through a multi-layered calculation to achieve its results:

  • Weighted Smoothing: The logic first calculates two separate weighted averages based on the user-defined period—one representing the full period and one representing half of that period.
  • Difference Calculation: By subtracting the full average from twice the half-average, the script captures the "momentum" or the immediate velocity of the price. This step is what allows the indicator to react much faster than a traditional moving average.
  • Final Smoothing: To ensure the resulting line isn't too erratic or "noisy," the script applies a final smoothing pass based on the square root of the period. This creates a balance between speed and stability, providing a clean visual trend.

Visual Representation

The script is designed to provide clear, actionable visual cues on your trading chart:

  • Trend Tracking: The primary output is a smooth line that follows price action. It helps traders identify the prevailing direction of the market (upward or downward).
  • Directional Color Changes: To make the indicator even more intuitive, the script includes logic to detect changes in direction. When the trend shifts, the colors change dynamically:
    • Lime Green: Generally signifies an upward bullish trend.
    • Red: Generally signifies a downward bearish trend.
    • Yellow/Neutral Transitions: Helps highlight moments where the trend is shifting or consolidating.

Summary for the User

In simple terms, this tool acts as a "fast-acting" trend guide. It takes the raw price data and filters out minor market noise to show you the core direction of the move. Because it uses weighted calculations, it tries to stay as close to the current price as possible, helping you identify trend reversals more quickly than standard moving averages would allow.

Indicators Used
Moving average indicatorMoving average indicator
Miscellaneous
Implements a curve of type %1
3 Views
0 Downloads
0 Favorites
HMA_Color_v02b
//+----------------+
//| HMA.mq4  by Ron|
//+----------------+

/*
MetaStock Formula
period:=Input("Period",1,200,20) ;
sqrtperiod:=Input("Square Root of Period",1,20,4);
Mov(2*(Mov(C,period/2,W))-Mov(C,period,W),sqrtperiod,W); 

SuperCharts Formula
Input: period (Default value 20)
waverage(2*waverage(close,period/2)-waverage(close,period), SquareRoot(Period)) 

Added color on direction change

*/


#property copyright "Ron Thompson"
#property link "http://www.metaquotes.net/"

//---- indicator settings
#property indicator_chart_window
#property indicator_buffers 3

#property indicator_color1 LimeGreen
#property indicator_color2 Yellow
#property indicator_color3 Red

//User input
extern int HMA_Period=14;

//---- indicator buffers
double ind_buffer0[];
double ind_buffer1[];
double ind_buffer2[];

double buffer[];

int draw_begin0;


//Custom init
int init()
{
//---- indicator buffers mapping
IndicatorBuffers(4);

if(   !SetIndexBuffer(0,ind_buffer0) 
   && !SetIndexBuffer(1,ind_buffer1)
   && !SetIndexBuffer(2,ind_buffer2) 
   && !SetIndexBuffer(3, buffer))
      Print("cannot set indicator buffers!");
// ArraySetAsSeries(ind_buffer1,true);

//---- drawing settings
SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,2);
SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,2);
SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,2);

draw_begin0=HMA_Period+MathFloor(MathSqrt(HMA_Period));

SetIndexDrawBegin(0,draw_begin0);
SetIndexDrawBegin(1,draw_begin0);
SetIndexDrawBegin(2,draw_begin0);

IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+1);

//---- name for DataWindow and indicator subwindow label
IndicatorShortName("HMA("+HMA_Period+")");
SetIndexLabel(0,"Hull Moving Average");

}


// Main Program loop
int start()
  {
   int limit,i;
   int counted_bars=IndicatorCounted();
   double tmp, tmpPrevious;
   
   double fullMA;
   double halfMA;
   
   int fullPeriod = HMA_Period;
   int halfPeriod = HMA_Period/2;
   int sqrtPeriod = MathFloor(MathSqrt(HMA_Period*1.00));

   //---- check for possible errors
   if(counted_bars<1)
     {
      for(i=1;i<=draw_begin0;i++)
        {
         buffer[Bars-i]=0;
        }
        
      for(i=1;i<=fullPeriod;i++)
        {
         ind_buffer0[Bars-i]=0;
         ind_buffer1[Bars-i]=0;
         ind_buffer2[Bars-i]=0;
        }
     }// if counted
     
   //---- last counted bar will be recounted
   if(counted_bars>0)
     {
      counted_bars--;
     }
        
   limit=Bars-counted_bars;
   //---- MA difference counted in the 1-st buffer
   for(i=0; i<limit; i++)
     {
      halfMA=iMA(NULL,0,halfPeriod,0,MODE_LWMA,PRICE_OPEN,i)*2;
      fullMA=iMA(NULL,0,fullPeriod,0,MODE_LWMA,PRICE_OPEN,i);
      buffer[i]=halfMA-fullMA;
     }

   //---- HMA counted in the 0-th buffer
   tmp=iMAOnArray(buffer,0,MathFloor(MathSqrt(HMA_Period)),0,MODE_LWMA,0);

   for(i=1; i<limit; i++)
     {
      tmpPrevious=iMAOnArray(buffer,0,MathFloor(MathSqrt(HMA_Period)),0,MODE_LWMA,i);
      if (tmpPrevious > tmp)
        {
         ind_buffer0[i] = EMPTY_VALUE;
         ind_buffer1[i] = EMPTY_VALUE;
         ind_buffer2[i] = tmpPrevious;
         ind_buffer2[i-1] = tmp; // !
        }
       else if (tmpPrevious < tmp)
        {
         ind_buffer0[i] = tmpPrevious;
         ind_buffer0[i-1] = tmp; // !
         ind_buffer1[i] = EMPTY_VALUE;
         ind_buffer2[i] = EMPTY_VALUE;
        }
       else
        {
         ind_buffer0[i] = CLR_NONE;
         ind_buffer1[i] = tmpPrevious;
         ind_buffer2[i-1] = tmp; // !
         ind_buffer2[i] = CLR_NONE;
        }
      tmp = tmpPrevious;
     }//for
  }

Comments