//+------------------------------------------------------------------+ //| PositionManager.mqh - Position tracking and validation | //| Checks for existing positions, prevents duplicates | //+------------------------------------------------------------------+ #ifndef __POSITIONMANAGER_MQH__ #define __POSITIONMANAGER_MQH__ #include "Config.mqh" #include "Logger.mqh" class CPositionManager { private: CLogger *mp_logger; public: // Constructor CPositionManager(CLogger *logger) { mp_logger = logger; } // Check if there is already an open position for this symbol and magic bool HasOpenPosition(const string symbol) { for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionSelectByTicket(PositionGetTicket(i))) { if(PositionGetString(POSITION_SYMBOL) == symbol && PositionGetInteger(POSITION_MAGIC) == g_magic_number) { return true; } } } return false; } // Get current position count for this symbol and magic int GetPositionCount(const string symbol) { int count = 0; for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionSelectByTicket(PositionGetTicket(i))) { if(PositionGetString(POSITION_SYMBOL) == symbol && PositionGetInteger(POSITION_MAGIC) == g_magic_number) { count++; } } } return count; } // Get current position type (OP_BUY, OP_SELL, or -1 if none) int GetPositionType(const string symbol) { for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionSelectByTicket(PositionGetTicket(i))) { if(PositionGetString(POSITION_SYMBOL) == symbol && PositionGetInteger(POSITION_MAGIC) == g_magic_number) { return (int)PositionGetInteger(POSITION_TYPE); } } } return -1; } // Get current position ticket (returns 0 if none) ulong GetPositionTicket(const string symbol) { for(int i = PositionsTotal() - 1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(PositionSelectByTicket(ticket)) { if(PositionGetString(POSITION_SYMBOL) == symbol && PositionGetInteger(POSITION_MAGIC) == g_magic_number) { return ticket; } } } return 0; } // Get current position profit double GetPositionProfit(const string symbol) { for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionSelectByTicket(PositionGetTicket(i))) { if(PositionGetString(POSITION_SYMBOL) == symbol && PositionGetInteger(POSITION_MAGIC) == g_magic_number) { return PositionGetDouble(POSITION_PROFIT); } } } return 0.0; } // Check if new position is allowed (not exceeding max positions) bool IsNewPositionAllowed(const string symbol) { int current_count = GetPositionCount(symbol); if(current_count >= g_max_positions) { if(mp_logger && g_debug_mode) mp_logger.Info(StringFormat("Max positions reached: %d >= %d", current_count, g_max_positions)); return false; } return true; } // Get total open lots for symbol and magic double GetTotalOpenLots(const string symbol) { double total_lots = 0.0; for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionSelectByTicket(PositionGetTicket(i))) { if(PositionGetString(POSITION_SYMBOL) == symbol && PositionGetInteger(POSITION_MAGIC) == g_magic_number) { total_lots += PositionGetDouble(POSITION_VOLUME); } } } return total_lots; } }; #endif //__POSITIONMANAGER_MQH__