
//+------------------------------------------------------------------+
//|                                                X_Heiken_Ashi.mq5 |
//|                                     blackfriday | Copyright 2015 |
//|                                email:     blackfriday2014@web.de |
//+------------------------------------------------------------------+
#property copyright "blackfriday 2016"
#property link      "http://www.forexfactory.com/blackfriday"
#property version   "1.30"

#property description "This code draws Heiken Ashi bars, Japanese candlesticks or an overlay of both"
#property description "Use arrows up or down to switch between bar types"
#property description ""


//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_plots   2


#define KEY_UP             38
#define KEY_DOWN           40


//--- Wicks
#property indicator_type1   DRAW_COLOR_BARS
#property indicator_width1  1
#property indicator_style1  STYLE_SOLID
#property indicator_label1  "HA low; HA high;"

//--- Body
#property indicator_type2   DRAW_COLOR_HISTOGRAM2
#property indicator_style2  STYLE_SOLID
#property indicator_label2  "HA open; HA close;"


//--- input data
enum candletype{Heiken_Ashi = 1, Overlay_HA_Japanese = 2, Std_Japanese = 3};   
input candletype CandleType = 1;                //Candle type  
input color BodyUpColor = clrDodgerBlue;        //Body up color
input color ShadowUpColor = clrCyan;            //Shadow up color
input color BodyDnColor = clrRed;               //Body down color
input color ShadowDnColor = clrDarkOrange;      //Shadow down color
input int   BodyWidth = 2;                      //Body width


//--- indicator buffers
double BodyOpenBuffer[], BodyCloseBuffer[], BodyColorBuffer[];
double OpenBuffer[], CloseBuffer[], LowBuffer[], HighBuffer[], WickColorBuffer[];
color ShadowUpC, ShadowDnC, BodyUpC, BodyDnC;
int BodyW, CType, CTypeOld;

 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,OpenBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,HighBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,LowBuffer,INDICATOR_DATA);
   SetIndexBuffer(3,CloseBuffer,INDICATOR_DATA);
   SetIndexBuffer(4,WickColorBuffer,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(5,BodyOpenBuffer,INDICATOR_DATA);
   SetIndexBuffer(6,BodyCloseBuffer,INDICATOR_DATA);
   SetIndexBuffer(7,BodyColorBuffer,INDICATOR_COLOR_INDEX);
   
//---
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- sets first bar from what index will be drawn
   IndicatorSetString(INDICATOR_SHORTNAME,"Heiken Ashi");
//--- sets drawing line empty value
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   
   CType = CandleType;  
   CTypeOld = CType; 
      
   
//--- Colors and Widths

   if (CandleType == 1)             //HA
   {
      ShadowUpC = ShadowUpColor;
      ShadowDnC = ShadowDnColor;
      BodyUpC = BodyUpColor;
      BodyDnC = BodyDnColor;
      BodyW = BodyWidth;
      
      // Wicks
      PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);   
      PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);
      PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,ShadowUpC);
      PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,ShadowDnC);
   
      // Bodies
      PlotIndexSetInteger(1,PLOT_LINE_WIDTH,2); 
      PlotIndexSetInteger(1,PLOT_COLOR_INDEXES,2);
      PlotIndexSetInteger(1,PLOT_LINE_COLOR,0,BodyUpC);
      PlotIndexSetInteger(1,PLOT_LINE_COLOR,1,BodyDnC); 
   
      //--- Chart Properties
      ChartSetInteger(0,CHART_COLOR_CHART_UP,clrNONE);
      ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,clrNONE);
      ChartSetInteger(0,CHART_COLOR_CHART_DOWN,clrNONE);
      ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,clrNONE);
      ChartSetInteger(0,CHART_MODE,CHART_CANDLES);
   
   }
   
   if (CandleType == 3)             //Japanese
   {
      ShadowUpC = clrLime;
      ShadowDnC = clrRed;
      BodyUpC = clrLime;
      BodyDnC = clrRed;
      BodyW = BodyWidth;
      
      // Wicks
      PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);   
      PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);
      PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,ShadowUpC);
      PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,ShadowDnC);
   
      // Bodies
      PlotIndexSetInteger(1,PLOT_LINE_WIDTH,2); 
      PlotIndexSetInteger(1,PLOT_COLOR_INDEXES,2);
      PlotIndexSetInteger(1,PLOT_LINE_COLOR,0,BodyUpC);
      PlotIndexSetInteger(1,PLOT_LINE_COLOR,1,BodyDnC); 
   
      //--- Chart Properties
      ChartSetInteger(0,CHART_COLOR_CHART_UP,clrNONE);
      ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,clrNONE);
      ChartSetInteger(0,CHART_COLOR_CHART_DOWN,clrNONE);
      ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,clrNONE);
      ChartSetInteger(0,CHART_MODE,CHART_CANDLES);
   
   }
   
   if (CandleType == 2)             //Overlay
   {
      ShadowUpC = clrNONE;
      ShadowDnC = clrNONE;
      BodyUpC = BodyUpColor;
      BodyDnC = BodyDnColor;
      BodyW = 3;
 
      // Wicks
      PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);   
      PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);
      PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,ShadowUpC);
      PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,ShadowDnC);
   
      // Bodies
      PlotIndexSetInteger(1,PLOT_LINE_WIDTH,2); 
      PlotIndexSetInteger(1,PLOT_COLOR_INDEXES,2);
      PlotIndexSetInteger(1,PLOT_LINE_COLOR,0,BodyUpC);
      PlotIndexSetInteger(1,PLOT_LINE_COLOR,1,BodyDnC); 
   
      //--- Chart Properties
      ChartSetInteger(0,CHART_MODE,CHART_BARS);
      ChartSetInteger(0,CHART_COLOR_CHART_UP,ShadowUpColor);
      ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,clrNONE);
      ChartSetInteger(0,CHART_COLOR_CHART_DOWN,ShadowDnColor);
      ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,clrNONE);
      ChartSetInteger(0,CHART_FOREGROUND,true);
      
   }    
  
//--- initialization done
  }
  
  
  

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void Ondeinit()
{
   //--- Re-set Chart Properties
   ChartSetInteger(0,CHART_MODE,CHART_CANDLES);
   ChartSetInteger(0,CHART_COLOR_CHART_UP,clrLime);
   ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,clrBlack);
   ChartSetInteger(0,CHART_COLOR_CHART_DOWN,clrLime);
   ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,clrWhite);
   
     
}  
  

//+------------------------------------------------------------------+
//| Chart events                                                     |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,         // Event identifier  
                  const long& lparam,   // Event parameter of long type
                  const double& dparam, // Event parameter of double type
                  const string& sparam  // Event parameter of string type
                  )
{


//--- the key has been pressed
   if(id==CHARTEVENT_KEYDOWN)
   {
      switch(int(lparam))
        {
         case KEY_UP:   
            CType += 1;
            if (CType > 3) CType = 1;
            break;
         case KEY_DOWN:
            CType -= 1;
            if (CType < 1) CType = 3;
            break;
        }
   }     
        
   if (CType == 1)             //HA
   {
      ShadowUpC = ShadowUpColor;
      ShadowDnC = ShadowDnColor;
      BodyUpC = BodyUpColor;
      BodyDnC = BodyDnColor;
      BodyW = BodyWidth;
      
      // Wicks
      PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);   
      PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);
      PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,ShadowUpC);
      PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,ShadowDnC);
   
      // Bodies
      PlotIndexSetInteger(1,PLOT_LINE_WIDTH,2); 
      PlotIndexSetInteger(1,PLOT_COLOR_INDEXES,2);
      PlotIndexSetInteger(1,PLOT_LINE_COLOR,0,BodyUpC);
      PlotIndexSetInteger(1,PLOT_LINE_COLOR,1,BodyDnC); 
   
      //--- Chart Properties
      ChartSetInteger(0,CHART_COLOR_CHART_UP,clrNONE);
      ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,clrNONE);
      ChartSetInteger(0,CHART_COLOR_CHART_DOWN,clrNONE);
      ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,clrNONE);
      ChartSetInteger(0,CHART_MODE,CHART_CANDLES);
   
   }
   
   if (CType == 3)             //Japanese
   {
      ShadowUpC = clrLime;
      ShadowDnC = clrRed;
      BodyUpC = clrLime;
      BodyDnC = clrRed;
      BodyW = BodyWidth;
      
      // Wicks
      PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);   
      PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);
      PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,ShadowUpC);
      PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,ShadowDnC);
   
      // Bodies
      PlotIndexSetInteger(1,PLOT_LINE_WIDTH,2); 
      PlotIndexSetInteger(1,PLOT_COLOR_INDEXES,2);
      PlotIndexSetInteger(1,PLOT_LINE_COLOR,0,BodyUpC);
      PlotIndexSetInteger(1,PLOT_LINE_COLOR,1,BodyDnC); 
   
      //--- Chart Properties
      ChartSetInteger(0,CHART_COLOR_CHART_UP,clrNONE);
      ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,clrNONE);
      ChartSetInteger(0,CHART_COLOR_CHART_DOWN,clrNONE);
      ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,clrNONE);
      ChartSetInteger(0,CHART_MODE,CHART_CANDLES);
   
   }
   
   if (CType == 2)             //Overlay
   {
      ShadowUpC = clrNONE;
      ShadowDnC = clrNONE;
      BodyUpC = BodyUpColor;
      BodyDnC = BodyDnColor;
      BodyW = 3;
 
      // Wicks
      PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);   
      PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);
      PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,ShadowUpC);
      PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,ShadowDnC);
   
      // Bodies
      PlotIndexSetInteger(1,PLOT_LINE_WIDTH,2); 
      PlotIndexSetInteger(1,PLOT_COLOR_INDEXES,2);
      PlotIndexSetInteger(1,PLOT_LINE_COLOR,0,BodyUpC);
      PlotIndexSetInteger(1,PLOT_LINE_COLOR,1,BodyDnC); 
   
      //--- Chart Properties
      ChartSetInteger(0,CHART_MODE,CHART_BARS);
      ChartSetInteger(0,CHART_COLOR_CHART_UP,ShadowUpColor);
      ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,clrNONE);
      ChartSetInteger(0,CHART_COLOR_CHART_DOWN,ShadowDnColor);
      ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,clrNONE);
      ChartSetInteger(0,CHART_FOREGROUND,true);
   }  
   ChartRedraw();
   

}
  
//+------------------------------------------------------------------+
//| Heiken Ashi                                                      |
//+------------------------------------------------------------------+
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 i,limit;
//--- preliminary calculations
   if(prev_calculated == 0 || (CType != CTypeOld))
   {
      //--- set first candle
      OpenBuffer[0]     = open[0];
      HighBuffer[0]     = high[0];
      LowBuffer[0]      = low[0];
      CloseBuffer[0]    = close[0];
      BodyOpenBuffer[0] = open[0];
      BodyCloseBuffer[0]= close[0];
      limit = 1;
      CTypeOld = CType;
   }
   else limit = prev_calculated - 1;

//--- the main loop of calculations
   for(i = limit; i < rates_total && !IsStopped(); i++)
   {
      double haOpen  = (BodyOpenBuffer[i - 1] + BodyCloseBuffer[i - 1]) / 2;
      double haClose = (open[i] + high[i] + low[i] + close[i]) / 4;
      double haHigh  = MathMax(high[i], MathMax(haOpen, haClose));
      double haLow   = MathMin(low[i], MathMin(haOpen, haClose));

      if (CType == 1 || CType == 2)
      {
         BodyOpenBuffer[i] = haOpen;
         BodyCloseBuffer[i]= haClose;
      
         OpenBuffer[i]     = open[i];
         HighBuffer[i]     = haHigh;
         LowBuffer[i]      = haLow;
         CloseBuffer[i]    = close[i];
      }
      else
      {
         BodyOpenBuffer[i] = open[i];
         BodyCloseBuffer[i]= close[i];
      
         OpenBuffer[i]     = open[i];
         HighBuffer[i]     = high[i];
         LowBuffer[i]      = low[i];
         CloseBuffer[i]    = close[i];
      }   
      

      //--- set candle color
      if(haOpen<haClose) {BodyColorBuffer[i]=0.0; WickColorBuffer[i]=0.0;}   // set color DodgerBlue
      else               {BodyColorBuffer[i]=1.0; WickColorBuffer[i]=1.0;}  // set color Red
     }
     
     long scale = ChartGetInteger(0,CHART_SCALE,0);
     if (scale == 5) PlotIndexSetInteger(1,PLOT_LINE_WIDTH,BodyW + 2); else PlotIndexSetInteger(1,PLOT_LINE_WIDTH,BodyW);

     
     
//--- done
   return(rates_total);
  }
//+------------------------------------------------------------------+


