mql5/Include/Escape/RiskManager.mqh

266 lines
12 KiB
MQL5
Raw Permalink Normal View History

2025-08-05 01:57:33 -04:00
//+------------------------------------------------------------------+
//| RiskManager.mqh |
//| Copyright 2025, EscapeEA |
//| https://www.escapeea.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, EscapeEA"
#property link "https://www.escapeea.com"
#property version "2.20" // Version bump for major enhancements
#property strict
// Standard Library Includes
#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\DealInfo.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\HistoryOrderInfo.mqh>
#include <Arrays\ArrayObj.mqh>
#include <Arrays\ArrayString.mqh>
#include <Arrays\ArrayDouble.mqh>
#include <Files\FileBin.mqh>
#include <Math\Stat\Math.mqh>
#include <Math\Stat\Normal.mqh>
// Forward declarations
class CSecurityManager;
// Risk error codes
enum ENUM_RISK_ERROR_CODES
{
RISK_ERROR_NONE = 0, // No error
RISK_ERROR_INVALID_STATE = 1000, // Invalid object state
RISK_ERROR_MEMORY = 1001, // Memory allocation failure
RISK_ERROR_INVALID_PARAM = 1002, // Invalid parameter
RISK_ERROR_IO = 1003, // I/O operation failed
RISK_ERROR_RATE_LIMIT = 1004, // Rate limit exceeded
RISK_ERROR_DAILY_LIMIT = 1005, // Daily limit reached
RISK_ERROR_TRADE_LIMIT = 1006, // Trade limit reached
RISK_ERROR_CONFIG = 1007, // Configuration error
RISK_ERROR_THREAD = 1008, // Threading error
RISK_ERROR_NOT_INITIALIZED = 1009, // Manager not initialized
RISK_ERROR_SYMBOL = 1010, // Invalid symbol
RISK_ERROR_VOLUME = 1011, // Invalid volume
RISK_ERROR_PRICE = 1012, // Invalid price
RISK_ERROR_STOPLOSS = 1013, // Invalid stop loss
RISK_ERROR_TAKEPROFIT = 1014, // Invalid take profit
RISK_ERROR_MARGIN = 1015, // Not enough margin
RISK_ERROR_MARKET_CLOSED = 1016, // Market is closed
RISK_ERROR_TRADE_DISABLED = 1017, // Trading is disabled
RISK_ERROR_ACCOUNT = 1018, // Account error
RISK_ERROR_TIMEOUT = 1019, // Operation timeout
RISK_ERROR_CONNECTION = 1020 // Connection error
};
// Risk error severity levels
enum ENUM_RISK_ERROR_SEVERITY
{
RISK_SEVERITY_NONE = 0, // No error
RISK_SEVERITY_INFO = 1, // Informational message
RISK_SEVERITY_WARNING = 2, // Warning - non-critical issue
RISK_SEVERITY_CRITICAL = 3, // Critical error - trading should be paused
RISK_SEVERITY_FATAL = 4 // Fatal error - immediate action required
};
// Position sizing methods
enum ENUM_POSITION_SIZING_METHOD
{
POSITION_SIZING_FIXED = 0, // Fixed lot size
POSITION_SIZING_RISK_BASED, // Based on account risk percentage
POSITION_SIZING_VOLATILITY, // Based on market volatility (ATR)
POSITION_SIZING_KELLY, // Kelly Criterion
POSITION_SIZING_OPTIMAL_F, // Optimal F
POSITION_SIZING_HYBRID, // Hybrid approach
POSITION_SIZING_MARTINGALE, // Martingale (use with caution)
POSITION_SIZING_ANTI_MARTINGALE // Anti-Martingale
};
// Position scaling methods
enum ENUM_POSITION_SCALING
{
SCALING_NONE = 0, // No scaling
SCALING_LINEAR, // Linear scaling with account growth
SCALING_SQRT, // Square root scaling
SCALING_LOGARITHMIC, // Logarithmic scaling
SCALING_AGGRESSIVE, // Aggressive scaling (exponential)
SCALING_CONSERVATIVE // Conservative scaling (diminishing returns)
};
// Trade direction
enum ENUM_TRADE_DIRECTION
{
TRADE_DIRECTION_LONG = 1, // Long position
TRADE_DIRECTION_SHORT = -1, // Short position
TRADE_DIRECTION_BOTH = 0 // Both directions
};
// Trade metrics structure for performance analysis
struct STradeMetrics
{
datetime timestamp; // Time of the trade
string symbol; // Symbol
double volume; // Trade volume in lots
double entryPrice; // Entry price
double exitPrice; // Exit price (0 if still open)
double stopLoss; // Stop loss level
double takeProfit; // Take profit level
double pips; // Pips gained/lost
double profit; // Profit/loss in account currency
double drawdown; // Drawdown at time of trade
double volatility; // Market volatility (ATR)
double spread; // Spread at time of trade
int duration; // Trade duration in seconds
string comment; // Additional comments
double winRate; // Current win rate when trade was opened
double riskReward; // Risk/reward ratio
double kellySize; // Kelly position size
double optimalFSize; // Optimal F position size
// Default constructor
STradeMetrics() : timestamp(0), symbol(""), volume(0), entryPrice(0), exitPrice(0),
stopLoss(0), takeProfit(0), pips(0), profit(0), drawdown(0),
volatility(0), spread(0), duration(0), winRate(0), riskReward(0),
kellySize(0), optimalFSize(0) {}
};
//+------------------------------------------------------------------+
//| CRiskManager - Advanced Risk Management Class |
//+------------------------------------------------------------------+
class CRiskManager
{
private:
// Thread synchronization
CCriticalSection m_cs; // Thread synchronization object
// Configuration
double m_riskPerTrade; // Risk percentage per trade (0.1-5.0%)
double m_dailyLossLimit; // Daily loss limit (% of account)
int m_maxOpenTrades; // Maximum number of open trades
int m_maxOrdersPerDay; // Maximum orders per day
// State
double m_dailyPnL; // Today's P&L
int m_todayTrades; // Trades executed today
bool m_initialized; // Initialization flag
datetime m_lastTradeDay; // Last trading day
// Error handling
string m_lastError; // Last error message
ENUM_RISK_ERROR_CODES m_lastErrorCode; // Last error code
ENUM_RISK_ERROR_SEVERITY m_lastErrorSeverity; // Error severity
// Position sizing
ENUM_POSITION_SIZING_METHOD m_sizingMethod; // Current sizing method
ENUM_POSITION_SCALING m_scalingMethod; // Position scaling method
double m_minPositionSize; // Minimum position size
double m_maxPositionSize; // Maximum position size
double m_positionSizeStep; // Position size step
double m_kellyFraction; // Kelly fraction (0-1)
double m_optimalFFraction; // Optimal F fraction (0-1)
double m_volatilityPeriod; // Period for volatility calculation
double m_volatilityMultiplier; // Volatility multiplier
// Caching
struct SSymbolCache
{
double lastPrice; // Last price
double atrValue; // Last ATR value
datetime lastUpdate; // Last update time
double spread; // Current spread
double pointValue; // Point value in account currency
SSymbolCache() : lastPrice(0), atrValue(0), lastUpdate(0), spread(0), pointValue(0) {}
};
CArrayObj* m_symbolCache; // Cache for symbol data
// Trade history
CArrayObj* m_tradeHistory; // Trade history for analysis
int m_maxHistorySize; // Maximum number of trades to keep in history
// Performance metrics
double m_equityPeak; // Peak equity for drawdown calculation
double m_maxDrawdown; // Maximum drawdown percentage
double m_winRate; // Current win rate
double m_avgWin; // Average win amount
double m_avgLoss; // Average loss amount
double m_riskRewardRatio; // Average risk/reward ratio
// Private methods
double CalculateRiskBasedSize(const string symbol, double entryPrice, double stopLoss, double riskAmount);
double CalculateVolatilitySize(const string symbol, double entryPrice, double stopLoss, double riskAmount);
double CalculateKellySize(double winRate, double winLossRatio, double riskAmount);
double CalculateOptimalFSize(double winRate, double winLossRatio, double riskAmount);
double CalculateHybridSize(const string symbol, double entryPrice, double stopLoss, double riskAmount);
double ScalePositionSize(double size, double accountGrowth);
// Helper methods
bool IsValidSymbol(const string symbol) const;
double NormalizeLotSize(double lots) const;
double GetATR(const string symbol, int timeframe, int period, int shift = 0) const;
void UpdateSymbolCache(const string symbol);
void UpdateTradeMetrics(const STradeMetrics& metrics);
double CalculateWinRate() const;
double CalculateWinLossRatio() const;
public:
// Constructor/Destructor
CRiskManager();
~CRiskManager();
// Initialization
bool Initialize();
void Deinitialize();
bool IsInitialized() const { return m_initialized; }
// Configuration
void SetRiskParameters(double riskPerTrade, double dailyLossLimit, int maxOpenTrades, int maxOrdersPerDay);
void SetPositionSizingMethod(ENUM_POSITION_SIZING_METHOD method) { m_sizingMethod = method; }
void SetPositionScaling(ENUM_POSITION_SCALING method) { m_scalingMethod = method; }
void SetPositionSizeLimits(double minSize, double maxSize, double step = 0.01);
void SetKellyFraction(double fraction) { m_kellyFraction = MathClamp(fraction, 0.0, 1.0); }
void SetOptimalFFraction(double fraction) { m_optimalFFraction = MathClamp(fraction, 0.0, 1.0); }
void SetVolatilityPeriod(int period) { m_volatilityPeriod = MathMax(5, period); }
void SetVolatilityMultiplier(double multiplier) { m_volatilityMultiplier = MathMax(0.1, multiplier); }
// Position sizing
double CalculatePositionSize(const string symbol, double entryPrice, double stopLoss, double riskAmount);
// Risk management
bool CheckTradeRisk(const string symbol, double lots, double entryPrice, double stopLoss, double takeProfit, ENUM_ORDER_TYPE orderType);
bool CheckDailyLossLimit() const;
bool CheckMaxOpenTrades() const;
bool CheckDrawdownLimit() const;
bool CheckVolatility(const string symbol) const;
// Trade event handlers
void OnTradeOpen(ulong ticket, const string symbol, ENUM_ORDER_TYPE orderType, double volume, double price, double stopLoss, double takeProfit);
void OnTradeClose(ulong ticket, const string symbol, ENUM_ORDER_TYPE orderType, double volume, double price, double profit, double swap);
// Performance analysis
double GetWinRate() const { return m_winRate; }
double GetMaxDrawdown() const { return m_maxDrawdown; }
double GetRiskRewardRatio() const { return m_riskRewardRatio; }
int GetTotalTrades() const { return m_tradeHistory.Total(); }
// Error handling
string GetLastError() const { return m_lastError; }
ENUM_RISK_ERROR_CODES GetLastErrorCode() const { return m_lastErrorCode; }
ENUM_RISK_ERROR_SEVERITY GetLastErrorSeverity() const { return m_lastErrorSeverity; }
// State management
void ResetDailyMetrics();
void ResetAllMetrics();
double GetDailyPnL() const { return m_dailyPnL; }
int GetTodayTrades() const { return m_todayTrades; }
// Reporting
string GenerateReport() const;
// Adversarial testing hooks
#ifdef ADVSECURITY_ENABLE_TESTING
friend class CRiskManagerTester;
#endif
};
// Include implementation
#include "RiskManager_Impl.mqh"