//+------------------------------------------------------------------+ //| EnhancedSecurity.mqh | //| Copyright 2025, EscapeEA | //| https://www.escapeea.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, EscapeEA" #property link "https://www.escapeea.com" #property version "2.00" #property strict #include #include #include #include #include "RiskManager.mqh" //+------------------------------------------------------------------+ //| Security Configuration | //+------------------------------------------------------------------+ input group "=== Security Settings ===" input int InpMaxOrderRate = 10; // Max orders per minute input int InpMaxPositionSize = 100; // Max position size in lots input double InpMaxSlippagePct = 1.0; // Max allowed slippage % input bool InpEnableTamperDetection = true; // Enable tamper detection input bool InpEnableRateLimiting = true; // Enable rate limiting input int InpMaxDailyTrades = 50; // Max trades per day //+------------------------------------------------------------------+ //| CSecurityManager class | //+------------------------------------------------------------------+ class CSecurityManager { private: // Security state struct SOrderRate { datetime lastOrderTime; int orderCount; }; // Members int m_dailyTradeCount; datetime m_lastTradeDay; double m_initialBalance; CArrayObj m_orderHistory; // Private methods bool IsTampered(); bool CheckRateLimit(); bool ValidateOrderParams(double volume, double price, double sl, double tp); public: // Constructor/Destructor CSecurityManager(); ~CSecurityManager(); // Public interface bool Initialize(); void Deinitialize(); bool ValidateTradeRequest(double volume, double price, double sl, double tp); void LogTrade(const string symbol, double volume, double price, double sl, double tp); bool IsTradingAllowed(); double GetMaxAllowedPositionSize(); double CalculateMaxSlippage(double price); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CSecurityManager::CSecurityManager() : m_dailyTradeCount(0), m_lastTradeDay(0), m_initialBalance(0) { m_orderHistory.Clear(); } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CSecurityManager::~CSecurityManager() { Deinitialize(); } //+------------------------------------------------------------------+ //| Initialize security manager | //+------------------------------------------------------------------+ bool CSecurityManager::Initialize() { // Reset daily trade count m_lastTradeDay = TimeCurrent() / 86400 * 86400; // Start of current day m_dailyTradeCount = 0; m_initialBalance = AccountInfoDouble(ACCOUNT_BALANCE); // Initialize order history m_orderHistory.Clear(); // Check for tampering if(InpEnableTamperDetection && IsTampered()) { Print("Security Alert: Potential tampering detected!"); return false; } return true; } //+------------------------------------------------------------------+ //| Clean up resources | //+------------------------------------------------------------------+ void CSecurityManager::Deinitialize() { // Clean up order history m_orderHistory.Clear(); } //+------------------------------------------------------------------+ //| Check for code tampering | //+------------------------------------------------------------------+ bool CSecurityManager::IsTampered() { // Simple checksum verification // Note: In a production environment, use cryptographic hashing // Check account balance for suspicious changes double currentBalance = AccountInfoDouble(ACCOUNT_BALANCE); if(MathAbs(currentBalance - m_initialBalance) / m_initialBalance > 0.5) { // 50% change Print("Security Alert: Suspicious account balance change detected!"); return true; } // Check for modified files (pseudo-code) // This is a placeholder - actual implementation would check file hashes return false; } //+------------------------------------------------------------------+ //| Validate trade request against security rules | //+------------------------------------------------------------------+ bool CSecurityManager::ValidateTradeRequest(double volume, double price, double sl, double tp) { // Check if trading is allowed if(!IsTradingAllowed()) { Print("Security: Trading is not allowed at this time"); return false; } // Check rate limiting if(InpEnableRateLimiting && !CheckRateLimit()) { Print("Security: Rate limit exceeded"); return false; } // Validate order parameters if(!ValidateOrderParams(volume, price, sl, tp)) { Print("Security: Invalid order parameters"); return false; } // Check daily trade limit datetime currentDay = TimeCurrent() / 86400 * 86400; if(currentDay > m_lastTradeDay) { m_dailyTradeCount = 0; m_lastTradeDay = currentDay; } if(m_dailyTradeCount >= InpMaxDailyTrades) { Print("Security: Daily trade limit reached"); return false; } return true; } //+------------------------------------------------------------------+ //| Check if trading is currently allowed | //+------------------------------------------------------------------+ bool CSecurityManager::IsTradingAllowed() { // Check if market is open (example implementation) MqlDateTime dt; TimeToStruct(TimeCurrent(), dt); // Don't trade on weekends if(dt.day_of_week == 0 || dt.day_of_week == 6) { return false; } // Example: Only trade during market hours int hour = dt.hour; if(hour < 1 || hour > 23) { // Example: 01:00 - 23:00 return false; } return true; } //+------------------------------------------------------------------+ //| Check order rate limit | //+------------------------------------------------------------------+ bool CSecurityManager::CheckRateLimit() { static datetime lastOrderTime = 0; static int orderCount = 0; datetime currentTime = TimeCurrent(); // Reset counter if more than a minute has passed if(currentTime - lastOrderTime > 60) { orderCount = 0; lastOrderTime = currentTime; } // Check if rate limit exceeded if(orderCount >= InpMaxOrderRate) { return false; } orderCount++; return true; } //+------------------------------------------------------------------+ //| Validate order parameters | //+------------------------------------------------------------------+ bool CSecurityManager::ValidateOrderParams(double volume, double price, double sl, double tp) { // Check volume if(volume <= 0 || volume > GetMaxAllowedPositionSize()) { Print("Security: Invalid volume: ", volume); return false; } // Check price double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); if(price <= 0 || price < bid * 0.5 || price > ask * 2.0) { Print("Security: Invalid price: ", price); return false; } // Check stop loss and take profit if(sl > 0 && MathAbs(price - sl) > CalculateMaxSlippage(price) * 3) { Print("Security: Stop loss too far from price"); return false; } if(tp > 0 && MathAbs(tp - price) > CalculateMaxSlippage(price) * 5) { Print("Security: Take profit too far from price"); return false; } return true; } //+------------------------------------------------------------------+ //| Log trade for security auditing | //+------------------------------------------------------------------+ void CSecurityManager::LogTrade(const string symbol, double volume, double price, double sl, double tp) { // In a real implementation, this would log to a secure, tamper-evident log PrintFormat("Security: Trade executed - %s %.2f lots @ %.5f, SL: %.5f, TP: %.5f", symbol, volume, price, sl, tp); // Update daily trade count m_dailyTradeCount++; } //+------------------------------------------------------------------+ //| Get maximum allowed position size | //+------------------------------------------------------------------+ double CSecurityManager::GetMaxAllowedPositionSize() { // Calculate based on account balance and risk parameters double maxSize = AccountInfoDouble(ACCOUNT_BALANCE) * 0.01; // 1% of balance return MathMin(maxSize, InpMaxPositionSize); } //+------------------------------------------------------------------+ //| Calculate maximum allowed slippage | //+------------------------------------------------------------------+ double CSecurityManager::CalculateMaxSlippage(double price) { return price * InpMaxSlippagePct / 100.0; } //+------------------------------------------------------------------+