Biblioteca/Include/locks.mqh
super.admin e43251bcde convert
2025-05-30 14:43:34 +02:00

368 lines
26 KiB
MQL5

#define NOT_LOCKED 1024
#define CLOSE_LOCK 2048
#define MODIFY_LOCK 4096
#define ALL_LOCKS 65535
bool CheckOrders(string psymbol,ulong magic)
{
for(int i=0;i<OrdersTotal();i++)
if (OrderGetTicket(i)>0)
if (OrderGetString(ORDER_SYMBOL)==psymbol)
//if((OrderGetInteger(ORDER_MAGIC)==magic)||(magic==ALL_LOCKS))
return (true);
return(false);
}
bool CheckHistory(string psymbol,datetime tini)
{
MqlDateTime todayend;
TimeLocal(todayend);
todayend.hour=23;
todayend.min=59;
todayend.sec=59;
HistorySelect(tini,StructToTime(todayend));
for(int i=0;i<HistoryDealsTotal();i++)
{
ulong ticket=HistoryDealGetTicket(i);
if (ticket>0)
if (HistoryDealGetString(ticket,DEAL_SYMBOL)==psymbol)
if ((HistoryDealGetInteger(ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT)||
(HistoryDealGetInteger(ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT_BY))
return (true);
}
return(false);
}
bool CheckPosition(string psymbol,ulong magic)
{
for(int i=0;i<PositionsTotal();i++)
if (PositionGetTicket(i)>0)
if (PositionGetString(POSITION_SYMBOL)==psymbol)
//if((PositionGetInteger(POSITION_MAGIC)==magic)||(magic==ALL_LOCKS))
return (true);
return(false);
}
class CLock
{
public:
ulong magic; //order/position magic number
datetime time; //order/position lauching time
double sl;//order sl
double tp;//order tp
double vol;//Volume final da posição. Posição de venda tem volume negativo
//--- Construtor default
CLock(void){magic=NOT_LOCKED;time=0;vol=0;}
void operator=(const CLock &r){magic=r.magic;time=r.time;sl=r.sl;tp=r.tp;vol=r.vol;}
void SetLock(ulong t_magic,datetime t_time,double t_vol)
{
vol=t_vol;
magic=t_magic;
time=t_time;
}
void SetMLock(ulong t_magic,datetime t_time,double t_sl,double t_tp){magic=t_magic;time=t_time;sl=t_sl;tp=t_tp;}
void ResetLock(void){magic=NOT_LOCKED;time=0;vol=0;}
bool CheckLock(string psymbol,datetime t_expiration)//verifica se há alguma ordem/posição com este magic
{
if (TimeLocal()<time) return(false);//trava se o tempo da trava for maior que o tempo atual. Usando o tempo da trava no futuro, bloqueia nova ordem por um tempo.
if (magic==NOT_LOCKED) return (true);//retorna true se não há trava
if (magic==CLOSE_LOCK)//ordem de fechamento de posição
{
//checa se há ordens e destrava
if (CheckOrders(psymbol,magic))
{
//Print("-------CLOSE Lock for symbol "+psymbol+" removed.Found Order magic "+IntegerToString(magic));
ResetLock();
return (true);
}
//if (CheckHistory(psymbol,magic))//verifica se há ordens no histórico e destrava
//{
// ResetLock();
// return (true);
//}
//checa se não há posições e destrava
if (!CheckPosition(psymbol,ALL_LOCKS))
{
//Print("-------CLOSE Lock for symbol "+psymbol+" removed. Not found Position magic "+IntegerToString(magic));
ResetLock();
return (true);
}
//não achou ordem ou ainda tem posição, checa expiração e destrava
if (TimeLocal()>(time+t_expiration))
{
//Print("-------CLOSE Lock for symbol "+psymbol+" expired. Magic "+IntegerToString(magic));
ResetLock();
return(true);
}
}
else if (magic==MODIFY_LOCK)//ordem de modificação
{
//checa se a posição foi modificada e destrava
for(int i=0;i<PositionsTotal();i++)
if (PositionGetTicket(i)>0)
if (PositionGetString(POSITION_SYMBOL)==psymbol)
if((PositionGetDouble(POSITION_SL)!=sl)||(PositionGetDouble(POSITION_TP)!=tp))
{
//Print("-------MODIFY Lock for symbol "+psymbol+" removed. Position magic "+IntegerToString(magic));
ResetLock();
return (true);
}
//checa expiração e destrava
if (TimeLocal()>(time+5))
{
//Print("-------MODIFY Lock for symbol "+psymbol+" expired. Magic "+IntegerToString(magic));
ResetLock();
return(true);
}
}
else//ordens de abertura de posição
{
//checa se há ordens e destrava
if (CheckOrders(psymbol,magic))
{
//Print("-------Lock for symbol "+psymbol+" removed.Found Order magic "+IntegerToString(magic));
ResetLock();
return (true);
}
//checa se há posições e destrava
if (CheckPosition(psymbol,magic))
{
double posvol=PositionGetDouble(POSITION_VOLUME);
if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) posvol=-posvol;
if (posvol==vol)//se achar só a posição, só destrava se o volume for atingido
{
//Print("-------Lock for symbol "+psymbol+" removed. Found Position magic "+IntegerToString(magic));
ResetLock();
return (true);
}
}
//não achou ordem ou posição, checa expiração e destrava
if (TimeLocal()>(time+t_expiration))
{
MyPrint("-------Lock for symbol "+psymbol+" expired. Magic "+IntegerToString(magic));
ResetLock();
return(true);
}
}
//ainda está travado
//Print("-------Lock for symbol "+psymbol+" Magic "+magic+" "+t_magic+" time"+time+" "+TimeCurrent());
return (false);
}
};
class PLock//position lock
{
public:
datetime time; //último tempo onde a posição foi vista
// ENUM_OP_TYPES direction;
PLock(void){time=0;}
void operator=(const PLock &r){time=r.time;/*direction=None;*/}
void SetLock()
{
time=TimeLocal();
//if (direction==None)
//{
// if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) direction=Sell;//direction guarda a direção do trade de fechamento da posição
// if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) direction=Buy;
//}
}
void ResetLock(void){time=0;}
bool CheckLock(string psymbol,datetime t_expiration)//verifica se há alguma ordem/posição com este magic
{
if (time==0) return(true);
else if (TimeLocal()<time) return(false);//trava se o tempo da trava for maior que o tempo atual. Usando o tempo da trava no futuro, bloqueia nova ordem por um tempo.
else if (PositionSelect(psymbol)) return(false);
else if(CheckHistory(psymbol,time-2)&&(TimeLocal()>(time+15)))//15 segundos depois que a posição sumiu, destrava
{
//Print("-------Found deal for symbol "+psymbol+" position lock removed.");
ResetLock();
return (true);
}
else if (TimeLocal()>(time+t_expiration))
{
MyPrint("-------Position lock for symbol "+psymbol+" expired ",TimeToString(time));
ResetLock();
return(true);
}
else return(false);
}
};
class ALock//Asset lock
{
public:
datetime time; //último tempo onde a posição foi vista
string mysymbol; //Ativo da trava
string fname; //Nome do arquivo da trava
ALock(void){time=0;}
void operator=(const ALock &r){time=r.time;mysymbol=r.mysymbol;fname=r.fname;}
void InitLock(string psymbol)
{
mysymbol=psymbol;
time=0;
string dirname="Ramdisk";
fname=dirname+"\\"+mysymbol+".lock";
if (!FileIsExist(dirname))
if (!FolderCreate(dirname))
{
Print("Error creating folder");
return;
}
int fhandle=INVALID_HANDLE;
while(fhandle==INVALID_HANDLE)
{
if (FileIsExist(fname)) return;
fhandle=FileOpen(fname,FILE_TXT|FILE_WRITE|FILE_CSV,";");
if (fhandle!=INVALID_HANDLE)
{
FileSeek(fhandle,0,SEEK_SET);
FileWrite(fhandle,EAMAGIC);
FileClose(fhandle);
Print("Creating asset lock for ",psymbol);
return;
}
Sleep(1000);//pausa antes de nova tentativa
}
}
void ResetLock(void)
{
if ((!CheckPosition(mysymbol,ALL_LOCKS))&&(!CheckOrders(mysymbol,ALL_LOCKS)))
{
int fhandle=FileOpen(fname,FILE_TXT|FILE_READ|FILE_CSV|FILE_SHARE_READ,";");
if (fhandle!=INVALID_HANDLE)
{
int mymagic=(int)FileReadNumber(fhandle);
if (mymagic==0)//se a trava já está zerada, só retorne
{
FileClose(fhandle);
return;
}
else//a trava não está zerada
{
if (time==0) time=TimeLocal()+15;//se não tem mais order/posição, e time=0, seta time 15 segundos no futuro
FileClose(fhandle);
if (time<=TimeLocal())//15 segundos depois de não haver mais ordem/posição, sera a trava
{
fhandle=FileOpen(fname,FILE_TXT|FILE_WRITE|FILE_READ|FILE_CSV,";");
if (fhandle!=INVALID_HANDLE)
{
FileSeek(fhandle,0,SEEK_SET);
FileWrite(fhandle,0);
time=0;
FileClose(fhandle);
MyPrint("Resetting asset lock for ",mysymbol);
return;
}
}
}
}
}
return;
}
bool CheckLock(int magic)//verifica se a trava está liberada para este magic
{
int fhandle=FileOpen(fname,FILE_TXT|FILE_READ|FILE_CSV|FILE_SHARE_READ,";");
if (fhandle!=INVALID_HANDLE)
{
int mymagic=(int)FileReadNumber(fhandle);
//if ((magic>=mymagic)||(mymagic==0))//hierarquia e position taking
if ((magic==mymagic)||(mymagic==0))
{
FileClose(fhandle);
//Print("Asset lock opened for ",mysymbol," magic ",magic);
return (true);
}
FileClose(fhandle);
}
return(false);
}
bool SetLock(int magic)//assume a trava para este magic
{
int fhandle=FileOpen(fname,FILE_TXT|FILE_WRITE|FILE_READ|FILE_CSV,";");
if (fhandle!=INVALID_HANDLE)
{
FileSeek(fhandle,0,SEEK_SET);
int mymagic=(int)FileReadNumber(fhandle);
if (magic==mymagic)
{
FileClose(fhandle);
MyPrint("Setting asset lock for ",mysymbol," magic ",IntegerToString(magic));
return (true);
}
if (mymagic==0)
{
FileSeek(fhandle,0,SEEK_SET);
FileWrite(fhandle,magic);
FileClose(fhandle);
MyPrint("Setting asset lock for ",mysymbol," magic ",IntegerToString(magic));
return (true);
}
FileClose(fhandle);
}
else MyPrint("Set asset lock failed!");
return(false);
}
bool CheckPosTake(int magic)//verifica se a trava está liberada para tomada de posição
{
int fhandle=FileOpen(fname,FILE_TXT|FILE_READ|FILE_CSV|FILE_SHARE_READ,";");
if (fhandle!=INVALID_HANDLE)
{
int mymagic=(int)FileReadNumber(fhandle);
if ((magic>=mymagic)||(mymagic==0))//hierarquia e position taking
//if ((magic==mymagic)||(mymagic==0))
{
FileClose(fhandle);
//Print("Asset lock opened for position taking",mysymbol," magic ",magic);
return (true);
}
FileClose(fhandle);
}
return(false);
}
bool SetPosTake(int magic)//assume a trava para este magic e toma a posição
{
int fhandle=FileOpen(fname,FILE_TXT|FILE_WRITE|FILE_READ|FILE_CSV,";");
if (fhandle!=INVALID_HANDLE)
{
FileSeek(fhandle,0,SEEK_SET);
int mymagic=(int)FileReadNumber(fhandle);
/* if (magic==mymagic)
{
FileClose(fhandle);
Print("Taking position ",mysymbol," magic ",magic);
return (true);
}*/
if (magic>mymagic)//hierarquia e position taking
{
FileSeek(fhandle,0,SEEK_SET);
FileWrite(fhandle,magic);
FileClose(fhandle);
MyPrint("Taking position ",mysymbol," magic ",IntegerToString(magic));
return (true);
}
FileClose(fhandle);
}
return(false);
}
bool CheckOwner(int magic)//verifica se este magic tem a trava do ativo
{
int fhandle=FileOpen(fname,FILE_TXT|FILE_READ|FILE_CSV|FILE_SHARE_READ,";");
if (fhandle!=INVALID_HANDLE)
{
int mymagic=(int)FileReadNumber(fhandle);
if (magic==mymagic)
{
FileClose(fhandle);
return (true);
}
FileClose(fhandle);
}
return(false);
}
};