Heiken_Ashi_Ma_T3_002
Download scriptThis technical indicator is designed to provide traders with a smoothed, visual representation of price action by combining two sophisticated trading concepts: Moving Averages and Heiken Ashi price dynamics.
Instead of showing raw, erratic market fluctuations, the script filters out "noise" to reveal the underlying trend more clearly. Here is a breakdown of the logic used:
1. The Foundation: Advanced Smoothing
The core of the script relies on calculating Moving Averages (MA). It offers two distinct ways to process this data:
- Standard Smoothing: Uses traditional moving average methods to calculate a baseline for price.
- T3 Smoothing: An optional, high-performance calculation designed to reduce "lag" while maintaining a very smooth curve. This allows the indicator to react more quickly to significant price movements than standard averages might.
2. The Transformation: Heiken Ashi Logic
The script takes the smoothed data and converts it into Heiken Ashi values. Unlike standard Japanese candlesticks, which represent the raw high and low of a specific period, Heiken Ashi candles are calculated based on averages.
- By applying this logic to the already smoothed moving averages (rather than the raw price), the script creates a "Trend Ribbon."
- This results in a visual flow where colors and candle sizes represent the momentum of the trend rather than just the volatile open-and-close prices.
3. Price Stabilization (The "Step" Feature)
To prevent the indicator from jumping erratically due to tiny price fluctuations, the script includes a stabilization layer. If the change in price between two points is smaller than a user-defined "Step," the script holds the previous value constant. This ensures the visual trend remains steady and readable for the human eye.
4. Trend Identification & Alerts
The indicator monitors the relationship between the opening and closing values of these processed candles to identify momentum shifts:
- Bullish Momentum: When the price structure transitions into a positive orientation, the script identifies a potential "Buy" signal.
- Bearish Momentum: When the structure flips to a negative orientation, it identifies a potential "Sell" signal.
If enabled, the system provides real-time alerts for these shifts. It is programmed with a "toggle" logic to ensure that you only receive one alert per trend change, preventing multiple notifications during a single sustained move.
Summary for the User
Essentially, this tool takes the messy reality of market price, smooths it out using advanced mathematical filters (T3 or standard MA), converts it into a trend-following visual format (Heiken Ashi), and alerts you when the direction of that trend shifts from up to down, or vice versa.
//+------------------------------------------------------------------+
//| Heiken Ashi Ma T3.mq4 |
//+------------------------------------------------------------------+
//| mod by Raff |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Forex-TSD.com "
#property link "http://www.forex-tsd.com/"
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1 Red
#property indicator_color2 CadetBlue
#property indicator_color3 Red
#property indicator_color4 CadetBlue
#property indicator_color5 Yellow
#property indicator_color6 Aqua
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 2
#property indicator_width4 2
#property indicator_width5 1
#property indicator_width6 1
//---- parameters
extern int MaPeriod = 3;
extern int MaMetod = 3;
extern int Step = 1;
extern int CountBars = 1500;
extern bool UseT3 = false;
extern double b = 0.618;
extern bool Alerts = false;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
double UpArrow[];
double DnArrow[];
//----
double e1,e2,e3,e4,e5,e6;
double c1,c2,c3,c4;
double n,w1,w2,b2,b3;
//----
int ExtCountedBars=0;
static bool TurnedUp = false;
static bool TurnedDown = false;
datetime timeprev=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//|------------------------------------------------------------------|
int init()
{
//---- indicators
IndicatorBuffers(6);
SetIndexStyle(0,DRAW_HISTOGRAM);
SetIndexBuffer(0, ExtMapBuffer1);
SetIndexStyle(1,DRAW_HISTOGRAM);
SetIndexBuffer(1, ExtMapBuffer2);
SetIndexStyle(2,DRAW_HISTOGRAM);
SetIndexBuffer(2, ExtMapBuffer3);
SetIndexStyle(3,DRAW_HISTOGRAM);
SetIndexBuffer(3, ExtMapBuffer4);
SetIndexBuffer(4, UpArrow);
SetIndexStyle(4,DRAW_ARROW);
SetIndexArrow(4,233);
SetIndexBuffer(5,DnArrow);
SetIndexStyle(5,DRAW_ARROW);
SetIndexArrow(5,234);
//---- indicator buffers mapping
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexBuffer(2,ExtMapBuffer3);
SetIndexBuffer(3,ExtMapBuffer4);
SetIndexBuffer(4,UpArrow);
SetIndexBuffer(5,DnArrow);
//---- variable reset
e1=0; e2=0; e3=0; e4=0; e5=0; e6=0;
c1=0; c2=0; c3=0; c4=0;
n=0;
w1=0; w2=0;
b2=0; b3=0;
b2=b*b;
b3=b2*b;
c1=-b3;
c2=(3*(b2+b3));
c3=-3*(2*b2+b+b3);
c4=(1+3*b+b3+3*b2);
n=MaPeriod;
if (n<1) n=1;
n = 1 + 0.5*(n-1);
w1 = 2 / (n + 1);
w2 = 1 - w1;
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
if(timeprev<iTime(NULL,0,0)) {TurnedDown = false; TurnedUp = false;timeprev=iTime(NULL,0,0);}
if (CountBars>Bars-1) CountBars=Bars-1;
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=CountBars;//-ExtCountedBars-1;
while(pos>=0)
{
if (UseT3)
{
maOpen=CalcT3(Open[pos]);
maClose=CalcT3(Close[pos]);
maLow=CalcT3(Low[pos]);
maHigh=CalcT3(High[pos]);
}
else
if (!UseT3)
{
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,MODE_LOW,pos);
maHigh=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_HIGH,pos);
}
haClose=(maOpen+maHigh+maLow+maClose)/4;
//haClose=(maOpen+maClose)/2+(((maClose-maOpen)/(maHigh-maLow))*MathAbs((maClose-maOpen)/2));
haOpen=(ExtMapBuffer3[pos+1]+ExtMapBuffer4[pos+1])/2;
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;
}
ExtMapBuffer3[pos]=haOpen;
ExtMapBuffer4[pos]=haClose;
if (Step>0) if( MathAbs(ExtMapBuffer1[pos]-ExtMapBuffer1[pos+1]) < Step*Point ) ExtMapBuffer1[pos]=ExtMapBuffer1[pos+1];
if (Step>0) if( MathAbs(ExtMapBuffer2[pos]-ExtMapBuffer2[pos+1]) < Step*Point ) ExtMapBuffer2[pos]=ExtMapBuffer2[pos+1];
if (Step>0) if( MathAbs(ExtMapBuffer3[pos]-ExtMapBuffer3[pos+1]) < Step*Point ) ExtMapBuffer3[pos]=ExtMapBuffer3[pos+1];
if (Step>0) if( MathAbs(ExtMapBuffer4[pos]-ExtMapBuffer4[pos+1]) < Step*Point ) ExtMapBuffer4[pos]=ExtMapBuffer4[pos+1];
if (Alerts==true)
{
UpArrow[pos]=EMPTY_VALUE; DnArrow[pos]=EMPTY_VALUE;
if (ExtMapBuffer3[pos]<ExtMapBuffer4[pos] && ExtMapBuffer4[pos+1]<ExtMapBuffer3[pos+1])
{
UpArrow[pos]=ExtMapBuffer4[pos+1]-(Ask-Bid);
if (UpArrow[0]!=EMPTY_VALUE && TurnedUp==false)
{
Alert("HAMa BUY: ",Symbol()," - ",Period()," at ", Close[0]," - ", TimeToStr(CurTime(),TIME_SECONDS));
TurnedDown = false;
TurnedUp = true;
}
}
if (ExtMapBuffer3[pos]>ExtMapBuffer4[pos] && ExtMapBuffer4[pos+1]>ExtMapBuffer3[pos+1])
{
DnArrow[pos]=ExtMapBuffer4[pos+1]+(Ask-Bid);
if (DnArrow[0]!=EMPTY_VALUE && TurnedDown==false)
{
Alert("HAMa SELL: ",Symbol()," - ",Period()," at ", Close[0]," - ", TimeToStr(CurTime(),TIME_SECONDS));
TurnedUp = false;
TurnedDown = true;
}
}
}
pos--;
}
//----
return(0);
}
double CalcT3(double CalcPrice)
{
e1 = w1*CalcPrice+w2*e1;
e2 = w1*e1 + w2*e2;
e3 = w1*e2 + w2*e3;
e4 = w1*e3 + w2*e4;
e5 = w1*e4 + w2*e5;
e6 = w1*e5 + w2*e6;
double T3=c1*e6 + c2*e5 + c3*e4 + c4*e3;
return(T3);
}
//+------------------------------------------------------------------+
Comments