Особенности языка mql5, тонкости и приёмы работы - страница 272

 

В тестере событие новый бар при мультисимвольной торговле.

// https://www.mql5.com/ru/forum/170952/page68#comment_6406566
#property indicator_chart_window
#property indicator_plots 0
enum inp
  {
   Tick,
   Bar
  };
input long Chart  = 0; // идентификатор графика-получателя события
input int Index   = 0;
input inp variant = Tick;
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total, const int prev_calculated, const int, const double &[])
  {
   if(prev_calculated)
      switch(variant)
        {
         case  Tick:
            EventChartCustom(Chart, 0, Index, 0, NULL);
            break;
         default:
            if(prev_calculated != rates_total)
               EventChartCustom(Chart, 0, Index, 0, NULL);
            break;
        }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Удобно. Быстро.

ЗЫ. Может уже где то это писали, но я не видел.
 
Aleksandr Slavskii #:

В тестере событие новый бар при мультисимвольной торговле.

Удобно. Быстро.

ЗЫ. Может уже где то это писали, но я не видел.

способ не рабочий, иногда бывает система на первом тике нового бара показывает информацию Прошлого на iCustom индикаторах, т.е. в массиве будет на 0 и 1 закрытом баре одно значение - "нет сигнала"

и так-же реквоты надо будет все обрабатывать

при просто индикаторе шпионе просто на М1 обрабатываем все действия и там не страшны будут реквоты и глюки первого тика, робот будет обрабатывать весь М1 сигналы и остальные ситуации

так же в этом случае можно легко контролировать размер максимального спреда, а не добавлять, проверки открылось-не открылось

Т.е. на первом тике получается у вас может 3 ситуации быть для не открытия сделки на Новом баре
 

https://www.mql5.com/en/forum/363210#comment_20862779

Это больше не работает? Не получается получить пустое поле на месте названия переменной после Left Alt и набора 0160. Может есть альтернатива?

How to show a blank Variable In Inputs Setting?
How to show a blank Variable In Inputs Setting?
  • 2021.02.20
  • lengendmt4
  • www.mql5.com
Looks simple, but how to code this blank Variable? Thanks...
 
Комментарии, не относящиеся к этой теме, были перенесены в "Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам".
 
fxsaber #:
В копилке.

Выделил изменения. На старом процессоре он работает быстрее.

Я внес несколько изменений в ваш код. Теперь он выглядит чище и выполняется быстрее.

void TimeToStruct2100( const datetime time, MqlDateTime &dt_struct )
{
  const uint t = (uint)time;
  const int n = (int)(t / (24 * 3600));
  const int tn = (n << 2) + 2;

  dt_struct.sec = (int)(t % 60);
  dt_struct.min = (int)(t / 60) % 60;
  dt_struct.hour = (int)(t / 3600) % 24;

  dt_struct.day_of_week = (n + THURSDAY) % 7;
  dt_struct.day_of_year = (tn % 1461) / 4;;

  dt_struct.year = (tn / 1461) + 1970; // to 2100
  const bool Flag = ((dt_struct.year & 3) == 0);

  static const int Months[13] = {0, -1, 30, 58, 89, 119, 150, 180, 211,242, 272, 303, 333};

  dt_struct.mon = (dt_struct.day_of_year < 31) ? 1 : ((dt_struct.day_of_year - Flag) * 5 + 166) / 153;
  dt_struct.day = dt_struct.day_of_year - Months[dt_struct.mon] - (Flag && dt_struct.mon >= 3);
//dt_struct.day = dt_struct.day_of_year - Months[dt_struct.mon] - (Flag && dt_struct.day_of_year > 59);

  return;
}
 
amrali #:

Я внес несколько изменений в ваш код. Теперь он выглядит чище и выполняется быстрее.

Очень хорошо. Замеры провести пока не могу.

 

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

Кэширование выполняется один раз в день. При каждом новом обращении к функции в течение одного дня будут обновляться только поля "hh:mm:ss".

Остальные поля "yyyy/mm/dd" будут возвращены как есть, из сохраненного кэша.

Конечно, все поля должны быть пересчитаны при передаче значения "времени" из другой даты.

void TimeToStruct2100( const datetime time, MqlDateTime &dt_struct )
{
  static const int Months[13] = {0, -1, 30, 58, 89, 119, 150, 180, 211,242, 272, 303, 333};
  static MqlDateTime last_result = {};
  static int last_days = 0;

  const uint t = (uint)time;
  const int n = (int)(t / (24 * 3600));
  const int tn = (n << 2) + 2;

  if (last_days != n)
  {
    last_days = n;
    last_result.day_of_week = (n + THURSDAY) % 7;
    last_result.day_of_year = (tn % 1461) / 4;;

    last_result.year = (tn / 1461) + 1970; // to 2100
    const bool Flag = ((last_result.year & 3) == 0);

    last_result.mon = (last_result.day_of_year < 31) ? 1 : ((last_result.day_of_year - Flag) * 5 + 166) / 153;
    last_result.day = last_result.day_of_year - Months[last_result.mon] - (Flag && last_result.mon >= 3);
  //dt_struct.day = dt_struct.day_of_year - Months[dt_struct.mon] - (Flag && dt_struct.day_of_year > 59);
  }

  dt_struct = last_result;
  dt_struct.hour= (int)(t / 3600) % 24;
  dt_struct.min = (int)(t / 60) % 60;
  dt_struct.sec = (int)(t % 60);

  return;
}
 

Самая быстрая замена встроенной функции TimeToStruct(),

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

bool TimeToStructFast(datetime time, MqlDateTime& dt_struct)
  {
   static const int Months[13] = {0, -1, 30, 58, 89, 119, 150, 180, 211,242, 272, 303, 333};
   uint t       = (uint)time;
   int  n       = (int)(t / (24 * 3600));
   int  tn      = (n << 2) + 2;
   int  dow     = (n + 4) % 7;
   int  doy     = (tn % 1461) / 4;
   int  year    = (tn / 1461) + 1970; // to 2100
   int  isleap  = ((year & 3) == 0);
   int  leapadj = ((doy < (isleap + 59)) ? 0 : (2 - isleap));
   int  mon     = ((((doy + leapadj) * 12) + 373) / 367);
   int  day     = doy - Months[mon] - (isleap && doy > 59);
   int  HH      = (int)(t / 3600) % 24;
   int  MM      = (int)(t / 60) % 60;
   int  SS      = (int)(t % 60);

   dt_struct.year           = year;
   dt_struct.mon            = mon;
   dt_struct.day            = day;
   dt_struct.hour           = HH;
   dt_struct.min            = MM;
   dt_struct.sec            = SS;
   dt_struct.day_of_week    = dow;
   dt_struct.day_of_year    = doy;
   return (true);
  }
//+------------------------------------------------------------------+
bool TimeToStructFast(datetime time, MqlDateTime& dt_struct)  // with once-a-day-cache
  {
   static const int Months[13] = {0, -1, 30, 58, 89, 119, 150, 180, 211,242, 272, 303, 333};
   static int last_days = 0;
   static MqlDateTime last_result = {};

   const uint t = (uint)time;
   const int  n = (int)(t / (24 * 3600));
   if (last_days != n)
     {
      int  tn      = (n << 2) + 2;
      int  dow     = (n + 4) % 7;
      int  doy     = (tn % 1461) / 4;
      int  year    = (tn / 1461) + 1970; // to 2100
      int  isleap  = ((year & 3) == 0);
      int  leapadj = ((doy < (isleap + 59)) ? 0 : (2 - isleap));
      int  mon     = ((((doy + leapadj) * 12) + 373) / 367);
      int  day     = doy - Months[mon] - (isleap && doy > 59);
      last_days = n;
      last_result.year          = year;
      last_result.mon           = mon;
      last_result.day           = day;
      last_result.day_of_week   = dow;
      last_result.day_of_year   = doy;
     }

   dt_struct = last_result;
   dt_struct.hour= (int)(t / 3600) % 24;
   dt_struct.min = (int)(t / 60) % 60;
   dt_struct.sec = (int)(t % 60);
   return (true);
  }

Ускорение примерно в 4-5 раз (для версии без кэша).

 
amrali #:

Самая быстрая замена встроенной функции TimeToStruct(),

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

Ускорение примерно в 4-5 раз (для версии без кэша).

Добавил сюда.

1 - 37.91 ns, контрольная сумма = 231124029785  // TimeToStruct
2 - 21.67 ns, контрольная сумма = 231124029785  // amrali
2 - 15.99 ns, контрольная сумма = 231124029785  // TimeToStruct2100
2 - 10.81 ns, контрольная сумма = 231124029785  // TimeToStruct2100 fxsaber
2 - 9.38 ns, контрольная сумма = 231124029785  // TimeToStruct2100 amrali2

Действительно, Ваш вариант самый быстрый. Поздравляю!

 

Высокопроизводительные (по сравнению со встроенными) функции времени, собранные с разных страниц этой темы (чтобы не потерялись):

//+------------------------------------------------------------------+
//|                                                    TimeUtils.mqh |
//|                                        Copyright © 2014, Amr Ali |
//|                             https://www.mql5.com/en/users/amrali |
//+------------------------------------------------------------------+
#property version "1.00"

//+==================================================================+
//| Extract Components of datetime: Sunday, yyyy.mm.dd hh:mm         |
//| Date and Time Functions                                          |
//+==================================================================+
int   TimeSecond( const datetime t );
int   TimeMinute( const datetime t );
int   TimeHour( const datetime t );
int   TimeDay( const datetime t );
int   TimeMonth( const datetime t );
int   TimeYear( const datetime t );
int   TimeDayOfYear( const datetime t );
int   TimeDayOfWeek( const datetime t );
bool  TimeToStructFast( datetime time, MqlDateTime& dt_struct );

//+==================================================================+
//| Create datetime From Components                                  |
//+==================================================================+
datetime CreateDateTime(MqlDateTime&  dt_struct);
datetime CreateDateTime(
   const int year,           // Year
   const int mon,            // Month
   const int day,            // Day
   const int hour = 0,       // Hour
   const int min = 0,        // Minutes
   const int sec = 0         // Seconds
   );

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

Файлы:
TimeUtils.mqh  9 kb