Same code as the luvinga repo's Include/core (commit "Refactor core/ ..."). - common.mqh (new): as-series contract, CRing<T> - session.mqh: now implemented (was declarations only); force-added because Experts/core is listed in .gitignore - candlesticks/swings/marketWatchFilter: no more input variables in headers; use configure() / constructor arguments - orderflow, fvg, equilibrium: multi-symbol safe, bug fixes Breaking: bots that relied on inpWatchTimeframe from marketWatchFilter.mqh (preReleasedBots/ttrades.mq5) must now declare that input themselves. signalLab.mqh is untouched by this commit. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
112 lines
4 KiB
MQL5
112 lines
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
|