Heiken Ashi vs. MTF Heiken Ashi -- Calculation Methods

 

Hi

I've found that there can be gaps in Heiken Ashi calculations when presented in MTF.

But not when heiken ashi is called from another indicator. Does this make sense?

A Heiken Ashi calculation uses the following formula

  double haClose=(Open[pos]+High[pos]+Low[pos]+Close[pos])/4;
  double haOpen=(ExtMapBuffer3[pos+1]+ExtMapBuffer4[pos+1])/2;
  double haHigh=MathMax(High[pos],MathMax(haOpen,haClose));
  double haLow=MathMin(Low[pos],MathMin(haOpen,haClose));

By calling it by i-values ..

   double haClose=(iOpen(NULL,tf,shift)+iHigh(NULL,tf,shift)+iLow(NULL,tf,shift)+iClose(NULL,tf,shift))/4;
   double haOpen=(ExtMapBuffer3[i+1]+ExtMapBuffer4[i+1])/2;
   double haHigh=MathMax(iHigh(NULL,tf,shift),MathMax(haOpen,haClose));
   double haLow=MathMin(iLow(NULL,tf,shift),MathMin(haOpen,haClose));

This calculation is similar to using a simple moving average on a period of 1.

By calling heiken ashi and making a mtf DRAW_SECTION indicator you get this

//+-----------------------#MTF Heiken Ashi---------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 clrNONE
#property indicator_color2 clrNONE
#property indicator_color3 IndianRed
#property indicator_color4 MediumSeaGreen
#property indicator_width1 0
#property indicator_width2 0
#property indicator_width3 2
#property indicator_width4 2
//+------------------------------------------------------------------+
input ENUM_TIMEFRAMES Timeframe = PERIOD_CURRENT; // Timeframe
//+------------------------------------------------------------------+
double ExtMapBuffer1[],ExtMapBuffer2[],ExtMapBuffer3[],ExtMapBuffer4[];
datetime last_bar;
//+------------------------------------------------------------------+
int init()
 {
 SetIndexStyle(0,DRAW_SECTION); SetIndexBuffer(0,ExtMapBuffer1);
 SetIndexStyle(1,DRAW_SECTION); SetIndexBuffer(1,ExtMapBuffer2);
 SetIndexStyle(2,DRAW_SECTION); SetIndexBuffer(2,ExtMapBuffer3);
 SetIndexStyle(3,DRAW_SECTION); SetIndexBuffer(3,ExtMapBuffer4);
 IndicatorShortName("MTF_Heikin_Ashi ("+strPeriod(Timeframe)+")");   
 return(0);
 }
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,const int prev_calculated,const datetime &time[],const double &open[],const double &high[],
                const double &low[],const double &close[],const long &tick_volume[],const long &volume[],const int &spread[]) 
 {
 int limit=1; int tf=Timeframe;
 if(prev_calculated==0) {limit=rates_total; last_bar=0;}
 for(int i=limit; i>=0; i--) 
  {
  int shift=iBarShift(NULL,tf,time[i],false);
  if(time[i]>=last_bar) 
   {
   ExtMapBuffer1[i]=iCustom(NULL,tf,"Heiken Ashi",0,shift);
   ExtMapBuffer2[i]=iCustom(NULL,tf,"Heiken Ashi",1,shift);
   ExtMapBuffer3[i]=iCustom(NULL,tf,"Heiken Ashi",2,shift);
   ExtMapBuffer4[i]=iCustom(NULL,tf,"Heiken Ashi",3,shift);
   }
  }
 return(rates_total); 
 }
//+------------------------------------------------------------------+
string strPeriod(int Per)
 { if(Per==PERIOD_CURRENT){Per=Period();}
 switch(Per)
  {
  case 1:return("M1");
  case 5:return("M5");
  case 15:return("M15");
  case 30:return("M30");
  case 60:return("H1");
  case 240:return("H4");
  case 1440:return("D1");
  case 10080:return("W1");
  case 43200:return("MN");
  }
 return("{ Unknown Period }");
 }
//+------------------------------------------------------------------+
//+------------------------Heiken Ashi-------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Red
#property indicator_color2 White
#property indicator_color3 Red
#property indicator_color4 White
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 3
#property indicator_width4 3
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
double ExtMapBuffer1[],ExtMapBuffer2[],ExtMapBuffer3[],ExtMapBuffer4[];
//+------------------------------------------------------------------+
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);
 IndicatorDigits(Digits); 
 return(0);
 }
//+------------------------------------------------------------------+
int start()
 {
 int pos,limit,counted_bars=IndicatorCounted();
 if(counted_bars<0){ return(-1); }
 if(counted_bars>0){ counted_bars--; }
 limit=Bars-counted_bars;       
 for(pos=limit; pos>=0; pos--)
  {
  double haClose=(Open[pos]+High[pos]+Low[pos]+Close[pos])/4;
  double haOpen=(ExtMapBuffer3[pos+1]+ExtMapBuffer4[pos+1])/2;
  double haHigh=MathMax(High[pos],MathMax(haOpen,haClose));
  double haLow=MathMin(Low[pos],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;
  }
 return(0);
 }
//+------------------------------------------------------------------+

But when you use the i-values calculation in an MTF calculation, you get this( with DRAW_SECTION for comparison )

Take note of the White color change occurring from the H1 chart which cannot be seen from the H4 chart which MTF-HA is set to.

//+----------------------------MTF HA--------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Red
#property indicator_color2 White
#property indicator_color3 Red
#property indicator_color4 White
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 3
#property indicator_width4 3
//+------------------------------------------------------------------+
input ENUM_TIMEFRAMES Timeframe = PERIOD_CURRENT; // Timeframe
//+------------------------------------------------------------------+
double ExtMapBuffer1[],ExtMapBuffer2[],ExtMapBuffer3[],ExtMapBuffer4[];
datetime last_bar;
//+------------------------------------------------------------------+
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);
 IndicatorDigits(Digits); 
 return(0);
 }
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,const int prev_calculated,const datetime &time[],const double &open[],const double &high[],
                const double &low[],const double &close[],const long &tick_volume[],const long &volume[],const int &spread[]) 
 {
 int limit=1; int tf=Timeframe;
 if(prev_calculated==0) {limit=rates_total-2; last_bar=0;}
 for(int i=limit; i>=0; i--) 
  {
  int shift=iBarShift(NULL,tf,time[i],false);
  if(time[i]>=last_bar) 
   {
   double haClose=(iOpen(NULL,tf,shift)+iHigh(NULL,tf,shift)+iLow(NULL,tf,shift)+iClose(NULL,tf,shift))/4;
   double haOpen=(ExtMapBuffer3[i+1]+ExtMapBuffer4[i+1])/2;
   double haHigh=MathMax(iHigh(NULL,tf,shift),MathMax(haOpen,haClose));
   double haLow=MathMin(iLow(NULL,tf,shift),MathMin(haOpen,haClose));
   if(haOpen<haClose)
    {
    ExtMapBuffer1[i]=haLow;
    ExtMapBuffer2[i]=haHigh;
    }
   else
    {
    ExtMapBuffer1[i]=haHigh;
    ExtMapBuffer2[i]=haLow;
    }
   ExtMapBuffer3[i]=haOpen;
   ExtMapBuffer4[i]=haClose;
   }
  }
 return(rates_total); 
 }
//+------------------------------------------------------------------+

And how about using iMA calculations? It appears to be the same as the i-values. (File is not attached)



In summary i-values are as bad to use as iMA and I think the solution would be to have a full array of the heiken ashi prices and then use that to make it work in MTF.


Why does it seem that, in making heiken ashi an MTF indicator, it's most accurate when called from another indicator?


Care to try out for yourself?

Files: