//+------------------------------------------------------------------+
//|                                                  RiskManager.mqh |
//|                              Copyright 2025, Professional Trader |
//|                          Advanced Risk Management System         |
//+------------------------------------------------------------------+

#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\TerminalInfo.mqh>

//+------------------------------------------------------------------+
//| Risk Management Class                                            |
//+------------------------------------------------------------------+
class CRiskManager
{
private:
   double            m_riskPercent;           // Risk percentage per trade
   double            m_maxDrawdown;           // Maximum allowed drawdown
   double            m_defaultStopLoss;       // Default stop loss in points
   double            m_defaultTakeProfit;     // Default take profit in points
   double            m_maxRiskPerTrade;       // Maximum risk per trade in currency
   double            m_maxPortfolioRisk;      // Maximum portfolio risk
   double            m_currentPortfolioRisk;  // Current portfolio risk
   double            m_maxDailyRisk;          // Maximum daily risk
   double            m_dailyLoss;             // Current daily loss
   datetime          m_lastDayReset;          // Last day when daily counters were reset
   bool              m_riskManagementEnabled; // Risk management enabled flag
   double            m_minRiskReward;         // Minimum risk/reward ratio
   bool              m_useVolatilityBasedSizing; // Use volatility-based sizing
   
   CAccountInfo      m_account;
   CPositionInfo     m_position;
   
public:
                     CRiskManager(double riskPercent = 2.0, double maxDrawdown = 15.0, 
                                 double defaultSL = 100.0, double defaultTP = 200.0);
                    ~CRiskManager();
   
   // Initialization
   bool              Initialize();
   
   // Core Risk Management Functions
   bool              CheckRiskLimits();
   double            CalculatePositionSize(double entryPrice, double stopLoss);
   double            CalculatePositionSize(ENUM_POSITION_TYPE posType, double entryPrice = 0, double stopLoss = 0);
   double            CalculateRiskAmount();
   bool              ValidateTradeRisk(double lotSize, double stopLossDistance);
   
   // Portfolio Risk Management
   void              UpdatePortfolioRisk();
   double            GetCurrentDrawdown();
   bool              IsDrawdownAcceptable();
   int               GetMaxAllowedPositions();
   bool              IsDailyRiskLimitReached();
   bool              IsRiskManagementEnabled() { return m_riskManagementEnabled; }
   
   // Position Sizing Methods
   double            FixedPercentRisk(double stopLossPoints);
   double            FixedLotSizing();
   double            ATRBasedSizing(double atrValue, double atrMultiplier = 2.0);
   double            VolatilityBasedSizing(double volatility);
   
   // Risk Validation
   bool              ValidateStopLoss(double entryPrice, double stopLoss, ENUM_POSITION_TYPE posType);
   bool              ValidateTakeProfit(double entryPrice, double takeProfit, ENUM_POSITION_TYPE posType);
   double            GetMinStopLossDistance();
   
   // Setters and Getters
   void              SetRiskPercent(double percent) { m_riskPercent = MathMax(0.1, MathMin(10.0, percent)); }
   void              SetMaxDrawdown(double drawdown) { m_maxDrawdown = MathMax(5.0, MathMin(50.0, drawdown)); }
   void              SetDefaultStopLoss(double sl) { m_defaultStopLoss = MathMax(10.0, sl); }
   void              SetDefaultTakeProfit(double tp) { m_defaultTakeProfit = MathMax(10.0, tp); }
   void              SetMaxDailyRisk(double dailyRisk) { m_maxDailyRisk = MathMax(1.0, MathMin(20.0, dailyRisk)); }
   void              SetStopLoss(double sl) { SetDefaultStopLoss(sl); }
   void              SetTakeProfit(double tp) { SetDefaultTakeProfit(tp); }
   
   double            GetRiskPercent() { return m_riskPercent; }
   double            GetMaxDrawdown() { return m_maxDrawdown; }
   double            GetCurrentPortfolioRisk() { return m_currentPortfolioRisk; }
   double            GetMaxRiskPerTrade() { return m_maxRiskPerTrade; }
   double            GetMaxDailyRisk() { return m_maxDailyRisk; }
   
   // Utility Functions
   double            GetAccountRiskCapacity();
   string            GetRiskReport();
   void              PrintRiskStatus();
   void              UpdateDailyRisk();
   
   bool              CanOpenNewPosition();
   void              UpdateRiskAssessment();
   double            CalculateOptimalLotSize(double riskAmount, double stopDistance);
   void              SetMaxRiskPerTrade(double maxRisk);
   void              SetMaxPortfolioRisk(double maxRisk);
   void              SetMinRiskReward(double minRR);
   void              EnableVolatilityBasedSizing(bool enable);
   double            GetTotalPortfolioRisk();

private:
   double            CalculateTickValue();
   double            GetCurrentEquity();
   double            GetCurrentBalance();
   int               CountOpenPositions();
   double            CalculateOpenPositionsRisk();
   void              ResetDailyCounters();
};

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CRiskManager::CRiskManager(double riskPercent, double maxDrawdown, double defaultSL, double defaultTP)
{
   m_riskPercent = MathMax(0.1, MathMin(10.0, riskPercent));
   m_maxDrawdown = MathMax(5.0, MathMin(50.0, maxDrawdown));
   m_defaultStopLoss = MathMax(10.0, defaultSL);
   m_defaultTakeProfit = MathMax(10.0, defaultTP);
   m_maxDailyRisk = 6.0; // Default 6% daily risk
   
   m_currentPortfolioRisk = 0.0;
   m_maxRiskPerTrade = 0.0;
   m_maxPortfolioRisk = m_maxDrawdown * 0.8; // 80% of max drawdown
   m_dailyLoss = 0.0;
   m_lastDayReset = TimeCurrent();
   m_riskManagementEnabled = true;
   
   m_minRiskReward = 1.5; // Default 1:1.5 risk/reward
   m_useVolatilityBasedSizing = false;
   
   UpdatePortfolioRisk();
   
   Print("Risk Manager initialized - Risk: ", m_riskPercent, "%, Max DD: ", m_maxDrawdown, "%");
}

//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CRiskManager::~CRiskManager()
{
   Print("Risk Manager destroyed");
}

//+------------------------------------------------------------------+
//| Initialize Risk Manager                                          |
//+------------------------------------------------------------------+
bool CRiskManager::Initialize()
{
   // Reset counters and update portfolio risk
   UpdatePortfolioRisk();
   UpdateDailyRisk();
   
   Print("Risk Manager initialized successfully");
   return true;
}

//+------------------------------------------------------------------+
//| Check if daily risk limit is reached                            |
//+------------------------------------------------------------------+
bool CRiskManager::IsDailyRiskLimitReached()
{
   UpdateDailyRisk();
   
   double equity = GetCurrentEquity();
   if(equity <= 0) return true;
   
   double dailyRiskPercent = (m_dailyLoss / equity) * 100.0;
   
   if(dailyRiskPercent >= m_maxDailyRisk)
   {
      Print("Daily risk limit reached: ", DoubleToString(dailyRiskPercent, 2), "% / ", DoubleToString(m_maxDailyRisk, 2), "%");
      return true;
   }
   
   return false;
}

//+------------------------------------------------------------------+
//| Update daily risk tracking                                       |
//+------------------------------------------------------------------+
void CRiskManager::UpdateDailyRisk()
{
   MqlDateTime currentTime, lastResetTime;
   TimeToStruct(TimeCurrent(), currentTime);
   TimeToStruct(m_lastDayReset, lastResetTime);
   
   // Reset daily counters if new day
   if(currentTime.day != lastResetTime.day)
   {
      ResetDailyCounters();
   }
   
   // Calculate current daily loss from positions
   double currentDailyLoss = 0.0;
   for(int i = 0; i < PositionsTotal(); i++)
   {
      if(m_position.SelectByIndex(i))
      {
         if(m_position.Symbol() == Symbol())
         {
            double positionProfit = m_position.Profit() + m_position.Swap() + m_position.Commission();
            if(positionProfit < 0)
            {
               // Check if position was opened today
               datetime openTime = m_position.Time();
               MqlDateTime openDateTime;
               TimeToStruct(openTime, openDateTime);
               
               if(openDateTime.day == currentTime.day)
               {
                  currentDailyLoss += MathAbs(positionProfit);
               }
            }
         }
      }
   }
   
   m_dailyLoss = currentDailyLoss;
}

//+------------------------------------------------------------------+
//| Reset daily counters                                             |
//+------------------------------------------------------------------+
void CRiskManager::ResetDailyCounters()
{
   m_dailyLoss = 0.0;
   m_lastDayReset = TimeCurrent();
   Print("Daily risk counters reset");
}

//+------------------------------------------------------------------+
//| Calculate position size (simplified version)                    |
//+------------------------------------------------------------------+
double CRiskManager::CalculatePositionSize(double entryPrice, double stopLoss)
{
   if(!m_riskManagementEnabled) return 0.1; // Default lot size
   
   double riskAmount = CalculateRiskAmount();
   if(riskAmount <= 0 || entryPrice <= 0 || stopLoss <= 0) return 0.0;
   
   // Calculate stop loss distance in price
   double slDistance = MathAbs(entryPrice - stopLoss);
   if(slDistance <= 0) return 0.0;
   
   // Calculate tick value
   double tickValue = CalculateTickValue();
   if(tickValue <= 0) return 0.0;
   
   // Calculate position size
   double lotSize = riskAmount / (slDistance * tickValue * 100000); // 100000 for standard lot
   
   // Apply broker limits
   double minLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN);
   double maxLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MAX);
   double stepLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_STEP);
   
   lotSize = MathMax(lotSize, minLot);
   lotSize = MathMin(lotSize, maxLot);
   lotSize = MathRound(lotSize / stepLot) * stepLot;
   
   return lotSize;
}

//+------------------------------------------------------------------+
//| Check if risk limits are within acceptable range                |
//+------------------------------------------------------------------+
bool CRiskManager::CheckRiskLimits()
{
   UpdatePortfolioRisk();
   UpdateDailyRisk();
   
   // Check daily risk limit
   if(IsDailyRiskLimitReached())
   {
      return false;
   }
   
   // Check current drawdown
   double currentDD = GetCurrentDrawdown();
   if(currentDD > m_maxDrawdown)
   {
      Print("RISK ALERT: Maximum drawdown exceeded - Current: ", DoubleToString(currentDD, 2), 
            "%, Max: ", DoubleToString(m_maxDrawdown, 2), "%");
      return false;
   }
   
   // Check portfolio risk
   if(m_currentPortfolioRisk > m_maxPortfolioRisk)
   {
      Print("RISK ALERT: Portfolio risk too high - Current: ", DoubleToString(m_currentPortfolioRisk, 2), 
            "%, Max: ", DoubleToString(m_maxPortfolioRisk, 2), "%");
      return false;
   }
   
   // Check account equity vs balance
   double equity = GetCurrentEquity();
   double balance = GetCurrentBalance();
   if(equity < balance * 0.9) // 10% equity drop from balance
   {
      Print("RISK ALERT: Equity significantly below balance - Equity: ", equity, ", Balance: ", balance);
      return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| Calculate optimal position size                                 |
//+------------------------------------------------------------------+
double CRiskManager::CalculatePositionSize(ENUM_POSITION_TYPE posType, double entryPrice, double stopLoss)
{
   double riskAmount = CalculateRiskAmount();
   if(riskAmount <= 0) return 0.0;
   
   // Get current price if entry price not provided
   if(entryPrice <= 0)
   {
      entryPrice = (posType == POSITION_TYPE_BUY) ? 
                   SymbolInfoDouble(Symbol(), SYMBOL_ASK) : 
                   SymbolInfoDouble(Symbol(), SYMBOL_BID);
   }
   
   // Use default stop loss if not provided
   if(stopLoss <= 0)
   {
      double slDistance = m_defaultStopLoss * SymbolInfoDouble(Symbol(), SYMBOL_POINT);
      stopLoss = (posType == POSITION_TYPE_BUY) ? 
                 entryPrice - slDistance : entryPrice + slDistance;
   }
   
   // Calculate stop loss distance in price
   double slDistance = MathAbs(entryPrice - stopLoss);
   if(slDistance <= 0) return 0.0;
   
   // Calculate tick value
   double tickValue = CalculateTickValue();
   if(tickValue <= 0) return 0.0;
   
   // Calculate position size
   double lotSize = riskAmount / (slDistance * tickValue * 100000); // 100000 for standard lot
   
   // Apply broker limits
   double minLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN);
   double maxLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MAX);
   double stepLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_STEP);
   
   lotSize = MathMax(lotSize, minLot);
   lotSize = MathMin(lotSize, maxLot);
   lotSize = MathRound(lotSize / stepLot) * stepLot;
   
   // Final validation
   if(!ValidateTradeRisk(lotSize, slDistance))
   {
      Print("Risk validation failed for calculated lot size");
      return 0.0;
   }
   
   return lotSize;
}

//+------------------------------------------------------------------+
//| Calculate risk amount based on account size and risk percentage |
//+------------------------------------------------------------------+
double CRiskManager::CalculateRiskAmount()
{
   double equity = GetCurrentEquity();
   double riskAmount = equity * (m_riskPercent / 100.0);
   
   // Ensure we don't risk more than maximum allowed
   m_maxRiskPerTrade = equity * 0.05; // Maximum 5% per trade
   riskAmount = MathMin(riskAmount, m_maxRiskPerTrade);
   
   return riskAmount;
}

//+------------------------------------------------------------------+
//| Validate trade risk                                             |
//+------------------------------------------------------------------+
bool CRiskManager::ValidateTradeRisk(double lotSize, double stopLossDistance)
{
   if(lotSize <= 0 || stopLossDistance <= 0) return false;
   
   // Calculate actual risk
   double tickValue = CalculateTickValue();
   double actualRisk = lotSize * stopLossDistance * tickValue * 100000;
   
   // Check against maximum risk per trade
   double maxRisk = CalculateRiskAmount();
   if(actualRisk > maxRisk * 1.1) // Allow 10% tolerance
   {
      Print("Trade risk too high - Actual: ", actualRisk, ", Max: ", maxRisk);
      return false;
   }
   
   // Check margin requirements
   double requiredMargin = lotSize * SymbolInfoDouble(Symbol(), SYMBOL_MARGIN_INITIAL);
   double freeMargin = m_account.FreeMargin();
   
   if(requiredMargin > freeMargin * 0.8) // Use max 80% of free margin
   {
      Print("Insufficient margin - Required: ", requiredMargin, ", Available: ", freeMargin);
      return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| Update current portfolio risk                                   |
//+------------------------------------------------------------------+
void CRiskManager::UpdatePortfolioRisk()
{
   m_currentPortfolioRisk = CalculateOpenPositionsRisk();
}

//+------------------------------------------------------------------+
//| Calculate current drawdown                                      |
//+------------------------------------------------------------------+
double CRiskManager::GetCurrentDrawdown()
{
   double equity = GetCurrentEquity();
   double balance = GetCurrentBalance();
   
   if(balance <= 0) return 0.0;
   
   double drawdown = (balance - equity) / balance * 100.0;
   return MathMax(0.0, drawdown);
}

//+------------------------------------------------------------------+
//| Check if drawdown is acceptable                                 |
//+------------------------------------------------------------------+
bool CRiskManager::IsDrawdownAcceptable()
{
   return GetCurrentDrawdown() <= m_maxDrawdown;
}

//+------------------------------------------------------------------+
//| Get maximum allowed positions                                   |
//+------------------------------------------------------------------+
int CRiskManager::GetMaxAllowedPositions()
{
   // Calculate based on risk per trade and maximum portfolio risk
   double riskPerTrade = m_riskPercent;
   double maxPortfolioRisk = m_maxDrawdown * 0.6; // Conservative approach
   
   int maxPositions = (int)(maxPortfolioRisk / riskPerTrade);
   return MathMax(1, MathMin(10, maxPositions)); // Between 1 and 10 positions
}

//+------------------------------------------------------------------+
//| Fixed percentage risk position sizing                           |
//+------------------------------------------------------------------+
double CRiskManager::FixedPercentRisk(double stopLossPoints)
{
   if(stopLossPoints <= 0) return 0.0;
   
   double riskAmount = CalculateRiskAmount();
   double tickValue = CalculateTickValue();
   
   double lotSize = riskAmount / (stopLossPoints * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * tickValue * 100000);
   
   // Apply broker limits
   double minLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN);
   double maxLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MAX);
   double stepLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_STEP);
   
   lotSize = MathMax(lotSize, minLot);
   lotSize = MathMin(lotSize, maxLot);
   lotSize = MathRound(lotSize / stepLot) * stepLot;
   
   return lotSize;
}

//+------------------------------------------------------------------+
//| Fixed lot sizing                                                |
//+------------------------------------------------------------------+
double CRiskManager::FixedLotSizing()
{
   double baseLot = 0.1; // Default base lot
   double equity = GetCurrentEquity();
   
   // Scale lot size with account size
   if(equity >= 10000) baseLot = 0.5;
   else if(equity >= 5000) baseLot = 0.3;
   else if(equity >= 1000) baseLot = 0.1;
   else baseLot = 0.01;
   
   return baseLot;
}

//+------------------------------------------------------------------+
//| ATR-based position sizing                                       |
//+------------------------------------------------------------------+
double CRiskManager::ATRBasedSizing(double atrValue, double atrMultiplier)
{
   if(atrValue <= 0) return FixedLotSizing();
   
   double stopLossDistance = atrValue * atrMultiplier;
   double stopLossPoints = stopLossDistance / SymbolInfoDouble(Symbol(), SYMBOL_POINT);
   
   return FixedPercentRisk(stopLossPoints);
}

//+------------------------------------------------------------------+
//| Volatility-based position sizing                               |
//+------------------------------------------------------------------+
double CRiskManager::VolatilityBasedSizing(double volatility)
{
   double baseLot = FixedLotSizing();
   
   // Adjust lot size based on volatility
   if(volatility > 0.03) // High volatility
      return baseLot * 0.7;
   else if(volatility < 0.01) // Low volatility
      return baseLot * 1.3;
   else
      return baseLot;
}

//+------------------------------------------------------------------+
//| Validate stop loss level                                       |
//+------------------------------------------------------------------+
bool CRiskManager::ValidateStopLoss(double entryPrice, double stopLoss, ENUM_POSITION_TYPE posType)
{
   if(entryPrice <= 0 || stopLoss <= 0) return false;
   
   double minDistance = GetMinStopLossDistance();
   double actualDistance = MathAbs(entryPrice - stopLoss);
   
   if(actualDistance < minDistance)
   {
      Print("Stop loss too close - Actual: ", actualDistance, ", Min: ", minDistance);
      return false;
   }
   
   // Check direction
   if(posType == POSITION_TYPE_BUY && stopLoss >= entryPrice)
   {
      Print("Invalid stop loss for BUY position");
      return false;
   }
   
   if(posType == POSITION_TYPE_SELL && stopLoss <= entryPrice)
   {
      Print("Invalid stop loss for SELL position");
      return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| Validate take profit level                                     |
//+------------------------------------------------------------------+
bool CRiskManager::ValidateTakeProfit(double entryPrice, double takeProfit, ENUM_POSITION_TYPE posType)
{
   if(entryPrice <= 0 || takeProfit <= 0) return false;
   
   // Check direction
   if(posType == POSITION_TYPE_BUY && takeProfit <= entryPrice)
   {
      Print("Invalid take profit for BUY position");
      return false;
   }
   
   if(posType == POSITION_TYPE_SELL && takeProfit >= entryPrice)
   {
      Print("Invalid take profit for SELL position");
      return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| Get minimum stop loss distance                                 |
//+------------------------------------------------------------------+
double CRiskManager::GetMinStopLossDistance()
{
   double spread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD) * SymbolInfoDouble(Symbol(), SYMBOL_POINT);
   double stopLevel = SymbolInfoInteger(Symbol(), SYMBOL_TRADE_STOPS_LEVEL) * SymbolInfoDouble(Symbol(), SYMBOL_POINT);
   
   return MathMax(spread * 2, stopLevel);
}

//+------------------------------------------------------------------+
//| Get account risk capacity                                       |
//+------------------------------------------------------------------+
double CRiskManager::GetAccountRiskCapacity()
{
   double equity = GetCurrentEquity();
   double maxRisk = equity * (m_maxDrawdown / 100.0);
   double currentRisk = m_currentPortfolioRisk * equity / 100.0;
   
   return maxRisk - currentRisk;
}

//+------------------------------------------------------------------+
//| Generate risk report                                            |
//+------------------------------------------------------------------+
string CRiskManager::GetRiskReport()
{
   string report = "=== RISK MANAGEMENT REPORT ===\n";
   report += "Account Equity: $" + DoubleToString(GetCurrentEquity(), 2) + "\n";
   report += "Risk per Trade: " + DoubleToString(m_riskPercent, 2) + "%\n";
   report += "Current Drawdown: " + DoubleToString(GetCurrentDrawdown(), 2) + "%\n";
   report += "Max Drawdown: " + DoubleToString(m_maxDrawdown, 2) + "%\n";
   report += "Portfolio Risk: " + DoubleToString(m_currentPortfolioRisk, 2) + "%\n";
   report += "Daily Risk: " + DoubleToString((m_dailyLoss / GetCurrentEquity()) * 100.0, 2) + "%\n";
   report += "Max Daily Risk: " + DoubleToString(m_maxDailyRisk, 2) + "%\n";
   report += "Open Positions: " + IntegerToString(CountOpenPositions()) + "\n";
   report += "Risk Capacity: $" + DoubleToString(GetAccountRiskCapacity(), 2) + "\n";
   report += "=============================";
   
   return report;
}

//+------------------------------------------------------------------+
//| Print current risk status                                       |
//+------------------------------------------------------------------+
void CRiskManager::PrintRiskStatus()
{
   Print(GetRiskReport());
}

//+------------------------------------------------------------------+
//| Calculate tick value                                            |
//+------------------------------------------------------------------+
double CRiskManager::CalculateTickValue()
{
   double tickValue = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE);
   if(tickValue <= 0)
   {
      // Fallback calculation
      tickValue = SymbolInfoDouble(Symbol(), SYMBOL_POINT) * 
                  SymbolInfoDouble(Symbol(), SYMBOL_TRADE_CONTRACT_SIZE);
   }
   
   return tickValue;
}

//+------------------------------------------------------------------+
//| Get current equity                                             |
//+------------------------------------------------------------------+
double CRiskManager::GetCurrentEquity()
{
   return m_account.Equity();
}

//+------------------------------------------------------------------+
//| Get current balance                                            |
//+------------------------------------------------------------------+
double CRiskManager::GetCurrentBalance()
{
   return m_account.Balance();
}

//+------------------------------------------------------------------+
//| Count open positions                                           |
//+------------------------------------------------------------------+
int CRiskManager::CountOpenPositions()
{
   int count = 0;
   for(int i = 0; i < PositionsTotal(); i++)
   {
      if(m_position.SelectByIndex(i))
      {
         if(m_position.Symbol() == Symbol())
            count++;
      }
   }
   return count;
}

//+------------------------------------------------------------------+
//| Calculate risk from open positions                             |
//+------------------------------------------------------------------+
double CRiskManager::CalculateOpenPositionsRisk()
{
   double totalRisk = 0.0;
   double equity = GetCurrentEquity();
   
   for(int i = 0; i < PositionsTotal(); i++)
   {
      if(m_position.SelectByIndex(i))
      {
         if(m_position.Symbol() == Symbol())
         {
            double positionRisk = 0.0;
            double stopLoss = m_position.StopLoss();
            
            if(stopLoss > 0)
            {
               double entryPrice = m_position.PriceOpen();
               double volume = m_position.Volume();
               double slDistance = MathAbs(entryPrice - stopLoss);
               double tickValue = CalculateTickValue();
               
               positionRisk = volume * slDistance * tickValue * 100000;
            }
            
            totalRisk += positionRisk;
         }
      }
   }
   
   return equity > 0 ? (totalRisk / equity) * 100.0 : 0.0;
}

//+------------------------------------------------------------------+
//| Check if new position can be opened                             |
//+------------------------------------------------------------------+
bool CRiskManager::CanOpenNewPosition()
{
   if(!m_riskManagementEnabled) return true;
   
   // Check risk limits
   if(!CheckRiskLimits()) return false;
   
   // Check daily risk limit
   if(IsDailyRiskLimitReached()) return false;
   
   // Check maximum positions
   int openPositions = CountOpenPositions();
   int maxPositions = GetMaxAllowedPositions();
   if(openPositions >= maxPositions)
   {
      Print("Maximum positions reached: ", openPositions, "/", maxPositions);
      return false;
   }
   
   // Check available margin
   double freeMargin = m_account.FreeMargin();
   double requiredMargin = SymbolInfoDouble(Symbol(), SYMBOL_MARGIN_INITIAL) * 0.1; // Minimum lot
   if(freeMargin < requiredMargin * 2) // Need at least 2x margin
   {
      Print("Insufficient free margin: ", freeMargin);
      return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| Update risk assessment                                          |
//+------------------------------------------------------------------+
void CRiskManager::UpdateRiskAssessment()
{
   UpdatePortfolioRisk();
   UpdateDailyRisk();
   
   // Log risk status if verbose logging is enabled
   static datetime lastLogTime = 0;
   if(TimeCurrent() - lastLogTime > 3600) // Log every hour
   {
      double currentDD = GetCurrentDrawdown();
      if(currentDD > m_maxDrawdown * 0.8) // Warn at 80% of max drawdown
      {
         Print("WARNING: Approaching maximum drawdown - Current: ", 
               DoubleToString(currentDD, 2), "%, Max: ", DoubleToString(m_maxDrawdown, 2), "%");
      }
      lastLogTime = TimeCurrent();
   }
}

//+------------------------------------------------------------------+
//| Calculate optimal lot size based on risk amount and stop distance |
//+------------------------------------------------------------------+
double CRiskManager::CalculateOptimalLotSize(double riskAmount, double stopDistance)
{
   if(riskAmount <= 0 || stopDistance <= 0) return 0.0;
   
   double tickValue = CalculateTickValue();
   if(tickValue <= 0) return 0.0;
   
   double lotSize = riskAmount / (stopDistance * tickValue * 100000);
   
   // Apply broker limits
   double minLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN);
   double maxLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MAX);
   double stepLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_STEP);
   
   lotSize = MathMax(lotSize, minLot);
   lotSize = MathMin(lotSize, maxLot);
   lotSize = MathRound(lotSize / stepLot) * stepLot;
   
   return lotSize;
}

//+------------------------------------------------------------------+
//| Set maximum risk per trade                                      |
//+------------------------------------------------------------------+
void CRiskManager::SetMaxRiskPerTrade(double maxRisk)
{
   m_maxRiskPerTrade = MathMax(0.1, MathMin(10.0, maxRisk));
}

//+------------------------------------------------------------------+
//| Set maximum portfolio risk                                      |
//+------------------------------------------------------------------+
void CRiskManager::SetMaxPortfolioRisk(double maxRisk)
{
   m_maxPortfolioRisk = MathMax(1.0, MathMin(50.0, maxRisk));
}

//+------------------------------------------------------------------+
//| Set minimum risk reward ratio                                   |
//+------------------------------------------------------------------+
void CRiskManager::SetMinRiskReward(double minRR)
{
   // This would be used in validation logic if needed
   // For now, just store it as a member variable
   // You might want to add: double m_minRiskReward; to private section
}

//+------------------------------------------------------------------+
//| Enable volatility based sizing                                 |
//+------------------------------------------------------------------+
void CRiskManager::EnableVolatilityBasedSizing(bool enable)
{
   // Implementation for volatility-based sizing
   // You might want to add: bool m_useVolatilityBasedSizing; to private section
}

//+------------------------------------------------------------------+
//| Get total portfolio risk                                        |
//+------------------------------------------------------------------+
double CRiskManager::GetTotalPortfolioRisk()
{
   return m_currentPortfolioRisk;
}