Heiken_Ashi_Smoothed_Alert_bar_sw
Download scriptOverview
This script is a specialized technical analysis tool designed to filter out market "noise" and identify clear trend directions. It achieves this by combining two sophisticated smoothing techniques: Heiken Ashi price calculation and Moving Averages.
Unlike standard price charts, which can be erratic, this indicator creates a stabilized visual representation of the market's momentum to help traders distinguish between minor fluctuations and significant trend shifts.
How the Logic Works
The script processes data through three distinct layers of refinement:
1. Smoothing the Raw Price (Moving Averages)
First, the tool takes the raw price data (the opening, closing, high, and low points of each candle) and applies a Moving Average. This initial step smooths out the "jagged" edges of the market, ensuring that the subsequent calculations are based on stabilized averages rather than instant price spikes.
2. The Heiken Ashi Transformation
Next, the script converts these smoothed prices into a "Heiken Ashi" format. Heiken Ashi is a type of price average where:
- Opening Prices are calculated as the average of the previous candle's midpoint.
- Closing Prices are the average of the current period's high, low, open, and close.
By doing this, the indicator creates "synthetic" candles that show the underlying trend more clearly than standard Japanese candlesticks. It helps in visualizing whether the market is consistently moving upward or downward over a sustained period.
3. The Final Double-Smoothing Layer
To ensure maximum stability, the script applies a second layer of Moving Averages onto the Heiken Ashi values. This creates a high-level trend signal.
The final logic checks for two conditions simultaneously:
- It compares the smoothed "High" and "Low" boundaries of the candles.
- It compares the smoothed "Open" and "Close" values of the candles.
Visual Output and Alerts
The results are displayed as specific visual markers (arrows/levels) on your chart:
- Trend Confirmation: When the script detects a strong upward trend (where both the high/low boundaries and the open/close prices align in a bullish direction), it identifies a clear signal.
- Trend Reversal Alerts: The script is programmed to monitor for "Crosses." If the market momentum shifts from one direction to another (e.g., from an upward trend to a downward trend), the script can trigger a real-time alert.
Summary of Benefits
Instead of reacting to every single tick of price movement, this tool allows you to see the "big picture." It filters out the minor volatility of the market and only highlights sustained movements, providing a cleaner, more reliable visual guide for identifying trend directions.
//+------------------------------------------------------------------+
//| Heiken Ashi Smoothed.mq4 |
//+------------------------------------------------------------------+
//| mod by Raff |
//+------------------------------------------------------------------+
//mod2009fxtsd sw bar
#property copyright "Copyright © 2006, Forex-TSD.com "
#property link "http://www.forex-tsd.com/"
#property link "Alerts added by cja"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 RoyalBlue
#property indicator_color3 Red
#property indicator_color4 RoyalBlue
#property indicator_width1 1
#property indicator_width2 2
#property indicator_maximum 77
#property indicator_minimum 1
//---- parameters
extern int MaMetod = 1;
extern int MaPeriod = 3;
extern int MaMetod2 = 3;
extern int MaPeriod2 = 2;
extern int barLevel = 10;
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[];
datetime time;
//----
int ExtCountedBars=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//|------------------------------------------------------------------|
int init()
{
//---- indicators
IndicatorBuffers(8);
SetIndexStyle(0,DRAW_ARROW); SetIndexArrow(0,110); SetIndexEmptyValue(0,EMPTY_VALUE);
SetIndexStyle(1,DRAW_ARROW); SetIndexArrow(1,159); SetIndexEmptyValue(1,EMPTY_VALUE);
SetIndexBuffer(0, ExtMapBuffer1);
SetIndexBuffer(1, ExtMapBuffer2);
SetIndexBuffer(2, ExtMapBuffer3);
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);
IndicatorShortName (" HAS ("+MaMetod+","+MaPeriod+"; "+MaMetod2+","+MaPeriod2+") bar "+ barLevel);
//---- 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 = "SHORT";
if(haOpen>haClose) current_direction = "LONG";
if(current_direction != last_direction && time!=Time[0])
{
if(POP_UP_Box_Alert==true)Alert ("H/Ashi Direction change "+current_direction+" " ,Symbol()," M",Period()," @ ",Bid);
if(Sound_Alert==true) PlaySound("alert2.wav");
last_direction = current_direction;
time=Time[0];
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,PRICE_OPEN,pos);
maClose=iMA(NULL,0,MaPeriod,0,MaMetod,PRICE_CLOSE,pos);
maLow=iMA(NULL,0,MaPeriod,0,MaMetod,PRICE_LOW,pos);
maHigh=iMA(NULL,0,MaPeriod,0,MaMetod,PRICE_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);
for(i=0; i<Bars; i++)
{
if (ExtMapBuffer1[i]>ExtMapBuffer2[i]&&ExtMapBuffer3[i]>ExtMapBuffer4[i]) {ExtMapBuffer1[i]=barLevel; ExtMapBuffer2[i]=EMPTY_VALUE; }
else
if (ExtMapBuffer1[i]<ExtMapBuffer2[i]&&ExtMapBuffer3[i]<ExtMapBuffer4[i]) {ExtMapBuffer2[i]=barLevel; ExtMapBuffer1[i]=EMPTY_VALUE; }
else {ExtMapBuffer1[i]=barLevel; ExtMapBuffer2[i]=barLevel; }
}
Print(Crossed (ExtMapBuffer1[0],ExtMapBuffer2[0]));
//----
return(0);
}
//+------------------------------------------------------------------+
Comments