368 lines
26 KiB
MQL5
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);
|
|
}
|
|
|
|
};
|