//+-------------------------------------------------------------------------------------------------------------------------------------------------+ //| Dr_abade_ea_9_3_3.mq4 | //+-------------------------------------------------------------------------------------------------------------------------------------------------+ /*------------------------------------------------------------------------------------------------------------------------------- specification ---// //-------------------------------------------------------------------------------------------------------------------------------------------------*/ //#property strict //=================================================================================================================================================// enum ENUM_TRADE_DIRECTION { BUY=1,SELL=2 }; enum ENUM_TF { current=0, M1=1, M5=5, M15=15, M30=30, H1=60, H4=240, D1=1440, W1=10080, MN1=43200 }; enum ENUM_BE_TYPE { EVERY_TICK=0, EVERY_BAR=1, EVERY_TICK_and_EVERY_BAR=2 }; //========================================================================================================================== external variables ===// input ENUM_TRADE_DIRECTION tradeDirection=BUY; input int nDeals=0;// input color colorBuy=clrYellow,// colorSell=clrRed;// input string Profit_line_name_buy="tp",// Profit_line_name_sell="s_tp";// input double _SL=0.0,//stop loss price, if 0 - off _TP=0.0;//take profit price, if 0 - off input ENUM_BE_TYPE BE_type=EVERY_TICK_and_EVERY_BAR;// input ENUM_TF BE_TF=current;//work timeframe of EA input double BE_distance_tick=0.0,// BE_distance_bar=0.0,// BE_indent=0.0,//breakeven indent Lot=0.1;// input bool useCandlesSL=false;// input int xCandles=3;// input double maxPipsSL=25.0;// input double maxSpread=2.5;//if 0 - not check maximum allowable spread input int Magic=135;// input ENUM_TF Tf=current;// //============================================================================================================================ global variables ===// datetime TimeNow, TimePrev, TimeLastStart; string Profit_line_name; double TickSize, TickValue, Spread, StopLevel, MinLot, MaxLot, LotStep, Pnt, Last_price, SL, TP; int order_type, T, nBO,nSO,nBS,nSS,nBL,nSL,nO,nS,nL,_nBO,_nSO,_nBS,_nSS,_nBL,_nSL,_nO,_nS,_nL,Slip; bool Ans, _Ans, Activate, FatalError, FreeMarginAlert, IsModify, IsTester, IsVisual; //=================================================================================================================================================// int OnInit() { Activate=false; FatalError=false; if(IsTesting() || IsOptimization() || IsVisualMode()) IsTester=true; else IsTester=false; if(!IsOptimization()) IsVisual=true; else IsVisual=false; if(Digits()==3 || Digits()==5) Pnt=10*Point(); else Pnt=Point(); GetMarketInfo(); HistoryCheck(); if(BE_type!=EVERY_TICK) TimePrev=iTime(NULL,BE_TF,0); Last_price=Bid; Activate=true; return(INIT_SUCCEEDED); } //================================================================================================= The deinitialization function of the expert ===// void OnDeinit(const int reason) { Comment(""); ObjectsDeleteAll(0,0,OBJ_HLINE); } //============================================================================================================= The main function of the expert ===// void OnTick() { if(!Activate || FatalError) return; if(!IsTester) GetMarketInfo(); if(!HistoryCheck()) return; int i=0, pos=0, index=0; double Line_price=0.0, sl_size=0.0; string Trade_line_name=""; _Ans=true; for(i=ObjectsTotal(ChartID(),0)-1; i>=0; i--) { Trade_line_name=ObjectName(i); if(StringFind(Trade_line_name,"used")!=-1) continue; if(ObjectType(Trade_line_name)==OBJ_TREND) { Line_price=ObjectGetValueByShift(Trade_line_name,0); if(tradeDirection==BUY&&ObjectGet(Trade_line_name,OBJPROP_COLOR)==colorBuy) { order_type=OP_BUY; Profit_line_name=Profit_line_name_buy; } else if(tradeDirection==SELL&&ObjectGet(Trade_line_name,OBJPROP_COLOR)==colorSell) { order_type=OP_SELL; Profit_line_name=Profit_line_name_sell; } else continue; if(nDeals>0) { numbOrders(); if(order_type==OP_BUY&&nBO-nSO>=nDeals) continue; else if(order_type==OP_SELL&&nSO-nBO>=nDeals) continue; } if(ND(Line_price-Bid)==0.0||(order_type==OP_BUY&&Last_priceLine_price)||(order_type==OP_SELL&&Last_price>Line_price&&Bid0.0&&((order_type==OP_BUY&&ND(Ask-iLow(NULL,Tf,iLowest(NULL,Tf,MODE_LOW,xCandles,0)))>maxPipsSL*Pnt)||(order_type==OP_SELL&&ND((iHigh(NULL,Tf,iHighest(NULL,Tf,MODE_HIGH,xCandles,0))+Spread)-Bid)>maxPipsSL*Pnt))) { ObjectSetString(0,Trade_line_name,OBJPROP_NAME,"used_"+Trade_line_name); Alert("Too large stop loss!"); continue; } if(maxSpread>0.0&&ND(Ask-Bid)>=maxSpread*Pnt) continue; if(MO(order_type,Lot,getNameLineSL(Line_price,order_type))==-1) continue; ObjectSetString(0,Trade_line_name,OBJPROP_NAME,"used_"+Trade_line_name); if(!useCandlesSL) { if(_TP>0.0) { TP=_TP; } else if(_TP==0.0 && Profit_line_name!="" && ObjectFind(0,Profit_line_name)!=-1) TP=ObjectGetValueByShift(Profit_line_name,0); else TP=0.0; if(_SL>0.0) { SL=_SL; } else if(_SL<=0.0) { SL=0.0; } if(SL==0.0 && TP==0.0) continue; } else { if(order_type==OP_BUY) { SL=iLow(NULL,Tf,iLowest(NULL,Tf,MODE_LOW,xCandles,0)); if(_TP<=0.0) TP=GetOrdDouble("op",T)+(GetOrdDouble("op",T)-SL); else TP=_TP; } else if(order_type==OP_SELL) { SL=iHigh(NULL,Tf,iHighest(NULL,Tf,MODE_HIGH,xCandles,0))+Spread; if(_TP<=0.0) TP=GetOrdDouble("op",T)-(SL-GetOrdDouble("op",T)); else TP=_TP; } } Ans=ModifyByTicket(T); if(!Ans&&_Ans) _Ans=false; } } }/*for*/ IsModify=_Ans; _Ans=true; for(pos=OrdersTotal()-1; pos>=0; pos--) { if(!OrderSelect(pos,SELECT_BY_POS)||OrderSymbol()!=Symbol()||id()!=Magic||type()>1) continue; if(!IsModify||(!useCandlesSL&&Profit_line_name!=""&&ObjectFind(0,Profit_line_name)!=-1)) { if(!useCandlesSL) { if(_TP>0.0) { TP=_TP; } else if(_TP<=0.0 && Profit_line_name!="" && ObjectFind(0,Profit_line_name)!=-1) TP=ObjectGetValueByShift(Profit_line_name,0); else TP=0.0; if(_SL>0.0) { SL=_SL; } else if(_SL<=0.0) { SL=0.0; } if(SL==0.0 && TP==0.0) continue; } else { index=iBarShift(NULL,Tf,ot()); if(type()==OP_BUY) { SL=iLow(NULL,Tf,iLowest(NULL,Tf,MODE_LOW,xCandles,index)); if(_TP<=0.0) TP=op()+(op()-SL); else TP=_TP; } else if(type()==OP_SELL) { SL=iHigh(NULL,Tf,iHighest(NULL,Tf,MODE_HIGH,xCandles,index))+Spread; if(_TP<=0.0) TP=op()-(SL-op()); else TP=_TP; } } Ans=ModifyByTicket(OrderTicket()); if(!Ans&&_Ans) _Ans=false; } }/*for*/ IsModify=_Ans; Last_price=Bid; CheckClose(); if(BE_type!=EVERY_TICK) TimeNow=iTime(NULL,BE_TF,0); Breakeven(); dnOpenOrderBE(); if(BE_type!=EVERY_TICK && TimePrev!=TimeNow) TimePrev=TimeNow; } //=================================================================================================================================================// double op(int t=-1) {if(t!=-1&&!OrderSelect(t,SELECT_BY_TICKET))return(0.0); else return(OrderOpenPrice());} //=================================================================================================================================================// int type(int t=-1) {if(t!=-1&&!OrderSelect(t,SELECT_BY_TICKET))return(0.0); else return(OrderType());} //=================================================================================================================================================// int id(int t=-1) {if(t!=-1&&!OrderSelect(t,SELECT_BY_TICKET))return(0.0); else return(OrderMagicNumber());} //=================================================================================================================================================// int ot(int t=-1) {if(t!=-1&&!OrderSelect(t,SELECT_BY_TICKET))return(0.0); else return((int)OrderOpenTime());} //=================================================================================================================================================// /*string getTLname(int i){switch(i){case 1:return(Trade_line_name_1); case 2:return(Trade_line_name_2); case 3:return(Trade_line_name_3); case 4:return(Trade_line_name_4); case 5:return(Trade_line_name_5); case 6:return(Trade_line_name_6); case 7:return(Trade_line_name_7); case 8:return(Trade_line_name_8); case 9:return(Trade_line_name_9); case 10:return(Trade_line_name_10); case 11:return(Trade_line_name_11); case 12:return(Trade_line_name_12); case 13:return(Trade_line_name_13); case 14:return(Trade_line_name_14); case 15:return(Trade_line_name_15); case 16:return(Trade_line_name_16); case 17:return(Trade_line_name_17); case 18:return(Trade_line_name_18); case 19:return(Trade_line_name_19); case 20:return(Trade_line_name_20); case 21:return(Trade_line_name_21); case 22:return(Trade_line_name_22); case 23:return(Trade_line_name_23); case 24:return(Trade_line_name_24); case 25:return(Trade_line_name_25); case 26:return(Trade_line_name_26); case 27:return(Trade_line_name_27); case 28:return(Trade_line_name_28); case 29:return(Trade_line_name_29); case 30:return(Trade_line_name_30); case 31:return(Trade_line_name_31); case 32:return(Trade_line_name_32); case 33:return(Trade_line_name_33); case 34:return(Trade_line_name_34); case 35:return(Trade_line_name_35); case 36:return(Trade_line_name_36); case 37:return(Trade_line_name_37); case 38:return(Trade_line_name_38); case 39:return(Trade_line_name_39); case 40:return(Trade_line_name_40); case 41:return(Trade_line_name_41); case 42:return(Trade_line_name_42); case 43:return(Trade_line_name_43); case 44:return(Trade_line_name_44); case 45:return(Trade_line_name_45); case 46:return(Trade_line_name_46); case 47:return(Trade_line_name_47); case 48:return(Trade_line_name_48); case 49:return(Trade_line_name_49); case 50:return(Trade_line_name_50); case 51:return(Trade_line_name_51); case 52:return(Trade_line_name_52); case 53:return(Trade_line_name_53); case 54:return(Trade_line_name_54); case 55:return(Trade_line_name_55); case 56:return(Trade_line_name_56); case 57:return(Trade_line_name_57); case 58:return(Trade_line_name_58); case 59:return(Trade_line_name_59); case 60:return(Trade_line_name_60);}return("");}*/ //=================================================================================================================================================// string getNameLineSL(double linePrice,int ordType) { string sl_line_name="",slLineName=""; double slPrice=0.0,slPricePrev=0.0; int i=0; for(i=ObjectsTotal(ChartID(),0)-1; i>=0; i--) { sl_line_name=ObjectName(i); if(StringFind(sl_line_name,"used")!=-1) continue; if(ObjectType(sl_line_name)==OBJ_TREND) { slPrice=ObjectGetValueByShift(sl_line_name,0); if(ordType==OP_BUY&&ObjectGet(sl_line_name,OBJPROP_COLOR)==colorSell) { if(slPriceslPricePrev)) { slLineName=sl_line_name; slPricePrev=slPrice; } } else if(ordType==OP_SELL&&ObjectGet(sl_line_name,OBJPROP_COLOR)==colorBuy) { if(slPrice>linePrice&&(slPricePrev==0.0||slPrice=0; pos--) { if(!OrderSelect(pos,SELECT_BY_POS,MODE_TRADES)||OrderSymbol()!=Symbol()||OrderMagicNumber()!=Magic||OrderType()>1) continue; sl_line_name=OrderComment(); if(ObjectFind(0,sl_line_name)!=-1) { slPrice=ObjectGetValueByShift(sl_line_name,0); if((OrderType()==OP_BUY&&Bid<=slPrice)||(OrderType()==OP_SELL&&Bid>=slPrice)) { if(CloseByTicket(OrderTicket())) { ObjectSetString(0,sl_line_name,OBJPROP_NAME,"used_"+sl_line_name); } } } }//for } //=================================================================================================================================================// bool CloseByTicket(int ticket, double lot=0.0) { if(!OrderSelect(ticket,SELECT_BY_TICKET)) return(false); if(OrderCloseTime()>0) return(true); if(lot<=0.0) lot=OrderLots(); double price; int i; color c; RefreshRates(); i=0; Ans=false; while(!Ans && i<5) { if(OrderType()==OP_BUY) { price=Bid; c=clrBlue; } else { price=Ask; c=clrRed; } Ans=OrderClose(OrderTicket(),NL(lot),ND(price),2*(int)MarketInfo(Symbol(),MODE_SPREAD),c); if(!Ans) { if(!Errors(GetLastError())) break; } i++; } /*while*/ return(Ans); } //=================================================================================================================================================// int GetTicket(string type="", string position="last", string list="trade") { int pos=0, i=0, ticket=0, ticket_prev=-1; if(list=="trade") { for(pos=OrdersTotal()-1; pos>=0; pos--) { if(!OrderSelect(pos,SELECT_BY_POS,MODE_TRADES) || OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue; if((type=="" && OrderType()>5)||(type=="market" && OrderType()>1)||(type=="buy" && OrderType()!=0)||(type=="sell" && OrderType()!=1)) continue; ticket=OrderTicket(); if((position=="first" && (ticket_prev==-1 || ticket_prev>ticket)) || (position=="last" && (ticket_prev==-1 || ticket_prev=0; pos--) { if(!OrderSelect(pos,SELECT_BY_POS,MODE_HISTORY) || OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue; if((type=="" && OrderType()>5)||(type=="market" && OrderType()>1)||(type=="buy" && OrderType()!=0)||(type=="sell" && OrderType()!=1)) continue; ticket=OrderTicket(); if((position=="first" && (ticket_prev==-1 || ticket_prev>ticket)) || (position=="last" && (ticket_prev==-1 || ticket_prev=0; pos--) { if(!OrderSelect(pos,SELECT_BY_POS,MODE_TRADES) || OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic || OrderType()>1) continue; op=OrderOpenPrice(); sl=OrderStopLoss(); tp=OrderTakeProfit(); datetime opentime=OrderOpenTime(); datetime itime=iTime(NULL,BE_TF,0); int oticket=OrderTicket(); string objname=(string)oticket; if(itime<=opentime) continue; string comm=OrderComment(); string check_com=StringSubstr(comm,0,5); if(check_com=="BE of") continue; string findcom="BE of "+objname; if(dnTotPos(findcom)>0) continue; if(OrderType()==OP_BUY) { if((BE_type!=EVERY_BAR && ND(Bid-op)>=BE_distance_tick*Pnt) || (BE_type!=EVERY_TICK && TimePrev!=TimeNow && ND(Bid-op)>=BE_distance_bar*Pnt)) { sl_lev=op+BE_indent*Pnt; c=clrBlue; if(ObjectFind(0,objname)<0) { HLineCreate(0,objname,0,sl_lev,c); } } else continue; } if(OrderType()==OP_SELL) { if((BE_type!=EVERY_BAR && ND(op-Ask)>=BE_distance_tick*Pnt) || (BE_type!=EVERY_TICK && TimePrev!=TimeNow && ND(op-Ask)>=BE_distance_bar*Pnt)) { sl_lev=op-BE_indent*Pnt; c=clrRed; if(ObjectFind(0,objname)<0) { HLineCreate(0,objname,0,sl_lev,c); } } else continue; } } } //=================================================================================================================================================// void dnOpenOrderBE() { double close1=iClose(NULL,BE_TF,1); int objtot=ObjectsTotal(); for(int i=objtot-1; i>=0; i--) { string objname=ObjectName(i); if(ObjectType(objname)!=OBJ_HLINE) continue; int nticket=StringToInteger(objname); double llevel=ObjectGetDouble(0,objname,OBJPROP_PRICE); if(!OrderSelect(nticket,SELECT_BY_TICKET,MODE_TRADES)) continue; int otype=OrderType(); double olot=OrderLots(); string comm="BE of "+(string)nticket; if(otype==OP_BUY) { if(close1>llevel && Bid<=llevel) { if(MO(OP_SELL,olot,comm)<0) { Print("Failed to Open Sell as BreakEven of ticket : ",(string) nticket); } else { if(!ObjectDelete(0,objname)) { Print("Failed to delete HLine ",objname); } } } } if(otype==OP_SELL) { if(close1=llevel) { if(MO(OP_BUY,olot,comm)<0) { Print("Failed to Open Buy as BreakEven of ticket : ",(string) nticket); } else { if(!ObjectDelete(0,objname)) { Print("Failed to delete HLine ",objname); } } } } } } //+------------------------------------------------------------------+ int MO(int type, double lot, string comment="") // market order { double price; color c; int i; T=-1; RefreshRates(); if(type==OP_BUY) { c=clrBlue; price=Ask; } else if(type==OP_SELL) { c=clrRed; price=Bid; } else return(T); if(AccountFreeMarginCheck(Symbol(),type,NL(lot))<=0.0 || GetLastError()==134) { if(!FreeMarginAlert) { Alert("Not enough money to send the order. Free Margin = ", DoubleToStr(AccountFreeMargin(),2)); FreeMarginAlert=true; } return(T); } FreeMarginAlert=false; while(T<0 && i<5) { T=OrderSend(Symbol(),type,NL(lot),ND(price),2*(int)MarketInfo(Symbol(),MODE_SPREAD),NULL,NULL,comment,Magic,NULL,c); if(T<0) { if(!Errors(GetLastError())) return(T); } i++; } /*while*/ return(T); } //=================================================================================================================================================// bool ModifyByTicket(int ticket) { if(SL==0.0 && TP==0.0) return(true); if(!OrderSelect(ticket,SELECT_BY_TICKET)) return(false); double sl=0.0, tp=0.0, _sl=OrderStopLoss(), _tp=OrderTakeProfit(), op=OrderOpenPrice(); int i=0; color c; RefreshRates(); if(OrderType()==OP_BUY) { if(TP>0.0) { tp=TP; if(ND(tp-Bid)0.0) { sl=SL; if(ND(Bid-sl)0.0) { tp=TP; if(ND(Ask-tp)0.0) { sl=SL; if(ND(sl-Ask)=0; pos--) { if(!OrderSelect(pos,SELECT_BY_POS)||OrderSymbol()!=Symbol()||OrderMagicNumber()!=Magic) continue; switch(OrderType()) { case 0: nBO++; break; case 1: nSO++; break; case 2: nBL++; break; case 3: nSL++; break; case 4: nBS++; break; case 5: nSS++; break; }/*switch*/ }//for nO=nBO+nSO; nS=nBS+nSS; nL=nBL+nSL; if(i==0) return; else if(i==1) { _nBO=nBO; _nSO=nSO; _nBS=nBS; _nSS=nSS; _nBL=nBL; _nSL=nSL; _nO=nO; _nS=nS; _nL=nL; } } //=================================================================================================================================================// bool HistoryCheck() { int i=0; while(i<10) { iTime(NULL,(int)Tf,0); // while if(GetLastError()!=4066) break; Sleep(1000); i++; } if(i==10) { Comment("Update failed. Go to the next attempt."); return(false); } Comment(""); return(true); } //=================================================================================================================================================// void GetMarketInfo() { TickSize=MarketInfo(Symbol(),MODE_TICKSIZE); TickValue=MarketInfo(Symbol(),MODE_TICKVALUE); Spread=MarketInfo(Symbol(),MODE_SPREAD)*Point; StopLevel=MarketInfo(Symbol(),MODE_STOPLEVEL)*Point; MinLot=MarketInfo(Symbol(),MODE_MINLOT); MaxLot=MarketInfo(Symbol(),MODE_MAXLOT); LotStep=MarketInfo(Symbol(),MODE_LOTSTEP); } //=================================================================================================================================================// double NL(double L) { return(MathRound(MathMin(MathMax(L, MinLot), MaxLot)/LotStep)*LotStep); } //=================================================================================================================================================// double ND(double A, int digits=0) { if(digits<=0) digits=Digits(); return(NormalizeDouble(A, digits)); } //=================================================================================================================================================// double NT(double A, int direction=0) { double _A=MathRound(A/TickSize)*TickSize; if(direction==1) { if(ND(A-_A)>0.0) _A+=TickSize; } else if(direction==-1) { if(ND(A-_A)<0.0) _A-=TickSize; } return(_A); } //=================================================================================================================================================// bool Errors(int Error) { if(Error==0) return(false); // No error switch(Error) { // Crucial errors: case 4: // Trade server is busy Sleep(3000); RefreshRates(); return(true); // Avoidable error case 129: // Wrong price case 135: // Price changed RefreshRates(); // Refresh data return(true); // Avoidable error case 136: // No prices. Waiting for a new tick. while(!RefreshRates()) Sleep(1); return(true); // Avoidable error case 137: // Broker is busy Sleep(3000); RefreshRates(); return(true); // Avoidable error case 146: // Trading subsystem is busy Sleep(500); RefreshRates(); return(true); // Avoidable error // Fatal error: case 2 : // Generic error case 5 : // The old version of the client terminal case 64: // Account blocked case 133: // Trading is prohibited Alert("A fatal error - expert stopped!"); FatalError=true; return(false); // Fatal error default: // Other variants return(false); } /*switch*/ } //=================================================================================================================================================// //+------------------------------------------------------------------+ //| Create the horizontal line | //+------------------------------------------------------------------+ bool HLineCreate(const long chart_ID=0, // chart's ID const string name="HLine", // line name const int sub_window=0, // subwindow index double price=0, // line price const color clr=clrRed, // line color const ENUM_LINE_STYLE style=STYLE_SOLID, // line style const int width=1, // line width const bool back=false, // in the background const bool selection=true, // highlight to move const bool hidden=true, // hidden in the object list const long z_order=0) // priority for mouse click { //--- if the price is not set, set it at the current Bid price level if(!price) price=SymbolInfoDouble(Symbol(),SYMBOL_BID); //--- reset the error value ResetLastError(); if(ObjectFind(name)>=0) { if(!ObjectDelete(name)) { Print(__FUNCTION__,": failed to delete a horizontal line! Error code = ",GetLastError()); return(false); } } //--- create a horizontal line if(!ObjectCreate(chart_ID,name,OBJ_HLINE,sub_window,0,price)) { Print(__FUNCTION__,": failed to create a horizontal line! Error code = ",GetLastError()); return(false); } //--- set line color ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); //--- set line display style ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style); //--- set line width ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width); //--- display in the foreground (false) or background (true) ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); //--- enable (true) or disable (false) the mode of moving the line by mouse //--- when creating a graphical object using ObjectCreate function, the object cannot be //--- highlighted and moved by default. Inside this method, selection parameter //--- is true by default making it possible to highlight and move the object ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); //--- hide (true) or display (false) graphical object name in the object list ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); //--- set the priority for receiving the event of a mouse click in the chart ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); //--- successful execution return(true); } //+------------------------------------------------------------------+ int dnTotPos(string ocom) { int total=0; int ordertotal=OrdersTotal(); for(int i=0; i