2026-02-06 18:23:12 +01:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| SessionLevels_Calculator.mqh |
|
2026-02-07 19:44:41 +01:00
|
|
|
//| Includes Data Synchronization logic. |
|
2026-02-06 18:23:12 +01:00
|
|
|
//| Copyright 2026, xxxxxxxx |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#property copyright "Copyright 2026, xxxxxxxx"
|
|
|
|
|
|
2026-02-07 19:44:41 +01:00
|
|
|
#include <MyIncludes\DataSync_Tools.mqh> // Include new tool
|
|
|
|
|
|
2026-02-06 18:23:12 +01:00
|
|
|
struct SessionLevels
|
|
|
|
|
{
|
|
|
|
|
double prev_high;
|
|
|
|
|
double prev_low;
|
|
|
|
|
double prev_close;
|
|
|
|
|
double curr_open;
|
|
|
|
|
bool valid;
|
|
|
|
|
};
|
|
|
|
|
|
2026-02-07 19:44:41 +01:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-02-06 18:23:12 +01:00
|
|
|
class CSessionLevelsCalculator
|
|
|
|
|
{
|
|
|
|
|
protected:
|
2026-02-07 19:44:41 +01:00
|
|
|
ENUM_TIMEFRAMES m_session_tf;
|
|
|
|
|
datetime m_last_calc_time_bar;
|
2026-02-06 18:23:12 +01:00
|
|
|
SessionLevels m_cached_levels;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
CSessionLevelsCalculator(void);
|
|
|
|
|
virtual ~CSessionLevelsCalculator(void) {};
|
|
|
|
|
|
|
|
|
|
bool Init(ENUM_TIMEFRAMES session_tf = PERIOD_D1);
|
2026-02-07 19:44:41 +01:00
|
|
|
bool GetLevels(string symbol, datetime time, SessionLevels &out_levels); // Added 'symbol' param
|
2026-02-06 18:23:12 +01:00
|
|
|
double GetDistanceATR(double price, double level, double atr);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-02-07 19:44:41 +01:00
|
|
|
//| |
|
2026-02-06 18:23:12 +01:00
|
|
|
//+------------------------------------------------------------------+
|
2026-02-07 19:44:41 +01:00
|
|
|
CSessionLevelsCalculator::CSessionLevelsCalculator(void) : m_session_tf(PERIOD_D1), m_last_calc_time_bar(0)
|
2026-02-06 18:23:12 +01:00
|
|
|
{
|
|
|
|
|
m_cached_levels.valid = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-02-07 19:44:41 +01:00
|
|
|
//| |
|
2026-02-06 18:23:12 +01:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CSessionLevelsCalculator::Init(ENUM_TIMEFRAMES session_tf)
|
|
|
|
|
{
|
|
|
|
|
m_session_tf = session_tf;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-02-07 19:44:41 +01:00
|
|
|
//| |
|
2026-02-06 18:23:12 +01:00
|
|
|
//+------------------------------------------------------------------+
|
2026-02-07 19:44:41 +01:00
|
|
|
bool CSessionLevelsCalculator::GetLevels(string symbol, datetime time, SessionLevels &out_levels)
|
2026-02-06 18:23:12 +01:00
|
|
|
{
|
2026-02-07 19:44:41 +01:00
|
|
|
// 0. Ensure Data is Ready (Force Sync)
|
|
|
|
|
if(!CDataSync::EnsureDataReady(symbol, m_session_tf))
|
|
|
|
|
return false;
|
2026-02-06 18:23:12 +01:00
|
|
|
|
2026-02-07 19:44:41 +01:00
|
|
|
// 1. Identify start time
|
|
|
|
|
datetime session_start_time = iTime(symbol, m_session_tf, iBarShift(symbol, m_session_tf, time));
|
|
|
|
|
if(session_start_time == 0)
|
2026-02-06 18:23:12 +01:00
|
|
|
return false;
|
|
|
|
|
|
2026-02-07 19:44:41 +01:00
|
|
|
// 2. Cache Check (Only works if symbol didn't change! Since we reuse calc, better reset cache or check symbol)
|
|
|
|
|
// For safety in script usage (switching symbols), let's skip cache or add symbol check
|
|
|
|
|
// Assuming script creates new calc per symbol or we just refresh. Let's force refresh for safety in Script loops.
|
2026-02-06 18:23:12 +01:00
|
|
|
|
|
|
|
|
// 3. Fetch Data
|
2026-02-07 19:44:41 +01:00
|
|
|
int shift = iBarShift(symbol, m_session_tf, time);
|
|
|
|
|
if(shift < 0)
|
2026-02-06 18:23:12 +01:00
|
|
|
return false;
|
|
|
|
|
|
2026-02-07 19:44:41 +01:00
|
|
|
MqlRates rates[];
|
|
|
|
|
ArraySetAsSeries(rates, true);
|
2026-02-06 18:23:12 +01:00
|
|
|
|
2026-02-07 19:44:41 +01:00
|
|
|
if(CopyRates(symbol, m_session_tf, shift, 2, rates) != 2)
|
|
|
|
|
return false;
|
2026-02-06 18:23:12 +01:00
|
|
|
|
2026-02-07 19:44:41 +01:00
|
|
|
m_cached_levels.prev_high = rates[1].high;
|
|
|
|
|
m_cached_levels.prev_low = rates[1].low;
|
|
|
|
|
m_cached_levels.prev_close = rates[1].close;
|
|
|
|
|
m_cached_levels.curr_open = rates[0].open;
|
|
|
|
|
|
|
|
|
|
if(m_cached_levels.prev_high == 0 || m_cached_levels.curr_open == 0)
|
|
|
|
|
return false;
|
2026-02-06 18:23:12 +01:00
|
|
|
|
2026-02-07 19:44:41 +01:00
|
|
|
m_cached_levels.valid = true;
|
2026-02-06 18:23:12 +01:00
|
|
|
out_levels = m_cached_levels;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-02-07 19:44:41 +01:00
|
|
|
//| |
|
2026-02-06 18:23:12 +01:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
double CSessionLevelsCalculator::GetDistanceATR(double price, double level, double atr)
|
|
|
|
|
{
|
2026-02-07 19:44:41 +01:00
|
|
|
if(atr <= 0.00000001)
|
2026-02-06 18:23:12 +01:00
|
|
|
return 0.0;
|
|
|
|
|
return (price - level) / atr;
|
|
|
|
|
}
|
|
|
|
|
//+------------------------------------------------------------------+
|