173 lines
4.4 KiB
Plaintext
173 lines
4.4 KiB
Plaintext
#ifndef HIT_POSITION_LIFECYCLE_MANAGER_MQH
|
|
#define HIT_POSITION_LIFECYCLE_MANAGER_MQH
|
|
|
|
#include <Trade/Trade.mqh>
|
|
|
|
// Ticket-based position lifecycle manager for hedging accounts.
|
|
class CHITPositionLifecycleManager
|
|
{
|
|
private:
|
|
string m_symbol;
|
|
ulong m_magic;
|
|
ulong m_deviation_points;
|
|
int m_close_after_seconds;
|
|
CTrade m_trade;
|
|
|
|
public:
|
|
CHITPositionLifecycleManager()
|
|
{
|
|
m_symbol = _Symbol;
|
|
m_magic = 0;
|
|
m_deviation_points = 10;
|
|
m_close_after_seconds = 0;
|
|
}
|
|
|
|
bool Init(const string symbol,
|
|
const ulong magic,
|
|
const ulong deviation_points,
|
|
const int close_after_seconds)
|
|
{
|
|
m_symbol = symbol;
|
|
m_magic = magic;
|
|
m_deviation_points = deviation_points;
|
|
m_close_after_seconds = close_after_seconds;
|
|
|
|
if(m_symbol == "")
|
|
{
|
|
Print("HITPositionLifecycleManager init failed: symbol is empty.");
|
|
return false;
|
|
}
|
|
|
|
ResetLastError();
|
|
if(!SymbolSelect(m_symbol, true))
|
|
{
|
|
Print("HITPositionLifecycleManager init failed: symbol=", m_symbol,
|
|
" err=", GetLastError());
|
|
return false;
|
|
}
|
|
|
|
m_trade.SetExpertMagicNumber(m_magic);
|
|
m_trade.SetDeviationInPoints((int)m_deviation_points);
|
|
m_trade.SetTypeFillingBySymbol(m_symbol);
|
|
|
|
return true;
|
|
}
|
|
|
|
void SetCloseAfterSeconds(const int close_after_seconds)
|
|
{
|
|
m_close_after_seconds = close_after_seconds;
|
|
}
|
|
|
|
int CountTargetPositions()
|
|
{
|
|
int count = 0;
|
|
|
|
for(int i = PositionsTotal() - 1; i >= 0; --i)
|
|
{
|
|
const ulong ticket = PositionGetTicket(i);
|
|
if(ticket == 0)
|
|
continue;
|
|
if(!PositionSelectByTicket(ticket))
|
|
continue;
|
|
if(!IsTargetSelectedPosition())
|
|
continue;
|
|
|
|
count++;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
bool CloseExpiredPositions()
|
|
{
|
|
if(m_close_after_seconds <= 0)
|
|
return false;
|
|
|
|
bool result = false;
|
|
const datetime current_time = TimeCurrent();
|
|
|
|
for(int i = PositionsTotal() - 1; i >= 0; --i)
|
|
{
|
|
const ulong ticket = PositionGetTicket(i);
|
|
if(ticket == 0)
|
|
continue;
|
|
|
|
ResetLastError();
|
|
if(!PositionSelectByTicket(ticket))
|
|
{
|
|
Print("HITPositionLifecycleManager select failed: ticket=", ticket,
|
|
" err=", GetLastError());
|
|
continue;
|
|
}
|
|
|
|
if(!IsTargetSelectedPosition())
|
|
continue;
|
|
|
|
const datetime entry_time = (datetime)PositionGetInteger(POSITION_TIME);
|
|
if(entry_time <= 0)
|
|
continue;
|
|
|
|
if(current_time - entry_time < m_close_after_seconds)
|
|
continue;
|
|
|
|
if(CloseSelectedPosition(ticket, "time limit"))
|
|
result = true;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private:
|
|
bool IsTargetSelectedPosition()
|
|
{
|
|
if(PositionGetString(POSITION_SYMBOL) != m_symbol)
|
|
return false;
|
|
if((ulong)PositionGetInteger(POSITION_MAGIC) != m_magic)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
string PositionTypeText(const ENUM_POSITION_TYPE type)
|
|
{
|
|
if(type == POSITION_TYPE_BUY)
|
|
return "BUY";
|
|
if(type == POSITION_TYPE_SELL)
|
|
return "SELL";
|
|
|
|
return "UNKNOWN";
|
|
}
|
|
|
|
bool CloseSelectedPosition(const ulong ticket,
|
|
const string reason)
|
|
{
|
|
const ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
|
|
const double volume = PositionGetDouble(POSITION_VOLUME);
|
|
|
|
ResetLastError();
|
|
if(!m_trade.PositionClose(ticket, m_deviation_points))
|
|
{
|
|
Print("HITPositionLifecycleManager close failed: ticket=", ticket,
|
|
" symbol=", m_symbol,
|
|
" magic=", m_magic,
|
|
" type=", PositionTypeText(type),
|
|
" volume=", DoubleToString(volume, 2),
|
|
" reason=", reason,
|
|
" retcode=", m_trade.ResultRetcode(),
|
|
" err=", GetLastError());
|
|
return false;
|
|
}
|
|
|
|
Print("HITPositionLifecycleManager closed position: ticket=", ticket,
|
|
" symbol=", m_symbol,
|
|
" magic=", m_magic,
|
|
" type=", PositionTypeText(type),
|
|
" volume=", DoubleToString(volume, 2),
|
|
" reason=", reason,
|
|
" retcode=", m_trade.ResultRetcode());
|
|
return true;
|
|
}
|
|
};
|
|
|
|
#endif
|