Features of the mql5 language, subtleties and tricks - page 259

 

How to do calculations in #define, so that this #define can then be used as a constant?

char A = 10, m = 0;

#define  С(void) {int B = A - 1; \
for(;;B--){ \
if(B == 4){B++; break;} if(++m == 5) break;} return B;}

int D = 20 - C();

lots of errors

 
fxsaber #:

That's a strange code. Have you compared performance with this solution?

Forum on trading, automated trading systems and testing trading strategies

Features of the mql5 language, subtleties and tricks

fxsaber, 2024.04.16 14:08

I wrote a custom TimeToSruct, it is not faster than the original. 

 
amrali #:
1 - 40.36 ns, контрольная сумма = 22407500695  // TimeToStruct
2 - 20.07 ns, контрольная сумма = 22407500695  // amrali
3 - 10.73 ns, контрольная сумма = 22407500695  // fxsaber
1 - 41.04 ns, контрольная сумма = 22407076366  // TimeToStruct
2 - 21.42 ns, контрольная сумма = 22407076366  // amrali
3 - 11.25 ns, контрольная сумма = 22407076366  // fxsaber
1 - 40.07 ns, контрольная сумма = 22407602371  // TimeToStruct
2 - 19.98 ns, контрольная сумма = 22407602371  // amrali
3 - 10.59 ns, контрольная сумма = 22407602371  // fxsaber
 
fxsaber #:
2024.04.21 19:46:42.686 benchmark_TimeToStruct2100 (EURUSD,H1)  Randomized benchmark:
2024.04.21 19:46:42.776 benchmark_TimeToStruct2100 (EURUSD,H1)  TimeToStruct() -> 84531 usec
2024.04.21 19:46:42.817 benchmark_TimeToStruct2100 (EURUSD,H1)  TimeToStructFast() -> 41000 usec
2024.04.21 19:46:42.843 benchmark_TimeToStruct2100 (EURUSD,H1)  TimeToStruct2100() -> 25932 usec
2024.04.21 19:46:42.843 benchmark_TimeToStruct2100 (EURUSD,H1)  sum1: 10540393813
2024.04.21 19:46:42.843 benchmark_TimeToStruct2100 (EURUSD,H1)  sum2: 10540393813
2024.04.21 19:46:42.843 benchmark_TimeToStruct2100 (EURUSD,H1)  sum3: 10540393813

Ok good we have multiple options to decode timestamps.

 
Andrei Iakovlev #:

How do you do calculations in #define so that this #define can then be used as a constant?

lots of errors

The task is to first perform the calculations (which are now inside #define), and only after the calculations write the value to the constant via #define. Is this possible?

 
amrali #:

Ok good we have multiple options to decode timestamps.

Where can we find <mql5_lib\base.mqh> ?
 
Alain Verleyen #:
Where can we find <mql5_lib\base.mqh> ?
Use xoroshiro library on codebase, this my private library.
 

help me to read these tables from csv.

2016-09-30,-0.65,-0.29
2016-11-18,-0.96,-0.58
2017-02-07,-1.91,-0.68
2017-02-21,-1.91,-0.68
2017-02-27,-2.91,-0.68
2017-02-28,-2.91,-0.68

2017-03-06,-5.1,-0.68

WRONG PARAMETR DATATATIME error like this

struct prices
{
datetime opentime; // date
double Bid; // bid price
double Ask; // ask price
};

prices arrs[];

void OnTick()
{

int h=FileOpen(name,FILE_READ|FILE_ANSI|FILE_COMMON);
if(h!=INVALID_HANDLE)
{
//--- read all data from the file into the array
FileReadArray(file_handle,arrs);
//--- get the array size
int size=ArraySize(arrs);
//--- print the data from the array
for(int i=0;i<size;i++)
Print("Date = ",arrs[i].opentime," Bid = ",arrs[i].Bid," Ask = ",arrs[i].Ask );
Print("Total data = ",size);
//--- close file
FileClose(file_handle);
}
else
Print("File open failed, error ",GetLastError());

can anyone tell me where the error is

Modified just now by rahu
 
amrali #:

A faster TimeToStruct() function to decode time-of-day variables to get all date and time components.

Some parts of the code can be reused to retrieve components of interest individually.

Benchmark:

Results:

I thought that the variant you suggested was the fastest, but it turned out to be even faster:

bool TimeToStruct2100(datetime time, MqlDateTime& dt_struct) {
   static const int dm[13] = {0, 0, 31, 59, 90, 120, 151, 181, 212,243, 273, 304, 334};
   static int last_days = 0;
   static int last_result_m = 0;
   static int last_result_y = 0;
   static int last_result_yd = 0;
   static int last_result_d = 0;
   int days    = (int)(time / (60 * 60 * 24));
   if (last_days!=days) {
      last_days = days;
      last_result_y    = ((days << 2) + 2) / 1461;
      last_result_yd = days - ((last_result_y * 1461 + 1) >> 2);
      int isleap  = ((last_result_y & 3) == 2);
      int leapadj = ((last_result_yd < (59 + isleap)) ? 0 : (2 - isleap));
      last_result_m   = ((((last_result_yd + leapadj) * 12) + 373) / 367);
      last_result_d   = last_result_yd-dm[last_result_m]+1 -((last_result_yd>59)?isleap:0);
   }

   int HH  = (int)((time / 3600) % 24)                   ;
   int MM  = (int)((time / 60) % 60)                     ;
   int SS  = (int)(time % 60)                            ;
   int dow = (days + 4) % 7                                 ;

   dt_struct.year           = last_result_y+1970;
   dt_struct.mon            = last_result_m;
   dt_struct.day            = last_result_d;
   dt_struct.hour           = HH;
   dt_struct.min            = MM;
   dt_struct.sec            = SS;
   dt_struct.day_of_week    = dow;
   dt_struct.day_of_year    = last_result_yd;
   return (true);
}

I piled together different methods that have already appeared here.
An additional advantage is that the function remembers in static variables the basic calculations and applies them if the day coincides with the day from the previous call to the function. In reality, such calls will be more than 90%. That's why the gain will be even greater than in this random test. But the test shows that this function is about three times faster than the standard one.

2024.05.01 23:42:20.421 TestDate3 (EURUSD,M1)   1 - 23.23 ns, контрольная сумма = 231120216492  // TimeToStruct
2024.05.01 23:42:21.639 TestDate3 (EURUSD,M1)   2 - 12.18 ns, контрольная сумма = 231120216492  // amrali
2024.05.01 23:42:22.361 TestDate3 (EURUSD,M1)   2 - 7.22 ns, контрольная сумма = 231120216492  // TimeToStruct2100
2024.05.01 23:42:31.374 TestDate3 (EURUSD,M1)   1 - 23.41 ns, контрольная сумма = 231122296278  // TimeToStruct
2024.05.01 23:42:32.603 TestDate3 (EURUSD,M1)   2 - 12.29 ns, контрольная сумма = 231122296278  // amrali
2024.05.01 23:42:33.350 TestDate3 (EURUSD,M1)   2 - 7.48 ns, контрольная сумма = 231122296278  // TimeToStruct2100
2024.05.01 23:42:39.681 TestDate3 (EURUSD,M1)   1 - 23.25 ns, контрольная сумма = 231122653514  // TimeToStruct
2024.05.01 23:42:40.895 TestDate3 (EURUSD,M1)   2 - 12.15 ns, контрольная сумма = 231122653514  // amrali
2024.05.01 23:42:41.629 TestDate3 (EURUSD,M1)   2 - 7.34 ns, контрольная сумма = 231122653514  // TimeToStruct2100
It should be additionally reminded that it works correctly until 28 February 2100, because it does not take into account the Gregorian calendar, in which 2100 will not be a leap year.
Files:
TestDate3.mq5  12 kb
 
Nikolai Semko #:

I've pieced together various methods that have appeared here before.

Added this one. x64.

1 - 39.83 ns, контрольная сумма = 23111710226  // TimeToStruct
2 - 24.80 ns, контрольная сумма = 23111710226  // amrali
3 - 16.08 ns, контрольная сумма = 23111710226  // TimeToStruct2100
4 - 12.30 ns, контрольная сумма = 23111710226  // TimeToStruct2100_fxsaber

It should be additionally reminded that it works correctly until 28 February 2100, because it does not take into account the Gregorian calendar, in which 2100 will not be a leap year.

You can remove this limitation by adding epochs.

Reason: