Files
EA/Buffer EA/Include/StateManager.mqh
Kunthawat Greethong 04aa2eb2e6 New EA and Indi
2026-01-25 10:34:54 +07:00

303 lines
10 KiB
Plaintext

//+------------------------------------------------------------------+
//| 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;
}
};
//+------------------------------------------------------------------+