//+------------------------------------------------------------------+ //| _OrderSend-Market - 3 Exits.mq4 | //| | //| | //+------------------------------------------------------------------+ #property copyright "SG" #property link "" extern string sOrderType = "----Market Order Type - Buy/Sell----"; extern bool BuyOrder = true; extern bool SellOrder = false; extern string sLots = "----Enter Number of Lots/divisible by 3----"; extern int Lots = 3; //Number of lots to open order with //-----Use Stop Loss value to calculate TP Targets extern string sValues = "----TP1 = 1:1 , TP2 = 2:1 , TP3 = Trail----"; extern double Limit = 1.272; //Limit Price Long - 2010/09/09 - E/U - 1.272 Limit / 1.2635 SL / 120 Trail / 1.2918 TP2 extern double StopLoss = 1.2635; //Initial StopLoss Value extern double TrailingStop = 120.00; //Trailing stop after TP2 extern string OpenTP2 = "---Enter TP2 Target -- TP1 = 1:1---"; extern double TakeProfit2 = 1.2918; //enter target TP2 if other than 2:1 , TP3 trail 1.2900 double dPoints; //Point Value int iMagic; //Magic # value bool bDraw = True; //Draw TP lines 1 time bool bSetSL = True; //Set initial SL @ first tick bool bCalcTP = True; //Set TP targets @ first tick bool bTP1 = True; //Monitor for TP1, modify SL @ first partial close bool bTP2 = False; //Monitor for TP2, activate trailing stop after 2nd partial close bool bTP3 = False; //Trailing Stop only for remaining 1/3 int Ticket, iLots; //return value for OrderLots() double TP1, TP2; //TP targets double dSL; //Initial SL value double dOpenPrice; //Order openprice function result double dTrSL; //Trailing stop value double dTrDiff; //Difference in pips between current stoploss value and target SL value bool bTP; //Take Profit confirmation bool bModSL; //Modify SL confirmation int iOrderType; double dPrice; double dPipDistance; bool bSLCheck = false; int Y = 0; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { if(BuyOrder == false && SellOrder == false) //If no order type selected { Print("No order type selected to open".); } if(BuyOrder == true && SellOrder == true) //If multiple order types selected { Print("Buy & Sell order selected. Only select 1 type."); } if((BuyOrder == true && SellOrder == false) || (BuyOrder == false && SellOrder == true)) //Correct order selection, send order { if(BuyOrder == true) { Print("Buy Stop Limit order selected."); iOrderType = 4; //dPrice = Ask; } if(SellOrder == true) { Print("Sell Stop Limit order selected."); iOrderType = 5; //dPrice = Bid; } iMagic = Magic(); //Determine Magic # GetPoints(); //Determine Point value string Symb = Symbol(); //int X; //X = MessageBox("Sending Buy Order",Symb,1); //if(X==1) // { Print("Opening Order"); int bOpen = OrderSend(Symbol(),iOrderType,Lots,Limit,0,0,0,0,iMagic,0,Blue); //Send order while initializing /* if (bOpen >0) { Print("Order Sent"); } } */ } ErrorCheck(); //Check for errors return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { ObjectDelete("TP1"); ObjectDelete("TP2"); return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { for(int i=1; i<=OrdersTotal(); i++) //cycle through orders { if (OrderSelect(i-1,SELECT_BY_POS)==True) //if an order is selected { if(iMagic!=OrderMagicNumber()) continue; //if order magic doesn't match, skip to the next one if(OrderType()== 4 || OrderType() == 5) continue; dOpenPrice = OrderOpenPrice(); //order open price iLots = OrderLots(); //Lots for current selected order Ticket = OrderTicket(); //Ticket for current selected order SetRRSL(); //Modify opened order 1 time, set SL CalcRRTP(); //Calculate TP values 1 time, 1:1 / 2:1 unless TP2 > 0 DrawTP(); //Draw TP 1 & TP2 1 time TP1MonitorRR(); //Wait for price to hit TP1, close 1/3 position/modify SL to breakeven TP2MonitorRR(); //After TP1, wait for price to hit TP2, close 1/2/ TrSL(); //Following 2 hard exits, trail price until close 6 if(bTP3==true)Y++; //Wait 1 tick after TP2 to trail SL for new ticket # } } ErrorCheck(); return(0); }
//+------------------------------------------------------------------+ int Magic () { int X = TimeCurrent(); return(X); } //------------------------------------------------------------------- double GetPoints() { if (Digits == 3 || Digits == 5) dPoints = Point * 10; else dPoints = Point; return(dPoints); } //------------------------------------------------------------------- void ErrorCheck() { int iError = GetLastError(); if(iError != 0) Alert("Error: ",iError); } //------------------------------------------------------------------- int GetTicket() { for(int i=1; i<=OrdersTotal(); i++) //cycle through orders { if (OrderSelect(i-1,SELECT_BY_POS)==True) //if an order is selected { if(iMagic!=OrderMagicNumber()) continue; //if order magic doesn't match, skip to the next one int Ticket = OrderTicket(); //Get new ticket # //Print("GetTicket() function, New Ticket = ",Ticket); } } return(Ticket); //Return new ticket # } //------------------------------------------------------------------- void SetRRSL() { if(bSetSL==True) //Set initial SL value { if(OrderType()==0) //if its a Buy order { Print("Calculating buy order SL."); dSL = StopLoss; //Determine SL value bModSL=OrderModify(Ticket,dOpenPrice,NormalizeDouble(dSL,Digits),0,0); //Modify open order to add SL value if(bModSL==True) //if order modify success { Print("SL set @ ",dSL); //confirm success of setting SL bModSL = false; //set ModSL to false bSetSL = false; //close inital SL task, SL has been set } } if(OrderType()==1) //if its a Sell order { Print("Calculating sell order SL."); dSL = StopLoss; //Determine SL value bModSL=OrderModify(Ticket,dOpenPrice,NormalizeDouble(dSL,Digits),0,0); //Modify open order to add SL value if(bModSL==True) //if order modify success { Print("SL set @ ",dSL); //confirm success of setting SL bModSL = false; //set ModSL to false bSetSL = false; //close inital SL task, SL has been set } } } } //---------------------------------------------------------------------------------- void CalcRRTP() { if(bCalcTP==true) //Only Calculate one time { if(OrderType()==0) { dPipDistance = dOpenPrice - dSL; Print("dOpenPrice = ",dOpenPrice," dSL = ",dSL," dPipDistance = ",dPipDistance); TP1 = dOpenPrice + dPipDistance; //TP1 TP2 = dOpenPrice + 2*dPipDistance; //TP2 if(TakeProfit2>0) TP2 = TakeProfit2; //For TP2 target other than 2:1 } if(OrderType()==1) { dPipDistance = dSL - dOpenPrice; Print("dOpenPrice = ",dOpenPrice," dSL = ",dSL," dPipDistance = ",dPipDistance); TP1 = dOpenPrice - dPipDistance; //TP1 TP2 = dOpenPrice - 2*dPipDistance; //TP2 if(TakeProfit2>0) TP2 = TakeProfit2; //For TP2 target other than 2:1 } Print("Calculated TP targets. TP1 = ",TP1," TP2 = ",TP2); bCalcTP = false; } } //--------------------------------------------------------------------------------------- void DrawTP() { if(bDraw==True) { Print("Drawing initial TP targets."); ObjectCreate("TP1",OBJ_HLINE,0,0,TP1); //Draw TP1 ObjectSet("TP1",OBJPROP_COLOR,Lime); ObjectSet("TP1",OBJPROP_STYLE,3); ObjectCreate("TP2",OBJ_HLINE,0,0,TP2); //Draw TP2 ObjectSet("TP2",OBJPROP_COLOR,Lime); ObjectSet("TP2",OBJPROP_STYLE,3); bDraw = False; //after drawing initial TP targets, close drawing task } }
void TP1MonitorRR() { if(bTP1==True) //TP1 Monitor { //--Buy order----------------------------------------------------------- if(OrderType()==0) //if its a buy order { if(Bid>=TP1) //if price hits TP1 { bTP = OrderClose(Ticket,iLots/3,Bid,0,Red); //CLose 1/3 position if (bTP==True) //if close success { Print("Closed 1/3 position @ 1:1 R/R. ",Lots/3," lots @ TP1."); //Confirm first TP Print("Modify SL to Break Even for new Ticket # ",GetTicket()); //Verifying new ticket after partial close ObjectDelete("TP1"); //delete TP1 line dTrSL = dOpenPrice; //calculating new trailing stop level bModSL = OrderModify(GetTicket(),dOpenPrice,NormalizeDouble(dTrSL,Digits),0,0); //Modify order SL following first partial TP if(bModSL==True) //if order modify success { bTP = False; //reset to default bTP1 = False; //shutdown TP1 cycle bModSL = false; //verify ordermodify, then set to false bTP2 = True; //Open TP2 cycle } } } } //--Sell order---------------------------------------------------------- if(OrderType()==1) //if its a sell order { if(Ask<=TP1) //if price hits TP1 { bTP = OrderClose(Ticket,iLots/3,Ask,0,Red); //CLose 1/3 position if (bTP==True) //if close success { Print("Closed 1/3 position @ 1:1 R/R. ",Lots/3," lots @ TP1."); //Confirm first TP Print("Modify SL to Break Even for new Ticket # ",GetTicket()); //Verifying new ticket after partial close ObjectDelete("TP1"); //delete TP1 line dTrSL = dOpenPrice; //calculating new trailing stop level bModSL = OrderModify(GetTicket(),dOpenPrice,NormalizeDouble(dTrSL,Digits),0,0); //Modify order SL following first partial TP if(bModSL==True) //if order modify success { bTP = False; //reset to default bTP1 = False; //shutdown TP1 cycle bModSL = false; //verify ordermodify, then set to false bTP2 = True; //Open TP2 cycle } } } } } }
void TP2MonitorRR() { if(bTP2==True) // after TP1 hit, Monitor for TP2 { if(OrderType()==0) //if its a buy order { if(Bid>=TP2) //if TP 2 is hit { bTP = OrderClose(Ticket,iLots/2,Bid,0,Red); //Close 1/2 order if(bTP==True) //if TP2 orderclose success { if(TakeProfit2==0) { Print("Closed 1/2 remaining order at TP2 @ 2:1 R/R."); //confirm TP 2 partial close } else { Print("Closed 1/2 remaing order at TP2."); } ObjectDelete("TP2"); //Delete SL ojbect lines bModSL = OrderModify(GetTicket(),dOpenPrice,NormalizeDouble(TP1,Digits),0,0); //Modify order SL following first partial TP bTP = false; //Completed TP task for TP2 monitor bTP2 = false; //end TP2 cycle Print("Activating trailing stop function."); bTP3 = true; //Open TP3 monitor bSLCheck = true; } } } if(OrderType()==1) { if(Ask<=TP2) //if TP 2 is hit { bTP = OrderClose(Ticket,iLots/2,Ask,0,Red); //Close 1/2 order if(bTP==True) //if TP2 orderclose success { if(TakeProfit2==0) { Print("Closed 1/2 remaining order at TP2 @ 2:1 R/R."); //confirm TP 2 partial close } else { Print("Closed 1/2 remaing order at TP2."); } ObjectDelete("TP2"); //Delete SL ojbect lines bModSL = OrderModify(GetTicket(),dOpenPrice,NormalizeDouble(TP1,Digits),0,0); //Modify order SL following first partial TP bTP = false; //Completed TP task for TP2 monitor bTP2 = false; //end TP2 cycle Print("Activating trailing stop function."); bTP3 = true; //Open TP3 monitor bSLCheck = true; } } } } }
// bTP = OrderClose(Ticket,iLots/3,Bid,0,Red); double minLot = MarketInfo(Symbol(), MODE_MINLOT), LotStep = MarketInfo(Symbol(), MODE_LOTSTEP), size = MathFloor(iLots/3/LotStep)*LotStep; if (size >= minLot) bTP = OrderClose(Ticket,size,Bid,0,Red);
Thanks for the help, going to make the above change. Been doing a lot of reading on those previous 2 links also. I'm still not understanding though why my GetTicket() function would not draw the new ticket number I need? I see both those links are related to what I'm asking about here but still don't understand how using an array will solve my problem?
if(bTP2==True) // after TP1 hit, Monitor for TP2 { if(OrderType()==0) //if its a buy order { if(Bid>=TP2) //if TP 2 is hit { bTP = OrderClose(Ticket,iLots/2,Bid,0,Red); //Close 1/2 order if(bTP==True) //if TP2 orderclose success { if(TakeProfit2==0) { Print("Closed 1/2 remaining order at TP2 @ 2:1 R/R."); //confirm TP 2 partial close } else { Print("Closed 1/2 remaing order at TP2."); } ObjectDelete("TP2"); //Delete SL ojbect lines bModSL = OrderModify(GetTicket(),dOpenPrice,NormalizeDouble(TP1,Digits),0,0); //Modify order SL following first partial TP bTP = false; //Completed TP task for TP2 monitor bTP2 = false; //end TP2 cycle Print("Activating trailing stop function."); bTP3 = true; //Open TP3 monitor bSLCheck = true; } }int GetTicket() { for(int i=1; i<=OrdersTotal(); i++) //cycle through orders { if (OrderSelect(i-1,SELECT_BY_POS)==True) //if an order is selected { if(iMagic!=OrderMagicNumber()) continue; //if order magic doesn't match, skip to the next one int Ticket = OrderTicket(); //Get new ticket # //Print("GetTicket() function, New Ticket = ",Ticket); } } return(Ticket); //Return new ticket # }
Init is called when EA is first loaded, on refresh, on change of timeframes/pairs.
- Magic number gets changed each time and EA forgets old orders.
- On terminal startup, EA gets attached and init is run, but the chart history hasn't yet been loaded. You should not be looking at any chart variables in init. That means no opening orders there.
Init is called when EA is first loaded, on refresh, on change of timeframes/pairs.
- Magic number gets changed each time and EA forgets old orders.
- On terminal startup, EA gets attached and init is run, but the chart history hasn't yet been loaded. You should not be looking at any chart variables in init. That means no opening orders there.
Made a few suggested changes.
void CalcPartialExits() { // bTP = OrderClose(Ticket,iLots/3,Bid,0,Red); double minLot = MarketInfo(Symbol(), MODE_MINLOT), LotStep = MarketInfo(Symbol(), MODE_LOTSTEP), size = MathFloor(Lots/3/LotStep)*LotStep; Part1 = MathFloor(Lots/3/LotStep)*LotStep; Part2 = MathFloor(Lots/3/LotStep)*LotStep; Part3 = Lots - Part1 - Part2; Print("Partial Exits: "," Part1 = ",Part1," Part2 = ",Part2," Part3 = ",Part3); //Print("minLot = ",minLot," LotStep = ",LotStep," size = ",size); //if (size >= minLot) bTP = OrderClose(Ticket,size,Bid,0,Red); }
Using the above function to calculate the partial exits based of of what was suggested. Any other suggestions as to what I can add/change before you would use this for simply placing limit order with 2 set partial exits and then a trailing stop for the rest of the trade.
Still been slowly learning about Arrays so I can figure out how to use what I am creating here in an EA with mulitiple orders so I can keep track of partial exits and trailing stops. If anyone has any thoughts on where I should look to learn this I would appreciate it. Thanks again.
Forgot to add the updated file. The price/time info in the comments work in strategy tester for anyone who wants to see how it works.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
This is my first project with trade operations. What I'm going for here is:
-Set a limit order upon initialize
-At first tick, Modify to Set SL Value, Set TP 1 and TP2 values, Draw Take profit lines
-Wait for price to hit TP1, sell 1/3 position then modify SL to breakeven
-Wait for price to thi TP2, close 1/2 remaining position, activate Trailing stop
-wait to Trail SL when TrSL value is closer to Price than previous set SL value
I thought I had all the problems worked out and it seemd to be working perfect in stategy tester. The values and dates I have commented in there work correct in stategy tester. The main problem I kept running into was getting the new Ticket # after a partial close. I thought I had it figured out with my Get Ticket() function but then woke up to the alerts in demo pasted below. I will post the entire code below as well with as many comments as I can to explain what I'm going for. If anyone has any ideas why I'm running into this problem I would appreciate it. Do I need to use Sleep() to pause after the partial close? Is there a better way to complete the partial close and modify SL? Being my first project with trade operations and still being new to this I'm sure I have things coded that could be more effecient. I appreciate any help or advice anyone has. Thanks
02:00:50 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: Calculating buy order SL.
02:00:50 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: modify #3645755 buy 3.00 GBPUSD at 1.59600 sl: 1.59000 tp: 0.00000 ok
02:00:50 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: SL set @ 1.59
02:00:50 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: dOpenPrice = 1.596 dSL = 1.59 dPipDistance = 0.006
02:00:50 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: Calculated TP targets. TP1 = 1.602 TP2 = 1.608
02:00:50 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: Drawing initial TP targets.
05:27:33 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: close #3645755 buy 1.00 GBPUSD at 1.59600 sl: 1.59000 at price 1.60222
05:27:33 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: Closed 1/3 position @ 1:1 R/R. 1 lots @ TP1.
05:27:33 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: Modify SL to Break Even for new Ticket # 0
05:27:33 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: invalid ticket for OrderModify function
05:27:33 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: Alert: Error: 4051
05:27:33 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: invalid lots number for OrderClose function
05:27:33 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: Alert: Error: 4051
05:27:33 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: invalid lots number for OrderClose function
05:27:33 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: Alert: Error: 4051
05:27:34 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: invalid lots number for OrderClose function
05:27:34 _OrderSend - Limit - 3 Exits - RR GBPUSD,H4: Alert: Error: 4051