Files
2026-05-28 19:06:07 +03:00

143 lines
4.1 KiB
Plaintext

//+------------------------------------------------------------------+
//| Core/State.mqh |
//+------------------------------------------------------------------+
#ifndef __STATE_MQH__
#define __STATE_MQH__
#include "Config.mqh"
struct EAState
{
double dailyPnL;
double weeklyPnL;
double totalOpenRisk;
int consecutiveLosses;
int totalTradesToday;
int totalTradesWeek;
bool dailyLimitHit;
bool weeklyLimitHit;
bool consecLossHalted;
bool spreadHalted;
datetime circuitBreakerUntil;
string circuitBreakerReason;
ENUM_BIAS currentBias;
ENUM_REGIME currentRegime;
ENUM_PATTERN lastPattern;
bool volumeConfirmed;
bool isBarClosedHTF;
bool isBarClosedMTF;
bool isBarClosedLTF;
datetime lastHTFBarTime;
datetime lastMTFBarTime;
datetime lastLTFBarTime;
VWAPState vwapState;
double swingHigh;
double swingLow;
bool bosBullish;
bool bosBearish;
AssetProfile assetProfile;
int openPositions;
double equityAtStart;
double equityAtWeekStart;
datetime lastTradeClose;
ENUM_EXIT_REASON lastExitReason;
double lastTradePnL;
string logDirectory;
bool loggerReady;
datetime lastDashboardUpdate;
};
class CSessionManager
{
private:
datetime m_lastSessionCheck;
int m_serverOffset;
datetime GetGMTTime() const
{
return TimeGMT();
}
public:
CSessionManager() : m_lastSessionCheck(0), m_serverOffset(0) {}
bool Init()
{
datetime serverNow = TimeCurrent();
datetime gmtNow = TimeGMT();
m_serverOffset = (int)((serverNow - gmtNow) / 3600);
if(InpDebugMode)
Print("[SessionManager] Server-GMT offset: ", m_serverOffset, " hours");
return true;
}
bool IsSessionValid(const AssetProfile &profile) const
{
if(profile.trade24_7) return true;
MqlDateTime dt;
TimeToStruct(TimeGMT(), dt);
int currentHour = dt.hour;
int currentDay = dt.day_of_week;
if(profile.skipWeekend && (currentDay == 0 || currentDay == 6))
return false;
if(profile.assetClass == ASSET_METAL && currentDay == 5 && currentHour >= 21)
return false;
if(profile.assetClass == ASSET_METAL && currentDay == 1 && currentHour < 1)
return false;
if(currentHour >= profile.sessionStartHour && currentHour < profile.sessionEndHour)
return true;
return false;
}
bool IsNewSession(const AssetProfile &profile) const
{
MqlDateTime dt;
TimeToStruct(TimeGMT(), dt);
if((profile.assetClass == ASSET_FOREX_MAJOR || profile.assetClass == ASSET_FOREX_CROSS ||
profile.assetClass == ASSET_METAL) && dt.hour == 8 && dt.min == 0)
return true;
if(profile.assetClass == ASSET_INDEX && dt.hour == 13 && dt.min == 30)
return true;
if(profile.assetClass == ASSET_CRYPTO && dt.hour == 0 && dt.min == 0)
return true;
return false;
}
datetime GetSessionStart(const AssetProfile &profile) const
{
datetime gmtNow = TimeGMT();
MqlDateTime dt;
TimeToStruct(gmtNow, dt);
datetime sessionStart = 0;
if(profile.assetClass == ASSET_INDEX)
{
if(dt.hour < 13 || (dt.hour == 13 && dt.min < 30))
sessionStart = StringToTime(StringFormat("%04d.%02d.%02d 13:30:00", dt.year, dt.mon, dt.day)) - 86400;
else
sessionStart = StringToTime(StringFormat("%04d.%02d.%02d 13:30:00", dt.year, dt.mon, dt.day));
}
else
{
if(dt.hour < 8)
sessionStart = StringToTime(StringFormat("%04d.%02d.%02d 08:00:00", dt.year, dt.mon, dt.day)) - 86400;
else
sessionStart = StringToTime(StringFormat("%04d.%02d.%02d 08:00:00", dt.year, dt.mon, dt.day));
}
return sessionStart + (m_serverOffset * 3600);
}
bool IsRolloverTime() const
{
MqlDateTime dt;
TimeToStruct(TimeCurrent(), dt);
if((dt.hour == 23 && dt.min >= 50) || (dt.hour == 0 && dt.min <= 10))
return true;
return false;
}
};
EAState g_state;
CSessionManager g_session;
#endif // __STATE_MQH__