100 lines
9.7 KiB
MQL5
100 lines
9.7 KiB
MQL5
double set_sl_tp(string psymbol,double price,double ATRB,
|
|
ENUM_STOP_TYPES Sl_TypeB,double SLLevelB,ENUM_TIMEFRAMES SlTimeframeB,int SlBarsB,double SlFixed)
|
|
{
|
|
double sl=0;
|
|
//if (optype==Buy)//sl buy, tp sell
|
|
switch(Sl_TypeB)
|
|
{
|
|
case Fluctuation:{sl=price-SLLevelB*ATRB;break;}
|
|
case Minimum:{sl=iLow(psymbol,SlTimeframeB,iLowest(psymbol,SlTimeframeB,MODE_LOW,SlBarsB))-SLLevelB*ATRB;break;}//pode ser o menor dos fechamentos,aberturas, máximos...
|
|
case Maximum:{sl=iLow(psymbol,SlTimeframeB,iLowest(psymbol,SlTimeframeB,MODE_LOW,SlBarsB))-SLLevelB*ATRB;break;}
|
|
//case Maximum:{sl=iHigh(psymbol,SlTimeframeB,iHighest(psymbol,SlTimeframeB,MODE_HIGH,SlBarsB))-SLLevelB*ATRB;break;}
|
|
case Mean:{sl=Avg(psymbol,SlBarsB,SlTimeframeB)-SLLevelB*ATRB;break;}
|
|
case Fixed:{sl=SlFixed;break;}
|
|
}
|
|
if (sl!=0)
|
|
{
|
|
if (AdjustSlTp) sl-=SymbolInfoDouble(psymbol,SYMBOL_TRADE_TICK_SIZE);
|
|
sl=NormalizePrice(psymbol,sl,true);
|
|
}
|
|
return(sl);
|
|
}
|
|
|
|
double set_tp_sl(string psymbol,double price,double ATRB,
|
|
ENUM_STOP_TYPES Tp_TypeB,double TPLevelB,ENUM_TIMEFRAMES TpTimeframeB,int TpBarsB,double TpFixed)
|
|
{
|
|
double tp=0;
|
|
//if (optype==Buy)//tp buy, sl sell
|
|
switch(Tp_TypeB)
|
|
{
|
|
case Fluctuation:{tp=price+TPLevelB*ATRB;break;}
|
|
//case Minimum:{tp=iLow(psymbol,TpTimeframeB,iLowest(psymbol,TpTimeframeB,MODE_LOW,TpBarsB))+TPLevelB*ATRB;break;}
|
|
case Minimum:{tp=iHigh(psymbol,TpTimeframeB,iHighest(psymbol,TpTimeframeB,MODE_HIGH,TpBarsB))+TPLevelB*ATRB;break;}
|
|
case Maximum:{tp=iHigh(psymbol,TpTimeframeB,iHighest(psymbol,TpTimeframeB,MODE_HIGH,TpBarsB))+TPLevelB*ATRB;break;}
|
|
case Mean:{tp=Avg(psymbol,TpBarsB,TpTimeframeB)+TPLevelB*ATRB;break;}
|
|
case Fixed:{tp=TpFixed;break;}
|
|
}
|
|
if (tp!=0)
|
|
{
|
|
if (AdjustSlTp) tp+=SymbolInfoDouble(psymbol,SYMBOL_TRADE_TICK_SIZE);
|
|
tp=NormalizePrice(psymbol,tp,true);
|
|
}
|
|
return(tp);
|
|
}
|
|
|
|
void ModifySlTp(string psymbol,double ATR,bool ExpPos,int PosExpTime,bool op_type,bool UseSLTrailing,bool UseTPTrailing,bool FadeTP,bool FadeSL,
|
|
ENUM_STOP_TYPES Sl_TypeM,double SLLevelM,ENUM_TIMEFRAMES SlTimeframeM,int SlBarsM,
|
|
ENUM_STOP_TYPES Tp_TypeM,double TPLevelM,ENUM_TIMEFRAMES TpTimeframeM,int TpBarsM,
|
|
CLock &lock,bool not_locked,double SlFixed,double TpFixed,bool SlPending,bool TpPending)//,bool usependingopen,bool usependingclose,bool usependingsltp,PositionData &PosData)
|
|
{//só vai ser chamada se não for pendente para sl/tp. Nesse caso sl/tp são a mercado, e a info fica na posição
|
|
|
|
if (!not_locked) return;
|
|
double asl=((!SlPending)?PositionGetDouble(POSITION_SL):0);
|
|
double atp=((!TpPending)?PositionGetDouble(POSITION_TP):0);
|
|
double aprice=PositionGetDouble(POSITION_PRICE_OPEN);
|
|
double nsl=((!SlPending)?SlFixed:0);
|
|
double ntp=((!TpPending)?TpFixed:0);
|
|
|
|
if (op_type==Buy)//buy
|
|
{
|
|
if ((UseSLTrailing)&&(!SlPending)) nsl=set_sl_tp(psymbol,aprice,ATR,Sl_TypeM,SLLevelM,SlTimeframeM,SlBarsM,SlFixed);
|
|
if ((UseTPTrailing)&&(!TpPending)) ntp=set_tp_sl(psymbol,aprice,ATR,Tp_TypeM,TPLevelM,TpTimeframeM,TpBarsM,TpFixed);
|
|
}
|
|
else if (op_type==Sell)//sell
|
|
{
|
|
if ((UseSLTrailing)&&(!SlPending)) nsl=set_tp_sl(psymbol,aprice,ATR,Sl_TypeM,SLLevelM,SlTimeframeM,SlBarsM,SlFixed);
|
|
if ((UseTPTrailing)&&(!TpPending)) ntp=set_sl_tp(psymbol,aprice,ATR,Tp_TypeM,TPLevelM,TpTimeframeM,TpBarsM,TpFixed);
|
|
}
|
|
|
|
if (ExpPos&&(TimeLocal()>(PositionGetInteger(POSITION_TIME)+PosExpTime*3600/2)))//diminui o tp/sl
|
|
{
|
|
double fadefactor=(1.5-(TimeLocal()-PositionGetInteger(POSITION_TIME))/(PosExpTime*3600.0));
|
|
if ((FadeTP)&&(!TpPending)) ntp=NormalizePrice(psymbol,aprice+fadefactor*(ntp-aprice),true);
|
|
if ((FadeSL)&&(!SlPending)) nsl=NormalizePrice(psymbol,aprice-fadefactor*(aprice-nsl),true);
|
|
}
|
|
|
|
double ticksize=SymbolInfoDouble(psymbol,SYMBOL_TRADE_TICK_SIZE);
|
|
if (( ((int)MathRound(nsl/ticksize)!=(int)MathRound(asl/ticksize))||((int)MathRound(ntp/ticksize)!=(int)MathRound(atp/ticksize)) )
|
|
&&((nsl>=0)&&(ntp>=0)))
|
|
{
|
|
if ((nsl!=0)&&(ntp!=0))
|
|
{
|
|
if (Trade.PositionModify(PositionGetInteger(POSITION_TICKET),nsl,ntp))
|
|
lock.SetMLock(MODIFY_LOCK,TimeLocal(),asl,atp);
|
|
else MyPrint("Erro modificando sl/tp ",IntegerToString(Trade.ResultRetcode()));
|
|
}
|
|
else if ((nsl==0)&&(ntp!=0))
|
|
{
|
|
if (Trade.PositionModify(PositionGetInteger(POSITION_TICKET),0,ntp))
|
|
lock.SetMLock(MODIFY_LOCK,TimeLocal(),0,atp);
|
|
else MyPrint("Erro modificando sl/tp ",IntegerToString(Trade.ResultRetcode()));
|
|
}
|
|
else if ((nsl!=0)&&(ntp==0))
|
|
{
|
|
if (Trade.PositionModify(PositionGetInteger(POSITION_TICKET),nsl,0))
|
|
lock.SetMLock(MODIFY_LOCK,TimeLocal(),asl,0);
|
|
else MyPrint("Erro modificando sl/tp ",IntegerToString(Trade.ResultRetcode()));
|
|
}
|
|
}
|
|
|
|
}
|