Время MetaTrader 4 / MQL4 отключено на -5 часов, но только при использовании времени epo c - PullRequest
0 голосов
/ 21 января 2020

Я работаю с MetaTrader4, работающим в WINE в Ubuntu 16.04. У меня есть простая встроенная функция, которая сохраняет время и другую информацию в файл, используя эту строку:

FileWrite(data_filehandle, "sys_time:" + (string)TimeLocal() + "." + StringFormat("%06lu", usec_instance) + ", sym:" + (string)Symbol() + ", tick_time:" + (string)last_tick.time + ", ask:" + (string)last_tick.ask + ", bid:" + (string)last_tick.bid);

Использование директивы:

#property strict

приведет к выводу времени в формате даты и времени. Удаление этой директивы приведет к ее выводу времени в формате epo c.

Когда используется формат даты и времени (с помощью «#property strict»), время будет правильным.

Это выводит:

sys_time:2020.01.21 07:38:02.994394, sym:EURUSD, tick_time:2020.01.21 14:38:03, ask:1.1104, bid:1.1103

Это соответствует моему системному времени правильно.

Теперь, если я уберу '#property strict', чтобы переключиться на epo c time

Выводит:

sys_time:1579592538.630395, sym:EURUSD, tick_time:1579617738, ask:1.1105, bid:1.11041

мое местное время:

$ date '+%s'
1579610544

$ date '+%Z %z'
EST -0500

мое время: 1579610544 - MT4 LocalTime: 1579592538 = 18006 секунд (что на 5 часов и 6 сес c позади меня)

Есть идеи о том, что может быть причиной этого? Я мог бы быть немного менее смущенным, если бы это было +5 часов, потому что это было бы по Гринвичу. Но это -5 часов, это Гавайи. Кроме того ... почему время правильно в одном формате, а не в другом?



Дополнительная информация

Я побежал еще тестирование с использованием дополнительных функций MQL4. Я заставил их постоянно выкачивать свои результаты в мой текстовый файл. Затем я быстро собрал сценарий BASH, чтобы проверить результаты. Я нашел следующее:

Используя этот код в MT4

FileWrite(data_filehandle, "TimeDaylightSavings(): " + (string)TimeDaylightSavings());
FileWrite(data_filehandle,"TimeLocal(): "+(string)TimeLocal());
FileWrite(data_filehandle,"TimeGMTOffset(): "+(string)TimeGMTOffset());
FileWrite(data_filehandle,"TimeGMT(): "+(string)TimeGMT()+"\n\n");

Дали этот вывод в мой текстовый файл (одна запись fre sh примерно каждую секунду):

TimeDaylightSavings(): 0
TimeLocal(): 1579601184
TimeGMTOffset(): 18000
TimeGMT(): 1579619184

Я запустил этот скрипт BASH для сканирования и проверки результатов в реальном времени:

#!/bin/bash

IFS=$'\n'$'\b';

while true
do
        my_time=$(date);
        my_epoc=$(date '+%s');
        my_record="$( cat EURUSD_price_data.txt| dos2unix | tail -5 )";


        mt4_time_local=$( echo "$my_record" | grep -w 'TimeLocal' );
        echo "Reading line: $mt4_time_local";
        mt4_time_local=$(echo $mt4_time_local | awk '{print $2}' );

        echo "My time: $my_time  -- My epoc: $my_epoc -- MT4_TimeLocal epoc: $mt4_time_local -- Difference: $(( $my_epoc - $mt4_time_local ))";

        mt4_time_GMT=$( echo "$my_record" | grep -w 'TimeGMT' );
        echo "Reading line: $mt4_time_GMT";
        mt4_time_GMT=$(echo $mt4_time_GMT | awk '{print $2}' );
        echo "My time: $my_time  -- My epoc: $my_epoc -- MT4_TimeGMT epoc: $mt4_time_GMT -- Difference: $(( $my_epoc - $mt4_time_GMT ))";


        echo "";
        sleep 1;
done

и получил такой результат:

Reading line: TimeLocal(): 1579601184
My time: Tue Jan 21 10:06:25 EST 2020  -- My epoc: 1579619185 -- MT4_TimeLocal epoc: 1579601184 -- Difference: 18001
Reading line: TimeGMT(): 1579619184
My time: Tue Jan 21 10:06:25 EST 2020  -- My epoc: 1579619185 -- MT4_TimeGMT epoc: 1579619184 -- Difference: 1

Теперь, если я добавлю '# строгое свойство 'чтобы вернуться обратно в формат даты и времени, я получаю:

TimeDaylightSavings(): 0
TimeLocal(): 2020.01.21 10:23:56
TimeGMTOffset(): 18000
TimeGMT(): 2020.01.21 15:23:56

Мое системное время:

$ date
Tue Jan 21 10:23:57 EST 2020



Заключение

По какой-то причине при получении epo c time TimeLocal () дает неправильное время (по какой-то причине гавайское время), но неожиданно TimeGMT () дает правильное время, даже если я нахожусь в часовом поясе EST.

Используя точно такой же код и настройку, при получении времени в формате Date Time (используя директиву #property strict) ситуация меняется на противоположную. TimeLocal () дает правильное время, а TimeGMT () дает неправильное время (но, по крайней мере, оно дает правильное время по Гринвичу)

Это ошибка в MT4 или что-то происходит за кулисами, которые у меня есть? еще не полностью поняли?

Ответы [ 2 ]

1 голос
/ 21 января 2020

Q : Любая идея о том, что может быть причиной этого?

#property strict является kill-switch на этапе компиляции, который меняет множество деталей о том, как синтаксически правильные композиции MQL4 будут поняты в {{* old '| " new "} -fashion

"Old" -MQL4 использовал int32 для datetime внутреннего хранилища, «Новый» -MQL4.56789… использует int64, поэтому любые пролонгации намного дальше.

FileWrite( data_filehandle, "sys_time:"
                          + (string)TimeLocal()                    // localhost-dependent
                          + "."
                          + StringFormat( "%06lu", usec_instance )
                          + ", sym:"
                          + (string)Symbol()
                          + ", tick_time:"
                          + (string)last_tick.time                 // Fx-QUOTE-dependent
                          + ", ask:"
                          + (string)last_tick.ask
                          + ", bid:"
                          + (string)last_tick.bid
                          );

См. TimeGMT() и TimeGMTOffset() для других встроенных опций.

0 голосов
/ 22 января 2020

После долгих чтений, размышлений и испытаний я нашел ответ (хотя я не знаю, о чем они думали, когда делали так).

Проблема здесь:

TimeDaylightSavings(): 0
TimeLocal(): 1579601184  <-- should be the same as TimeGMT(). Epoc does not respect timezone
TimeGMTOffset(): 18000
TimeGMT(): 1579619184

Unix epo c время основано на событии, которое произошло 1 января 1970 г. 00:00 UT C. Это не уважает часовые пояса. Предполагается, что она всегда будет одинаковой для всех на Земле.

Из исходной задачи вы также можете видеть, что каждый раз, когда я использую команду:

date '+%s'

, которую дает мне моя система правильный Unix epo c, который соответствует выводу TimeGMT () из MT4. Так что проблема не в моей системе.

Однако выше мы видим, что TimeLocal () не обрабатывает epo c так, как должно. Он корректирует unix epo c в попытке компенсировать мой часовой пояс. Такое поведение, вероятно, позволяет добиться правильного времени при отображении в формате даты и времени. Проблема в том, что когда его просят произвести время в формате epo c, он все еще выполняет преобразование часового пояса, что нарушает само значение времени Unix epo c.

Итак, Решение (насколько я могу судить) состоит в том, чтобы просто использовать TimeGMT () в любое время, когда мне нужно правильное значение Unix epo c. Кажется довольно сумасшедшим, что мне приходится специально избегать использования TimeLocal () в некоторых случаях ... но я полагаю, что так оно и есть?

...