New EA and Indi
This commit is contained in:
303
Buffer EA/Include/StateManager.mqh
Normal file
303
Buffer EA/Include/StateManager.mqh
Normal file
@@ -0,0 +1,303 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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;
|
||||
}
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
Reference in New Issue
Block a user