Download MetaTrader 5

Drawing Short Horizontal Lines

To add comments, please log in or register
sd59
499
sd59  

 am trying to draw short horizontal lines that form part of a 'cross' on charts using the OBJ_TREND function.

void DrawLines(double price, int tf, color col)
{
 datetime time_zero = iTime(NULL,tf,bar);                //bar is global
 int barshift_zero = iBarShift(NULL,0,time_zero);
 datetime time_shift_minus = Time[barshift_zero + 20];   //add 20 bars to create line length to the left of centre of cross
 datetime time_shift_plus = (time_zero+(time_zero - time_shift_minus));    //create line length to right of centre of cross
  
 ObjectCreate("h4time",OBJ_TREND,0,time_shift_plus,price,time_shift_minus,price);
 ObjectSet("h4time",OBJPROP_COLOR,col);
 ObjectSet("h4time",OBJPROP_WIDTH,2); 
 ObjectSet("h4time",OBJPROP_STYLE,STYLE_DASHDOT);
 ObjectSet("h4time", OBJPROP_RAY,false);  
 
 WindowRedraw();
 
 return;

 This code creates this:

 

I have left out the code to draw the vertical part of the cross for ease. You can see that the line to the right of centre is not the same length as the line to the left due to 'Weekend' time bars - i.e the scale is not linear!!!!

This is on the 4 hour chart. If the 30M chart is chosen there is no problem because the scale becomes more linear relative to the time being added to create the new line (although this also could be better - see below).

 

I know I can convert Price/Time to X,Y coords but as far as I understand there is no function to draw a short horizontal line using only coordinates.

Any ideas please?

thanks 

Carl Schreiber
6692
Carl Schreiber  

hmm - you just have to calculate the middle of the cross correctly:

int idxMiddle = (idxBarEndOfHorLine+idxBegOfHorLine)/2 // =>  find a solution for 0.5 outcomes
datetime tmeMiddle = Time[idxMiddle];

sd59
499
sd59  
gooly:

hmm - you just have to calculate the middle of the cross correctly:


This is my fault for not explaining fully and putting in full code but the centre of the cross is the first point calculated - this is the key Time/Date point - the lines are just for show and emphasis. The vertical line is easy and consistent because the time scale is linear. My code above calculates a 20 bar (random) time span to the left and adds the same time span (in seconds) to form the right hand side of the cross. It's very frustrating that MQL cannot just use the OBJ_HLINE function properly which of course has a time/price variable input but makes no difference and draws the line across the whole chart!!

Anyway, the reason it doesn't work with the code I am using is because the bars are drawn as 4 hours bars but at weekends there is a 2 day gap between bars.  

Carl Schreiber
6692
Carl Schreiber  

".. 4 hours bars but at weekends there is a 2 day gap between bars" - that bars don't have a weekend gap!

why do you

1) add 20 bars (to the left) but

2) do not subtract 20 bars for the other side (right)?

that would give you 20 Bars to the left and 20 to the right?
sd59
499
sd59  
datetime time_shift_minus = Time[barshift_zero - 20]; 

This does not work if the line projects beyond Time[0] - you get an error "array out of range" because you cannot have Time[-1].

The 20 bars is arbitrary it can be anything depending on how long you want the line to be. I work out the line length to the left in seconds (difference in time between centre of cross and 20 bars away) and add the same amount of seconds to the right side. Bars do have a weekend gap! Use your cursor and move through a range and you will see at some stage the day will jump by 2 days  i.e from Friday to Sunday night when the market opens.

Keith Watford
Moderator
9641
Keith Watford  

You have to reset the 2nd time value at every new bar

Use iBarShift to find the center of the cross

if you find that eg. 15 bars have been drawn to the left of the current bar, you then know that another 5 need to be drawn.

So you set the 2nd time value as Time[0] + 5*PeriodSeconds() 

 

Edit: you can reduce the checking by restricting it to when Bar [0] is a Sunday/Monday and Bar[1] is a Friday 

sd59
499
sd59  

It' useful to know there is a PeriodSeconds() function I don't think this was available previously! (old MT4).

I'm not sure you are completely correct but you have given me an idea which I will need to try. We have to ignore the fact that I have drawn a 'cross' - as I mentioned it is just for emphasis and in fact forget completely about the vertical line.

The starting point is literally a 'point' i.e Time[5]/1.1234 (time/price coordinate). The challenge is to draw a short horizontal line that extends either side of that point equally for all timeframes (for aesthetic effect).

If you count 'X' seconds to the left even using PeriodSeconds() all it does is convert 'X' Bars to seconds. If there is a weekend in the time span being calculated but there isn't on the right hand side of the starting point the whole thing becomes

non-linear. i.e the line will be longer on the right because the 'seconds' are not being chewed up by a 'weekend'. 

I think I understand what you are saying which is to check how many weekends (weekend Bars) there are either side of the starting point and compensate accordingly. This might work but is a real drag for just drawing a line!!

Why isn't there a function that allows you to draw a line like this using coordinates? Completely independent of time? 

Keith Watford
Moderator
9641
Keith Watford  

"Why isn't there a function that allows you to draw a line like this using coordinates? Completely independent of time? "

Draw a rectangle label just a few pixels wide. 

sd59
499
sd59  

good idea, might do that! I still have to ask the question why MQL can't do this but for just a simple line?

thanks

Alain Verleyen
Moderator
31186
Alain Verleyen  
sd59:

...

Why isn't there a function that allows you to draw a line like this using coordinates? Completely independent of time?

#include <Canvas\canvas.mqh>
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   CCanvas canvas;
   
   canvas.CreateBitmapLabel(0,0,"Test",0,0,500,500,COLOR_FORMAT_ARGB_NORMALIZE);
   canvas.LineHorizontal(100,200,150,ColorToARGB(clrRed));
   canvas.LineVertical(150,100,200,ColorToARGB(clrRed));
   canvas.Update();
  }
sd59
499
sd59  
Sorry, what is this? MQL?
123
To add comments, please log in or register