The Hull Trend indicator is designed to provide traders with a clear visual representation of market momentum and direction by smoothing out price fluctuations. Instead of simply following the price closely, it utilizes a sophisticated mathematical approach to filter out "noise," making it easier to identify the overarching trend on a trading chart.
Core Logic and Methodology
The script operates through a three-step calculation process to derive its trend signals:
1. Weighted Averages (The Foundation) The indicator begins by calculating two different Linear Weighted Moving Averages (LWMA). The first is based on a shorter timeframe (half of the primary period), and the second is based on the full period defined by the user. By comparing these two, the script identifies the "velocity" or change in price movement.
2. The Difference Calculation The logic then subtracts one weighted average from the other. This specific step highlights the difference in momentum between the short-term and long-term movements. Essentially, it captures how quickly the price is accelerating or decelerating at any given moment.
3. Smoothing and Final Trend Identification To ensure the signal isn't erratic, the script applies a final smoothing pass (a moving average of the difference calculation). This results in the "Hull" trend. The indicator then compares this final smoothed value against the initial momentum data to determine the current market state.
Visual Representation on the Chart
The tool translates these complex calculations into a user-friendly visual format:
- Trend Tracking: Based on whether the calculated values are higher or lower than one another, the script identifies the "High" and "Low" boundaries of the trend.
- Visual Cues: The indicator renders these results as specific visual elements (histograms or lines) on your chart.
- Dynamic Response: Because it uses a "Weighted" system, the indicator is designed to be more responsive to recent price action than a standard moving average, while still maintaining enough smoothness to prevent frequent, misleading signals during choppy market conditions.
In summary, this script acts as a trend-following filter. It analyzes the speed and weight of price changes to determine the dominant direction, helping traders stay aligned with the prevailing momentum of the market.
//+------------------------------------------------------------------+
//| Hull Trend.mq4 |
//| Copyright © 2005, adoleh2000 |
//| adoleh2000@yahoo.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, adoleh2000."
#property link "adoleh2000@yahoo.com"
//---- indicator settings
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_color3 EMPTY
#property indicator_color4 EMPTY
//---- indicator parameters
extern int HMA_Period=20;
extern double Price=PRICE_OPEN;
extern double Displacement=0;
//---- indicator buffers
double ind_buffer0[];
double ind_buffer1[];
double HighBuffer[];
double LowBuffer[];
int draw_begin0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicator buffers mapping
//IndicatorBuffers(4);
// ArraySetAsSeries(ind_buffer1,true);
//---- drawing settings
SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,1);
SetIndexStyle(1,DRAW_HISTOGRAM,STYLE_SOLID,1);
SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,1);
SetIndexStyle(3,DRAW_LINE,STYLE_SOLID,1);
SetIndexBuffer(0,HighBuffer);
SetIndexBuffer(1,LowBuffer);
SetIndexBuffer(2,ind_buffer0);
SetIndexBuffer(3,ind_buffer1);
draw_begin0=HMA_Period+MathFloor(MathSqrt(HMA_Period));
SetIndexDrawBegin(0,draw_begin0);
SetIndexDrawBegin(1,draw_begin0);
SetIndexDrawBegin(2,draw_begin0);
SetIndexDrawBegin(3,draw_begin0);
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+1);
//---- name for DataWindow and indicator subwindow label
IndicatorShortName("HMA("+HMA_Period+")");
SetIndexLabel(0,"Hull Moving Average");
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence |
//+------------------------------------------------------------------+
int start()
{
int limit,i,shift;
int counted_bars=IndicatorCounted();
//---- check for possible errors
if(counted_bars<1)
{
for(i=1;i<=draw_begin0;i++) ind_buffer0[Bars-i]=0;
for(i=1;i<=HMA_Period;i++) ind_buffer1[Bars-i]=0;
}
//---- 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++)
ind_buffer1[i]=iMA(NULL,0,MathFloor(HMA_Period/2),0,MODE_LWMA,Price,i)*2-iMA(NULL,0,HMA_Period,0,MODE_LWMA,Price,i);
//---- HMA counted in the 0-th buffer
for(i=0; i<limit; i++)
ind_buffer0[i]=iMAOnArray(ind_buffer1,0,MathFloor(MathSqrt(HMA_Period)),0,MODE_LWMA,i+Displacement);
//Comment ("MA=",ind_buffer1[i],"; ","HMA=",ind_buffer0[i]);
for (shift=i; shift>=0;shift--)
{
if (ind_buffer1[shift] > ind_buffer0[shift])
{
HighBuffer[shift]=High[shift];
LowBuffer[shift]=Low[shift];
}
else
if (ind_buffer1[shift]< ind_buffer0[shift])
{
LowBuffer[shift]=High[shift];
HighBuffer[shift]=Low[shift];
}
}
//---- done
return(0);
}
Comments