//+------------------------------------------------------------------+ //| xpMaEA_v3.mq4 | //| Coders' Guru | //| http://www.xpworx.com | //| Last Modification = 2011.09.15 | //+------------------------------------------------------------------+ #property copyright "Coders' Guru" #property link "http://www.xpworx.com" //+------------------------------------------------------------------+ extern string t = "Trailing Stop Method"; extern string t0 = " 0. None"; extern string t1 = " 1. Standard"; extern string t2 = " 2. BreakEven"; extern string t3 = " 3. Jumping"; extern int TrailingStopMethod = 1; extern string ST = "Standard Trail Settings"; extern int TrailingStop = 21; extern string BE="Break even settings"; extern int BreakEvenPips = 5; extern int BreakEvenProfit = 2; extern string JSL="Jumping stop loss settings"; extern int JumpingStopPips = 15; extern bool AddBEP = true; //+------------------------------------------------------------------+ extern string _ = "Trade limits"; extern double Lots = 1; extern int TakeProfit =100; extern int StopLoss = 50; extern int Slippage = 5; extern bool UseMoneyManagement = true; extern double MaximumRisk = 0.1; extern int MagicNumber = 12345; extern bool AutoGenerateMagicNumber = true; //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ #define MODE_DEMA 4 #define MODE_TEMA 5 #define MODE_T3MA 6 #define MODE_JMA 7 #define MODE_HMA 8 #define MODE_DECEMA 9 #define MODE_SALT 10 //+------------------------------------------------------------------+ extern int MA_Period = 25; extern int MA_Type = MODE_TEMA; extern int MA_Applied = PRICE_CLOSE; extern double T3MA_VolumeFactor = 0.8; extern double JMA_Phase = 0; extern int Step_Period = 1; extern int BarsCount = 200; extern bool Alert_On = false; extern bool Arrows_On = true; extern bool Email_On = false; //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //--- Global variables double mPoint = 0.0001; //+------------------------------------------------------------------ int init() { if(AutoGenerateMagicNumber) MagicNumber = GetMagicNumber(558854); mPoint = GetPoint(); return(0); } //+------------------------------------------------------------------+ int deinit() { Comment(""); return(0); } //+------------------------------------------------------------------+ int start() { int passedTime = TimeCurrent()-Time[0]; if (passedTime<240) return(0); //+------------------------------------------------------------------+ double signal = iCustom(NULL,0,"xpMA",MA_Period,MA_Type,MA_Applied,T3MA_VolumeFactor,JMA_Phase,Step_Period,BarsCount, Alert_On,Arrows_On,Email_On,3,0); bool BuyCondition = false , SellCondition = false , CloseBuyCondition = false , CloseSellCondition = false; if (signal==1) BuyCondition = true; if (signal==-1) SellCondition = true; if (BuyCondition) CloseSellCondition = true; if (SellCondition) CloseBuyCondition = true; if(UseMoneyManagement) Lots=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1); if(TradeExist(MagicNumber)==false) { int ticket; if(BuyCondition) //<-- BUY condition { if(NewBar(0)) ticket = OpenOrder(true,OP_BUY,0,Lots,Slippage,StopLoss,TakeProfit,MagicNumber,WindowExpertName(),5,500); } if(SellCondition) //<-- SELL condition { if(NewBar(1)) ticket = OpenOrder(true,OP_SELL,0,Lots,Slippage,StopLoss,TakeProfit,MagicNumber,WindowExpertName(),5,500); } } for(int cnt = 0 ; cnt < OrdersTotal() ; cnt++) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if (OrderSymbol() == Symbol() && OrderMagicNumber()== MagicNumber) { if(CloseBuyCondition && OrderType()==OP_BUY) CloseOrder(OrderTicket(),0,Slippage,5,500); if(CloseSellCondition && OrderType()==OP_SELL) CloseOrder(OrderTicket(),0,Slippage,5,500); } } // Modified to allow different typ[es of trailing stops HandleTrailingStop(MagicNumber); return(0); } //+------------------------------------------------------------------+ double nd(double value) { return(NormalizeDouble(value,Digits)); } //+------------------------------------------------------------------+ int OpenOrder(bool STP, int TradeType, double Price, double TradeLot, int TradeSlippage, double TradeStopLoss, double TradeTakeProfit, int TradeMagicNumber, string TradeComment , int TriesCount, int Pause) { int ticket=0, cnt=0; bool DobuleLimits; double point = GetPoint(); double ask,bid; if(Price>0) { ask = nd(Price); bid = nd(Price); } else { ask = nd(Ask); bid = nd(Bid); } if(TradeStopLoss==0 && TradeTakeProfit==0) DobuleLimits = false; else { if(TradeStopLoss!=0) DobuleLimits = TradeStopLoss-MathFloor(TradeStopLoss)>0; else DobuleLimits = TradeTakeProfit-MathFloor(TradeTakeProfit)>0; } double sl=0,tp=0; if(STP==true) { if(TradeType == OP_BUY) { if(DobuleLimits==true) { if(TradeStopLoss==0) sl = 0; else sl = nd(TradeStopLoss); if(TradeTakeProfit==0) tp = 0; else tp = nd(TradeTakeProfit); for(cnt = 0 ; cnt < TriesCount ; cnt++) { if(sl==0 && tp==0) { ticket=OrderSend(Symbol(),OP_BUY,TradeLot,ask,TradeSlippage,0,0,TradeComment,TradeMagicNumber,0,Green); } else { ticket=OrderSend(Symbol(),OP_BUY,TradeLot,ask,TradeSlippage,0,0,TradeComment,TradeMagicNumber,0,Green); if(ticket>-1) { OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES); OrderModify(ticket,OrderOpenPrice(),sl,tp,0,Green); } } if(ticket==-1){Print("error=",GetLastError()," ask=",ask," bid=",bid," sl=",sl," tp=",tp," lots=",TradeLot); Sleep(Pause); continue;} else {break;} } } if(DobuleLimits==false) { if(TradeStopLoss==0) sl = 0; else sl = nd(ask-TradeStopLoss*point); if(TradeTakeProfit==0) tp = 0; else tp = nd(ask+TradeTakeProfit*point); for(cnt = 0 ; cnt < TriesCount ; cnt++) { if(sl==0 && tp==0) { ticket=OrderSend(Symbol(),OP_BUY,TradeLot,ask,TradeSlippage,0,0,TradeComment,TradeMagicNumber,0,Green); } else { ticket=OrderSend(Symbol(),OP_BUY,TradeLot,ask,TradeSlippage,0,0,TradeComment,TradeMagicNumber,0,Green); if(ticket>-1) { OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES); OrderModify(ticket,OrderOpenPrice(),sl,tp,0,Green); } } if(ticket==-1){Print("error=",GetLastError()," ask=",ask," bid=",bid," sl=",sl," tp=",tp," lots=",TradeLot); Sleep(Pause); continue;} else {break;} } } } if(TradeType == OP_SELL) { if(DobuleLimits==true) { if(TradeStopLoss==0) sl = 0; else sl = nd(TradeStopLoss); if(TradeTakeProfit==0) tp = 0; else tp = nd(TradeTakeProfit); for(cnt = 0 ; cnt < TriesCount ; cnt++) { if(sl==0 && tp==0) { ticket=OrderSend(Symbol(),OP_SELL,TradeLot,bid,TradeSlippage,0,0,TradeComment,TradeMagicNumber,0,Red); } else { ticket=OrderSend(Symbol(),OP_SELL,TradeLot,bid,TradeSlippage,0,0,TradeComment,TradeMagicNumber,0,Red); if(ticket>-1) { OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES); OrderModify(ticket,OrderOpenPrice(),sl,tp,0,Red); } } if(ticket==-1){Print("order=",TradeType," error=",GetLastError()," ask=",ask," bid=",bid," sl=",sl," tp=",tp," lots=",TradeLot); Sleep(Pause); continue;} else {break;} } } if(DobuleLimits==false) { if(TradeStopLoss==0) sl = 0; else sl = nd(bid+TradeStopLoss*point); if(TradeTakeProfit==0) tp = 0; else tp = nd(bid-TradeTakeProfit*point); for(cnt = 0 ; cnt < TriesCount ; cnt++) { if(sl==0 && tp==0) { ticket=OrderSend(Symbol(),OP_SELL,TradeLot,bid,TradeSlippage,0,0,TradeComment,TradeMagicNumber,0,Red); } else { ticket=OrderSend(Symbol(),OP_SELL,TradeLot,bid,TradeSlippage,0,0,TradeComment,TradeMagicNumber,0,Red); if(ticket>-1) { OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES); OrderModify(ticket,OrderOpenPrice(),sl,tp,0,Red); } } if(ticket==-1){Print("order=",TradeType," error=",GetLastError()," ask=",ask," bid=",bid," sl=",sl," tp=",tp," lots=",TradeLot); Sleep(Pause); continue;} else {break;} } } } } if(STP==false) { if(TradeType == OP_BUY) { if(DobuleLimits==true) { if(TradeStopLoss==0) sl = 0; else sl = nd(TradeStopLoss); if(TradeTakeProfit==0) tp = 0; else tp = nd(TradeTakeProfit); for(cnt = 0 ; cnt < TriesCount ; cnt++) { ticket=OrderSend(Symbol(),OP_BUY,TradeLot,ask,TradeSlippage,sl,tp,TradeComment,TradeMagicNumber,0,Green); if(ticket==-1){Print("order=",TradeType," error=",GetLastError()," ask=",ask," bid=",bid," sl=",sl," tp=",tp," lots=",TradeLot); Sleep(Pause); continue;} else {break;} } } if(DobuleLimits==false) { if(TradeStopLoss==0) sl = 0; else sl = nd(ask-TradeStopLoss*point); if(TradeTakeProfit==0) tp = 0; else tp = nd(ask+TradeTakeProfit*point); for(cnt = 0 ; cnt < TriesCount ; cnt++) { ticket=OrderSend(Symbol(),OP_BUY,TradeLot,ask,TradeSlippage,sl,tp,TradeComment,TradeMagicNumber,0,Green); if(ticket==-1){Print("order=",TradeType," error=",GetLastError()," ask=",ask," bid=",bid," sl=",sl," tp=",tp," lots=",TradeLot); Sleep(Pause); continue;} else {break;} } } } if(TradeType == OP_SELL) { if(DobuleLimits==true) { if(TradeStopLoss==0) sl = 0; else sl = nd(TradeStopLoss); if(TradeTakeProfit==0) tp = 0; else tp = nd(TradeTakeProfit); for(cnt = 0 ; cnt < TriesCount ; cnt++) { ticket=OrderSend(Symbol(),OP_SELL,TradeLot,bid,TradeSlippage,sl,tp,TradeComment,TradeMagicNumber,0,Red); if(ticket==-1){Print("order=",TradeType," error=",GetLastError()," ask=",ask," bid=",bid," sl=",sl," tp=",tp," lots=",TradeLot); Sleep(Pause); continue;} else {break;} } } if(DobuleLimits==false) { if(TradeStopLoss==0) sl = 0; else sl = nd(bid+TradeStopLoss*point); if(TradeTakeProfit==0) tp = 0; else tp = nd(bid-TradeTakeProfit*point); for(cnt = 0 ; cnt < TriesCount ; cnt++) { ticket=OrderSend(Symbol(),OP_SELL,TradeLot,bid,TradeSlippage,sl,tp,TradeComment,TradeMagicNumber,0,Red); if(ticket==-1){Print("order=",TradeType," error=",GetLastError()," ask=",ask," bid=",bid," sl=",sl," tp=",tp," lots=",TradeLot); Sleep(Pause); continue;} else {break;} } } } } return(ticket); } //+------------------------------------------------------------------+ bool NewBar(int ref) { static datetime LastTime[10]; if (Time[0] != LastTime[ref]) { LastTime[ref] = Time[0]; return (true); } return (false); //else } //+------------------------------------------------------------------+ bool TradeExist(int magic) { int total = OrdersTotal(); for(int cnt = 0 ; cnt < total ; cnt++) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if (OrderMagicNumber()== magic && OrderType()<=OP_SELL) return (true); } return (false); } //+------------------------------------------------------------------+ bool CloseOrder(int ticket, double lots, int slippage, int tries, int pause) { bool result=false; double ask = nd(Ask); double bid = nd(Bid); if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) { if(OrderType()==OP_BUY) { for(int c = 0 ; c < tries ; c++) { if(lots==0) result = OrderClose(OrderTicket(),OrderLots(),bid,slippage,Violet); else result = OrderClose(OrderTicket(),lots,bid,slippage,Violet); if(result==true) break; else { Sleep(pause); continue; } } } if(OrderType()==OP_SELL) { for(c = 0 ; c < tries ; c++) { if(lots==0) result = OrderClose(OrderTicket(),OrderLots(),ask,slippage,Violet); else result = OrderClose(OrderTicket(),lots,ask,slippage,Violet); if(result==true) break; else { Sleep(pause); continue; } } } } return(result); } void HandleTrailingStop(int MagicNumber) { switch (TrailingStopMethod) { case 1 : if(TrailingStop>0)TrailOrders(TrailingStop,MagicNumber); break; case 2: BreakEvenStopLoss(MagicNumber); break; case 3 : JumpingStopLoss(MagicNumber); break; } } //+------------------------------------------------------------------+ bool TrailOrders(int ts, int magic) { if(ts<=0) return(false); bool result; double point = GetPoint(); double ask = nd(Ask); double bid = nd(Bid); for(int cnt=0;cnt point*ts) { if(OrderStopLoss()>(ask+point*ts)+point || OrderStopLoss()==0) { result = OrderModify(OrderTicket(),OrderOpenPrice(),ask+point*ts,OrderTakeProfit(),0,Red); } } } if(OrderType()==OP_BUY) { if(bid-OrderOpenPrice() > point*ts) { if(OrderStopLoss()<(bid-point*ts)-point || OrderStopLoss()==0) { result = OrderModify(OrderTicket(),OrderOpenPrice(),bid-point*ts,OrderTakeProfit(),0,Green); } } } } } return(result); } int GetMagicNumber(int base) { int Reference = 0; string symbol = StringUpperCase(Symbol()); if (StringFind(symbol,"AUDCAD")>-1) Reference = base + 1001 + Period(); if (StringFind(symbol,"AUDJPY")>-1) Reference = base + 2002 + Period(); if (StringFind(symbol,"AUDNZD")>-1) Reference = base + 3003 + Period(); if (StringFind(symbol,"AUDUSD")>-1) Reference = base + 4004 + Period(); if (StringFind(symbol,"CHFJPY")>-1) Reference = base + 5005 + Period(); if (StringFind(symbol,"EURAUD")>-1) Reference = base + 6006 + Period(); if (StringFind(symbol,"EURCAD")>-1) Reference = base + 7007 + Period(); if (StringFind(symbol,"EURCHF")>-1) Reference = base + 8008 + Period(); if (StringFind(symbol,"EURGBP")>-1) Reference = base + 9009 + Period(); if (StringFind(symbol,"EURJPY")>-1) Reference = base + 1010 + Period(); if (StringFind(symbol,"EURUSD")>-1) Reference = base + 1111 + Period(); if (StringFind(symbol,"GBPCHF")>-1) Reference = base + 1212 + Period(); if (StringFind(symbol,"GBPJPY")>-1) Reference = base + 1313 + Period(); if (StringFind(symbol,"GBPUSD")>-1) Reference = base + 1414 + Period(); if (StringFind(symbol,"NZDJPY")>-1) Reference = base + 1515 + Period(); if (StringFind(symbol,"NZDUSD")>-1) Reference = base + 1616 + Period(); if (StringFind(symbol,"USDCHF")>-1) Reference = base + 1717 + Period(); if (StringFind(symbol,"USDJPY")>-1) Reference = base + 1818 + Period(); if (StringFind(symbol,"USDCAD")>-1) Reference = base + 1919 + Period(); if (Reference == 0) Reference = base + 2020 + Period(); return(Reference); } //+------------------------------------------------------------------+ string StringUpperCase(string str) { int s = StringLen(str); int chr = 0; string temp; for (int c = 0 ; c < s ; c++) { chr = StringGetChar(str,c); if (chr >= 97 && chr <=122) chr = chr - 32; temp = temp + CharToStr(chr); } return (temp); } //+------------------------------------------------------------------+ double GetPoint(string symbol = "") { if(symbol=="" || symbol == Symbol()) { if(Point==0.00001) return(0.0001); else if(Point==0.001) return(0.01); else return(Point); } else { RefreshRates(); double tPoint = MarketInfo(symbol,MODE_POINT); if(tPoint==0.00001) return(0.0001); else if(tPoint==0.001) return(0.01); else return(tPoint); } } //+------------------------------------------------------------------+ void BreakEvenStopLoss(int magic) // Move stop loss to breakeven { double point = GetPoint(); bool result; bool ShowAlerts=true; double ask = nd(Ask); double bid = nd(Bid); // Now selected from menu // if (!BreakEven) return; // User has not chosen this option, so abort for(int cnt=0;cnt= OrderOpenPrice () + (point*BreakEvenPips) && OrderStopLoss()0 && ShowAlerts==true) Alert("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket()); } } if (OrderType()==OP_SELL) { if (ask <= OrderOpenPrice() - (point*BreakEvenPips) && (OrderStopLoss()>OrderOpenPrice()|| OrderStopLoss()==0)) { result = OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()-(BreakEvenProfit*point),OrderTakeProfit(),0,CLR_NONE); if (result>0 && ShowAlerts==true) Alert("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket()); } } } } } // End BreakevenStopLoss sub void JumpingStopLoss(int magic) // Jump sl by pips and at intervals chosen by user { double point = GetPoint(); double sl; double ask = nd(Ask); double bid = nd(Bid); bool ShowAlerts=true; // Now selected from menu // if (!JumpingStop) return(0); // User has not chosen this option, so abort int ticket; for(int cnt=0;cnt= OrderOpenPrice() + (JumpingStopPips*point)) { sl=OrderOpenPrice(); if (AddBEP==true) sl=sl+(BreakEvenProfit*point); // If user wants to add a profit to the break even ticket = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE); if (ticket>0) { if (ShowAlerts==true) Alert("Jumping stop set at breakeven ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket()); Print("Jumping stop set at breakeven: ", OrderSymbol(), ": SL ", sl, ": Ask ", ask); } return(0); } } //close if (sl==0 || sl= (sl + JumpingStopPips) if (bid>= sl + ((JumpingStopPips*2)*point) && sl>= OrderOpenPrice()) { sl=sl+(JumpingStopPips*point); ticket = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE); if (ticket>0) { if (ShowAlerts==true) Alert("Jumping stop set at ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket()); Print("Jumping stop set: ", OrderSymbol(), ": SL ", sl, ": Ask ", ask); } }// close if (bid>= sl + (JumpingStopPips*point) && sl>= OrderOpenPrice()) } if (OrderType()==OP_SELL) { // First check if sl needs setting to breakeven if (sl==0 || sl>OrderOpenPrice()) { if (ask <= OrderOpenPrice() - (JumpingStopPips*point)) { sl=OrderOpenPrice(); if (AddBEP==true) sl=sl-(BreakEvenProfit*point); // If user wants to add a profit to the break even ticket = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE); if (ticket>0) { if (ShowAlerts==true) Alert("Jumping stop set at breakeven ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket()); Print("Jumping stop set at breakeven: ", OrderSymbol(), ": SL ", sl, ": Ask ", ask); } return(0); } } //close if (sl==0 || sl>OrderOpenPrice() // Decrement sl by sl - JumpingStopPips. // This will happen when market price <= (sl - JumpingStopPips) if (bid<= sl - ((JumpingStopPips*2)*point) && sl<= OrderOpenPrice()) { sl=sl-(JumpingStopPips*point); ticket = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE); if (ticket>0) { if (ShowAlerts==true) Alert("Jumping stop set at ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket()); Print("Jumping stop set: ", OrderSymbol(), ": SL ", sl, ": Ask ", ask); } }// close if (bid>= sl + (JumpingStopPips*point) && sl>= OrderOpenPrice()) } } } } //End of JumpingStopLoss sub