Why are MT5 ENUM_TIMEFRAMES strange?

 

In MT5, using Print(PERIOD_M1,PERIOD_M5, etc...), we get:

  • M1    1
  • M5    5
  • M15  15
  • M30  30
  • H1    16385
  • H4    16388
  • D1    16408
  • W1   32769
  • MN1  49153

In MT4, the ENUM constants were conveniently the minutes, but why have they chosen obscure constants for higher timeframes?

Chart Timeframes - MQL4 Documentation
  • docs.mql4.com
Chart Timeframes - MQL4 Documentation
 

I agree with you, the definition of these values in MT5 is a little strange.

I think it depends on the design. Let me decode these values:

1. minutes time frames:

   M1 = 0<<15+1, M5 = 0<<15+5, M15 = 0<<15+15, M30=0<<15+30

2. hours and days time frames:

   H1 = 1<<15+1, H4 = 1<<15+4, D1 = 1<<15+24

3. week time frame:

   W1 = 2<<15+1

4. month time frame:

   MN1 = 3<<15+1 

 
data46:

In MT5, using Print(PERIOD_M1,PERIOD_M5, etc...), we get:

  • M1    1
  • M5    5
  • M15  15
  • M30  30
  • H1    16385
  • H4    16388
  • D1    16408
  • W1   32769
  • MN1  49153

In MT4, the ENUM constants were conveniently the minutes, but why have they chosen obscure constants for higher timeframes?

There is no point to use the numeric values. What to do ?
 
Alain Verleyen:
There is no point to use the numeric values. What to do ?

Perhaps there is; what if I wanted to check timestamps:

if (tick.time != (rates[0].time + PERIOD_M5)) processNewCandle(); 

To state there's 'no point' seems like you're not embracing coding creativity.

I say this because using CopyRates or any derivative of that function such as CopyClose, CopyTime, etc absolutely hammers CPU. The fastest way to access data is using the MqlTick structure.

I presume CopyRates does a lot of processing in the background, such as checking raw files if the data exists and then polling the server to retrieve missing data. Caching tick data seems a way around this bottleneck, but there's not enough info in the MqlTick structure, as it's a pure sequential stream of data that has no concept of open, closes et al.

Hence my question was to somehow compare timestamps using MqlTick.

 
Jian Chen:

I agree with you, the definition of these values in MT5 is a little strange.

I think it depends on the design. Let me decode these values:

1. minutes time frames:

   M1 = 0<<15+1, M5 = 0<<15+5, M15 = 0<<15+15, M30=0<<15+30

2. hours and days time frames:

   H1 = 1<<15+1, H4 = 1<<15+4, D1 = 1<<15+24

3. week time frame:

   W1 = 2<<15+1

4. month time frame:

   MN1 = 3<<15+1 

Thanks for your reply Jian.

Is that a bitwise operation? I'm a simpleton and using numeric constants would be far more intuitive.

 
data46:

Perhaps there is; what if I wanted to check timestamps:

To state there's 'no point' seems like you're not embracing coding creativity.

There is no point to use the numeric values. Your code doesn't make sense even with MT4.

You probably need PeriodSeconds() function.

 
Alain Verleyen:

There is no point to use the numeric values. Your code doesn't make sense even with MT4.

You probably need PeriodSeconds() function.

My snippet was psuedo-code; thanks for the PeriodSeconds() function, I'll see if it fulfils my needs.
 
data46:

Perhaps there is; what if I wanted to check timestamps:

To state there's 'no point' seems like you're not embracing coding creativity.

I say this because using CopyRates or any derivative of that function such as CopyClose, CopyTime, etc absolutely hammers CPU. The fastest way to access data is using the MqlTick structure.

I presume CopyRates does a lot of processing in the background, such as checking raw files if the data exists and then polling the server to retrieve missing data. Caching tick data seems a way around this bottleneck, but there's not enough info in the MqlTick structure, as it's a pure sequential stream of data that has no concept of open, closes et al.

Hence my question was to somehow compare timestamps using MqlTick.

What makes more coding sense?  Using the constant name in your coding, or trying to use the values themselves?  I do not call doing that "coding creativity", I call that making the job harder than it has to be.  In programming (at least the courses I have taken) you use the constant name specifically because it is just that, a constant.  If you need to calculate values from that, it is easier to use the constant name in your equations.  I agree that the constant values need to be correct for what they are trying to figure out, but that is how MQL is working currently, apparently.
 
     if(Period() < PERIOD_MN1) { LabelPeriod = Period(); } else { LabelPeriod = PERIOD_MN1 + 10000 ; } 
     
     if(LabelPeriod == 16385) { LabelPeriod = 60 ; } else
     if(LabelPeriod == 16388) { LabelPeriod = 240 ; } else
     if(LabelPeriod == 16408) { LabelPeriod = 1440 ; } else 
     if(LabelPeriod == 32769) { LabelPeriod = 10080 ; } else 

     if(LabelPeriod == 49153) { LabelPeriod = 43200 ; } 


It is not elegant but it works.

Yes, I could use CASE.

I found this:


1. Chart Periods

In MQL5 chart period constants changed, and some new time periods (M2, M3, M4, M6, M10, M12, H2, H3, H6, H8, H12) were added. To convert MQL4 time periods you can use the following function:

ENUM_TIMEFRAMES TFMigrate(int tf)
  {
   switch(tf)
     {
      case 0: return(PERIOD_CURRENT);
      case 1: return(PERIOD_M1);
      case 5: return(PERIOD_M5);
      case 15: return(PERIOD_M15);
      case 30: return(PERIOD_M30);
      case 60: return(PERIOD_H1);
      case 240: return(PERIOD_H4);
      case 1440: return(PERIOD_D1);
      case 10080: return(PERIOD_W1);
      case 43200: return(PERIOD_MN1);
      
      case 2: return(PERIOD_M2);
      case 3: return(PERIOD_M3);
      case 4: return(PERIOD_M4);      
      case 6: return(PERIOD_M6);
      case 10: return(PERIOD_M10);
      case 12: return(PERIOD_M12);
      case 16385: return(PERIOD_H1);
      case 16386: return(PERIOD_H2);
      case 16387: return(PERIOD_H3);
      case 16388: return(PERIOD_H4);
      case 16390: return(PERIOD_H6);
      case 16392: return(PERIOD_H8);
      case 16396: return(PERIOD_H12);
      case 16408: return(PERIOD_D1);
      case 32769: return(PERIOD_W1);
      case 49153: return(PERIOD_MN1);      
      default: return(PERIOD_CURRENT);
     }
  }

It should be noted, that in MQL5 the numerical values of chart timeframe constants (from H1) are not equal to the number of minutes of a bar (for example, in MQL5, the numerical value of constant  PERIOD_H1=16385, but in MQL4 PERIOD_H1=60). You should take it into account when converting to MQL5, if numerical values of MQL4 constants are used in MQL4 programs.

To determine the number of minutes of the specified time period of the chart, divide the value, returned by function PeriodSeconds by 60.


HERE:  https://www.mql5.com/en/articles/81

Documentation on MQL5: Common Functions / PeriodSeconds
Documentation on MQL5: Common Functions / PeriodSeconds
  • www.mql5.com
[in]  Value of a chart period from the enumeration ENUM_TIMEFRAMES. If the parameter isn't specified, it returns the number of seconds of the current chart period, at which the program runs.
 
data46: In MT4, the ENUM constants were conveniently the minutes, but why have they chosen obscure constants for higher timeframes?
  1. No idea, but irrevalent. Just use PeriodSeconds(PERIOD_CURRENT)/60 and you have the same thing.
  2. Generally you shouldn't care about the value. Generally enums should have values 0, 1, 2… so you can do next=curr+1. Because of the "convenience" you had to write inconvenient functions to do that.
 

Of course there is point to use number values of any Enum, in this case we simply may need to check something on many/all time frames and here is my solution for this in case anyone yet need it

 do{//time frames loop

 if(ManyTimeFrames) 

 if(tf==0) tf=30;// M30

 else if(tf==30)tf=16385;//H1

 else if(tf==16385)tf=16388;//H4

 else if(tf==16388)tf=16408;//D1

 else if(tf==16408)tf=-1;//to exit

..............

..............

 }while(ManyTimeFrames&&tf>0);


This solution works for/iterates on time frame M30, H1, H4, D1 you can expand it if you like upon your needs

Reason: