Biblioteca2/Include/manage.mqh

662 lines
54 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 14:43:36 +02:00
<EFBFBD><EFBFBD>
double TradeSizeOptimized(string Psymbol,double slot,bool maxlimit)
{
double lot=slot;
//--- normalize and check limits
double stepvol=SymbolInfoDouble(Psymbol,SYMBOL_VOLUME_STEP);
if (stepvol!=0) lot=stepvol*MathFloor(lot/stepvol);
else lot=0;
double minvol=SymbolInfoDouble(Psymbol,SYMBOL_VOLUME_MIN);
if(lot<minvol)
lot=minvol;
double maxvol=SymbolInfoDouble(Psymbol,SYMBOL_VOLUME_MAX);
if((lot>maxvol)&&maxlimit)
lot=stepvol*MathFloor(maxvol/stepvol);;
return (lot);
}
double NormalizePrice(string Psymbol,double price,bool type)
{
double ret=0,stepprice=SymbolInfoDouble(Psymbol,SYMBOL_TRADE_TICK_SIZE);
if (stepprice!=0)
{
if (type) ret=stepprice*floor(price/stepprice);
else ret=stepprice*ceil(price/stepprice);
}
return(ret);
}
double CalcVol(string psymbol,double atr,double risco)
{
double vol=0;
double tick_size=SymbolInfoDouble(psymbol,SYMBOL_TRADE_TICK_SIZE);
double tick_value=SymbolInfoDouble(psymbol,SYMBOL_TRADE_TICK_VALUE);
double SaldoConta=Money.Balance();
double RiscoMaximoPar=risco*SaldoConta;//100.000*0,005=500
if ((atr!=INT_MIN)&&(atr>0))//INT_MIN==fixed(!VolFixed)
{
if(SymbolInfoInteger(psymbol,SYMBOL_TRADE_CALC_MODE)==SYMBOL_CALC_MODE_FOREX)//FOREX
{
int bIsUSD;
double TickLote, Ask, AskNomeSegundoPar, ValorPipProjetado;
string NomeSegundoPar;
TickLote = tick_value;
Ask = atr;
bIsUSD = 1+StringFind(psymbol,"USD",0);
ValorPipProjetado = (RiscoMaximoPar)*tick_size;
AskNomeSegundoPar = 0;
NomeSegundoPar = "";
//bIsUSD == 4 implica XXX/USD
if(bIsUSD==4){if ((TickLote!=0)&&(Ask!=0)){vol = ValorPipProjetado/(TickLote*Ask);
vol = TradeSizeOptimized(psymbol,vol,false);
//PrintTest(bIsUSD,ValorPipProjetado,tick_size,tick_value,TickLote,NomeSegundoPar,AskNomeSegundoPar,Ask,vol);
return(vol);}}
//bIsUSD == 1 implica USD/XXX
if(bIsUSD==1){if ((TickLote!=0)&&(Ask!=0)){vol = ValorPipProjetado/(TickLote/Ask);
vol = TradeSizeOptimized(psymbol,vol,false);
//PrintTest(bIsUSD,ValorPipProjetado,tick_size,tick_value,TickLote,NomeSegundoPar,AskNomeSegundoPar,Ask,vol);
return(vol);}}
///////////////////////////////////////////////////
// bIsUSD == 0 implica XXX/XXX; //
// XXX/XXX implica 2 casos, exemplos: //
// //
// Caso 1 (AUDNZD) = (NZDUSD) / (AUDNZD) //
// //
// Caso 2 (EURCHF) = (1/USDCHF) / (EURCHF) //
// //
///////////////////////////////////////////////////
NomeSegundoPar = psymbol;
string TresUltimosCaracteresDoPar = StringSubstr(NomeSegundoPar,3);
//Setando valores iniciais...
NomeSegundoPar = TresUltimosCaracteresDoPar+"USD";
AskNomeSegundoPar = SymbolInfoDouble(NomeSegundoPar,SYMBOL_ASK);
//Caso 1
if(AskNomeSegundoPar != 0 ){vol = ValorPipProjetado/((TickLote*AskNomeSegundoPar)/Ask);
vol = TradeSizeOptimized(psymbol,vol,false);
//PrintTest(bIsUSD,ValorPipProjetado,tick_size,tick_value,TickLote,NomeSegundoPar,AskNomeSegundoPar,Ask,vol);
return(vol);}
//Caso 2
if(AskNomeSegundoPar == 0 ){NomeSegundoPar = "USD"+TresUltimosCaracteresDoPar;
AskNomeSegundoPar = SymbolInfoDouble(NomeSegundoPar,SYMBOL_ASK);
if(AskNomeSegundoPar != 0 ){vol = ValorPipProjetado/((TickLote*(1.0/AskNomeSegundoPar)/Ask));
vol = TradeSizeOptimized(psymbol,vol,false);
//PrintTest(bIsUSD,ValorPipProjetado,tick_size,tick_value,TickLote,NomeSegundoPar,AskNomeSegundoPar,Ask,vol);
return(vol);}}
} //ACIMA = FOREX, ABAIXO = FUTURO
if(SymbolInfoInteger(psymbol,SYMBOL_TRADE_CALC_MODE)==SYMBOL_CALC_MODE_EXCH_FUTURES)//BMF
{
if (tick_value!=0)
vol=TradeSizeOptimized(psymbol,RiscoMaximoPar*tick_size/(tick_value*atr),false);
}
else
{
vol=TradeSizeOptimized(psymbol,RiscoMaximoPar/atr,false);
}
return (vol);
}
else if (atr==INT_MIN) return(Nvol*SymbolInfoDouble(psymbol,SYMBOL_VOLUME_MIN));
//else if (atr<0) return(Nvol*SymbolInfoDouble(psymbol,SYMBOL_VOLUME_MIN))
else return(0);
}
double calc_profit(string psymbol,ENUM_DEAL_TYPE type,ulong magic=ALL_LOCKS)
{
MqlDateTime thisday;
TimeLocal(thisday);
thisday.hour=9;
thisday.min=0;
thisday.sec=0;
//thisday.day=1;
datetime today=StructToTime(thisday);
HistorySelect(today,TimeLocal());
int total=HistoryDealsTotal();
double varday=0;
for (int i=0;i<total;i++)
{
ulong ticket=HistoryDealGetTicket(i);
if ((ticket!=0)
&&(HistoryDealGetString(ticket,DEAL_SYMBOL)==psymbol)
//&&((HistoryDealGetInteger(ticket,DEAL_MAGIC)==magic)||(magic==ALL_LOCKS))
&&(HistoryDealGetInteger(ticket,DEAL_TYPE)==type))
varday+=HistoryDealGetDouble(ticket,DEAL_PROFIT);
}
return(varday);
}
int count_stops(string psymbol,ENUM_DEAL_TYPE type,ulong magic)
{
MqlDateTime thisday;
TimeLocal(thisday);
thisday.hour=9;
thisday.min=0;
thisday.sec=0;
//thisday.day=1;
datetime today=StructToTime(thisday);
HistorySelect(today,TimeLocal());
int total=HistoryDealsTotal();
int nstops=0;
for (int i=0;i<total;i++)
{
ulong ticket=HistoryDealGetTicket(i);
if ((ticket!=0)
&&(HistoryDealGetString(ticket,DEAL_SYMBOL)==psymbol)
//&&(HistoryDealGetInteger(ticket,DEAL_MAGIC)==magic)
&&(HistoryDealGetInteger(ticket,DEAL_TYPE)==type)
//&&(HistoryDealGetInteger(ticket,DEAL_REASON)==DEAL_REASON_SL))
&&(HistoryDealGetDouble(ticket,DEAL_PROFIT)<0)
)
nstops++;
}
return(nstops);
}
double float_profit(string psymbol,ENUM_POSITION_TYPE type,ulong magic=ALL_LOCKS)
{
if (PositionSelect(psymbol)
&&(PositionGetInteger(POSITION_TYPE)==type)
//&&((PositionGetInteger(POSITION_MAGIC)==magic)||(magic==ALL_LOCKS))
)
return(PositionGetDouble(POSITION_PROFIT));
else
return(0);
}
//----------Ordens pendentes---------
//usada em conjunto com as ordens pendentes somente
class OrderData
{
string fname;
string symbol;
bool book;
public:
double sl;
double tp;
double priceref;//pre<EFBFBD>o inicial da ordem
double atr;
double trailing_target;
datetime last_time;
OrderTypes order_type;//tipo de ordem pendente
//inicializa<EFBFBD><EFBFBD>o
void PositionData()
{
sl=0;
tp=0;
priceref=0;
atr=0;
book=false;
trailing_target=0;
last_time=0;
order_type=OTNone;
}
//reseta as vari<EFBFBD>veis
bool Reset()
{
sl=0;
tp=0;
priceref=0;
atr=0;
trailing_target=0;
last_time=0;
order_type=OTNone;
if (book)
{
MarketBookRelease(symbol);
book=false;
}
return(SavePositionData());
}
//inicializa<EFBFBD><EFBFBD>o completa
bool InitPositionData(string psymbol)
{
sl=0;
tp=0;
priceref=0;
atr=0;
trailing_target=0;
last_time=0;
order_type=OTNone;
symbol=psymbol;
book=false;
string dirname="PositionData";
fname=dirname+"\\"+symbol+".position";
if (!FileIsExist(dirname))
if (!FolderCreate(dirname))
{
Print("Error creating position folder");
return(false);
}
int fhandle=INVALID_HANDLE;
int cnt=0;
while(fhandle==INVALID_HANDLE)
{
if (FileIsExist(fname))
{
Print("Loading position data for ",symbol);
LoadPositionData();
return(true);
}
fhandle=FileOpen(fname,FILE_TXT|FILE_WRITE|FILE_CSV,";");
if (fhandle!=INVALID_HANDLE)
{
FileWrite(fhandle,sl,tp,priceref,atr,trailing_target,last_time,order_type);
FileClose(fhandle);
Print("Creating position data for ",symbol);
return(true);
}
Sleep(1000);//pausa antes de nova tentativa
if (cnt>100)
{
Print("ERROR Creating position data for ",symbol);
return(false);
}
cnt++;
}
return(false);
}
//grava as vari<EFBFBD>veis no disco
bool SavePositionData()
{
int fhandle=FileOpen(fname,FILE_TXT|FILE_WRITE|FILE_CSV,";");
if (fhandle!=INVALID_HANDLE)
{
FileWrite(fhandle,sl,tp,priceref,atr,trailing_target,last_time,order_type);
FileClose(fhandle);
return(true);
}
return(false);
}
//l<EFBFBD> as vari<EFBFBD>veis do disco
bool LoadPositionData()
{
int fhandle=FileOpen(fname,FILE_TXT|FILE_READ|FILE_CSV,";");
if (fhandle!=INVALID_HANDLE)
{
sl=FileReadNumber(fhandle);
tp=FileReadNumber(fhandle);
priceref=FileReadNumber(fhandle);
atr=FileReadNumber(fhandle);
trailing_target=FileReadNumber(fhandle);
last_time=(datetime)FileReadNumber(fhandle);
order_type=(OrderTypes)FileReadNumber(fhandle);
FileClose(fhandle);
return(true);
}
return(false);
}
//retorna os dados da ordem
void GetPositionData(double& osl,double& otp,OrderTypes& ot,double& opriceref,double& oatr,double& otarget,datetime& otime)
{
otp=tp;
osl=sl;
ot=order_type;
opriceref=priceref;
oatr=atr;
otarget=trailing_target;
otime=last_time;
}
//seta os dados da ordem
bool SetPositionData(double osl,double otp,OrderTypes ot,double opriceref,double oatr,double otarget,datetime otime)
{
sl=osl;
tp=otp;
order_type=ot;
priceref=opriceref;
atr=oatr;
trailing_target=otarget;
last_time=otime;
if (!book)
{
MarketBookAdd(symbol);
book=true;
}
return(SavePositionData());
}
//verifica se a pendente expirou e a deleta
void CheckPendingExpiration(int orderexpiration,bool auction)
{
datetime ordertime=(datetime)OrderGetInteger(ORDER_TIME_SETUP);
datetime thistime=TimeCurrent();
if ((thistime>(ordertime+OrdExp*60))&&(!auction))
Trade.OrderDelete(OrderGetInteger(ORDER_TICKET));
}
// This MQL5 function is used to manage trailing orders in a trading system. It takes several parameters related to different trailing strategies and modifies the order based on these strategies and current market conditions.
//
// The function first retrieves the current bid and ask prices, as well as the tick size for the symbol. It then gets the open price and volume of the order.
//
// The function then retrieves the market book information and determines the maximum buy and sell volumes and the corresponding prices. It also determines the back price, which is the price behind the current order price in the market book.
//
// The function then checks if the order is a buy limit or sell limit order and adjusts the back price and maximum price accordingly.
//
// The function then determines the target price based on various trailing strategies. If the order is a buy limit order, it checks if the current price is not equal to the target price and if the tolerance and target conditions are met. If these conditions are met, it modifies the order to the target price. If not, it checks if the aggression strategy is enabled and if the current price is not equal to the ask price. If these conditions are met, it modifies the order to the ask price.
//
// If the order is a sell limit order, it does a similar check and modifies the order to the target price or bid price based on the conditions.
//
// This function is used to dynamically adjust the order price based on market conditions and the specified trailing strategies. It helps to maximize the profit and minimize the loss in a trading system.
//
void OrderTrailing(/*TrailingTypes trailing*/bool TTTop,bool TTMountain,bool TTSoma1,bool TTEscape,bool TTAlvo,bool TTTol,double TTTolFrac,bool TTAggression)
{
double bid=SymbolInfoDouble(symbol,SYMBOL_BID);
double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);
double ticksize=SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE);
double backprice=0,maxbuy=0,maxsell=0,max=0;
double myprice=OrderGetDouble(ORDER_PRICE_OPEN);
double myvolume=OrderGetDouble(ORDER_VOLUME_CURRENT);
backprice=myprice;
//---------book---------
MqlBookInfo BookInfo[];
MarketBookGet(_Symbol,BookInfo);
for(int i=0;i<ArraySize(BookInfo);i++)
{
if ((OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_LIMIT)&&(BookInfo[i].type==BOOK_TYPE_SELL))
{
if (BookInfo[i].volume>maxsell)
{
maxsell=BookInfo[i].volume_real;
max=BookInfo[i].price;
}
if ((BookInfo[i].price==myprice)&&(i!=0)) backprice=BookInfo[i-1].price;
}
if ((OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_LIMIT)&&(BookInfo[i].type==BOOK_TYPE_BUY))
{
if (BookInfo[i].volume>maxbuy)
{
maxbuy=BookInfo[i].volume_real;
max=BookInfo[i].price;
}
if ((BookInfo[i].price==myprice)&&(i!=(ArraySize(BookInfo)-1))) backprice=BookInfo[i+1].price;
}
}
if (OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_LIMIT) {backprice+=ticksize;if (maxbuy>myvolume) max+=ticksize;}
else if (OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_LIMIT) {backprice-=ticksize;if (maxsell>myvolume) max-=ticksize;}
//backprice=price -> tem que pegar pelo book - soma 1 ticksize se for buy, subtrai 1 ticksize se for sell
//max=price -> max deveria ser pre<EFBFBD>o do volume m<EFBFBD>ximo (maxbuy,maxsell) (+1,-1)
//se sou o m<EFBFBD>ximo, n<EFBFBD>o muda max
//----------------------
if (OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_LIMIT)
{
double tgtprice=(TTTop?bid:(TTMountain?max:bid));
datetime tempo=TimeLocal()-last_time;
if (TTSoma1&&(!TTEscape)&&(myprice==MathMax(tgtprice,myprice))&&(tempo>60)) tgtprice=MathMax(tgtprice,myprice)+ticksize;//soma 1
double tol=(tgtprice-priceref)/atr;
if ((!TTSoma1)&&TTEscape&&(myprice==tgtprice)&&(myprice!=backprice))//Escape: se sou bid/ask e o pre<EFBFBD>o atr<EFBFBD>s de mim +-1 ticksize n<EFBFBD>o sou eu, elimine o gap
Trade.OrderModify(OrderGetInteger(ORDER_TICKET),NormalizePrice(symbol,backprice,true),0,0,(ENUM_ORDER_TYPE_TIME)OrderGetInteger(ORDER_TYPE_TIME),(datetime)OrderGetInteger(ORDER_TIME_EXPIRATION));
else if ((myprice!=tgtprice)//me coloca no bid ou antes da montanha
&&(TTTol?(tol<TTTolFrac):true)//Toler<EFBFBD>ncia
&&(TTAlvo?(tgtprice<=trailing_target):true)//Alvo
)
{
Trade.OrderModify(OrderGetInteger(ORDER_TICKET),NormalizePrice(symbol,tgtprice,true),0,0,(ENUM_ORDER_TYPE_TIME)OrderGetInteger(ORDER_TYPE_TIME),(datetime)OrderGetInteger(ORDER_TIME_EXPIRATION));
last_time=TimeLocal();
}
else if (TTAggression&&(myprice!=ask)//Se n<EFBFBD>o posso escapar, e j<EFBFBD> sou o bid ou antes da montanha, testa a agress<EFBFBD>o
&&(TTTol?(((ask-priceref)/atr)<TTTolFrac):true)//Toler<EFBFBD>ncia
&&(TTAlvo?(ask<=trailing_target):true)//Alvo
)
{
Trade.OrderModify(OrderGetInteger(ORDER_TICKET),NormalizePrice(symbol,ask,true),0,0,(ENUM_ORDER_TYPE_TIME)OrderGetInteger(ORDER_TYPE_TIME),(datetime)OrderGetInteger(ORDER_TIME_EXPIRATION));
last_time=TimeLocal();
}
}
if (OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_LIMIT)
{
double tgtprice=(TTTop?ask:(TTMountain?max:ask));
datetime tempo=TimeLocal()-last_time;;
if (TTSoma1&&(!TTEscape)&&(myprice==MathMin(tgtprice,myprice))&&(tempo>60)) tgtprice=MathMin(tgtprice,myprice)-ticksize;//soma 1
double tol=(priceref-tgtprice)/atr;
if ((!TTSoma1)&&TTEscape&&(myprice==tgtprice)&&(myprice!=backprice))//Escape: se sou bid/ask e o pre<EFBFBD>o atr<EFBFBD>s de mim +-1 ticksize n<EFBFBD>o sou eu, elimine o gap
Trade.OrderModify(OrderGetInteger(ORDER_TICKET),NormalizePrice(symbol,backprice,true),0,0,(ENUM_ORDER_TYPE_TIME)OrderGetInteger(ORDER_TYPE_TIME),(datetime)OrderGetInteger(ORDER_TIME_EXPIRATION));
else if ((myprice!=tgtprice)//me coloca no bid ou antes da montanha
&&(TTTol?(tol<TTTolFrac):true)//Toler<EFBFBD>ncia
&&(TTAlvo?(tgtprice>=trailing_target):true)//Alvo
)
{
Trade.OrderModify(OrderGetInteger(ORDER_TICKET),NormalizePrice(symbol,tgtprice,true),0,0,(ENUM_ORDER_TYPE_TIME)OrderGetInteger(ORDER_TYPE_TIME),(datetime)OrderGetInteger(ORDER_TIME_EXPIRATION));
last_time=TimeLocal();
}
else if (TTAggression&&(myprice!=bid)//Se n<EFBFBD>o posso escapar, e j<EFBFBD> sou o ask ou antes da montanha, testa a agress<EFBFBD>o
&&(TTTol?(((priceref-bid)/atr)<TTTolFrac):true)//Toler<EFBFBD>ncia
&&(TTAlvo?(bid>=trailing_target):true)//Alvo
)
{
Trade.OrderModify(OrderGetInteger(ORDER_TICKET),NormalizePrice(symbol,bid,true),0,0,(ENUM_ORDER_TYPE_TIME)OrderGetInteger(ORDER_TYPE_TIME),(datetime)OrderGetInteger(ORDER_TIME_EXPIRATION));
last_time=TimeLocal();
}
}
}
};
bool PositionClosePartial(string psymbol,double myvol,bool usepending)
{
double pvol=PositionGetDouble(POSITION_VOLUME);
double cvol=myvol;
if (cvol>pvol) cvol=pvol;
if (usepending)
{
if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
return(Trade.SellLimit(cvol,SymbolInfoDouble(psymbol,SYMBOL_ASK),psymbol,0,0,ORDER_TIME_SPECIFIED,TimeLocal()+OrdExp*60,"Close"));
if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
return(Trade.BuyLimit(cvol,SymbolInfoDouble(psymbol,SYMBOL_BID),psymbol,0,0,ORDER_TIME_SPECIFIED,TimeLocal()+OrdExp*60,"Close"));
}
else
{
if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) return(Trade.Sell(cvol,psymbol,0,0,0,"Close"));
if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) return(Trade.Buy(cvol,psymbol,0,0,0,"Close"));
}
return (false);
}
bool PositionClose(bool usepending,string psymbol,CLock &lock,bool usevollimit=false,double vollimitfrac=0.01,double mvol=0)
{
double thisvol=PositionGetDouble(POSITION_VOLUME);
if (usevollimit)
{
if (thisvol>(vollimitfrac*mvol)) thisvol=TradeSizeOptimized(psymbol,vollimitfrac*mvol,false);//limita o volume a x% da m<EFBFBD>dia
if (PositionClosePartial(psymbol,thisvol,usepending))
{
MyPrint("Closing: "+psymbol);
lock.SetLock(CLOSE_LOCK,TimeLocal()+15,0);
return(true);
}
}
else
{
if (usepending)
{
if (PositionClosePartial(psymbol,thisvol,usepending))
{
MyPrint("Closing: "+psymbol);
lock.SetLock(CLOSE_LOCK,TimeLocal()+15,0);
return(true);
}
}
else
{
if (Trade.PositionClose(psymbol))//(PositionClosePartial(psymbol,thisvol))
{
MyPrint("Closing: "+psymbol);
lock.SetLock(CLOSE_LOCK,TimeLocal()+15,0);
return(true);
}
}
}
MyPrint("Error closing: "+psymbol);
return(false);
}
bool CheckDT(bool possel,string psymbol,bool not_locked,CLock &lock,bool usevollimit,double vollimitfrac,double mvol)
{
bool dtend=false;
MqlDateTime today;
TimeLocal(today);
if (Forex2) return(false);
if (((today.hour>=DTHour)&&(today.min>=DTMin))||(today.hour>=(DTHour+1)))//hor<EFBFBD>rio de fechamento day trade
{
if (possel&&not_locked)
{
// if(Trade.PositionClose(psymbol))
if (PositionClose(false,psymbol,lock,usevollimit,vollimitfrac,mvol))//n<EFBFBD>o fechar usando pendentes
{
MyPrint("Closing hor<00>rio day trade: "+psymbol);
// lock.SetLock(CLOSE_LOCK,TimeLocal()+15,0);
}
}
dtend=true;
}
if (((today.hour<=OCHour)&&(today.min<=OCMin))||(today.hour<(OCHour))) dtend=false;//hor<EFBFBD>rio operacional
else dtend=true;
return(dtend);
}
bool ExpiraPos(bool usepending,OrderData &PosData,string psymbol,int Pexp,bool not_locked,CLock &lock,bool usevollimit,double vollimitfrac,double mvol)
{
if ((TimeLocal()>(PositionGetInteger(POSITION_TIME)+Pexp*3600))&&not_locked)//expira<EFBFBD><EFBFBD>o de posi<EFBFBD><EFBFBD>es
{
if (usepending)
{
double sl=0,tp=0,priceref=0,atr=0,target=0;
datetime lasttime=0;
OrderTypes ot=OTNone;
PosData.GetPositionData(sl,tp,ot,priceref,atr,target,lasttime);
double bid=SymbolInfoDouble(psymbol,SYMBOL_BID),ask=SymbolInfoDouble(psymbol,SYMBOL_ASK);
if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) priceref=ask;
else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) priceref=bid;
//TODO: set the target
if (PosData.SetPositionData(sl,tp,OTClose,priceref,atr,target,TimeLocal()))
if (PositionClose(true,psymbol,lock,usevollimit,vollimitfrac,mvol))
{
MyPrint("Closing expira<00><00>o: "+psymbol);
lock.SetLock(CLOSE_LOCK,TimeLocal()+15,0);
}
}
else
{
if (PositionClose(false,psymbol,lock,usevollimit,vollimitfrac,mvol))
{
MyPrint("Closing expira<00><00>o: "+psymbol);
lock.SetLock(CLOSE_LOCK,TimeLocal()+15,0);
}
}
return true;
}
return false;
}
bool open_buy(string psymbol,double ATR,double vol,
ENUM_STOP_TYPES Sl_TypeA,double SLLevelA,ENUM_TIMEFRAMES SlTimeframeA,int SlBarsA,
ENUM_STOP_TYPES Tp_TypeA,double TPLevelA,ENUM_TIMEFRAMES TpTimeframeA,int TpBarsA,
string op_cmt,int op_magic,bool UsePending,double OSlippage,CLock &lock,double SlFixed,double TpFixed
)
{
double price=SymbolInfoDouble(psymbol,SYMBOL_ASK);
double bid=SymbolInfoDouble(psymbol,SYMBOL_BID);
double sl=0;
double tp=0;
sl=set_sl_tp(psymbol,price,ATR,Sl_TypeA,SLLevelA,SlTimeframeA,SlBarsA,SlFixed);
tp=set_tp_sl(psymbol,price,ATR,Tp_TypeA,TPLevelA,TpTimeframeA,TpBarsA,TpFixed);
if ((sl>=0)&&(tp>=0)&&(vol>0)
&&(sl!=0?(sl<price):true)
&&(tp!=0?(tp>price):true)
)
{
//Print (MyName+": "+psymbol+": "+op_cmt+" SL:",sl," TP:",tp);
Trade.SetExpertMagicNumber(op_magic);
if (UsePending)
{
if (OSlippage!=0) price=NormalizePrice(psymbol,bid+OSlippage,true);
double posvol=0;
if (PositionSelect(psymbol))
{
posvol=PositionGetDouble(POSITION_VOLUME);
if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) posvol=-posvol;
}
if (Trade.BuyLimit(vol,price,psymbol,0,0,ORDER_TIME_SPECIFIED,TimeLocal()+OrdExp*60,op_cmt))
{
MyPrint (MyName+": "+psymbol+": "+op_cmt+" SL:",DoubleToString(sl,2)," TP:",DoubleToString(tp,2));
lock.SetLock(op_magic,TimeLocal()+15,vol+posvol);
}
}
else
{
double posvol=0;
if (PositionSelect(psymbol))
{
posvol=PositionGetDouble(POSITION_VOLUME);
if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) posvol=-posvol;
}
if (Trade.Buy(vol,psymbol,price,sl,tp,op_cmt))
{
MyPrint (MyName+": "+psymbol+": "+op_cmt+" SL:",DoubleToString(sl,2)," TP:",DoubleToString(tp,2));
lock.SetLock(op_magic,TimeLocal()+15,vol+posvol);
}
}
return true;
}
return false;
}
bool open_sell(string psymbol,double ATR,double vol,
ENUM_STOP_TYPES Sl_TypeA,double SLLevelA,ENUM_TIMEFRAMES SlTimeframeA,int SlBarsA,
ENUM_STOP_TYPES Tp_TypeA,double TPLevelA,ENUM_TIMEFRAMES TpTimeframeA,int TpBarsA,
string op_cmt,int op_magic,bool UsePending,double OSlippage,CLock &lock,double SlFixed,double TpFixed
)
{
double price=SymbolInfoDouble(psymbol,SYMBOL_BID);
double ask=SymbolInfoDouble(psymbol,SYMBOL_ASK);
double sl=0;
double tp=0;
sl=set_tp_sl(psymbol,price,ATR,Sl_TypeA,SLLevelA,SlTimeframeA,SlBarsA,SlFixed);
tp=set_sl_tp(psymbol,price,ATR,Tp_TypeA,TPLevelA,TpTimeframeA,TpBarsA,TpFixed);
if ((sl>=0)&&(tp>=0)&&(vol>0)
&&(sl!=0?(sl>price):true)
&&(tp!=0?(tp<price):true)
)
{
Trade.SetExpertMagicNumber(op_magic);
if (UsePending)
{
if (OSlippage!=0) price=NormalizePrice(psymbol,ask-OSlippage,true);
double posvol=0;
if (PositionSelect(psymbol))
{
posvol=PositionGetDouble(POSITION_VOLUME);
if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) posvol=-posvol;
}
if (Trade.SellLimit(vol,price,psymbol,0,0,ORDER_TIME_SPECIFIED,TimeLocal()+OrdExp*60,op_cmt))
{
MyPrint (MyName+": "+psymbol+": "+op_cmt+" SL:",DoubleToString(sl,2)," TP:",DoubleToString(tp,2));
lock.SetLock(op_magic,TimeLocal()+15,posvol-vol);
}
}
else
{
double posvol=0;
if (PositionSelect(psymbol))
{
posvol=PositionGetDouble(POSITION_VOLUME);
if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) posvol=-posvol;
}
if (Trade.Sell(vol,psymbol,price,sl,tp,op_cmt))
{
MyPrint (MyName+": "+psymbol+": "+op_cmt+" SL:",DoubleToString(sl,2)," TP:",DoubleToString(tp,2));
lock.SetLock(op_magic,TimeLocal()+15,posvol-vol);
}
}
return true;
}
return false;
}