Ошибка в функциях TimeGMT() и TimeCurrent()?

 

Есть время заданное по поясу GMT.

Задача: получить максимум и минимум на баре с определенным временем для сервера, находящегося в другом часовом поясе.

Пытаюсь сделать так:

-------------------------------------------------------------------------------

input datetime hour_X=D'2017.01.01 00:00:00'; 

int OnInit()

  {

   return(INIT_SUCCEEDED);

  }

int OnCalculate(const int rates_total,

                const int prev_calculated,

                const datetime &time[],

                const double &open[],

                const double &high[],

                const double &low[],

                const double &close[],

                const long &tick_volume[],

                const long &volume[],

                const int &spread[])

  {

 int  barsFromEvent;

  barsFromEvent=iBarShift(NULL,0,hour_X - (TimeGMT()-TimeCurrent()));

  Print("Bars=", barsFromEvent, "   time=", TimeToStr(hour_X - (TimeGMT() - TimeCurrent()),TIME_DATE|TIME_MINUTES), "   timecurrent=", TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES));

      Print("ASK=",Ask,"    HIGH[",barsFromEvent,"]=",(High[barsFromEvent]+bueDistance*MathPow(10,Digits*(-1))),"    H[",barsFromEvent,"]=",High[barsFromEvent]);

      Print("Bid=",Bid,"    LOW[",barsFromEvent,"]=",(Low[barsFromEvent]-sellDistance*MathPow(10,Digits*(-1))),"    L[",barsFromEvent,"]=",Low[barsFromEvent]);    

}

-------------------------------------------------------------------------------------------------

В итоге получаю:

2017.04.18 23:28:24.093 LF-Tics_Trailing_time_autoSL AUDUSD,M1: Bars=91   time=2017.04.18 18:57   timecurrent=2017.04.18 20:28
2017.04.18 23:28:21.136 LF-Tics_Trailing_time_autoSL AUDUSD,M1: Bid=0.7544    LOW[91]=-9999.2451    L[91]=0.7549
2017.04.18 23:28:21.136 LF-Tics_Trailing_time_autoSL AUDUSD,M1: ASK=0.7547    HIGH[91]=10000.7552    H[91]=0.7552
2017.04.18 23:28:21.136 LF-Tics_Trailing_time_autoSL AUDUSD,M1: Bars=91   time=2017.04.18 18:57   timecurrent=2017.04.18 20:28
2017.04.18 23:28:11.991 LF-Tics_Trailing_time_autoSL AUDUSD,M1: Bid=0.7544    LOW[90]=-9999.245    L[90]=0.755
2017.04.18 23:28:11.991 LF-Tics_Trailing_time_autoSL AUDUSD,M1: ASK=0.7547    HIGH[90]=10000.7552    H[90]=0.7552
2017.04.18 23:28:11.991 LF-Tics_Trailing_time_autoSL AUDUSD,M1: Bars=90   time=2017.04.18 18:58   timecurrent=2017.04.18 20:28
2017.04.18 23:28:11.296 LF-Tics_Trailing_time_autoSL AUDUSD,M1: Bid=0.7544    LOW[91]=-9999.2451    L[91]=0.7549
2017.04.18 23:28:11.296 LF-Tics_Trailing_time_autoSL AUDUSD,M1: ASK=0.7547    HIGH[91]=10000.7552    H[91]=0.7552
2017.04.18 23:28:11.296 LF-Tics_Trailing_time_autoSL AUDUSD,M1: Bars=91   time=2017.04.18 18:57   timecurrent=2017.04.18 20:28
2017.04.18 23:28:06.413 LF-Tics_Trailing_time_autoSL AUDUSD,M1: Bid=0.7544    LOW[91]=-9999.2451    L[91]=0.7549
2017.04.18 23:28:06.413 LF-Tics_Trailing_time_autoSL AUDUSD,M1: ASK=0.7547    HIGH[91]=10000.7552    H[91]=0.7552
2017.04.18 23:28:06.413 LF-Tics_Trailing_time_autoSL AUDUSD,M1: Bars=91   time=2017.04.18 18:57   timecurrent=2017.04.18 20:28
2017.04.18 23:28:06.288 LF-Tics_Trailing_time_autoSL AUDUSD,M1: Bid=0.7544    LOW[91]=-9999.2451    L[91]=0.7549
2017.04.18 23:28:06.288 LF-Tics_Trailing_time_autoSL AUDUSD,M1: ASK=0.7547    HIGH[91]=10000.7552    H[91]=0.7552
2017.04.18 23:28:06.288 LF-Tics_Trailing_time_autoSL AUDUSD,M1: Bars=91   time=2017.04.18 18:57   timecurrent=2017.04.18 20:28
2017.04.18 23:28:02.913 LF-Tics_Trailing_time_autoSL AUDUSD,M1: Bid=0.7544    LOW[90]=-9999.245    L[90]=0.755
2017.04.18 23:28:02.913 LF-Tics_Trailing_time_autoSL AUDUSD,M1: ASK=0.7547    HIGH[90]=10000.7552    H[90]=0.7552

2017.04.18 23:28:02.913 LF-Tics_Trailing_time_autoSL AUDUSD,M1: Bars=90   time=2017.04.18 18:58   timecurrent=2017.04.18 20:28 

Почему для указанного времени (2017.04.18 18:57) на одной и той же минуте несколько раз изменяется помер бара (Bars=) и время сервера (time=...)?


 

1. Старайтесь код оформлять как код, удобнее читать

input datetime hour_X=D'2017.01.01 00:00:00'; 

int OnInit() {
    return(INIT_SUCCEEDED);
}

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
    int  barsFromEvent = iBarShift(NULL,0,hour_X - (TimeGMT()-TimeCurrent()));
    Print("Bars=", barsFromEvent, "   time=", TimeToStr(hour_X - (TimeGMT() - TimeCurrent()),TIME_DATE|TIME_MINUTES), "   timecurrent=", 
          TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES));
    Print("ASK=",Ask,"    HIGH[",barsFromEvent,"]=",(High[barsFromEvent]+bueDistance*MathPow(10,Digits*(-1))),"    H[",barsFromEvent,"]=",High[barsFromEvent]);
    Print("Bid=",Bid,"    LOW[",barsFromEvent,"]=",(Low[barsFromEvent]-sellDistance*MathPow(10,Digits*(-1))),"    L[",barsFromEvent,"]=",Low[barsFromEvent]);    
}

2. TimeCurrent() - возвращает последнее известное время сервера, а не текущее время сервера. Поэтому если его сравнивать с локальным временем системы TimeGMT(), то разница будет всегда "плясать". Рекомендую разницу посчитать в OnInit и округлить до часа, а затем использовать округленное значение.

3. Вы используете iBarShift с "нестрогим" поиском, т.е. если в это время есть дырка в истории, то будет выдано ближайшее значение, и с учетом "пляски" времени, это может быть бар либо до дырки либо после.

 
Aleksei Radchenko:

1. Старайтесь код оформлять как код, удобнее читать

2. TimeCurrent() - возвращает последнее известное время сервера, а не текущее время сервера. Поэтому если его сравнивать с локальным временем системы TimeGMT(), то разница будет всегда "плясать". Рекомендую разницу посчитать в OnInit и округлить до часа, а затем использовать округленное значение.

3. Вы используете iBarShift с "нестрогим" поиском, т.е. если в это время есть дырка в истории, то будет выдано ближайшее значение, и с учетом "пляски" времени, это может быть бар либо до дырки либо после.


1. Хорошо, учту на будущее.

2. В данном случае не существенно, т.к. в течении минуты приходит несколько котировок и при округлении до минуты пляски быть не должно. В других программах подобных плясок нет. Если бы промежуток между тиками был более минуты - тогда другое дело, а в подобных условиях - однозначно алгоритмическая ошибка.

3. Подобное поведение начинается с первого бара. Получается, что первый бар в истории секунду назад был, сейчас куда-то пропал, через две секунды опять появился из ниоткуда?


Наиболее вероятная причина такого поведения - алгоритм определения ближайшего бара. Если к разнице TimeGMT() - TimeCurrent() добавлять 29 секунд, то результат более стабильный.  

Считать разницу в OnInit можно если достаточно часто перезапускаешь программу. Не исключено, что ДЦ может сменить зону по какой-либо причине.

Причина обращения: