147 lines
4.0 KiB
Plaintext
147 lines
4.0 KiB
Plaintext
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| 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__
|