Heiken_Ashi_Smoothed_Alert_005
Download scriptOverview of the Heiken Ashi Smoothed Indicator
This script is designed to provide a cleaner, more stabilized view of market price action on your trading chart. By utilizing "Heiken Ashi" principles combined with multiple layers of moving averages, it filters out the immediate "noise" of standard price candles (the rapid up and down fluctuations) to help identify the underlying trend more clearly.
Core Logic and Processing
The indicator operates through a multi-step calculation process to transform raw market data into smoothed visual signals:
1. Data Smoothing (The Foundation) Instead of looking at the raw prices of each individual candle, the script first calculates several moving averages based on your chosen periods and methods. It looks at four specific price points: the Open, Close, High, and Low. This initial step ensures that the data being analyzed is already slightly "buffered" against sudden, erratic price spikes.
2. Heiken Ashi Transformation Once the base data is smoothed, the script applies the Heiken Ashi logic. Unlike standard candles, which show exactly what happened in a time period, Heikin Ashi candles represent an average of the price movement. The script calculates:
- A synthetic "Open" and "Close" price based on previous data points.
- A recalculated "High" and "Low" that accounts for these new averages.
3. Secondary Smoothing Layer After the Heiken Ashi values are generated, the script applies a second round of smoothing (using your secondary period settings). This creates a final polished result. This double-layer approach—smoothing the data before turning it into Heikin Ashi candles, and then smoothing the resulting candles again—is what makes this "Smoothed" version unique. It is intended to produce much steadier visual lines than a standard Heiken Ashi indicator.
Visual Representation
The script renders these calculations as histograms on your chart. By comparing the different smoothed layers (specifically looking at the relationship between the high and low boundaries of the transformed candles), it provides a visual cue of the market's momentum.
Automated Alerts
Beyond just being a visual tool, the script includes an intelligent "Direction Change" detection system. It constantly monitors the relationship between the synthetic Open and Close prices:
- Trend Detection: If the price average shifts from a "Long" (bullish) state to a "Short" (bearish) state—or vice versa—the script identifies this as a potential trend reversal.
- Notifications: Depending on your settings, the script can automatically trigger a pop-up box alert or play a sound file the moment it detects that the market direction has flipped.
Summary for the Trader
This tool is designed for traders who find standard price charts too cluttered or "choppy." By filtering the data through multiple mathematical averages, it attempts to show you the "true" flow of the market, highlighting the prevailing trend while suppressing minor price fluctuations that might otherwise lead to false signals.
//+------------------------------------------------------------------+
//| Heiken Ashi Smoothed.mq4 |
//+------------------------------------------------------------------+
//| mod by Raff |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Forex-TSD.com "
#property link "http://www.forex-tsd.com/"
#property link "Alerts added by cja"
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Red
#property indicator_color2 RoyalBlue
#property indicator_color3 Red
#property indicator_color4 RoyalBlue
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 3
#property indicator_width4 3
//---- parameters
extern int MaMetod = 2;
extern int MaPeriod = 6;
extern int MaMetod2 = 3;
extern int MaPeriod2 = 2;
extern bool POP_UP_Box_Alert = false;
extern bool Sound_Alert = false;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
double ExtMapBuffer5[];
double ExtMapBuffer6[];
double ExtMapBuffer7[];
double ExtMapBuffer8[];
//----
int ExtCountedBars=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//|------------------------------------------------------------------|
int init()
{
//---- indicators
IndicatorBuffers(8);
SetIndexStyle(0,DRAW_HISTOGRAM, 0);
SetIndexBuffer(0, ExtMapBuffer1);
SetIndexStyle(1,DRAW_HISTOGRAM, 0);
SetIndexBuffer(1, ExtMapBuffer2);
SetIndexStyle(2,DRAW_HISTOGRAM, 0);
SetIndexBuffer(2, ExtMapBuffer3);
SetIndexStyle(3,DRAW_HISTOGRAM, 0);
SetIndexBuffer(3, ExtMapBuffer4);
//----
SetIndexDrawBegin(0,5);
//---- indicator buffers mapping
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexBuffer(2,ExtMapBuffer3);
SetIndexBuffer(3,ExtMapBuffer4);
SetIndexBuffer(4,ExtMapBuffer5);
SetIndexBuffer(5,ExtMapBuffer6);
SetIndexBuffer(6,ExtMapBuffer7);
SetIndexBuffer(7,ExtMapBuffer8);
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//---- TODO: add your code here
return(0);
}
bool Crossed (double haOpen , double haClose )
{
static string last_direction = "";
string current_direction = "";
if(haOpen<=haClose) current_direction = "LONG";
if(haOpen>haClose) current_direction = "SHORT";
if(current_direction != last_direction)
{
if(POP_UP_Box_Alert==true)Alert ("H/Ashi Direction change "+current_direction+" " ,Symbol()," ",Period()," @ ",Bid);
if(Sound_Alert==true) PlaySound("alert2.wav");
last_direction = current_direction;
return (true);
}
else
{
return (false);
}
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
double maOpen, maClose, maLow, maHigh;
double haOpen, haHigh, haLow, haClose;
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-1;
while(pos>=0)
{
maOpen=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_OPEN,pos);
maClose=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_CLOSE,pos);
maLow=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_LOW,pos);
maHigh=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_HIGH,pos);
haOpen=(ExtMapBuffer5[pos+1]+ExtMapBuffer6[pos+1])/2;
haClose=(maOpen+maHigh+maLow+maClose)/4;
haHigh=MathMax(maHigh, MathMax(haOpen, haClose));
haLow=MathMin(maLow, MathMin(haOpen, haClose));
if (haOpen<haClose)
{
ExtMapBuffer7[pos]=haLow;
ExtMapBuffer8[pos]=haHigh;
}
else
{
ExtMapBuffer7[pos]=haHigh;
ExtMapBuffer8[pos]=haLow;
}
ExtMapBuffer5[pos]=haOpen;
ExtMapBuffer6[pos]=haClose;
pos--;
}
int i;
for(i=0; i<Bars; i++) ExtMapBuffer1[i]=iMAOnArray(ExtMapBuffer7,Bars,MaPeriod2,0,MaMetod2,i);
for(i=0; i<Bars; i++) ExtMapBuffer2[i]=iMAOnArray(ExtMapBuffer8,Bars,MaPeriod2,0,MaMetod2,i);
for(i=0; i<Bars; i++) ExtMapBuffer3[i]=iMAOnArray(ExtMapBuffer5,Bars,MaPeriod2,0,MaMetod2,i);
for(i=0; i<Bars; i++) ExtMapBuffer4[i]=iMAOnArray(ExtMapBuffer6,Bars,MaPeriod2,0,MaMetod2,i);
Print(Crossed (ExtMapBuffer1[0],ExtMapBuffer2[0]));
//----
return(0);
}
//+------------------------------------------------------------------+
Comments