Author: MT4 release WizardSerg <wizardserg@mail.ru>, ?? ??????? ForexMagazine #104
SMA C

This tool is designed to provide a visual representation of market trends by calculating the Hull Moving Average (HMA). Unlike standard moving averages that can sometimes lag behind current price action, this script uses a specific mathematical approach to smooth out price data while maintaining high responsiveness to recent movements.

Core Logic and Functionality

The script processes price data through several layers of calculation to determine the trend:

1. Weighted Data Processing The tool begins by calculating two distinct weighted moving averages based on your chosen period. It then applies a specific formula—multiplying the shorter-term average by two and subtracting the longer-term average. This step is designed to reduce "noise" in the market while preserving the direction of the price movement.

2. Smoothing and Final Mapping After the initial weighted calculation, the script performs an additional smoothing pass. It takes the square root of your period setting to determine how much extra smoothing is required. This ensures that the final line on your chart is fluid and not jagged, making it easier for a human observer to identify the underlying momentum.

3. Dynamic Trend Identification The most distinct feature of this script is its ability to automatically separate "Up" trends from "Down" trends:

  • Uptrend Detection: When the calculated average begins to move upward, the script highlights this movement in a specific color (Lime).
  • Downtrend Detection: When the average begins to move downward, the script highlights this movement in a different color (Red).
  • Transition Logic: The logic is programmed to recognize the exact moment the trend shifts. When the direction flips from positive to negative (or vice versa), it assigns the data points to the appropriate visual buffer, effectively "switching" the active line on your chart.

Summary for the User

In practical terms, this script acts as a sophisticated trend-following indicator. Instead of showing you a single, static average, it dynamically identifies whether the current momentum is bullish or bearish. By visually separating these two states into different colors, it allows you to see clearly where the market has shifted direction without the visual clutter of overlapping lines.

Indicators Used
Moving average indicatorMoving average indicator
Miscellaneous
Implements a curve of type %1
18 Views
0 Downloads
0 Favorites
SMA C
//+------------------------------------------------------------------+ 
//| HMA.mq4 
//| Copyright © 2006 WizardSerg <wizardserg@mail.ru>, ?? ??????? ForexMagazine #104 
//| wizardserg@mail.ru 
//|                         Revised by IgorAD,igorad2003@yahoo.co.uk |   
//|                                        http://www.forex-tsd.com/ |                                      
//+------------------------------------------------------------------+
#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 Lime 
#property indicator_color2 Red 
//---- input parameters 
extern int       period=36; 
extern int       method=1;                         // MODE_SMA 
extern int       price=0;                          // PRICE_CLOSE 
//---- buffers 
double Uptrend[];
double Dntrend[];
double ExtMapBuffer[]; 


//+------------------------------------------------------------------+ 
//| Custom indicator initialization function                         | 
//+------------------------------------------------------------------+ 
int init() 
{ 
    IndicatorBuffers(3);  
    SetIndexBuffer(0, Uptrend); 
    //ArraySetAsSeries(Uptrend, true); 
    SetIndexBuffer(1, Dntrend); 
    //ArraySetAsSeries(Dntrend, true); 
    SetIndexBuffer(2, ExtMapBuffer); 
    ArraySetAsSeries(ExtMapBuffer, true); 
    
    SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,5);
    SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,5);
    
    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[], trend[]; 
    
    if(e > Bars) 
        e = Bars;    

    ArrayResize(vect, e); 
    ArraySetAsSeries(vect, true);
    ArrayResize(trend, e); 
    ArraySetAsSeries(trend, 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++)
     
        ExtMapBuffer[x] = iMAOnArray(vect, 0, p, 0, method, x);        
    
    for(x = e-period; x >= 0; x--)
    {     
        trend[x] = trend[x+1];
        if (ExtMapBuffer[x]> ExtMapBuffer[x+1]) trend[x] =1;
        if (ExtMapBuffer[x]< ExtMapBuffer[x+1]) trend[x] =-1;
    
    if (trend[x]>0)
    { Uptrend[x] = ExtMapBuffer[x]; 
      if (trend[x+1]<0) Uptrend[x+1]=ExtMapBuffer[x+1];
      Dntrend[x] = EMPTY_VALUE;
    }
    else              
    if (trend[x]<0)
    { 
      Dntrend[x] = ExtMapBuffer[x]; 
      if (trend[x+1]>0) Dntrend[x+1]=ExtMapBuffer[x+1];
      Uptrend[x] = EMPTY_VALUE;
    }              
    
    //Print( " trend=",trend[x]);
    }
    
    return(0); 
} 
//+------------------------------------------------------------------+ 

Comments