//+------------------------------------------------------------------+ //| StateManager.mqh | //| Universal Buffer Reader EA v2.0 | //+------------------------------------------------------------------+ #property copyright "Copyright 2025" #property link "" #property version "1.00" #property strict //+------------------------------------------------------------------+ //| CStateManager - Manages persistent state using Global Variables | //+------------------------------------------------------------------+ class CStateManager { private: string m_symbol; int m_magic_number; string m_prefix; string m_gv_accum_loss; string m_gv_consec_loss; // Logging bool m_enable_debug; public: //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CStateManager() { m_symbol = ""; m_magic_number = 0; m_prefix = "UnivBufEA"; m_enable_debug = false; m_gv_accum_loss = ""; m_gv_consec_loss = ""; } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ ~CStateManager() { } //+------------------------------------------------------------------+ //| Set parameters | //+------------------------------------------------------------------+ void SetParameters(string symbol, int magic_number, bool enable_debug = false) { // Validate parameters if(symbol == "") { Print("[ERROR] Invalid symbol: empty string"); } m_symbol = symbol; if(magic_number <= 0) { Print("[ERROR] Invalid magic number: ", magic_number, ". Using default 24680"); m_magic_number = 24680; } else { m_magic_number = magic_number; } m_enable_debug = enable_debug; // Build Global Variable names m_gv_accum_loss = BuildGVName("_AccumLoss"); m_gv_consec_loss = BuildGVName("_ConsecLoss"); if(m_enable_debug) { Print("[StateManager] Parameters set:"); Print(" Symbol: ", m_symbol); Print(" Magic number: ", m_magic_number); Print(" GV Accum Loss: ", m_gv_accum_loss); Print(" GV Consec Loss: ", m_gv_consec_loss); } } //+------------------------------------------------------------------+ //| Set debug mode | //+------------------------------------------------------------------+ void SetDebugMode(bool enable_debug) { m_enable_debug = enable_debug; } //+------------------------------------------------------------------+ //| Load state from Global Variables | //+------------------------------------------------------------------+ bool LoadState(double &accumulated_loss, int &consecutive_losses) { if(m_enable_debug) { Print("[StateManager] Loading state..."); } accumulated_loss = 0; consecutive_losses = 0; // Load accumulated loss if(GlobalVariableCheck(m_gv_accum_loss)) { accumulated_loss = GlobalVariableGet(m_gv_accum_loss); // Validate accumulated loss if(accumulated_loss < 0) { Print("[WARNING] Invalid accumulated loss found: ", accumulated_loss, ". Resetting to 0"); accumulated_loss = 0; GlobalVariableSet(m_gv_accum_loss, 0); } Print("[StateManager] Loaded accumulated loss: ", DoubleToString(accumulated_loss, 2)); } else { if(!GlobalVariableSet(m_gv_accum_loss, 0)) { Print("[ERROR] Failed to initialize accumulated loss Global Variable"); return false; } Print("[StateManager] Initialized accumulated loss: 0"); } // Load consecutive losses if(GlobalVariableCheck(m_gv_consec_loss)) { consecutive_losses = (int)GlobalVariableGet(m_gv_consec_loss); // Validate consecutive losses if(consecutive_losses < 0) { Print("[WARNING] Invalid consecutive losses found: ", consecutive_losses, ". Resetting to 0"); consecutive_losses = 0; GlobalVariableSet(m_gv_consec_loss, 0); } Print("[StateManager] Loaded consecutive losses: ", consecutive_losses); } else { if(!GlobalVariableSet(m_gv_consec_loss, 0)) { Print("[ERROR] Failed to initialize consecutive losses Global Variable"); return false; } Print("[StateManager] Initialized consecutive losses: 0"); } if(m_enable_debug) { Print("[StateManager] State loaded successfully"); } return true; } //+------------------------------------------------------------------+ //| Save state to Global Variables | //+------------------------------------------------------------------+ bool SaveState(double accumulated_loss, int consecutive_losses) { if(m_enable_debug) { Print("[StateManager] Saving state..."); Print(" Accumulated loss: ", DoubleToString(accumulated_loss, 2)); Print(" Consecutive losses: ", consecutive_losses); } // Validate inputs if(accumulated_loss < 0) { Print("[ERROR] Invalid accumulated loss to save: ", accumulated_loss); return false; } if(consecutive_losses < 0) { Print("[ERROR] Invalid consecutive losses to save: ", consecutive_losses); return false; } bool result = true; // Save accumulated loss if(!GlobalVariableSet(m_gv_accum_loss, accumulated_loss)) { int error = GetLastError(); Print("[ERROR] Failed to save accumulated loss. Error code: ", error); result = false; } // Save consecutive losses if(!GlobalVariableSet(m_gv_consec_loss, consecutive_losses)) { int error = GetLastError(); Print("[ERROR] Failed to save consecutive losses. Error code: ", error); result = false; } if(result && m_enable_debug) { Print("[StateManager] State saved successfully"); } return result; } //+------------------------------------------------------------------+ //| Clear state (for backtesting) | //+------------------------------------------------------------------+ bool ClearState() { if(m_enable_debug) { Print("[StateManager] Clearing state..."); } bool result = true; // Delete accumulated loss if(GlobalVariableCheck(m_gv_accum_loss)) { if(!GlobalVariableDel(m_gv_accum_loss)) { int error = GetLastError(); Print("[ERROR] Failed to delete accumulated loss. Error code: ", error); result = false; } else { Print("[StateManager] Deleted accumulated loss Global Variable"); } } else { Print("[StateManager] Accumulated loss Global Variable not found (already cleared)"); } // Delete consecutive losses if(GlobalVariableCheck(m_gv_consec_loss)) { if(!GlobalVariableDel(m_gv_consec_loss)) { int error = GetLastError(); Print("[ERROR] Failed to delete consecutive losses. Error code: ", error); result = false; } else { Print("[StateManager] Deleted consecutive losses Global Variable"); } } else { Print("[StateManager] Consecutive losses Global Variable not found (already cleared)"); } if(result) { Print("[StateManager] State cleared successfully"); } return result; } //+------------------------------------------------------------------+ //| Get Global Variable names | //+------------------------------------------------------------------+ void GetGVNames(string &accum_loss_name, string &consec_loss_name) { accum_loss_name = m_gv_accum_loss; consec_loss_name = m_gv_consec_loss; } //+------------------------------------------------------------------+ //| Check if state exists | //+------------------------------------------------------------------+ bool StateExists() { bool accum_exists = GlobalVariableCheck(m_gv_accum_loss); bool consec_exists = GlobalVariableCheck(m_gv_consec_loss); return (accum_exists || consec_exists); } private: //+------------------------------------------------------------------+ //| Build Global Variable name | //+------------------------------------------------------------------+ string BuildGVName(string suffix) { return m_prefix + "_" + m_symbol + "_" + IntegerToString(m_magic_number) + suffix; } }; //+------------------------------------------------------------------+