Search code examples
c#mt4

How does MetaTrader 4 script 'normalize' time?


I try to understand the MetaTrader 4 scripting language ( and convert a couple of scripts to C# ), so I started with the PeriodConverter.mq4 ( it came with the MT4 install ).

Here are the values for the script:

periodseconds == 1800

Time[start_pos] == 2013/11/20 07:00

Here is the part of the script I'm having trouble understanding:

//--- normalize open time
rate.time=Time[start_pos]/periodseconds;
rate.time*=periodseconds;

this gives me a result of 2013/11/20 04:00 not 2013/11/20 07:00 as I would have expected

More Detail:

If I run the PeriodConverter.mq4 script from MT4 saying I want to use the FSTE100 1hour data and the period multiplier I want is 5 hours, this will give periodseconds a value of 18000 ( see extracts from the script below ).

int      i,start_pos,periodseconds;
// Period() == 60 because I'm using a 1hour chart
// InpPeriodMultiplier == 5 because I want 5 hour increments
int      i_period=Period()*InpPeriodMultiplier; 
periodseconds=i_period*60;

so, 60 * 5 * 60 == 18000. If I now run the script using the data below:

2013.11.20,07:00,6669.3,6677.5,6669.3,6674.2,456

rate.time will be 04:00 But how did it get this value? I tried converting it to C# to see if I could duplicate the result

var x = new DateTime(2013, 11, 20, 7, 0, 0); 
var ticks1 = x.Ticks / 18000;
var ticks2 = ticks1 * 18000;
DateTime myDateTime = new DateTime(ticks2);

But this gave me the same value that I start with 2013/11/20 07:00

So how does MT4 get 04:00 from 07:00? and is it possible to duplicate this in C#?

Thanks in advance.

WITH HELP FROM JOSEPH THE PROBLEM HAS BEEN RESOLVED!

Here is my working test code for anyone who needs it

    // working with seconds
    var x = new DateTime(2013, 11, 20, 7, 0, 0);
    // number of seconds since 12:00:00, 01-01-0001
    var sec1 = x.Ticks / TimeSpan.TicksPerSecond;
    // number of seconds since 12:00:00, 01-01-1970
    var sec2 = sec1 - (new DateTime(1970, 1, 1, 0, 0, 0).Ticks / TimeSpan.TicksPerSecond);
    // rate.time=Time[start_pos]/periodseconds
    var newRateTimeInSeconds = sec2 / 18000;
    newRateTimeInSeconds *= 18000;
    DateTime myDateTime = new DateTime((newRateTimeInSeconds * TimeSpan.TicksPerSecond) + new DateTime(1970, 1, 1, 0, 0, 0).Ticks);

Solution

  • Consider the followings:

    • In C#, 10mil ticks to 1 second. So, it should not be / 1800. We should use var sec1 = x.Ticks / (1800 * TimeSpan.TicksPerSecond);
    • The BASE datetime value is 01.01.0001 in C#, while in MQL4, it is 01-01-1970.
    • This is very important distinction when we convert the datetime value to integer.
    • If we take integer viTime = TimeCurrent(), viTime is the number of seconds ELAPSED since 01-01-1970.
    • This is VERY important; vs C#'s Tick, which is the value of 100-nanosecond intervals that have elapsed since 12:00:00, 01-01-0001.
    • To get the same MQL4's integer viTime = TimeCurrent() in C#, you need to get the sec value in C#, then deduct the sec value of 01-01-1970 from it.