286 lines
9.9 KiB
MQL5
286 lines
9.9 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| 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;
| |||
}
| |||
//+------------------------------------------------------------------+
|