Heiken Ashi MA T3 new_003
Download scriptThis indicator is designed to provide a smoothed visual representation of market price action by combining two sophisticated charting methodologies: Heiken Ashi and the T3 Moving Average.
Core Logic Overview
The script functions by layering these two technical concepts to filter out "market noise" (minor, erratic price fluctuations) while maintaining the trend's integrity. It works in three primary stages:
1. The Smoothing Layer (T3 Moving Average)
Instead of using standard moving averages which can sometimes be laggy or jumpy, this script utilizes a T3 Moving Average. The T3 is a refined mathematical formula designed to reduce the "lag" typically found in other averages while remaining very smooth.
The script allows for two modes here:
- T3 Average Mode: It calculates specific price points (Open, Close, High, and Low) using the T3 logic independently.
- Standard Moving Average Mode: As a fallback, it can use traditional moving averages if the specific T3 calculation is not selected.
2. The Trend Visualization Layer (Heiken Ashi)
Once the price data has been smoothed by the T3 logic, the script applies Heiken Ashi calculations. Heiken Ashi candles are known for making trends much easier to see by averaging price information.
The script specifically looks at:
- Opening Prices: Derived from the previous period's data to ensure continuity.
- Closing Prices: Calculated as an average of the highs, lows, and opens/closes.
- Highs and Lows: Adjusted based on whether the current trend is bullish (upward) or bearish (downward).
3. The Stability Filter (Step Logic)
One unique feature of this script is the "Step" filter. This acts as a stabilizer. If the price movement between one candle and the next is smaller than a user-defined "Step" value, the script will keep the indicator's value the same as the previous candle.
This prevents the visual bars from flickering or moving erratically during periods of very low volatility, ensuring that the trend only changes when there is a meaningful move in price.
Summary for the User
When you view this on a chart, you are not seeing raw price data. You are seeing a "smoothed" version of the market where:
- Volatility is dampened by the T3 Moving Average math.
- Trend clarity is enhanced by the Heiken Ashi candle logic.
- Micro-fluctuations are ignored by the Step filter, allowing you to focus on the primary direction of the market rather than temporary price "jitters."
//+------------------------------------------------------------------+
//| Heiken Ashi Ma T3.mq4 |
//+------------------------------------------------------------------+
//| mod by Raff |
//| 2009 mod by mladen |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008,Forex-TSD.com"
#property link "http://www.forex-tsd.com/"
#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 2
#property indicator_width4 2
//
//
//
//
//
extern int MaPeriod = 10;
extern int MaMetod = 2;
extern int Step = 10;
extern bool BetterFormula = false;
extern bool T3Average = true;
extern double T3Hot = 0.618;
extern bool T3Original = false;
//
//
//
//
//
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
//
//
//
//
//
double emas[][24];
double alpha;
double c1;
double c2;
double c3;
double c4;
//+------------------------------------------------------------------+
//| |
//|------------------------------------------------------------------|
//
//
//
//
//
int init()
{
SetIndexBuffer(0, ExtMapBuffer1); SetIndexStyle(0,DRAW_HISTOGRAM);
SetIndexBuffer(1, ExtMapBuffer2); SetIndexStyle(1,DRAW_HISTOGRAM);
SetIndexBuffer(2, ExtMapBuffer3); SetIndexStyle(2,DRAW_HISTOGRAM);
SetIndexBuffer(3, ExtMapBuffer4); SetIndexStyle(3,DRAW_HISTOGRAM);
//
//
//
//
//
double a = T3Hot;
c1 = -a*a*a;
c2 = 3*(a*a+a*a*a);
c3 = -3*(2*a*a+a+a*a*a);
c4 = 1+3*a+a*a*a+3*a*a;
MaPeriod = MathMax(1,MaPeriod);
if (T3Original)
alpha = 2.0/(1.0 + MaPeriod);
else alpha = 2.0/(2.0 + (MaPeriod-1.0)/2.0);
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
//
//
//
//
//
int start()
{
double maOpen, maClose, maLow, maHigh;
double haOpen, haClose, haLow, haHigh;
int counted_bars=IndicatorCounted();
int pointModifier;
int i,limit;
//
//
//
//
//
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
limit = Bars-counted_bars;
if (ArrayRange(emas,0) != Bars) ArrayResize(emas,Bars);
if (Digits==3 || Digits==5)
pointModifier = 10;
else pointModifier = 1;
//
//
//
//
//
for(int pos=limit; pos >= 0; pos--)
{
if (T3Average)
{
maOpen = iT3(Open[pos] ,pos, 0);
maClose = iT3(Close[pos],pos, 6);
maLow = iT3(Low[pos] ,pos,12);
maHigh = iT3(High[pos] ,pos,18);
}
else
{
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);
}
//
//
//
//
//
if (BetterFormula) {
if (maHigh!=maLow)
haClose = (maOpen+maClose)/2+(((maClose-maOpen)/(maHigh-maLow))*MathAbs((maClose-maOpen)/2));
else haClose = (maOpen+maClose)/2; }
else haClose = (maOpen+maHigh+maLow+maClose)/4;
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*pointModifier*Point ) ExtMapBuffer1[pos]=ExtMapBuffer1[pos+1];
if( MathAbs(ExtMapBuffer2[pos]-ExtMapBuffer2[pos+1]) < Step*pointModifier*Point ) ExtMapBuffer2[pos]=ExtMapBuffer2[pos+1];
if( MathAbs(ExtMapBuffer3[pos]-ExtMapBuffer3[pos+1]) < Step*pointModifier*Point ) ExtMapBuffer3[pos]=ExtMapBuffer3[pos+1];
if( MathAbs(ExtMapBuffer4[pos]-ExtMapBuffer4[pos+1]) < Step*pointModifier*Point ) ExtMapBuffer4[pos]=ExtMapBuffer4[pos+1];
}
}
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
//
//
//
//
//
double iT3(double price,int shift,int buffer)
{
int i = Bars-shift-1;
if (i < 1)
{
emas[i][0+buffer] = price;
emas[i][1+buffer] = price;
emas[i][2+buffer] = price;
emas[i][3+buffer] = price;
emas[i][4+buffer] = price;
emas[i][5+buffer] = price;
}
else
{
emas[i][0+buffer] = emas[i-1][0+buffer]+alpha*(price -emas[i-1][0+buffer]);
emas[i][1+buffer] = emas[i-1][1+buffer]+alpha*(emas[i][0+buffer]-emas[i-1][1+buffer]);
emas[i][2+buffer] = emas[i-1][2+buffer]+alpha*(emas[i][1+buffer]-emas[i-1][2+buffer]);
emas[i][3+buffer] = emas[i-1][3+buffer]+alpha*(emas[i][2+buffer]-emas[i-1][3+buffer]);
emas[i][4+buffer] = emas[i-1][4+buffer]+alpha*(emas[i][3+buffer]-emas[i-1][4+buffer]);
emas[i][5+buffer] = emas[i-1][5+buffer]+alpha*(emas[i][4+buffer]-emas[i-1][5+buffer]);
}
return(c1*emas[i][5+buffer] + c2*emas[i][4+buffer] + c3*emas[i][3+buffer] + c4*emas[i][2+buffer]);
}
Comments