Download MetaTrader 5

Question about OBJPROP_TIMEFRAMES

To add comments, please log in or register
mar
1147
mar  

Hi,

I made a small script which should tell me if a horizontal line is visible in the current timeframe. The line I plotted is only visible on H1 but whatever timeframe I choose I always get "true" as a response.  I doubt that bool is the correct initialization because there are no timeframe-flags as a result. Can someone help? Thanks!!

void OnStart()
  {
//---
   bool lineVisible = ObjectGet("test", OBJPROP_TIMEFRAMES);
   Alert(lineVisible);
  }
whroeder1
15304
whroeder1  
mar: I always get "true" as a response.

OBJPROP_TIMEFRAMES

15

int

Value can be one or combination (bitwise addition) of object visibility constants to set/get timeframe object property

PROP_TIMEFRAMES returns a bitmask 1=M1, 2=M5, 64=D1... Since it is visible, the int value is non-zero and non-zero is "always" true
Keith Watford
Moderator
10359
Keith Watford  

I don't know if this is the best way to do it.

I've only tested it a little, so please give it a try

void OnStart()
  {
   bool lineVisible=false;
   if( ObjectFind(0,"test")<0)
     {
      lineVisible=false;
      Print(lineVisible);
      return;
     }
   int obj_timeframe=(int)ObjectGet("test",OBJPROP_TIMEFRAMES);
   if(obj_timeframe==0)
     {
      lineVisible=true;
      Print(lineVisible);
      return;
     }

   if(Period()==PERIOD_MN1)
     {
      if(obj_timeframe>255)
         lineVisible=true;
     }
   else
     {
      int y=0;
      switch(Period())
        {
         case PERIOD_M1:  y=7;  break;
         case PERIOD_M5:  y=6;  break;
         case PERIOD_M15: y=5;  break;
         case PERIOD_M30: y=4;  break;
         case PERIOD_H1:  y=3;  break;
         case PERIOD_H4:  y=2;  break;
         case PERIOD_D1:  y=1;  break;
         case PERIOD_W1:  y=0;  break;
        }

      uchar x=(uchar)obj_timeframe;
      x=(uchar)(x<<y);
      if(x>127)
         lineVisible=true;
     }
   Print(lineVisible);

  }
//+------------------------------------------------------------------+
mar
1147
mar  

Hey guys, thanks for the help!

GumRai, it works perfect! I try to figure out why you separate the monthly from the other timeframes and what the part with uchar means. I think that it because of the bitmask but I want to figure out what exactly it does. Pretty crazy that so much coding is necessary just to check if an object is visible in a particular timeframe.

Keith Watford
Moderator
10359
Keith Watford  
mar:

Hey guys, thanks for the help!

GumRai, it works perfect! I try to figure out why you separate the monthly from the other timeframes and what the part with uchar means. I think that it because of the bitmask but I want to figure out what exactly it does. Pretty crazy that so much coding is necessary just to check if an object is visible in a particular timeframe.

I did it that way as I have no clue how to work with hexadecimal numbers

uchar is a single byte and can only hold 8 timeframes and if it is visible on the monthly tf

ObjectGet("test",OBJPROP_TIMEFRAMES)

 will exceed the maximum value (255) that can be stored in a byte.

As I said, it may not be the best way to do it, but it seemed an interesting puzzle and I enjoyed trying to solve it within my knowledge boundaries. 

honest_knave
Moderator
2373
honest_knave  
Nicely done GumRai.
Keith Watford
Moderator
10359
Keith Watford  
honest_knave:
Nicely done GumRai.

Thank you,

that's a really nice comment :) 

mar
1147
mar  

If it is the best way to do it or not, it works perfect for me. And thank you for the explanation. :)

Maybe WHRoeder could show how to do it with hexadecimal values that you can also profit from this thread. 

Keith Watford
Moderator
10359
Keith Watford  
mar:

If it is the best way to do it or not, it works perfect for me. And thank you for the explanation. :)

Maybe WHRoeder could show how to do it with hexadecimal values that you can also profit from this thread. 

I already benefited from this thread. I had to think about how to apply my knowledge to solve the problem. It made such a nice change from most queries that have been repeated so many times.
Alain Verleyen
Moderator
31972
Alain Verleyen  

Just for fun.

By the way I found 2 bugs in the process, see comments (first one already found by Gumrai)

input string   objname="test";
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   long objTimeframes=0;
   ENUM_TIMEFRAMES period=(ENUM_TIMEFRAMES)Period();

//--- Get visibility property of the object
   if(ObjectGetInteger(0,"test",OBJPROP_TIMEFRAMES,0,objTimeframes))
     {
      long mask=-1;
      //--- set mask from period
      switch(period)
        {
         case PERIOD_M1 : mask=0x0001; break;         // The object is drawn in 1-minute chart
         case PERIOD_M5 : mask=0x0002; break;         // The object is drawn in 5-minute chart
         case PERIOD_M15: mask=0x0004; break;         // The object is drawn in 15-minute chart
         case PERIOD_M30: mask=0x0008; break;         // The object is drawn in 30-minute chart
         case PERIOD_H1 : mask=0x0010; break;         // The object is drawn in 1-hour chart
         case PERIOD_H4 : mask=0x0020; break;         // The object is drawn in 4-hour chart
         case PERIOD_D1 : mask=0x0040; break;         // The object is drawn in day charts
         case PERIOD_W1 : mask=0x0080; break;         // The object is drawn in week charts
         case PERIOD_MN1: mask=0x0100; break;         // The object is drawn in month charts     
         default:
            break;
        }
      //--- check mask. Special cases : 
      //---    1° BUG 1: if "Show on all timeframes" is enabled, objTimeframes=0 is returned and not '0x01ff' as stated in documentation.
      //---    2° BUG 2: it's not possible with MT4 to disable "Show on all timeframes" without enabled at least 1 period ;
      //---              but it's possible to set it to -1 with mql4. In this case, MT4 object properties window will display erroneously "Show on all timeframes" enabled.
      if(objTimeframes==0 || (objTimeframes!=-1 && (objTimeframes&mask)==mask))
        {
         printf("Object %s is visible on this chart %s",objname,EnumToString(period));
        }
      else
        {
         printf("Object %s exists but is not visible on this chart %s",objname,EnumToString(period));
        }
     }
//--- ObjectGetInteger error processing
   else
     {
      int err=GetLastError();
      if(err==ERR_OBJECT_DOES_NOT_EXIST)
        {
         printf("Object %s doesn't exist!",objname);
        }
      else
        {
         printf("Error(%i) whily getting properties of %s",err,objname);
        }
     }
  }
//+------------------------------------------------------------------+
Files:
66479_1.mq4 4 kb
whroeder1
15304
whroeder1  
  1. WHRoeder:

    OBJPROP_TIMEFRAMES

    15

    int

    Value can be one or combination (bitwise addition) of object visibility constants to set/get timeframe object property

    PROP_TIMEFRAMES returns a bitmask 1=M1, 2=M5, 64=D1... Since it is visible, the int value is non-zero and non-zero is "always" true

    GumRai: I did it that way as I have no clue how to work with hexadecimal numbers

    mar: Maybe WHRoeder could show how to do it with hexadecimal values that you can also profit from this thread. 
    int TFmask = ObjectGet("test",OBJPROP_TIMEFRAMES);
    if(TFmask & OBJ_PERIOD_H1 != 0) Print("Visible on H1");
    //        ^ Bitwise Operations - MQL4 Documentation
    

  2. Don't hard code numbers.
         switch(period)
            {
             case PERIOD_M1 : mask=0x0001; break;         // The object is drawn in 1-minute chart
             case PERIOD_M5 : mask=0x0002; break;         // The object is drawn in 5-minute chart
             case PERIOD_M15: mask=0x0004; break;         // The object is drawn in 15-minute chart
             case PERIOD_M30: mask=0x0008; break;         // The object is drawn in 30-minute chart
             case PERIOD_H1 : mask=0x0010; break;         // The object is drawn in 1-hour chart
             case PERIOD_H4 : mask=0x0020; break;         // The object is drawn in 4-hour chart
             case PERIOD_D1 : mask=0x0040; break;         // The object is drawn in day charts
             case PERIOD_W1 : mask=0x0080; break;         // The object is drawn in week charts
             case PERIOD_MN1: mask=0x0100; break;         // The object is drawn in month charts     
    
    Write self-documenting code.
    enum eTF         = { eTF_M1,        eTF_M5,        eTF_M15,        eTF_M30, 
                         eTF_H1,        eTF_H4,        eTF_D1,         eTF_W1,        eTF_MN1, 
                         eTF_COUNT }
    int periods[]    = { PERIOD_M1,     PERIOD_M5,     PERIOD,M15,     PERIOD_M30
                         PERIOD_H1,     PERIOD_H4,     PERIOD_D1,      PERIOD_W1,     PERIOD_MN1 }
    int visibility[] = { OBJ_PERIOD_M1, OBJ_PERIOD_M5, OBJ_PERIOD,M15, OBJ_PERIOD_M30
                         OBJ_PERIOD_H1, OBJ_PERIOD_H4, OBJ_PERIOD_D1,  OBJ_PERIOD_W1, OBJ_PERIOD_MN1 }
    int TfToPeriod(eTF tf){
       return periods[eTF];
    }
    eTF PeriodToTf(int period = PERIOD_CURRENT){
       if (period == PERIOD_CURRENT) period = _period;
       enum tf = eTF_M1; 
       while(periods[tf] != period) ++tf;
       return tf;
    }
    int PeriodToVisibility(int period = PERIOD_CURRENT){
       return visibility[ PeriodToTf(period) ];
    }
    
12
To add comments, please log in or register