Issues with first Trade Operations EA

 

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

 
//+------------------------------------------------------------------+
//|                                  _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);
 
WHRoeder:


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.

  1. Magic number gets changed each time and EA forgets old orders.
  2. 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.
 
WHRoeder:

Init is called when EA is first loaded, on refresh, on change of timeframes/pairs.

  1. Magic number gets changed each time and EA forgets old orders.
  2. 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.

Reason: