How do candles get their colour?

 

It's probably too simple for words, but I can't figure out how these code snippets work...

SetIndexStyle(0,DRAW_HISTOGRAM, 0, BodyWidth, BlueZone);
SetIndexBuffer(0, ExtMapBuffer1);

SetIndexStyle(1,DRAW_HISTOGRAM, 0, BodyWidth, RedZone);
SetIndexBuffer(1, ExtMapBuffer2);
.
.
.
if(ZTOpen>ZTClose)                 // bear
{
   ExtMapBuffer1[i] = ZTOpen;      // this gets painted red from top (open) to bottom (close)
   ExtMapBuffer2[i] = ZTClose;     // ExtMapBuffer1 is blue, ExtMapBuffer2 is red
}
if(ZTOpen<ZTClose)                 // bull
{
   ExtMapBuffer1[i] = ZTClose;     // this gets painted blue from top (close) to bottom (open)
   ExtMapBuffer2[i] = ZTOpen;
}
Would someone please explain the mechanics of DRAW_HISTOGRAM?
 
Aren't the colours are BlueZone and RedZone ?
 
Hi Helmut, You can think of it this way. Two histograms (ExtMapBuffer1 &2) are plotted one on top of the other. When the open is on the bottom it reveal the other histogram underneath
 
cameofx:
Hi Helmut, You can think of it this way. Two histograms (ExtMapBuffer1 &2) are plotted one on top of the other. When the open is on the bottom it reveal the other histogram underneath
Thank you, cameofx, so what gets set to the bottom governs what shows? But in each case, the top value is set to ExtMapBuffer1 (either open or close), and the bottom value is set to the other, so why does it paint one red and the other blue? Yes, fxcourt, BlueZone is blue and RedZone is red.
 
engcomp:
Thank you, cameofx, so what gets set to the bottom governs what shows? But in each case, the top value is set to ExtMapBuffer1 (either open or close), and the bottom value is set to the other, so why does it paint one red and the other blue? Yes, fxcourt, BlueZone is blue and RedZone is red.

I think that the piece of information which you are missing is this:

The drawing mode of DRAW_HISTOGRAM having been applied to the main window indicator has its special features, as well. A histogram is drawn between corresponding values of two index arrays.

Should be mentioned in the language specification, but isn't. Instead, the above quote was taken from this article: https://www.mql5.com/en/articles/1497. In other words, if you use DRAW_HISTOGRAM in the main chart window, rather than a sub-window, then you automatically get a floating histogram based on two buffer values.

 
jjc:

I think that the piece of information which you are missing is this:

The drawing mode of DRAW_HISTOGRAM having been applied to the main window indicator has its special features, as well. A histogram is drawn between corresponding values of two index arrays.

Should be mentioned in the language specification, but isn't. Instead, the above quote was taken from this article: https://www.mql5.com/en/articles/1497. In other words, if you use DRAW_HISTOGRAM in the main chart window, rather than a sub-window, then you automatically get a floating histogram based on two buffer values.



jjc, that was certainly the piece I was missing. I bookmarked the article because it will take some time for me to digest it. Thank you for the lead, Helmut.

 

Thank you, cameofx, so what gets set to the bottom governs what shows? But in each case, the top value is set to ExtMapBuffer1 (either open or close), and the bottom value is set to the other, so why does it paint one red and the other blue? Yes, fxcourt, BlueZone is blue and RedZone is red.

Jjc's referral is certainly useful as the explanation of the feature. But as you and others, I also have been intrigued by how the code's mechanic worked. So I rearranged the order of the variables without changing the principal value assignment to get a better view of it. 

We all know that Open price is fixed and the Close is floating till new candle begins. Doesn't matter also if Open is not fixed; it is just our point of reference.  

SetIndexStyle(0,DRAW_HISTOGRAM, 0, BodyWidth, BlueZone);
SetIndexBuffer(0, ExtMapBuffer1);

SetIndexStyle(1,DRAW_HISTOGRAM, 0, BodyWidth, RedZone);
SetIndexBuffer(1, ExtMapBuffer2);


if(ZTClose < ZTOpen)                 // bear
{
   ExtMapBuffer1[i] = ZTOpen;      // this gets painted red from top (open) to bottom (close)
   ExtMapBuffer2[i] = ZTClose;     // ExtMapBuffer1 is blue, ExtMapBuffer2 is red
}
if(ZTClose > ZTOpen)                 // bull
{
   ExtMapBuffer2[i] = ZTOpen;
   ExtMapBuffer1[i] = ZTClose;     // this gets painted blue from top (close) to bottom (open)

}

e.g. ZTOpen = 1.3075 ; ZTClose is currently 1.3090 -- higher than ZTOpen so bull bracket is fulfilled

ExtMapBuffer1 = 1.3090;
ExtMapBuffer2 = 1.3075;

      ZTOpen = 1.3075 ; ZTClose is currently 1.3020 -- lower than ZTOpen so bear bracket is fulfilled

ExtMapBuffer1 = 1.3075;
ExtMapBuffer2 = 1.3020;  

you can draw your own conclusion from this. I have regarded histogram pair candle drawing on main chart as flipping it also in other post. FWIW. 

 
cameofx:

you can draw your own conclusion from this. I have regarded histogram pair candle drawing on main chart as flipping it also in other post. FWIW.

It's interesting that your "post" refers to Heiken Ashi because my example was taken from Heiken Ashi Zone Trade.

The code obviously works but I still have a problem getting my mind around the question "why?" But I'll get it eventually.

In "post" you say...

if( prev_average of buf_3_&_buf_4 < current_price_average )
{ use haLow as the top price & use haHigh as the bottom price }  // this would have the effect of flipping the histogram pair to the opposite color 
else
{ use haHigh as the top price & haLow as the bottom price }
...but above the high price always goes into buffer 1 and the low price into buffer 2, so how do they know to paint one red and the other blue?
 
engcomp:

It's interesting that your "post" refers to Heiken Ashi because my example was taken from Heiken Ashi Zone Trade. [...]

In "post" you say... but above the high price always goes into buffer 1 and the low price into buffer 2, so how do they know to paint one red and the other blue?

Well Heiken ashi for one is convenient to draw on main chart with DRAW_HISTOGRAM (won't work on separate window). 

I've changed again the arrangement above to illustrate the histogram pair moving on chart. Imagine this sequence of event : 

 

ExtMapBuffer1 = 1.3090;  // Bull candle body is forming; the histogram is colored blue (ExtMapBufer1 was assigned blue color. So it make sense)
ExtMapBuffer2 = 1.3075;  // imagine it floating from 1.3090 to 1.3080 ... to 90 again ...(color is still blue)

ExtMapBuffer1 = 1.3075;  // and now it's drop to 75 the same as the open price of ExtMapBuffer2;  
ExtMapBuffer2 = 1.3075;  // We have ourselves a Doji body;

ExtMapBuffer1 = 1.3075;  // now imagine close price drop pass 75 to 20; bear condition is fulfilled the ExtMapBuffer1 stayed/stucked at 75
ExtMapBuffer2 = 1.3020;  // while ExtMapBuffer2 which previously was stucked at 75 now is able to elongate to 20 and show its assigned color of red. 

 

That's the best I can come up with. MT developer who designed it obviously have the definitive answer. 

Btw, if it's dead equal doji, no color will be shown;
which probably explains why the candle setup on F8 needs Line graph to be given color of choice as well.  

 
cameofx:

Well Heiken ashi for one is convenient to draw on main chart with DRAW_HISTOGRAM (won't work on separate window).

I've changed again the arrangement above to illustrate the histogram pair moving on chart. Imagine this sequence of event :

ExtMapBuffer1 = 1.3090; // Bull candle body is forming; the histogram is colored blue (ExtMapBufer1 was assigned blue color. So it make sense)
ExtMapBuffer2 = 1.3075; // imagine it floating from 1.3090 to 1.3080 ... to 90 again ...(color is still blue)

ExtMapBuffer1 = 1.3075; // and now it's drop to 75 the same as the open price of ExtMapBuffer2;
ExtMapBuffer2 = 1.3075; // We have ourselves a Doji body;

ExtMapBuffer1 = 1.3075; // now imagine close price drop pass 75 to 20; bear condition is fulfilled the ExtMapBuffer1 stayed/stucked at 75
ExtMapBuffer2 = 1.3020; // while ExtMapBuffer2 which previously was stucked at 75 now is able to elongate to 20 and show its assigned color of red.

That's the best I can come up with. MT developer who designed it obviously have the definitive answer.

Btw, if it's dead equal doji, no color will be shown;
which probably explains why the candle setup on F8 needs Line graph to be given color of choice as well.

Here is the complete Heiken Ashi code as published by MetaTrader. The body is in buffers 3 (open) and 4 (close).

What you say, I think, is this: the body gets the colour of the buffer with the larger value, red (bear) if 3>4 and white (bull) if 4>3.

For the shadow, we must test open v close and put the larger value (the High) into buffer 2 (white) if bull or buffer 1 (red) if bear.

This rule of painting the floating bar with the colour of the buffer that holds the larger value must be built into DRAW_HISTOGRAM

So if you want to use Heiken Ashi in an EA you have to read buffers 1 and 2 to see which holds the larger value.

Thank you for sorting out my mind on this question.

//+------------------------------------------------------------------+
//|                                                  Heiken Ashi.mq4 |
//|                      Copyright c 2004, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
//| For Heiken Ashi we recommend next chart settings ( press F8 or   |
//| select on menu 'Charts'->'Properties...'):                       |
//|  - On 'Color' Tab select 'Black' for 'Line Graph'                |
//|  - On 'Common' Tab disable 'Chart on Foreground' checkbox and    |
//|    select 'Line Chart' radiobutton                               |
//+------------------------------------------------------------------+
#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

//----
extern color color1 = Red;
extern color color2 = White;
extern color color3 = Red;
extern color color4 = White;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
//----
int ExtCountedBars=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//|------------------------------------------------------------------|
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_HISTOGRAM, 0, 1, color1);
   SetIndexBuffer(0, ExtMapBuffer1);
   SetIndexStyle(1,DRAW_HISTOGRAM, 0, 1, color2);
   SetIndexBuffer(1, ExtMapBuffer2);
   SetIndexStyle(2,DRAW_HISTOGRAM, 0, 3, color3);
   SetIndexBuffer(2, ExtMapBuffer3);
   SetIndexStyle(3,DRAW_HISTOGRAM, 0, 3, color4);
   SetIndexBuffer(3, ExtMapBuffer4);
//----
   SetIndexDrawBegin(0,10);
   SetIndexDrawBegin(1,10);
   SetIndexDrawBegin(2,10);
   SetIndexDrawBegin(3,10);
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexBuffer(1,ExtMapBuffer2);
   SetIndexBuffer(2,ExtMapBuffer3);
   SetIndexBuffer(3,ExtMapBuffer4);
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- TODO: add your code here
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   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)
     {
      haOpen=(ExtMapBuffer3[pos+1]+ExtMapBuffer4[pos+1])/2;
      haClose=(Open[pos]+High[pos]+Low[pos]+Close[pos])/4;
      haHigh=MathMax(High[pos], MathMax(haOpen, haClose));
      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;
           pos--;
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+
 

cameofx:

Btw, if it's dead equal doji, no color will be shown;


I think a Doji gets the bear colour.

      if (haOpen<haClose) // bull
       {
         ExtMapBuffer1[pos]=haLow;
         ExtMapBuffer2[pos]=haHigh;
        } 
      else                // bear
        {
         ExtMapBuffer1[pos]=haHigh;
         ExtMapBuffer2[pos]=haLow;
        } 
Reason: