//+-----------------------------------------------------------------------------+ //| PIVOTEMA3.mq4 | //| | //| 6/14/2006 Modified by Robert Hill to use different ideas for trailing stop | //| and to show errors if they occur on order processing. | //| 6/20/2006 Modified to check for Symbol and Comment match to close orders | //| 6/22/2006 Modified to use magic number instead of comment to identify trades| //| 6/23/2006 Modified code to fit my normal template | //+-----------------------------------------------------------------------------+ #property copyright "orBanAway aka cucurucu" #property link "" #include //---- extern int timeframe =0; extern double StopLoss =50; extern double TakeProfit =350; extern bool UseTrailingStop=true; extern int TrailingStopType=2; // Type 1 moves stop immediately, Type 2 waits til value of TS is reached extern double TrailingStop=50; // Change to whatever number of pips you wish to trail your position with. extern double FirstMove=30; // Type 3 first level pip gain extern double FirstStopLoss=50; // Move Stop to Breakeven extern double SecondMove=40; // Type 3 second level pip gain extern double SecondStopLoss=50; // Move stop to lock is profit extern double ThirdMove=50; extern double TrailingStop3=50; // Move stop and trail from there extern string Name_Expert ="PivotEMA3RLHv4"; extern int Slippage =3; extern bool UseSound =true; extern string NameFileSound ="shotgun.wav"; extern double Lots =1; //extern double ProfitModifySL = 50; int MagicNumber; int TradesInThisSymbol; int t= 0; int D,A; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int init() { MagicNumber=3000 + func_Symbol2Val(Symbol())*100 + func_TimeFrame_Const2Val(Period()); //---- return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int deinit(){return(0);} //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CheckExitCondition(string TradeType) { if(timeframe==0) {timeframe=Period();} //---- double M=iMA(Symbol(),timeframe,3,0,MODE_EMA,PRICE_OPEN,0); // EMA3 Open double M1=iMA(Symbol(),timeframe,3,0,MODE_EMA,PRICE_OPEN,1); // Previous EMA3 Open double MC=iMA(Symbol(),timeframe,3,0,MODE_EMA,PRICE_CLOSE,0); // EMA3 Close // double O=iCustom(Symbol(),timeframe,"Heiken Ashi",2,0); //Heiken Ashi Open double C=iCustom(Symbol(),timeframe,"Heiken Ashi",3,0); //Heiken Ashi Close // double TR=iATR(Symbol(),timeframe,1,0); //True Range double ATR4=iATR(Symbol(),timeframe,4,0); //Average True Range double ATR8=iATR(Symbol(),timeframe,8,0); double ATR12=iATR(Symbol(),timeframe,12,0); double ATR24=iATR(Symbol(),timeframe,24,0); // double TR1=iATR(Symbol(),timeframe,1,1); // Previous True Range double A4=iATR(Symbol(),timeframe,4,1); // Previous Average True Range double A8=iATR(Symbol(),timeframe,8,1); double A12=iATR(Symbol(),timeframe,12,1); double A24=iATR(Symbol(),timeframe,24,1); double TR2=iATR(Symbol(),timeframe,1,2); // double P=iCustom(Symbol(),1440,"Pivot",0,0); // Daily Pivot //---- bool YesClose; A=0; if (A4=P) && (CTR1)||(TR1>TR2)) && (A>0) && (MCTR1) && (A>0)){closeAllOrders();t=0;return(0);} //closing longs if HA changes colour } if (TradeType=="SELL") { if ((M1<=P) && (C>O) && (M>P) && ((TR>TR1)||(TR1>TR2)) && (A>0) && (MC>M)) YesClose=true; //if ((t==2) && (C>O) && (D==DayOfYear()) && (TR>TR1) && (A>0)){closeAllOrders();t=0;return(0);} //closing shorts if HA changes colour } return(YesClose); } //+------------------------------------------------------------------+ //| CheckEntryCondition | //| Check if entry condition is met | //+------------------------------------------------------------------+ bool CheckEntryCondition(string TradeType) { bool YesTrade; //---- if(timeframe==0) {timeframe=Period();} double M=iMA(Symbol(),timeframe,3,0,MODE_EMA,PRICE_OPEN,0); // EMA3 Open double M1=iMA(Symbol(),timeframe,3,0,MODE_EMA,PRICE_OPEN,1); // Previous EMA3 Open double MC=iMA(Symbol(),timeframe,3,0,MODE_EMA,PRICE_CLOSE,0); // EMA3 Close // Speed up processing for backtesting // If one of the rules is false then no need to check the rest if (TradeType=="BUY" && MC<=M) return(false); if (TradeType=="SELL" && MC>=M) return(false); // double TR=iATR(Symbol(),timeframe,1,0); //True Range double ATR4=iATR(Symbol(),timeframe,4,0); //Average True Range double ATR8=iATR(Symbol(),timeframe,8,0); double ATR12=iATR(Symbol(),timeframe,12,0); double ATR24=iATR(Symbol(),timeframe,24,0); // double TR1=iATR(Symbol(),timeframe,1,1); // Previous True Range double A4=iATR(Symbol(),timeframe,4,1); // Previous Average True Range double A8=iATR(Symbol(),timeframe,8,1); double A12=iATR(Symbol(),timeframe,12,1); double A24=iATR(Symbol(),timeframe,24,1); double TR2=iATR(Symbol(),timeframe,1,2); //---- A=0; if (A4=P) return(false); if (TradeType=="BUY" && M<=P) return(false); if (TradeType=="SELL" && M1<=P) return(false); if (TradeType=="SELL" && M>=P) return(false); // double O=iCustom(Symbol(),timeframe,"Heiken Ashi",2,0); //Heiken Ashi Open double C=iCustom(Symbol(),timeframe,"Heiken Ashi",3,0); //Heiken Ashi Close //---- YesTrade=false; if (TradeType=="BUY") { if ((M1<=P) && (C>O) && (M>P) && ((TR>TR1)||(TR1>TR2)) && (A>0) && (MC>M)) YesTrade=true; D=DayOfYear(); } // Check for cross down if (TradeType=="SELL") { if ((M1>=P) && (CTR1)||(TR1>TR2)) && (A>0) && (MC=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); if(OrderSymbol()!=Symbol()) continue; if(OrderMagicNumber()!=MagicNumber) continue; if(OrderType()==OP_BUY) NumBuyTrades++; if(OrderType()==OP_SELL)NumSellTrades++; } NumPositions=NumBuyTrades + NumSellTrades; return(NumPositions); } //+------------------------------------------------------------------+ //| Handle Open Positions | //| Check if any open positions need to be closed or modified | //+------------------------------------------------------------------+ int HandleOpenPositions() { int cnt; bool YesClose; double pt; // for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); if(OrderSymbol()!=Symbol()) continue; if(OrderMagicNumber()!=MagicNumber) continue; if(OrderType()==OP_BUY) { if (CheckExitCondition("BUY")) { CloseOrder(OrderTicket(),OrderLots(),Bid); } else { if (UseTrailingStop) { HandleTrailingStop("BUY",OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit()); } } } if(OrderType()==OP_SELL) { if (CheckExitCondition("SELL")) { CloseOrder(OrderTicket(),OrderLots(),Ask); } else { if(UseTrailingStop) { HandleTrailingStop("SELL",OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit()); } } } } } //+------------------------------------------------------------------+ //| HandleTrailingStop | //| Type 1 moves the stoploss without delay. | //| Type 2 waits for price to move the amount of the trailStop | //| before moving stop loss then moves like type 1 | //| Type 3 uses up to 3 levels for trailing stop | //| Level 1 Move stop to 1st level | //| Level 2 Move stop to 2nd level | //| Level 3 Trail like type 1 by fixed amount other than 1 | //| Possible future types | //| Type 4 uses 2 for 1, every 2 pip move moves stop 1 pip | //| Type 5 uses 3 for 1, every 3 pip move moves stop 1 pip | //+------------------------------------------------------------------+ int HandleTrailingStop(string type, int ticket, double op, double os, double tp) { double pt, TS=0; double bos,bop,opa,osa; //---- if (type=="BUY") { switch(TrailingStopType) { case 1: pt=Point*StopLoss; if(Bid-os > pt) ModifyStopLoss(ticket,op,Bid-pt,tp); break; case 2: pt=Point*TrailingStop; if(Bid-op > pt) { if(os < Bid - pt || os==0) ModifyStopLoss(ticket,op,Bid - pt,tp); } break; case 3: if (Bid - op > FirstMove * Point) { TS=op + FirstMove*Point - FirstStopLoss * Point; if (os < TS) { ModifyStopLoss(ticket,op,TS,tp); } } if (Bid - op > SecondMove * Point) { TS=op + SecondMove*Point - SecondStopLoss * Point; if (os < TS) { ModifyStopLoss(ticket,op,TS,tp); } } if (Bid - op > ThirdMove * Point) { TS=Bid - TrailingStop3*Point; if (os < TS) { ModifyStopLoss(ticket,op,TS,tp); } } break; } return(0); } if (type== "SELL") { switch(TrailingStopType) { case 1: pt=Point*StopLoss; if(os - Ask > pt) ModifyStopLoss(ticket,op,Ask+pt,tp); break; case 2: pt=Point*TrailingStop; if(op - Ask > pt) { if(os > Ask+pt || os==0) ModifyStopLoss(ticket,op,Ask+pt,tp); } break; case 3: if (op - Ask > FirstMove * Point) { TS=op - FirstMove * Point + FirstStopLoss * Point; if (os > TS) { ModifyStopLoss(ticket,op,TS,tp); } } if (op - Ask > SecondMove * Point) { TS=op - SecondMove * Point + SecondStopLoss * Point; if (os > TS) { ModifyStopLoss(ticket,op,TS,tp); } } if (op - Ask > ThirdMove * Point) { TS=Ask + TrailingStop3 * Point; if (os > TS) { ModifyStopLoss(ticket,op,TS,tp); } } break; } } return(0); } //+------------------------------------------------------------------+ //| Modify Open Position Controls | //| Try to modify position 3 times | //+------------------------------------------------------------------+ void ModifyStopLoss(int ord_ticket,double ord_op, double ldStopLoss,double ord_tp) { int CloseCnt, err; //---- CloseCnt=0; while(CloseCnt < 3) { if (OrderModify(ord_ticket,ord_op,ldStopLoss,ord_tp,0,Aqua)) { CloseCnt=3; if (UseSound) PlaySound(NameFileSound); } else { err=GetLastError(); Print(CloseCnt," Error modifying order : (", err , ") " + ErrorDescription(err)); if (err>0) CloseCnt++; } } } //+------------------------------------------------------------------+ //| Open Buy | //| Open a new trade using Buy | //| If Stop Loss or TakeProfit are used the values are calculated | //| for each trade | //+------------------------------------------------------------------+ void OpenBuy() { int err,ticket; double ldLot, ldStop, ldTake; string lsComm; ldLot=GetSizeLot(); // ldStop=0; if(StopLoss > 0)ldStop=Ask - StopLoss * Point ; ldTake=0; if (TakeProfit>0) ldTake=NormalizeDouble(GetTakeProfitBuy(),Digits); lsComm=GetCommentForOrder(); ticket=OrderSend(Symbol(),OP_BUY,ldLot,NormalizeDouble(Ask,Digits),Slippage,ldStop,ldTake,lsComm,MagicNumber,0,Blue); if(ticket<=0) { err=GetLastError(); Print("Error opening BUY order [" + lsComm + "]: (" + err + ") " + ErrorDescription(err)); } else { if (UseSound) PlaySound(NameFileSound); } } //+------------------------------------------------------------------+ //| Open Sell | //| Open a new trade using Sell | //| If Stop Loss or TakeProfit are used the values are calculated | //| for each trade | //+------------------------------------------------------------------+ void OpenSell() { int err, ticket; double ldLot, ldStop, ldTake; string lsComm; //---- ldLot=GetSizeLot(); ldStop=0; if(StopLoss > 0)ldStop=Bid + StopLoss * Point ; ldTake=0; if (TakeProfit > 0) ldTake=NormalizeDouble(GetTakeProfitSell(),Digits); lsComm=GetCommentForOrder(); // ticket=OrderSend(Symbol(),OP_SELL,ldLot,NormalizeDouble(Bid,Digits),Slippage,ldStop,ldTake,lsComm,MagicNumber,0,Red); if(ticket<=0) { err=GetLastError(); Print("Error opening Sell order [" + lsComm + "]: (" + err + ") " + ErrorDescription(err)); } else { if (UseSound) PlaySound(NameFileSound); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string GetCommentForOrder() { return(Name_Expert); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetSizeLot() { /*if (t==0) Lots=MathCeil(AccountFreeMargin()/2500); //Money Management - Disabled for now, while still testing! Print("Lots=",Lots); Print("FreeMargin=",AccountFreeMargin()); */ return(Lots); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetTakeProfitBuy() { return(Ask+TakeProfit*Point); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetTakeProfitSell() { return(Bid-TakeProfit*Point); } //+------------------------------------------------------------------+ //| Close Open Position Controls | //| Try to close position 3 times | //+------------------------------------------------------------------+ void CloseOrder(int ticket,double numLots,double close_price) { int CloseCnt, err; // try to close 3 Times CloseCnt=0; while(CloseCnt < 3) { if (OrderClose(ticket,numLots,close_price,Slippage,Red)) { CloseCnt=3; } else { err=GetLastError(); Print(CloseCnt," Error closing order : (", err , ") " + ErrorDescription(err)); if (err > 0) CloseCnt++; } } } //+------------------------------------------------------------------+ //| Functions used to calculate unique magic number | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Time frame interval appropriation function | //+------------------------------------------------------------------+ int func_TimeFrame_Const2Val(int Constant) { switch(Constant) { case 1: // M1 return(1); case 5: // M5 return(2); case 15: return(3); case 30: return(4); case 60: return(5); case 240: return(6); case 1440: return(7); case 10080: return(8); case 43200: return(9); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int func_Symbol2Val(string symbol) { string mySymbol=StringSubstr(symbol,0,6); // Handle problem of trailing m on mini accounts. if(mySymbol=="AUDCAD") return(1); if(mySymbol=="AUDJPY") return(2); if(mySymbol=="AUDNZD") return(3); if(mySymbol=="AUDUSD") return(4); if(mySymbol=="CHFJPY") return(5); if(mySymbol=="EURAUD") return(6); if(mySymbol=="EURCAD") return(7); if(mySymbol=="EURCHF") return(8); if(mySymbol=="EURGBP") return(9); if(mySymbol=="EURJPY") return(10); if(mySymbol=="EURUSD") return(11); if(mySymbol=="GBPCHF") return(12); if(mySymbol=="GBPJPY") return(13); if(mySymbol=="GBPUSD") return(14); if(mySymbol=="NZDUSD") return(15); if(mySymbol=="USDCAD") return(16); if(mySymbol=="USDCHF") return(17); if(mySymbol=="USDJPY") return(18); return(19); } //+------------------------------------------------------------------+