//+-----------------------------------------------------+ //| EXPERT ADVISOR UpdateStops.mq4 | //| copy to [MT4\experts] folder and recompile | //| status messages printed in Experts tab of terminal | //+-----------------------------------------------------+ //| This is free experimental software. | //| No guarantees are expressed or implied. | //| Feedback welcome via Forex Factory private message. | //+-----------------------------------------------------+ #property copyright "Copyright © 2009 Robert Dee" #property link "www.forexfactory.com/member.php?u=12983" #property show_inputs // Updated and Modified 08/01/2009 By Ken Wilsdon. // Updates: Added MoveStopBEProfit to lock in profits at BreakEven; Changed default settings; Added Remarks to parameters for clarity. // Added FiveDigitBroker. Corrected error in sell trailing stop. #define EA_MAGIC 20090801 #define EA_NAME "UpdateStops to BE" // EA parameters extern string Main = "== Main Settings =="; extern string TP = "== Take Profits =="; extern int TakeProfit1 = 5; // close part of the trade when this target is reached extern int TakeProfit2 = 10; // close part of the trade when this target is reached extern string EquityTPPercent = "== Percentage of Equity TP =="; extern int TakeProfit1Percent = 50; // percentage of trade to close when TakeProfit1 is reached extern int TakeProfit2Percent = 50; // percentage of trade to close when TakeProfit2 is reached extern string NoStopLoss = "== Settings if No Stop Loss=="; extern int HardStop = 20; // if SL is missing then SL will be added using HardStop value (0 means disabled) extern string MoveBE = "== Move to BreakEven When Reached =="; extern int MoveStop = 5; // move stop to BE Profit (breakeven Profit) when this profit target reached (0 means disabled) extern string BEProfit = "== Pips of BreakEven Profit LockedIn=="; extern int MoveStopBEProfit = 1; // when the stop is moved, MoveStopBEProfit is the pips of profit that will be locked in extern string TrailStop = "== After BE Profit, Trailing Stop =="; extern int TrailingStop = 5; // AFTER stop is moved to BE Profit, the stop is trailed pip for pip (0 means disabled) extern string Slippage = "== Maximum Broker Slippage for TP =="; extern int MaxBrokerSlippage = 4; // do not take profit if broker slippage is greater than MaxBrokerSlippage extern bool FiveDigitBroker = true; // Set to true if using five digit broker, false otherwise // global variables datetime warningtime; double atr, pip; // named values make code more readable #define TP1 1 #define TP2 2 //+------------------------------------------------------------------+ //| Calculate the number of lots to close at TakeProfit levels 1 & 2 //+------------------------------------------------------------------+ double TakeProfitLots(double orderlots, int tplevel) { double minbrokerlots = MarketInfo(Symbol(),MODE_MINLOT); double maxbrokerlots = MarketInfo(Symbol(),MODE_MAXLOT); double lots; if(tplevel == TP1) lots = NormalizeDouble(orderlots*TakeProfit1Percent/100,1); if(tplevel == TP2) lots = NormalizeDouble(orderlots*TakeProfit2Percent/(100-TakeProfit1Percent),1); if (lots > 9.9) lots = NormalizeDouble(lots,0); // do not use fractional lots above 9.9, round to nearest whole lot if (lots < 0.01) lots = 0.01; // this EA transaction limit if (lots > maxbrokerlots) lots = maxbrokerlots; // broker server transaction limit return(lots); } //+------------------------------------------------------------------+ //| Count closed orders in history that match open price & open time //+------------------------------------------------------------------+ int OrderCloseCount(double openprice, datetime opentime) { int closecount=0; int i=0; while(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) { i++; // increment order counter if(OrderSymbol() != Symbol()) continue; // order is not for this symbol, go to next order if(OrderOpenPrice() == openprice && OrderOpenTime() == opentime) closecount++; } return(closecount); } //+------------------------------------------------------------------+ //| Find orders that belong to this Symbol and take profit as needed //+------------------------------------------------------------------+ void TakeProfits() { int ordertype; double openprice; datetime opentime; double orderlots; int orderticket; int closecount; int i=0; while(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { i++; // increment order counter if(OrderSymbol() != Symbol()) continue; // order is not for this symbol, go to next order // get all data from currently selected open order because OrderCloseCount() will change order selection ordertype = OrderType(); openprice = OrderOpenPrice(); opentime = OrderOpenTime(); orderlots = OrderLots(); orderticket = OrderTicket(); closecount = OrderCloseCount(openprice,opentime); RefreshRates(); if(ordertype == OP_SELL) { if(Ask <= openprice-TakeProfit1*pip && closecount < 1) // if Ask price has reached TakeProfit1 OrderClose(orderticket,TakeProfitLots(orderlots,TP1),Ask,MaxBrokerSlippage,Black); if(Ask <= openprice-TakeProfit2*pip && closecount < 2) // if Ask price has reached TakeProfit2 OrderClose(orderticket,TakeProfitLots(orderlots,TP2),Ask,MaxBrokerSlippage,Black); } if(ordertype == OP_BUY) { if(Bid >= openprice+TakeProfit1*pip && closecount < 1) // if Bid price has reached TakeProfit1 OrderClose(orderticket,TakeProfitLots(orderlots,TP1),Bid,MaxBrokerSlippage,Black); if(Bid >= openprice+TakeProfit2*pip && closecount < 2) // if Bid price has reached TakeProfit2 OrderClose(orderticket,TakeProfitLots(orderlots,TP2),Bid,MaxBrokerSlippage,Black); } } // end of while() }// end of TakeProfits() //+------------------------------------------------------------------+ //| Find orders that belong to this EA and move stops as needed //+------------------------------------------------------------------+ void MoveStops() { int spread = MarketInfo(Symbol(),MODE_SPREAD); // current spread for this pair double asklow = Low[0]; // lowest ask price on this candle double bidhigh = High[0]; // highest bid price on this candle int i=0; while(OrderSelect(i,SELECT_BY_POS)) { i++; // increment order counter if(OrderSymbol() != Symbol()) continue; // order is not for this symbol, go to next order RefreshRates(); if(OrderType() == OP_SELL) { if(HardStop > 0) if(OrderStopLoss() == 0) // if stop loss not set OrderModify(OrderTicket(),OrderOpenPrice(),(OrderOpenPrice()+HardStop*pip),OrderTakeProfit(),0,CLR_NONE); if(MoveStop > 0) if(asklow <= OrderOpenPrice()-MoveStop*pip && OrderStopLoss() > OrderOpenPrice()) // if price has reached MoveStop target OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()-MoveStopBEProfit*pip,OrderTakeProfit(),0,CLR_NONE); if(TrailingStop > 0) if(OrderStopLoss() > asklow+TrailingStop*pip && OrderStopLoss() <= OrderOpenPrice()) // if stoploss > (low price + TrailingStop) OrderModify(OrderTicket(),OrderOpenPrice(),asklow+TrailingStop*pip,OrderTakeProfit(),0,CLR_NONE); } if(OrderType() == OP_BUY) { if(HardStop > 0) if(OrderStopLoss() == 0) // if stop loss not set OrderModify(OrderTicket(),OrderOpenPrice(),(OrderOpenPrice()-HardStop*pip),OrderTakeProfit(),0,CLR_NONE); if(MoveStop > 0) if(bidhigh >= OrderOpenPrice()+MoveStop*pip && OrderStopLoss() < OrderOpenPrice()) // if price has reached MoveStop target OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+MoveStopBEProfit*pip,OrderTakeProfit(),0,CLR_NONE); if(TrailingStop > 0) if(OrderStopLoss() < bidhigh-TrailingStop*pip && OrderStopLoss() >= OrderOpenPrice()) // if stoploss < (high price - TrailingStop) OrderModify(OrderTicket(),OrderOpenPrice(),bidhigh-TrailingStop*pip,OrderTakeProfit(),0,CLR_NONE); } } // end of while() }// end of MoveStops() //+------------------------------------------------------------------+ //| Start function | //+------------------------------------------------------------------+ void start() { ///////////////////////////////////// // Verify that it is OK to continue if(warningtime != Time[0]) // print the failure message only once per candle, not every tic { if(IsConnected() == False) Print("IsConnected() says the client terminal is disconnected from the server"); if(IsExpertEnabled() == False) Print("IsExpertEnabled() says that expert advisors are NOT enabled"); if(IsTradeContextBusy() == True) Print("IsTradeContextBusy() says that trading thread is occupied by another EA"); if(IsTradeAllowed() == False) Print("IsTradeAllowed() says that trading is NOT allowed at this time"); if(IsStopped() == True) Print("IsStopped() says this EA has been commanded to stop operations"); warningtime = Time[0]; } if(IsConnected() == False)return; if(IsExpertEnabled() == False)return; if(IsTradeContextBusy() == True)return; if(IsTradeAllowed() == False)return; if(IsStopped() == True)return; if (FiveDigitBroker) pip = Point * 10; else pip = Point; //////////////////////////// // TRADE MANAGEMENT ACTIONS TakeProfits(); // take profits first before anything else MoveStops(); } void init() { Print("Copyright © 2009 Robert Dee All Rights Reserved, Version "+EA_MAGIC); Print("Missing SL values will be set to "+HardStop+" pips loss"); Print(OrdersTotal()+" orders currently being monitored"); Print("Minimum Broker lots = "+MarketInfo(Symbol(),MODE_MINLOT)); }