2025-05-30 16:35:54 +02:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| SignalITF.mqh |
|
|
|
|
|
//| Copyright 2000-2023, MetaQuotes Ltd. |
|
|
|
|
|
//| https://www.mql5.com |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#include "..\Expert\ExpertSignalCustom.mqh"
|
|
|
|
|
// wizard description start
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Description of the class |
|
|
|
|
|
//| Title=Signals of intraday time filter |
|
|
|
|
|
//| Type=SignalAdvanced |
|
|
|
|
|
//| Name=IntradayTimeFilter |
|
|
|
|
|
//| ShortName=ITF |
|
|
|
|
|
//| Class=CSignalITF |
|
|
|
|
|
//| Page=signal_time_filter |
|
|
|
|
|
//| Parameter=GoodHourOfDay,int,-1,Good hour |
|
|
|
|
|
//| Parameter=BadHoursOfDay,int,0,Bad hours (bit-map) |
|
|
|
|
|
//| Parameter=GoodDayOfWeek,int,-1,Good day of week |
|
|
|
|
|
//| Parameter=BadDaysOfWeek,int,0,Bad days of week (bit-map) |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
// wizard description end
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Class CSignalITF. |
|
|
|
|
|
//| Appointment: Class trading signals time filter. |
|
|
|
|
|
//| Derives from class CExpertSignal. |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
class CSignalITF : public CExpertSignalCustom
|
|
|
|
|
{
|
|
|
|
|
protected:
|
|
|
|
|
//--- input parameters
|
|
|
|
|
int m_good_minute_of_hour;
|
|
|
|
|
long m_bad_minutes_of_hour;
|
|
|
|
|
int m_good_hour_of_day;
|
|
|
|
|
int m_bad_hours_of_day;
|
|
|
|
|
int m_good_day_of_week;
|
|
|
|
|
int m_bad_days_of_week;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
CSignalITF(void);
|
|
|
|
|
~CSignalITF(void);
|
|
|
|
|
//--- methods initialize protected data
|
|
|
|
|
void GoodMinuteOfHour(int value) { m_good_minute_of_hour = value; }
|
|
|
|
|
void BadMinutesOfHour(long value) { m_bad_minutes_of_hour = value; }
|
|
|
|
|
void GoodHourOfDay(int value) { m_good_hour_of_day = value; }
|
2026-07-22 22:51:04 -04:00
|
|
|
//--- value is used directly as the bitmask tested in Direction() via (1 << hour) - no conversion.
|
|
|
|
|
//--- A prior ConvertToBinary() step re-encoded the value's binary digits as a NEW decimal number
|
|
|
|
|
//--- before use (e.g. 5 -> 101), which matched neither "raw bitmask" nor "type binary digits in
|
|
|
|
|
//--- decimal" as a consistent interpretation, so any input other than a pure power-of-two selected
|
|
|
|
|
//--- the wrong hours/days. Removed; Inputs.mqh documents these as plain bitmasks, so use them as such.
|
|
|
|
|
void BadHoursOfDay(int value) { m_bad_hours_of_day = value; }
|
2025-05-30 16:35:54 +02:00
|
|
|
void GoodDayOfWeek(int value) { m_good_day_of_week = value; }
|
2026-07-22 22:51:04 -04:00
|
|
|
void BadDaysOfWeek(int value) { m_bad_days_of_week = value; }
|
2025-05-30 16:35:54 +02:00
|
|
|
//--- methods of checking conditions of entering the market
|
|
|
|
|
virtual double Direction(void);
|
|
|
|
|
};
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Constructor |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
CSignalITF::CSignalITF(void) : m_good_minute_of_hour(-1),
|
|
|
|
|
m_bad_minutes_of_hour(0),
|
|
|
|
|
m_good_hour_of_day(-1),
|
|
|
|
|
m_bad_hours_of_day(0),
|
|
|
|
|
m_good_day_of_week(-1),
|
|
|
|
|
m_bad_days_of_week(0)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Destructor |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
CSignalITF::~CSignalITF(void)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Check conditions for time filter. |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
double CSignalITF::Direction(void)
|
|
|
|
|
{
|
|
|
|
|
MqlDateTime s_time;
|
2026-07-26 12:12:14 -04:00
|
|
|
//--- GMT, not TimeCurrent() (broker/server time) - CSignalSessionFilter's London/NY/Tokyo windows
|
|
|
|
|
//--- are already GMT-based; using two different time bases across these two hour-of-day filters
|
|
|
|
|
//--- meant an operator configuring both was unknowingly reasoning about two different clocks,
|
|
|
|
|
//--- offset by the broker server's UTC delta.
|
|
|
|
|
TimeToStruct(TimeGMT(), s_time);
|
2025-05-30 16:35:54 +02:00
|
|
|
//--- check days conditions
|
|
|
|
|
if(!((m_good_day_of_week == -1 || m_good_day_of_week == s_time.day_of_week) &&
|
|
|
|
|
!(m_bad_days_of_week & (1 << s_time.day_of_week))))
|
|
|
|
|
return(EMPTY_VALUE);
|
|
|
|
|
//--- check hours conditions
|
|
|
|
|
if(!((m_good_hour_of_day == -1 || m_good_hour_of_day == s_time.hour) &&
|
|
|
|
|
!(m_bad_hours_of_day & (1 << s_time.hour))))
|
|
|
|
|
return(EMPTY_VALUE);
|
2026-07-26 12:12:14 -04:00
|
|
|
//--- check minutes conditions - shift as `long` (m_bad_minutes_of_hour's own type): minutes go up to
|
|
|
|
|
//--- 59, and shifting a 32-bit int by >=32 is undefined behavior in MQL5/C++.
|
2025-05-30 16:35:54 +02:00
|
|
|
if(!((m_good_minute_of_hour == -1 || m_good_minute_of_hour == s_time.min) &&
|
2026-07-26 12:12:14 -04:00
|
|
|
!(m_bad_minutes_of_hour & ((long)1 << s_time.min))))
|
2025-05-30 16:35:54 +02:00
|
|
|
return(EMPTY_VALUE);
|
|
|
|
|
//--- condition OK
|
|
|
|
|
return(0.0);
|
|
|
|
|
}
|
|
|
|
|
//+------------------------------------------------------------------+
|