Indicator is drawn in foreground on live chart but in background in the strategy tester

 

Hi All,

I use 

ChartSetInteger(0,CHART_FOREGROUND,true);

to have the candles (not filled with color) in the foreground. Then I add an indicator and then the algo is drawing stuff on the chart. In the strategy tester, the indicator is in the background and all objects I draw are in front of the indicator but of course behind the real candles as CHART_FOREGROUND is set to true. So everyting is as wished but if I add my EA to live chart, the added indicator is always drawn in front of all my other objects I add over time. For my objects I draw I use of course:

ObjectSetInteger(0,id_Label,OBJPROP_BACK,false);

So, I am wondering why I have different behaviour in strategy tester and on live chart?

Any ideas?

 

Could you post screenshots as I don't understand anything to your problem :-D

In what code is placed this CHART_FOREGROUND statement ? your EA ?

 

Hi Alain, sorry for not getting back to you earlier but after taking my EA live I decided to take a bigger break from all this stuff as my head was almost exploding at that time ;-)

Using screenshots, I try to explain my issue again:

The following screenshot is taken from Strategy Tester. The dark blue and dark red bars (not filled) are the normal OHLC bars. I use ChartSetInteger(0,CHART_FOREGROUND,true); to bring them to the front. Afterwards, I add the indicator which adds the filled blue and red bars. As can be seen, those bars are behind the normal OHLC candles. Then EA is running and price keeps moving and at certain points I draw different objects into the chart such as OBJ_TREND or OBJ_ARROW etc. using the option ObjectSetInteger(0,.....,OBJPROB_BACK,false); to bring those objects to the front otherwise, in particular small arrows, are printed behind the filled blue and red bars and cannot be seen. The screenshot also shows such a OBJ_TREND line in dark blue and dotted. And due to setting OBJPROP_BACK to false it is printed/added in front of the filled and the normal OHLC candles. So that is how it should work and this is how the Strategy Tester displays it.

Strategy Tester


Now, applying the same code/EA to live data (same broker and same account) and what happens is that the objects such as OBJ_TREND or OBJ_ARROW etc. are drawn behind the filled and the normal OHLC bars even though OBJPROB_BACK is set to false as it is the same code. Since I draw quite a descent amount of objects onto the chart to better understand what the EA is doing most of them are hidden behind the filled bars coming from the indicator as explained above and thus I do not see what is going on ;-)

Live Account

 
algotrader01:

Hi Alain, sorry for not getting back to you earlier but after taking my EA live I decided to take a bigger break from all this stuff as my head was almost exploding at that time ;-)

Using screenshots, I try to explain my issue again:

The following screenshot is taken from Strategy Tester. The dark blue and dark red bars (not filled) are the normal OHLC bars. I use ChartSetInteger(0,CHART_FOREGROUND,true); to bring them to the front. Afterwards, I add the indicator which adds the filled blue and red bars. As can be seen, those bars are behind the normal OHLC candles. Then EA is running and price keeps moving and at certain points I draw different objects into the chart such as OBJ_TREND or OBJ_ARROW etc. using the option ObjectSetInteger(0,.....,OBJPROB_BACK,false); to bring those objects to the front otherwise, in particular small arrows, are printed behind the filled blue and red bars and cannot be seen. The screenshot also shows such a OBJ_TREND line in dark blue and dotted. And due to setting OBJPROP_BACK to false it is printed/added in front of the filled and the normal OHLC candles. So that is how it should work and this is how the Strategy Tester displays it.


Now, applying the same code/EA to live data (same broker and same account) and what happens is that the objects such as OBJ_TREND or OBJ_ARROW etc. are drawn behind the filled and the normal OHLC bars even though OBJPROB_BACK is set to false as it is the same code. Since I draw quite a descent amount of objects onto the chart to better understand what the EA is doing most of them are hidden behind the filled bars coming from the indicator as explained above and thus I do not see what is going on ;-)

Now I understand the problem.

So you set the chart in the foreground and you are surprised to see your objects in the background ?

The problem is this function doesn't work in the Strategy Tester. (Bug or feature ?).

ChartSetInteger(0,CHART_FOREGROUND,true);

Fix your code.

 

Good morning Alain and thanks for your reply. 

I am not surprised to see the objects in the background. Since the normal OHLC candles are not filled or in other words they are transparent as only the frame of the candles is shown all other objects I add via code are drawn behind but are still visible because the OHLC candles are not filled. 

  1. In my OnInit() function I first set the chart settings such as ChartSetInteger(0,CHART_FOREGROUND,true);
  2. At the end of the OnInit() I add the indicator using the iCustom() function
  3. And then within the actual code after some time more objects such as OBJ_TREND or OBJ_ARROW are added with OBJPROB_BACK set to false

I thought the chart behaves kind of like a stack. If I draw an object at position x,y and afterwards I draw another object at the same position x,y it is put in front of the first object. If I add a third object at position x,y it will be put in front of the first two objects and so on. That is why I was thinking all objects should actually be drawn in front of the indicator producing the blue and red filled candlesticks as they are added later on in the code and as described in (2.) the indicator is already added at the end of the OnInit() function

And as shown in the first image, in the Strategy Tester this behaviour seems to work. All objects such as the trendlines, arrows etc. are always drawn in front of the filled red and blue bars and that is how I want it to be. However, of course, the normal OHLC candles always stay in the very front but since they are transparent/not filled you can still see all the other objects behind.


Apart from that, when in my code I comment out:

ChartSetInteger(0,CHART_FOREGROUND,true);

What happens is that the filled bars are printed in front of the normal OHLC candles and thus I see only parts of it:

tester2

So for me it seems that 

ChartSetInteger(0,CHART_FOREGROUND,true);

works in the Strategy Tester.

 
algotrader01:

Good morning Alain and thanks for your reply. 

I am not surprised to see the objects in the background. Since the normal OHLC candles are not filled or in other words they are transparent as only the frame of the candles is shown all other objects I add via code are drawn behind but are still visible because the OHLC candles are not filled. 

  1. In my OnInit() function I first set the chart settings such as ChartSetInteger(0,CHART_FOREGROUND,true);
  2. At the end of the OnInit() I add the indicator using the iCustom() function
  3. And then within the actual code after some time more objects such as OBJ_TREND or OBJ_ARROW are added with OBJPROB_BACK set to false

I thought the chart behaves kind of like a stack. If I draw an object at position x,y and afterwards I draw another object at the same position x,y it is put in front of the first object. If I add a third object at position x,y it will be put in front of the first two objects and so on. That is why I was thinking all objects should actually be drawn in front of the indicator producing the blue and red filled candlesticks as they are added later on in the code and as described in (2.) the indicator is already added at the end of the OnInit() function

And as shown in the first image, in the Strategy Tester this behaviour seems to work. All objects such as the trendlines, arrows etc. are always drawn in front of the filled red and blue bars and that is how I want it to be. However, of course, the normal OHLC candles always stay in the very front but since they are transparent/not filled you can still see all the other objects behind.


Apart from that, when in my code I comment out:

What happens is that the filled bars are printed in front of the normal OHLC candles and thus I see only parts of it:

So for me it seems that 

works in the Strategy Tester.

Theoretical assumptions again.

Please provide code to demonstrate your issue if you need coding help.

ChartSetInteger(0,CHART_FOREGROUND,true);

DOES NOT work correctly in the Strategy Tester (Build 2981).

 

I think I know now what is going on:

On live chart if you set chart to foreground it is applied to the chart itself as well as all indicators added to the main chart. so both are brought to the foreground moving my trendlines and arrows etc to the back.

In the Strategy Tester when you set chart to foreground it is only applied to the chart itself but not to the indicators. Since my normal OHLC bars are not filled I can see all objects as wished in the Strategy Tester. If this is now a bug in the tester or on the live chart I don't know but this is what is going on.

I have found this post at which you have also commented at:

https://www.mql5.com/en/forum/189037

Not sure if it is worth it to redraw the normal candles or the indicator bars or using CCanvas class as suggest by you. Maybe implementing a second indicator which draws bars that are not filled based on the normal OHLC values might do the trick but noch sure how to exactly do this.


EDIT:
I used the MQL5 indicator ColorBars and changed it to draw candlesticks using 

#property indicator_type1   DRAW_CANDLES

Unfortunately, you can only specify three different colors:

#property indicator_color1  clrWhite,clrGreen,clrRed

First color = colors of outlines and wicks

Second color = bullish candle body color

Third color = bearish candle body color

So it seems that it is not possible to color the outline/wicks of bearish and bullish candles in two different colors

Draw indicator behind chart
Draw indicator behind chart
  • 2017.04.02
  • www.mql5.com
Is it possible to draw an indicator (such as DRAW_BARS style) behind the chart rather than on top of it? I.e...
 

Hello, I have tried to rewrite the standard ColorBars indicator to only plot the outline/frame of the candlesticks and to change the color according to open>close and open<close. It works apart from that when I change the color using

PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,clrYellow);

it always changes the color of ALL candles and not only the one currently calculated. 

//+------------------------------------------------------------------+
//|                                                    ColorBars.mq5 |
//|                   Copyright 2009-2020, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009-2020, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"

#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots   1
//--- plot ColorBars
#property indicator_label1  "ColorBars"
#property indicator_type1   DRAW_CANDLES
#property indicator_color1  clrWhite,clrWhite,clrWhite
#property indicator_label1  "Open;High;Low;Close"
//--- indicator buffers
double ExtOpenBuffer[];
double ExtHighBuffer[];
double ExtLowBuffer[];
double ExtCloseBuffer[];
double ExtColorsBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicators
   SetIndexBuffer(0,ExtOpenBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,ExtHighBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,ExtLowBuffer,INDICATOR_DATA);
   SetIndexBuffer(3,ExtCloseBuffer,INDICATOR_DATA);
   SetIndexBuffer(4,ExtColorsBuffer,INDICATOR_COLOR_INDEX);
//--- don't show indicator data in DataWindow
   PlotIndexSetInteger(0,PLOT_SHOW_DATA,false);
//--- set accuracy
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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=0;
   bool candle_up=true;
//--- set position for beginning
   if(i<prev_calculated)
      i=prev_calculated-1;
//--- start calculations
   while(i<rates_total && !IsStopped())
   {  ExtOpenBuffer[i]=open[i];
      ExtHighBuffer[i]=high[i];
      ExtLowBuffer[i]=low[i];
      ExtCloseBuffer[i]=close[i];
      //--- determine volume change
      if(i>0)
      {  if(open[i]>=close[i-1])
            candle_up=true;
         else
            candle_up=false;
      }
      if(candle_up)
      {  PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,clrYellow);
         ExtColorsBuffer[i]=0.0;
      }
      else
      {  PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,clrPurple);
         Sleep(10000);
         ExtColorsBuffer[i]=0.0;
      }
      i++;
   }
//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+

I also had a look at the standard ColorCandlesDaily indicator but I think with "DRAW_COLOR_CANDLES" it is not possible to change the outline/frame of the candles but only the entire color of the candles. However here it works to change the color of single candles.


So to summarize what I am trying to achieve is to redraw the standard candlesticks to have the outline/frame/shade (whatever you wanna call it; in the chart options it is called Bar Up and Bar Down) drawn in different colors when open>clos and open<close as can bee seen in the screenshots above. For the candlestick fillings I would apply clrNone or clrWhite as I am having a white Backgroung.

Any ideas?

Discover new MetaTrader 5 opportunities with MQL5 community and services
Discover new MetaTrader 5 opportunities with MQL5 community and services
  • www.mql5.com
MQL5: language of trade strategies built-in the MetaTrader 5 Trading Platform, allows writing your own trading robots, technical indicators, scripts and libraries of functions
 

Sorry but I said you already 2 times it's the Strategy Tester which doesn't use the CHART_FOREGROUND statement correctly. If it's a bug, a feature or something not yet implemented I don't know, but it's a fact, on a live chart all is owrking as expected and documented. Still you are wondering which one is correct. I don't have time to lose with such things. When I answer on technical stuff, 99.9% of the time I know what I am talking about, you are free to take it or not of course. But if you don't take it, I am just not interested to continue losing my time.

I am 100% sure it's trivial to do it with objects. Doing it with buffers I am not sure as I never tried it, maybe you could use several plot instead of one if really needed. Using Canvas is an option but certainly not the most simple unless you have a "high-level" library already ready to do it, I will not go this way in your place.

I wish you good luck, you will certainly find a solution.

 
Alain Verleyen :

Sorry but I said you already 2 times it's the Strategy Tester which doesn't use the CHART_FOREGROUND statement correctly. ***

Have you checked the 'tester.tpl' chart template?

 

Hi Alain, I am sorry to read that you somehow feel annoyed/offended by my post(s). This was for sure not my intention. I also believe you that it is a bug. The intention of the post was only to explain the bug not to say it is none. Just outline it for otheres who are interested in. And then I just tried to find a solution for my issue presenting what I have tried and asking for any other ideas. Not more not less. I frequently use this forum to find solutions either asking myself or checking on already presented soltuions and I find it very very helpful in most of the cases. So again I am sorry if I somehow offended you in any way. Was not meant to be!


@Vladimir:

I haven't yet checked the tester template. I know what it is and used it once a couple of years ago but I will have a look at it to see if it can be of any help for me. Thanks for the hint. 


EDIT:

@Alain:

Sorry, I forgot to comment your suggestions. I thought of using OBJ_RECTANGLE but it needs two different timepoints otherwise it ends up being just a straight line. One could use OBJ_TREND but and increase thickness but then it is a filled line overlaying the indicator bars again. For now I do not have any other ideas using simple objects. I do not really understand what you mean with "maybe you could use several plot instead of one if really needed". If I use two buffers the second one will always paint over the other but probably you mean something different. Unfortunately, I haven't really used Canvas yet. I know you can create transparent objects...

@Vladimir:

Meanwhile I saved my chart setup into a .tpl file and had a look at it but it is not clear to me how this might be of any help? Could you explain your thoughts in more detail?


Thank you!