112 righe
4 KiB
MQL5
112 righe
4 KiB
MQL5
#ifndef CORE_SESSION_MQH
| |||
#define CORE_SESSION_MQH
| |||
//+------------------------------------------------------------------+
| |||
//| session.mqh - time before price: daily trading windows |
| |||
//| |
| |||
//| A window is a daily span in minutes since midnight SERVER time |
| |||
//| (use HM(9, 30) for 09:30). start > end wraps past midnight, so |
| |||
//| HM(22, 0) .. HM(6, 0) is a valid Asian-style window. The start |
| |||
//| minute is inclusive and the end minute exclusive. |
| |||
//| |
| |||
//| Ids returned by defineWindow() stay valid for the object's life; |
| |||
//| removeWindow() retires an id but never hands it out again. |
| |||
//+------------------------------------------------------------------+
| |||
#include "common.mqh"
| |||
| |||
#define SESSION_ALL_DAYS 0x7F // bit n = weekday n, 0 = Sunday .. 6 = Saturday
| |||
| |||
class CSession
| |||
{
| |||
private:
| |||
struct SWindow
| |||
{
| |||
int startMinute;
| |||
int endMinute;
| |||
int dayMask;
| |||
bool live;
| |||
};
| |||
SWindow m_windows[];
| |||
| |||
bool covers(const SWindow &w, const datetime t) const;
| |||
| |||
public:
| |||
static int HM(const int hour, const int minute = 0) { return hour * 60 + minute; }
| |||
| |||
//--- true and sessionIndex set on success; false on an invalid window
| |||
bool defineWindow(const int startMinute, const int endMinute, int &sessionIndex,
| |||
const int dayMask = SESSION_ALL_DAYS);
| |||
void removeWindow(const int sessionIndex);
| |||
//--- t = 0 means TimeCurrent(). Pass a bar's time when replaying history.
| |||
bool isSessionActive(const int sessionIndex, const datetime t = 0) const;
| |||
bool isThisTimeASession(const datetime t = 0) const { return whichSession(t) >= 0; }
| |||
//--- id of the first live window that covers t, or -1
| |||
int whichSession(const datetime t = 0) const;
| |||
int windowCount() const;
| |||
};
| |||
| |||
//+------------------------------------------------------------------+
| |||
bool CSession::defineWindow(const int startMinute, const int endMinute, int &sessionIndex, const int dayMask)
| |||
{
| |||
if(startMinute < 0 || startMinute >= 1440 || endMinute < 0 || endMinute > 1440
| |||
|| startMinute == endMinute || (dayMask & SESSION_ALL_DAYS) == 0)
| |||
return false;
| |||
| |||
const int n = ArraySize(m_windows);
| |||
if(ArrayResize(m_windows, n + 1) != n + 1)
| |||
return false;
| |||
| |||
m_windows[n].startMinute = startMinute;
| |||
m_windows[n].endMinute = endMinute;
| |||
m_windows[n].dayMask = dayMask & SESSION_ALL_DAYS;
| |||
m_windows[n].live = true;
| |||
sessionIndex = n;
| |||
return true;
| |||
}
| |||
| |||
void CSession::removeWindow(const int sessionIndex)
| |||
{
| |||
if(sessionIndex >= 0 && sessionIndex < ArraySize(m_windows))
| |||
m_windows[sessionIndex].live = false;
| |||
}
| |||
| |||
bool CSession::covers(const SWindow &w, const datetime t) const
| |||
{
| |||
MqlDateTime dt;
| |||
TimeToStruct(t, dt);
| |||
if((w.dayMask & (1 << dt.day_of_week)) == 0)
| |||
return false;
| |||
| |||
const int minute = dt.hour * 60 + dt.min;
| |||
if(w.startMinute < w.endMinute)
| |||
return minute >= w.startMinute && minute < w.endMinute;
| |||
return minute >= w.startMinute || minute < w.endMinute; // wraps midnight
| |||
}
| |||
| |||
bool CSession::isSessionActive(const int sessionIndex, const datetime t) const
| |||
{
| |||
if(sessionIndex < 0 || sessionIndex >= ArraySize(m_windows) || !m_windows[sessionIndex].live)
| |||
return false;
| |||
return covers(m_windows[sessionIndex], t == 0 ? TimeCurrent() : t);
| |||
}
| |||
| |||
int CSession::whichSession(const datetime t) const
| |||
{
| |||
const datetime when = (t == 0) ? TimeCurrent() : t;
| |||
for(int i = 0; i < ArraySize(m_windows); i++)
| |||
{
| |||
if(m_windows[i].live && covers(m_windows[i], when))
| |||
return i;
| |||
}
| |||
return -1;
| |||
}
| |||
| |||
int CSession::windowCount() const
| |||
{
| |||
int n = 0;
| |||
for(int i = 0; i < ArraySize(m_windows); i++)
| |||
if(m_windows[i].live)
| |||
n++;
| |||
return n;
| |||
}
| |||
| |||
#endif // CORE_SESSION_MQH
|