События времени из тиковых данных

8 ноября 2025, 10:45
Aleksei Kuznetsov
2
48

Получение момента появления новой минуты, часа, дня, недели и месяца. Так же можно использовать функции OnMinute, OnHour, OnDay, OnWeek, OnMonth ...
Может пригодиться, как замена OnTimer() в режиме математических расчетов и в других случаях.

void OnTick(){
   static MqlTick Tick;
   if (SymbolInfoTick(_Symbol, Tick)){
      Strategy(Tick);
   }
}
double Sum = 0;
void Strategy(MqlTick& Tick){  if( isNewMinute(Tick.time)){Sum += Tick.bid+Tick.ask;}} // сумма первых тиков в минуте


void OnMinute(datetime &t){/*Print("Minute: ",GetMinute(t));*/}
void OnHour  (datetime &t){/*Print("Hour: ",GetHour(t));*/}
void OnDay   (datetime &t){Print("Day: ",GetDay(t), " DayOfWeek: ",GetDayOfWeek(t));}
void OnWeek  (datetime &t){Print("Week: ",GetWeek(t));}
void OnMonth (int &m){Print("Month: ",m);}

bool isNewMinute(datetime &t){ static int next_m=-1; if(t < next_m){ return false; } else { next_m = (GetMinute0(t)+1)*60;             OnMinute(t); isNewHour(t);                 return true;}}
bool isNewHour  (datetime &t){ static int next_h=-1; if(t < next_h){ return false; } else { next_h = (GetHour0(t)+1)*3600;             OnHour(t);   isNewDay(t);                  return true;}}
bool isNewDay   (datetime &t){ static int next_d=-1; if(t < next_d){ return false; } else { next_d = (GetDay(t)+1)*86400;              OnDay(t);    isNewWeek(t); isNewMonth (t); return true;}}
bool isNewWeek  (datetime &t){ static int next_w=-1; if(t < next_w){ return false; } else { next_w = ((GetWeek(t)+1)*7-THURSDAY)*86400;OnWeek(t);                                 return true;}}// -THURSDAY смещение к воскресенью
bool isNewMonth (datetime &t){ static int prev_M=-1; static MqlDateTime tm; TimeToStruct(t,tm); if(prev_M == tm.mon ){ return false; } else { prev_M = tm.mon; OnMonth(tm.mon);   return true;}}

int GetDay      (datetime &t){return((int)( t / 86400));}//current Day from 1 Jan 1971
int GetWeek     (datetime &t){return((int)((t / 86400 + THURSDAY) / 7 ));}//current Week from 1 Jan 1971. THURSDAY on 1 Jan 1971
int GetDayOfWeek(datetime &t){return((int)((t / 86400 + THURSDAY) % 7 ));}//current DayOfWeek. 86400 sec in day.  7 days in week.  THURSDAY on 1 Jan 1971
int GetHour     (datetime &t){return((int)((t / 3600) % 24));}//current hour in day. 3600 sec in hour
int GetHour0    (datetime &t){return((int)( t / 3600));}//current hour from 1 Jan 1971
int GetMinute   (datetime &t){return((int)((t / 60) % 60));}//current minute in hour. 60 sec in minute
int GetMinute0  (datetime &t){return((int)( t / 60));}//current minute from 1 Jan 1971
int GetSec      (datetime &t){return((int)( t % 86400));}//current second in day. 86400 sec in day
int GetSecM     (datetime &t){return((int)( t % 60));}//current second in minute

Ненужные вызовы можно удалить. Например если нужны только OnWeek() то вызовы OnMinute(), OnHour(), OnDay(), OnMonth() можно удалить. И т.п.

isNewWeek() ответит true и вызовет OnWeek() - на первом тике с 0:00:00 воскресенья. Если тиков в воскресенье нет, то при любом первом тике, например в понедельник, если в понедельник праздник и тоже нет тиков, то во вторник.

isNewMonth() работает медленно, - её надо из определения начала дня isNewDay() вызывать, а не на каждом тике. Остальные функции можно на каждом тике или как предложено в примере из предыдущей проверки, например isNewDay() - из isNewHour().