HMA_TwoTone_v1
Download scriptThis script is designed to function as a specialized technical analysis tool for the MetaTrader platform, specifically generating a visual trend indicator known as the Hull Moving Average (HMA). The primary goal of this logic is to provide traders with a smoother, faster-reacting trend line compared to traditional moving averages, reducing the "lag" that typically occurs when price data is averaged.
Core Logic and Methodology
The script operates through a multi-layered calculation process to refine the movement of price data:
- Dynamic Weighting: The logic begins by taking the raw price data and applying Weighted Moving Averages (WMA). Unlike a simple average, this method gives more importance to recent price action.
- Two-Step Calculation: To achieve its unique smoothness, the script performs a mathematical "difference" calculation. It calculates two separate moving averages—one based on half of the user-defined period and one based on the full period. By doubling the shorter average and subtracting the longer one, the script effectively isolates the momentum of the price.
- Smoothing Pass: After performing the initial momentum calculation, the script runs a secondary pass over that result. It applies another moving average to this intermediate data. This "double-smoothing" is what allows the indicator to stay tight to the price action while remaining visually fluid and free of excessive noise.
Visual Output and Behavior
The script produces two distinct visual elements on your chart:
- Trend Line: The primary output is a smooth line that follows the price trend. Because of its mathematical construction, it responds quickly to sudden price pivots while filtering out minor market fluctuations.
- Peak Detection: The logic includes a secondary check that identifies specific points where the trend line begins to flatten or turn. It tracks these values to help identify local highs or lows in the market cycle.
User Customization
The script allows for three main adjustments to tailor the logic to different trading styles:
- Period: Determines how many bars of history the indicator looks back at. A higher number makes the line smoother but slower; a lower number makes it faster and more sensitive to recent price changes.
- Method: Allows the user to choose the type of underlying moving average calculation.
- Price: Lets the user decide which price point (such as Close, Open, High, or Low) should be used as the foundation for the calculations.
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
//| HMA.mq4
//| Copyright © 2006 WizardSerg <wizardserg@mail.ru>, ?? ??????? ForexMagazine #104
//| wizardserg@mail.ru
//| Adapted March 7 2006 by request from Secxces by FloFri
//+------------------------------------------------------------------+
#property copyright "MT4 release WizardSerg <wizardserg@mail.ru>, ?? ??????? ForexMagazine #104"
#property link "wizardserg@mail.ru"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
//---- input parameters
extern int period=21;
extern int method=0; // MODE_SMA
extern int price=0; // PRICE_CLOSE
//---- buffers
double ExtMapBuffer1[], ExtMapBuffer2[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
IndicatorBuffers(2);
SetIndexBuffer(0, ExtMapBuffer1);
SetIndexBuffer(1, ExtMapBuffer2);
ArraySetAsSeries(ExtMapBuffer1, true);
ArraySetAsSeries(ExtMapBuffer2, true);
IndicatorShortName("Hull Moving Average("+period+")");
return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
// ???? ????? ?????? ??????
return(0);
}
//+------------------------------------------------------------------+
//| ?????????? ??????? |
//+------------------------------------------------------------------+
double WMA(int x, int p)
{
return(iMA(NULL, 0, p, 0, method, price, x));
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars = IndicatorCounted();
if(counted_bars < 0)
return(-1);
int x = 0;
int p = MathSqrt(period);
int e = Bars - counted_bars + period + 1;
double vect[];
if(e > Bars)
e = Bars;
ArrayResize(vect, e);
ArraySetAsSeries(vect, true);
for(x = 0; x < e; x++)
{
vect[x] = 2*WMA(x, period/2) - WMA(x, period);
// Print("Bar date/time: ", TimeToStr(Time[x]), " close: ", Close[x], " vect[", x, "] = ", vect[x], " 2*WMA(p/2) = ", 2*WMA(x, period/2), " WMA(p) = ", WMA(x, period));
}
for(x = 0; x < e-period; x++) {
ExtMapBuffer1[x] = iMAOnArray(vect, 0, p, 0, method, x);
}
for(x = 0; x < e-period; x++) {
if( ExtMapBuffer1[x] <= ExtMapBuffer1[x+1] ) {
ExtMapBuffer2[x] = ExtMapBuffer1[x];
//ExtMapBuffer1[x+1] = EMPTY_VALUE;
}
}
Comment(ExtMapBuffer1[0]);
return(0);
}
//+------------------------------------------------------------------+
Comments