HMA_Color_v02
Download scriptThis script implements a specialized technical analysis tool known as the Hull Moving Average (HMA). Its primary purpose is to provide traders with a smoothed trend line that reacts much faster to price changes than traditional moving averages, while still filtering out the "noise" or minor fluctuations of the market.
How the Logic Works
The script calculates the Hull Moving Average through a multi-step mathematical process designed to balance speed and smoothness:
1. Weighted Price Averaging Instead of looking at simple averages, the logic utilizes "Linearly Weighted" averages. It takes the current price data and applies a specific weight to it based on the time period you choose (the HMA Period). This ensures that recent price action carries more significance than older data.
2. The Difference Calculation The script creates two distinct weighted averages:
- One based on half of your chosen period.
- One based on the full period. By doubling the "half-period" average and subtracting the "full-period" average, the script captures the momentum of the price movement more aggressively.
3. Final Smoothing To prevent the line from becoming too jagged or erratic (which can happen when you prioritize speed), the script performs a final smoothing pass on that difference. It calculates a secondary weighted average based on the square root of your chosen period. This "rounds off" the corners of the data to create a clean, flowing line.
Visual Representation and Behavior
The script is designed to be highly visual, helping you identify the direction of the market trend instantly:
- Trend Tracking: The core result is a smooth line that follows the price action closely. Because of its unique math, it stays "tight" to the price during strong trends but remains steady during consolidation.
- Directional Color Coding: The script includes logic to change colors based on the direction of the move. It tracks whether the current value of the average is higher or lower than the previous one.
- When the trend turns upward, the line changes color to indicate bullish momentum.
- When the trend turns downward, the line changes color to indicate bearish momentum.
- If the price remains flat and the average does not move significantly, the script handles these transitions to keep the visual data clear and readable.
In summary, this tool is designed for traders who need to see where the market is heading in real-time without the significant "lag" usually associated with standard moving averages.
//+----------------+
//| 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_CLOSE,i)*2;
fullMA=iMA(NULL,0,fullPeriod,0,MODE_LWMA,PRICE_CLOSE,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