This script is a specialized technical analysis tool designed to help traders identify momentum shifts and potential entry points in the financial markets. It works by combining several different mathematical concepts—specifically moving averages, price extremes, and "Heikin Ashi" logic—into a single visual indicator on your trading chart.
How the Logic Works
1. Multi-Layered Data Processing Instead of looking at just the current price, the tool analyzes four specific components of a candle simultaneously: the Open, High, Low, and Close. It applies a "Hull" style moving average calculation to these points. This is done to smooth out the market noise while ensuring the indicator remains responsive to recent price changes.
2. Dynamic Price Modeling The script uses a unique method to calculate "synthetic" price values. It takes the smoothed data from the previous period and blends it with current high and low extremes. This creates a more fluid representation of market movement than a standard moving average, helping to highlight the underlying trend more clearly.
3. Trend Visualization The tool plots four different data lines (buffers) on your chart:
- It tracks specific price boundaries (Highs and Lows) based on whether the current momentum is positive or negative.
- It calculates a smoothed opening price and a smoothed closing price to create a visual representation of the trend's "body."
4. Automated Signal Detection The core utility of this script is its ability to recognize specific turning points. It looks for "crossovers" where the smoothed trend lines flip their relationship relative to one another:
- Buy Signals: Triggered when the indicator detects a specific shift in the momentum moving from downward to upward.
- Sell Signals: Triggered when the indicator detects a shift from upward to downward momentum.
5. Real-Time Notifications To keep you informed without needing to watch the screen constantly, the script includes an automated alert system. When the logic identifies one of these trend reversals:
- It triggers a pop-up alert on your trading platform.
- If enabled in the settings, it can automatically send an email containing the specific asset name, the current price (Ask/Bid), and the exact time of the signal.
Summary for the User
Essentially, this tool filters out the "jitter" of the market to show you a smoothed path of where the price is heading. It then watches that path for us; the moment it detects the trend "folding" in on itself to change direction, it notifies you immediately via sound or email so you can react to the new market move.
//+------------------------------------------------------------------+
//| Hull_O_H_L_C.mq4 |
//| Copyright © 2007, None |
//| Planet.Earth.Redistribution |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, None"
#property link "Planet.Earth.Redistribution"
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Red
#property indicator_color2 Blue
#property indicator_color3 Red
#property indicator_color4 Blue
//---- parameters
extern int MaMethod = 1;
extern int MaPeriod = 60;
extern int DrawType = 2;
extern int OpCl_Width = 2;
extern int ShowBars = 250;
double alertBar;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
double maOpen, maClose, maLow, maHigh;
double haOpen, haHigh, haLow, haClose;
extern int EmailON=1;
//----
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," Mode 0 ");
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexEmptyValue(1,EMPTY_VALUE);
SetIndexDrawBegin(1,MaPeriod);
SetIndexStyle(1,DrawType,STYLE_SOLID,1);
SetIndexLabel(1," Mode 1 ");
SetIndexBuffer(2,ExtMapBuffer3);
SetIndexEmptyValue(2,EMPTY_VALUE);
SetIndexDrawBegin(2,MaPeriod);
SetIndexStyle(2,DrawType,STYLE_SOLID,OpCl_Width);
SetIndexLabel(2," Mode 2 ");
SetIndexBuffer(3,ExtMapBuffer4);
SetIndexEmptyValue(3,EMPTY_VALUE);
SetIndexDrawBegin(3,MaPeriod);
SetIndexStyle(3,DrawType,STYLE_SOLID,OpCl_Width);
SetIndexLabel(3," Mode 3 ");
//---- 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);
ExtCountedBars=IndicatorCounted();
//---- check for possible errors
if (ExtCountedBars<0) return(-1);
//---- last counted bar will be recounted
if (ExtCountedBars>0) ExtCountedBars--;
//int pos=Bars-ExtCountedBars-2;
int pos=ShowBars;
if (pos >= (Bars-ExtCountedBars-2)) pos = Bars-ExtCountedBars-2;
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;
if (ExtMapBuffer3[pos]<ExtMapBuffer4[pos] && ExtMapBuffer4[pos+1]<ExtMapBuffer3[pos+1] && Bars>alertBar)
{
Alert("Hull BUY: ",Symbol()," - ",Period()," at ", Close[0]," - ", TimeToStr(CurTime(),TIME_SECONDS));
if (EmailON==1) SendMail("Hull BUY alert","SELL signal at Ask="+DoubleToStr(Ask,4)+", Bid="+DoubleToStr(Bid,4)+", Date="+TimeToStr(CurTime(),TIME_DATE)+" "+TimeHour(CurTime())+":"+TimeMinute(CurTime())+" Symbol="+Symbol()+" Period="+Period());
alertBar = Bars;
}
if (ExtMapBuffer3[pos]>ExtMapBuffer4[pos] && ExtMapBuffer4[pos+1]>ExtMapBuffer3[pos+1] && Bars>alertBar)
{
Alert("Hull SELL: ",Symbol()," - ",Period()," at ", Close[0]," - ", TimeToStr(CurTime(),TIME_SECONDS));
if (EmailON==1) SendMail("Hull SELL alert","SELL signal at Ask="+DoubleToStr(Ask,4)+", Bid="+DoubleToStr(Bid,4)+", Date="+TimeToStr(CurTime(),TIME_DATE)+" "+TimeHour(CurTime())+":"+TimeMinute(CurTime())+" Symbol="+Symbol()+" Period="+Period());
alertBar = Bars;
}
pos--;
}
//----
return(0);
}
//+------------------------------------------------------------------+
Comments