EA unable to open 3rd trade - desperately need help

 

Hi folks, I am a newbie in coding and I am coding a Zone Recovery EA, but I am stuck with this problem for a while and still unable to fix it.

I've extracted out a section of the source code as you can see below. This section of codes is supposed to make the EA do the following:

1) Open a BUY order when there is no active trade

2) If price moves downwards against my BUY order for a certain amount of pips distance, the EA will open a SELL order

3) After the SELL order is opened and if the price moves up again for a certain amount of pips distance, the EA will open another BUY order

When I do backtesting, the EA has no problem entering the first and second trades with the defined SL and TP, but for some reason it is always unable to enter the 3rd trade.

Below is the extract of the source. I've spent a number of late nights trying to figure this out but still unable to fix. So any help or advice is greatly appreciated! :)

//This first section of codes is to open the first trade (BUY order) and no issue with this.
  if(OpenOrdersTotal==0)
  {   
      BuyLevel=MarketInfo(Symbol(),MODE_ASK);
      SellLevel=BuyLevel-RecoveryZoneWidth;
      UpperLevel=BuyLevel+DistanceToTakeProfit;
      LowerLevel=BuyLevel-RecoveryZoneWidth-DistanceToTakeProfit;
      
      Order1Ticket=OrderSend(Symbol(),OP_BUY,Order1LotSize,Ask,3,0,0,NULL,MagicNumber,0,Green);
      if(OrderSelect(Order1Ticket,SELECT_BY_TICKET,MODE_TRADES)==true)
      {
         if(OrderModify(Order1Ticket,OrderOpenPrice(),LowerLevel,UpperLevel,0,CLR_NONE))
            Print("Order ",Order1Ticket," was successfully modified.");
         else Print("Order ",Order1Ticket," was NOT successfully modified.",GetLastError());
         OpenOrdersTotal=CountOrders();
         RefreshRates();
      }
  }
     
//This second section of codes is to open the second trade (SELL order) and no issue with this.      
  if(MarketInfo(Symbol(),MODE_BID)<=SellLevel && OpenOrdersTotal==1 && OpenOrdersTotal<=MaxOrders)
  {
      Order2Ticket=OrderSend(Symbol(),OP_SELL,Order2LotSize,Bid,3,0,0,NULL,MagicNumber,0,Red);
      if(OrderSelect(Order2Ticket,SELECT_BY_TICKET,MODE_TRADES)==true)
      {
         if(OrderModify(Order2Ticket,OrderOpenPrice(),UpperLevel,LowerLevel,0,CLR_NONE))
            Print("Order ",Order2Ticket," was successfully modified.");
         else Print("Order ",Order2Ticket," was NOT successfully modified.",GetLastError());
         OpenOrdersTotal=CountOrders();
         RefreshRates();
      }  
  }
  
 //This third section of codes is to open the third trade (BUY order) but always unable to enter this third trade.
  if(MarketInfo(Symbol(),MODE_ASK)>=BuyLevel && OpenOrdersTotal==2 && OpenOrdersTotal<=MaxOrders)
  {
      Order3Ticket=OrderSend(Symbol(),OP_BUY,Order3LotSize,Ask,3,0,0,NULL,MagicNumber,0,Green);
      if(OrderSelect(Order3Ticket,SELECT_BY_TICKET,MODE_TRADES)==true)
      {
         if(OrderModify(Order3Ticket,OrderOpenPrice(),LowerLevel,UpperLevel,0,CLR_NONE))
            Print("Order ",Order3Ticket," was successfully modified.");
         else Print("Order ",Order3Ticket," was NOT successfully modified.",GetLastError());
         OpenOrdersTotal=CountOrders();
         RefreshRates();
      }
  }




//This is a function to count the total no. of Open Orders.
int CountOrders()
{
   int TotalCount=0;
   int i=0;

   for(i=OrdersTotal()-1; i>=0; i--)
 {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
      if(OrderSymbol()==Symbol())
      if(OrderType()==OP_BUY || OrderType()==OP_SELL)
      TotalCount++;
   }  
   return(TotalCount);
}
 
  1. Don't paste code
    Play video
    Please edit your post.
    For large amounts of code, attach it.

  2. Order2Ticket=OrderSend(Symbol(),OP_SELL,Order2LotSize,Bid,3,0,0,NULL,MagicNumber,0,Red);
    Check your return codes (OrderSend) What are Function return values ? How do I use them ? - MQL4 forum and Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles
  3. Order3Ticket=OrderSend(Symbol(),OP_BUYSTOP,Order3LotSize,Ask,3,0,0,NULL,MagicNumber,0,Green);
    You can't post a pending order at current market price.
 

Hi WHRoeder, thanks for responding to my post. I forgot to mention I am also a newbie to this forum :)

Actually the line of code that you've highlighted was intended to be a OP_BUY instead, not OP_BUYSTOP. I was just playing around hoping to workaround the issue.

The OrderSend function is supposed to return the integer value of the ticket number. Is there something wrong with the codes?

int Order1Ticket=0;
int Order2Ticket=0;
int Order3Ticket=0;


Order3Ticket=OrderSend(Symbol(),OP_BUY,Order3LotSize,Ask,3,0,0,NULL,MagicNumber,0,Green);

 
I've corrected in my first post the OrderSend function to be OP_BUY (instead of OP_BUYSTOP) in the 3rd section of the codes. But even if it is OP_BUY, the EA is still not opening the 3rd trade. I've tried many many trial and error but changing the codes here and there but unfortunately still can't find what is preventing the EA from entering the 3rd trade.
 

Following is the journal log from the MT4 backtester. From the log, the first and second trades are correctly opened with SL and TP correctly set.

But it just refused to enter the 3rd trade, and there is no error in the log. Do you know what could be wrong?

2015.04.18 02:03:54.670 EURUSD,M1: 4160923 tick events (92931 bars, 4161924 bar states) processed within 1326 ms (total time 1950 ms)
2015.04.18 02:03:53.438 2015.01.07 00:07  Tester: take profit #2 at 1.18560 (1.18537 / 1.18552)
2015.04.18 02:03:53.375 2015.01.05 00:02  Tester: stop loss #1 at 1.18560 (1.18549 / 1.18564)
2015.04.18 02:03:53.360 2015.01.02 19:11  The Recovery Algorithm (5) EURUSD,M1: Order 2.0 was successfully modified.
2015.04.18 02:03:53.360 2015.01.02 19:11  The Recovery Algorithm (5) EURUSD,M1: modify #2 sell 0.08 EURUSD at 1.20060 sl: 1.22060 tp: 1.18560 ok
2015.04.18 02:03:53.360 2015.01.02 19:11  The Recovery Algorithm (5) EURUSD,M1: open #2 sell 0.08 EURUSD at 1.20060 ok
2015.04.18 02:03:53.360 2015.01.02 09:00  The Recovery Algorithm (5) EURUSD,M1: Order 1.0 was successfully modified.
2015.04.18 02:03:53.360 2015.01.02 09:00  The Recovery Algorithm (5) EURUSD,M1: modify #1 buy 0.01 EURUSD at 1.20560 sl: 1.18560 tp: 1.22060 ok
2015.04.18 02:03:53.360 2015.01.02 09:00  The Recovery Algorithm (5) EURUSD,M1: open #1 buy 0.01 EURUSD at 1.20560 ok
2015.04.18 02:03:53.344 The Recovery Algorithm (5) inputs: InitialLotSize=0.01; RecoveryZoneWidth=50; DistanceToTakeProfit=150; TakeProfit=10; FirstOrderBuyOrSell=0; MaxOrders=10; MagicNumber=1234;
2015.04.18 02:03:52.720 TestGenerator: spread set to 15
2015.04.18 02:03:52.705 Expert The Recovery Algorithm (5) EURUSD,M1: removed

 

If you had done as WHRoeder suggested and checked the return from the order send, you might get some clue.

But I think that it is highly likely that the price did not  actually return to the level that would trigger the 3rd trade as The EURUSD was in free fall at that time.

Did you actually check that conditions were met to open the 3rd trade? 

 
GumRai:

If you had done as WHRoeder suggested and checked the return from the order send, you might get some clue.

But I think that it is highly likely that the price did not  actually return to the level that would trigger the 3rd trade as The EURUSD was in free fall at that time.

Did you actually check that conditions were met to open the 3rd trade? 

Hi GumRai, thanks for replying to my post. I truly appreciate each and every reply and advice. Let me do a "Print" check to the return from the order send as well as to check the conditions of the 3rd trade. So there is nothing wrong with how my code are written?
 

I don't see anything too wrong with your code, but it is always a good habit to avoid unnecessary function calls to keep it as efficient as possible.

  {//This first section of codes is to open the first trade (BUY order) and no issue with this.
   if(OpenOrdersTotal==0)  //This function is called every tick to test the condition, so not really necessary to call again
     {
      BuyLevel=MarketInfo(Symbol(),MODE_ASK);
      SellLevel=BuyLevel-RecoveryZoneWidth;
      UpperLevel=BuyLevel+DistanceToTakeProfit;
      LowerLevel=BuyLevel-RecoveryZoneWidth-DistanceToTakeProfit;

      Order1Ticket=OrderSend(Symbol(),OP_BUY,Order1LotSize,Ask,3,0,0,NULL,MagicNumber,0,Green);
      if(Order1Ticket>0 && OrderSelect(Order1Ticket,SELECT_BY_TICKET,MODE_TRADES)==true)
        {
         if(OrderModify(Order1Ticket,OrderOpenPrice(),LowerLevel,UpperLevel,0,CLR_NONE))
            Print("Order ",Order1Ticket," was successfully modified.");
         else Print("Order ",Order1Ticket," was NOT successfully modified.",GetLastError());
         //OpenOrdersTotal=CountOrders();
         OpenOrdersTotal++;
         RefreshRates();                  //Why call after placing the order?
        }
      else
        {
         //Error report for failed OrderSend
        }
     }
 
GumRai:

I don't see anything too wrong with your code, but it is always a good habit to avoid unnecessary function calls to keep it as efficient as possible.

 

I have finally solved the issue by using stop order for the 3rd trade as well as the subsequent trades. Backed tested it and the algorithm worked as intended. Thank you GumRai for your advice, much appreciated :)
 
.
Reason: