| //+------------------------------------------------------------------+
|
| //| 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 <Trade\PositionInfo.mqh>
|
| #include <Trade\DealInfo.mqh>
|
| #include <Trade\Trade.mqh>
|
| #include <Arrays\ArrayObj.mqh>
|
| #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;
|
| }
|
| //+------------------------------------------------------------------+
|