Обсуждение статьи "Работаем с датами и временем в MQL5"

 

Опубликована статья Работаем с датами и временем в MQL5:

Трейдерам и разработчикам торговых инструментов очень важно понимать, как хорошо и эффективно обращаться с датами и временем. В статье я покажу, как мы можем обращаться с датами и временем при создании эффективных торговых инструментов.

Никто в сфере финансового рынка не скрывает важность времени и то, как оно может повлиять на торговые решения и результаты. MQL5 (MetaQuotes Language 5) предлагает решение для эффективной работы с датой и временем. Мы можем справиться с этой важной темой с помощью множества приложений, которые можно запрограммировать как часть нашей торговой системы, но сначала рассмотрим наиболее важные аспекты этой темы на языке программирования MQL5.

Автор: Mohamed Abdelmaaboud

 

Стоило бы упомянуть, что  StructToTime, TimeToStruct и особенно TimeToString и StringToTime - это довольно "дорогие" операции и в критичных по времени ситуациях их иногда можно заменить более простыми.

В частности, очень не рекомендуется получать начало суток напрашивающимся способом:

StringToTime(TimeToString(TimeCurrent(),TIME_DATE))

лучше сделать:

TimeCurrent() / 86400 * 86400

Из-за целочисленной арифметики остаток от деления будет отброшен.


Или, иногда достаточно знать время, прошедшее от начала суток, а год, месяц, число, день недели не важны (или их можно получать единожды при наступлении новых суток).

В секундах: time % 86400

Часы: time % 86400 / 3600

Минуты: time % 3600 / 60

Секунды: time % 60

 

Решая задачу присвоения уникальных имен объектам (типа ARROW) используем время в секундах:

//+------------------------------------------------------------------+

int TimeInSec(datetime date)
  {
   MqlDateTime tm;
   TimeToStruct(date, tm);
   int sec_int = tm.day * 24 *3600 + tm.hour * 3600 + tm.min * 60 + tm.sec * 1;
   return(sec_int);
  }

//+------------------------------------------------------------------+

int TimeMinute(datetime date)
  {
   MqlDateTime tm;
   TimeToStruct(date, tm);
   return(tm.min);
  }

 
gerien #:

Решая задачу присвоения уникальных имен объектам (типа ARROW) используем время в секундах:

По-моему, гораздо дешевле организовать глобальный инкрементный счётчик.

 
gerien #:
int TimeMinute(datetime date)
  {
   MqlDateTime tm;
   TimeToStruct(date, tm);
   return(tm.min);
  }

Вот как раз то, о чём я говорил. Неэффективное использование "дорогой" функции TimeToStruct.

Достаточно просто вот такого:

int TimeMinute(datetime date)
  {
   return((int)(date % 3600 / 60));
  } 
 
gerien #:

Решая задачу присвоения уникальных имен объектам (типа ARROW) используем время в секундах:

//+------------------------------------------------------------------+

int TimeInSec(datetime date)
  {
   MqlDateTime tm;
   TimeToStruct(date, tm);
   int sec_int = tm.day * 24 *3600 + tm.hour * 3600 + tm.min * 60 + tm.sec * 1;
   return(sec_int);
  }

//+------------------------------------------------------------------+

int TimeMinute(datetime date)
  {
   MqlDateTime tm;
   TimeToStruct(date, tm);
   return(tm.min);
  }

всё гораздо проще - datetime это и есть секунды. Его ненадо разбирать через TimeToStruct чтобы потом перемножать и складывать поля

long timeIsSeconds = (long)TimeCurrent();

если у вас алгоритм гарантирует отсутствие двух стрелок за одну секунду - то подойдёт.

 
Maxim Kuznetsov #:

Он там от начала месяца секунды берёт, видимо, чтоб короче число было.

Хотя с почти (если не нужен обратный пересчёт имени объекта в день месяца) тем же результатом можно взять остаток от деления TimeCurrent() на число, близкое к среднему числу секунд в месяце.

 
JRandomTrader #:

Он там от начала месяца секунды берёт, видимо, чтоб короче число было.

Хотя с почти (если не нужен обратный пересчёт имени объекта в день месяца) тем же результатом можно взять остаток от деления TimeCurrent() на число, близкое к среднему числу секунд в месяце.

а вычесть из одной даты другую (начало месяца) не позволяет какая-то хитрая религия ? :-)

на практике - если где-то внутри нужно знать точное начало месяца, дня, недели то они однократно считаются и запоминаются. Чтобы лишний раз на каждый чих не пересчитывать

datetime thisDayTime, nextDayTime;
datetime thisYearTime,thisMonTime;
int thisYear, thisMon;

// вызывать внутри всех обработчиков OnXXX терминала- это прототип службы времени
void TimeService() {
    datetime now=TimeCurrent();
    if (now>=nextDayTime) {
        MqlDateTime dt; TimeToStruct(dt,now);
        dt.hour=dt.min=dt.sec=0;
        thisDayTime=StructToTime(dt);
        nextDayTime=thisDayTime+24*60*60;
        OnDay();  /// обработчик "начало дня"
        if (dt.month!=thisMon|| dt.year!=thisYear) {
               thisMon=dt.month;
               dt.day=0; thisMon=StructToTime(dt);
               OnMon();   /// обработчик "начало месяца"
        }

        if ( dt.year!=thisYear ) {
               thisYear=dt.year; 
               dt.month=0; thisYearTime=StructToTime(dt);
               OnYear();  /// обработчик "начало года"
        }
    }
}

 

Сорри, вспомнилось в тему:

Фредерик Браун
Конец начал

Профессор Джонс долгое время работал над теорией времени.
- И сегодня я нашел ключевое уравнение, - сказал он своей дочери как-то утром.
- Время это поле. Я создал  машину, которая способна управлять этим полем.
Он протянул руку и, нажимая кнопку, сказал:
- Это заставит время идти назад идти время заставит это
- :сказал, кнопку нажимая, и руку протянул он.
- Полем этим управлять способна которая, машину создал я. Поле это время,
- утром как-то дочери своей он сказал. - Уравнение ключевое нашел я сегодня и.
Времени теорией над работал время долгое Джонс профессор.

Начал конец
Браун Фредерик
 
JRandomTrader #:

Сорри, вспомнилось в тему:

Наверное, стоило не только порядок слов перевернуть, но и порядок букв ;)
 
JRandomTrader #:

Сорри, вспомнилось в тему:

Вспомнил советскую фантастическую повесть, где дочь за перед экспериментом отца в институте времени твердила ему "укпонк имжан", а он не понимал её детское баловство.

А она спасла его этим.

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