Hull_HAMA_001
Download scriptThis script is a specialized technical analysis tool designed for the MetaTrader platform. It combines two distinct types of financial logic—the Hull Moving Average (HMA) and Heikin-Ashi pricing—to create a smoothed visual representation of price action on a trading chart.
Core Logic Overview
The primary goal of this script is to filter out "market noise" (minor, insignificant price fluctuations) while maintaining the responsiveness of the trend. It achieves this through a multi-layered calculation process:
1. The Moving Average Foundation
Instead of looking at raw price data immediately, the script first calculates several different moving averages based on the high, low, open, and close prices of the candles. By using a specific mathematical formula (multiplying a shorter average by two and subtracting a longer average), it creates a "Hull" effect. This specifically aims to reduce the lag typically found in standard moving averages, allowing the indicator to react more quickly to sudden price changes.
2. Heikin-Ashi Integration
The script then applies "Heikin-Ashi" logic to these smoothed values. Heikin-Ashi is a type of price charting that uses averages to determine the current price levels rather than raw data. This results in:
- Smoother Trends: It helps identify whether the momentum is bullish or bearish by creating a more continuous flow on the chart.
- Balanced Open/Close Prices: It calculates "synthetic" open and close prices based on previous data, which helps stabilize the visual output.
3. Dynamic Highs and Lows
The script determines the highest and lowest points of each period by comparing the smoothed Hull values against the synthetic Heikin-Ashi open and close prices. Depending on whether the trend is moving up or down, it swaps these values to ensure that the resulting visual lines clearly define the boundaries of the current price movement.
Visual Output
The tool renders four distinct data components onto your chart:
- High and Low Bounds: These represent the upper and lower limits of the smoothed price action.
- Open/Close Averages: These provide the internal "body" levels of the calculation, helping traders see the core strength of the current trend.
Summary for the User
Essentially, this script takes volatile market data, "filters" it through a high-speed moving average formula, and then "smooths" it using Heikin-Ashi logic. For a trader, this means the indicator provides a cleaner, more readable view of market trends, making it easier to identify the direction of price movement without being distracted by minor, erratic price jumps.
//+------------------------------------------------------------------+
//| Hull_O_H_L_C.mq4 HA |
//| Copyright © 2007, None |
//|Hull_HAMA Planet.Earth.Redistribution |
//+------------------------------------------------------------------+
//mod 2008 fxtsd ki
#property copyright "Copyright © 2007, None"
#property link "Planet.Earth.Redistribution"
//----
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 OrangeRed
#property indicator_color2 RoyalBlue
#property indicator_color3 Red
#property indicator_color4 DodgerBlue
//---- parameters
extern int MaMethod =3; //0-3
extern int MaPeriod =14;
extern int DrawType =2; //0-2
extern int OpCl_Width= 2;
extern int ShowBars =1200;
extern string notes_ = "MaMethod: SMA0 EMA1 SMMA2 LWMA3; DrawType: 0line 1section 2Histo";
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
double maOpen, maClose, maLow, maHigh;
double haOpen, haHigh, haLow, haClose;
//----
int ExtCountedBars=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//|------------------------------------------------------------------|
int init()
{
//---- indicators
IndicatorBuffers(4);
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexEmptyValue(0,EMPTY_VALUE);
// SetIndexDrawBegin(0,MaPeriod);
SetIndexStyle(0,DrawType,STYLE_SOLID,1);
SetIndexLabel(0,"Hull_HA("+MaPeriod+")Hi ");
//
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexEmptyValue(1,EMPTY_VALUE);
// SetIndexDrawBegin(1,MaPeriod);
SetIndexStyle(1,DrawType,STYLE_SOLID,1);
SetIndexLabel(1,"Hull_HA("+MaPeriod+")Lo");
//
SetIndexBuffer(2,ExtMapBuffer3);
SetIndexEmptyValue(2,EMPTY_VALUE);
// SetIndexDrawBegin(2,MaPeriod);
SetIndexStyle(2,DrawType,STYLE_SOLID,OpCl_Width);
SetIndexLabel(2,"Hull_HA("+MaPeriod+")OpCl");
//
SetIndexBuffer(3,ExtMapBuffer4);
SetIndexEmptyValue(3,EMPTY_VALUE);
// SetIndexDrawBegin(3,MaPeriod);
SetIndexStyle(3,DrawType,STYLE_SOLID,OpCl_Width);
SetIndexLabel(3,"Hull_HA("+MaPeriod+")ClOp");
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//---- TODO: add your code here
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
// if(Bars<=10) return(0);
if(Bars<=MathPow(MaPeriod,2)) return(0);
int CountedBars=IndicatorCounted();
//---- check for possible errors
if (CountedBars<0) return(-1);
//---- last counted bar will be recounted
if (CountedBars>0) CountedBars--;
//int pos=Bars-ExtCountedBars-2;
int pos,limit;
//if (pos>=(Bars-ExtCountedBars-2)) pos=Bars-ExtCountedBars-2;
limit=Bars-CountedBars;
limit = MathMin(limit, ShowBars+MathPow(MaPeriod,2));
for (pos=limit;pos>=0;pos--)
{
//while(pos>=0)
maOpen =iMA(Symbol(),0,MathFloor(MaPeriod/2),0,MaMethod,PRICE_OPEN ,pos)*2-iMA(Symbol(),0,MaPeriod,0,MaMethod,PRICE_OPEN ,pos);
maClose=iMA(Symbol(),0,MathFloor(MaPeriod/2),0,MaMethod,PRICE_CLOSE,pos)*2-iMA(Symbol(),0,MaPeriod,0,MaMethod,PRICE_CLOSE,pos);
maLow =iMA(Symbol(),0,MathFloor(MaPeriod/2),0,MaMethod,PRICE_LOW ,pos)*2-iMA(Symbol(),0,MaPeriod,0,MaMethod,PRICE_LOW ,pos);
maHigh =iMA(Symbol(),0,MathFloor(MaPeriod/2),0,MaMethod,PRICE_HIGH ,pos)*2-iMA(Symbol(),0,MaPeriod,0,MaMethod,PRICE_HIGH ,pos);
//----
haHigh=MathMax(maHigh, MathMax(haOpen, haClose));
haLow=MathMin(maLow, MathMin(haOpen, haClose));
if (haOpen<haClose)
{
ExtMapBuffer1[pos]=haLow;
ExtMapBuffer2[pos]=haHigh;
}
else
{
ExtMapBuffer1[pos]=haHigh;
ExtMapBuffer2[pos]=haLow;
}
haOpen=(ExtMapBuffer3[pos+1]+ExtMapBuffer4[pos+1])/2;
ExtMapBuffer3[pos]=haOpen;
haClose=(maOpen+maHigh+maLow+maClose)/4;
ExtMapBuffer4[pos]=haClose;
// pos--;
}
//----
for (int i=0;i<indicator_buffers;i++) SetIndexDrawBegin(i,Bars-ShowBars);
return(0);
}
//+------------------------------------------------------------------+
Comments