problem opening multiple orders

 

Hi MQL4 folks,

I have created a basic BB EA that goes long on the middle bb and goes short on the upper band. Both long and short orders are closed at

the middle BB.


I have added a timer that allows a new trade to execute every 15 minutes if a signal is generated which appears to work ok. My problem

is that if a trade is already open, it doesn't open a new one. 


Can you please look over my code to suggest possible solutions. I feel it may have something to do with the OpenOrdersThisPair function, but am not sure.


Your help would be much appreciated!

//+------------------------------------------------------------------+

//|                                            Mean Reversion EA.mq4 |

//|                        Copyright 2017, MetaQuotes Software Corp. |

//|                                             https://www.mql5.com |

//+------------------------------------------------------------------+

#property copyright "Copyright 2017, MetaQuotes Software Corp."

#property link      "https://www.mql5.com"

#property version   "1.00"

#property strict


   extern double LotSize=0.01;

   extern double StopLoss=30;

   extern double TakeProfit=30;

   extern int BollingerPeriod=20;

   extern int BollingerDeviation=2;

   extern int MagicNumber=1234;

   extern int WaitTime=15; 


//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+

int OnInit()

  {

//---

 

//---

   return(INIT_SUCCEEDED);

  }

//+------------------------------------------------------------------+

//| Expert deinitialization function                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

  {

//---

   

  }

//+------------------------------------------------------------------+

//| Expert tick function                                             |

//+------------------------------------------------------------------+

void OnTick()

  {


     CheckForBollingerBandTrade();

     CloseAtMiddleBand();

    

  }

//+------------------------------------------------------------------+

//|       Check for Bollinger entry                                  |

//+------------------------------------------------------------------+


void CheckForBollingerBandTrade()

{

  

   double LowerBB=iBands(NULL,0,BollingerPeriod,BollingerDeviation,0,0,MODE_LOWER,1);

double UpperBB=iBands(NULL,0,BollingerPeriod,BollingerDeviation,0,0,MODE_UPPER,1);

   

   

      if(Ask<=LowerBB)

       OrderEntry(0);

  

      if(Bid>=UpperBB)

      OrderEntry(1);      

      

}

//+------------------------------------------------------------------------------+

//|         Order Entry Function                                                 |

//+------------------------------------------------------------------------------+


void OrderEntry(int direction)

{

   int buyticket=0,sellticket=0; 

   static datetime TimeSent;


   if(direction==0)

   

   {

    

    if(OpenOrdersThisPair(Symbol())<=5)

    if (TimeCurrent() >= TimeSent + (WaitTime *60))

    buyticket = OrderSend(Symbol(),OP_BUY,LotSize,Ask,3,0,0,NULL,MagicNumber,0,Green);

    TimeSent = TimeCurrent();

    if(buyticket>0)

       if (OrderModify(buyticket,OrderOpenPrice(),Ask-StopLoss*Point,NULL,0,CLR_NONE))

         Print("Order ",buyticket," was successfully modified.");

           else Print("Order ",buyticket," was NOT successfully modified.",GetLastError());

   }

         

   if(direction==1)

   {

      

      

      if(OpenOrdersThisPair(Symbol())<=5)

      if (TimeCurrent()>= TimeSent + (WaitTime * 60))

      sellticket = OrderSend(Symbol(),OP_SELL,LotSize,Bid,3,0,0,NULL,MagicNumber,0,Red);

      TimeSent = TimeCurrent();

      if(sellticket>0)

         if (OrderModify(sellticket,OrderOpenPrice(),Bid+StopLoss*Point,NULL,0,CLR_NONE))

           Print("Order ",sellticket," was successfully modified.");

              else Print("Order ",sellticket," was NOT successfully modified.",GetLastError());

   }    

}


//+------------------------------------------------------------------+

//checks to see if any orders open on this currency pair.

//+------------------------------------------------------------------+

  int OpenOrdersThisPair(string pair)

{

  int total=0;


   for(int i=OrdersTotal()-1; i >= 0; i--)

 {

      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

         if(OrderSymbol()== pair) total++;

 }

 return (total);

}


//+--------------------------------------------------------------------+

//|       Close at middle band                                         |

//+--------------------------------------------------------------------+


void CloseAtMiddleBand()


{

double MiddleBB=iBands(NULL,0,BollingerPeriod,BollingerDeviation,0,0,MODE_MAIN,1);


 if (Bid<=MiddleBB)closesell();

      if (Ask>=MiddleBB)closebuy(); 

}


//+------------------------------------------------------------------+

//|    Close orders                                                  |

//+------------------------------------------------------------------+


void closebuy()

{

 

     for(int i=OrdersTotal()-1; i >= 0; i--)

    {

     if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

       if(OrderType()==OP_BUY)

                

     if (OrderClose(OrderTicket(),LotSize,High[0],3,CLR_NONE))

          Print("Closed", OrderTicket(), "successfully");

             else Print("Buy order",OrderTicket(), "was NOT closed successfully");

             

    }

}

  

 void closesell()

{

 

     for(int i=OrdersTotal()-1; i >= 0; i--)

    {

     if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

      if (OrderType()==OP_SELL)

         

     if (OrderClose(OrderTicket(),LotSize,Low[0],3,CLR_NONE))

          Print("Closed", OrderTicket(), "successfully");

             else Print("Buy order",OrderTicket(), "was NOT closed successfully");

             

    }

} 

  

  /////////////////////////////////////////////////////////////////////////////////////

  

 
Automated Trading and Strategy Testing
Automated Trading and Strategy Testing
  • www.mql5.com
MQL5: language of trade strategies built-in the MetaTrader 5 Trading Platform, allows writing your own trading robots, technical indicators, scripts and libraries of functions
 

timothysmith78:

My problem is that if a trade is already open, it doesn't open a new one. 

Can you please look over my code to suggest possible solutions.

  1. Please use
SRC
    Play video
    Please edit your post.
    For large amounts of code, attach it.
    General rules and best pratices of the Forum. - General - MQL5 programming forum

    I don't know how you got <div class="code">, which is why your post has no highlighting and is double spaced. Instead use SRC which generates <pre class="code">.

  2. if(Ask<=LowerBB)        OrderEntry(0);
    if(Bid>=UpperBB)        OrderEntry(1);
    
    Why are you using 0/1 which you call direction? Just use the trade constants OP_BUY, OP_SELL so your code is self-documenting. Order Properties - Trade Constants - Standard Constants, Enumerations and Structures - MQL4 Reference

  3. if (TimeCurrent() >= TimeSent + (WaitTime *60))
    buyticket = OrderSend(Symbol(),OP_BUY,LotSize,Ask,3,0,0,NULL,MagicNumber,0,Green);
    TimeSent = TimeCurrent();
    if(buyticket>0)
       if (OrderModify(buyticket,OrderOpenPrice(),Ask-StopLoss*Point,NULL,0,CLR_NONE))
          Print("Order ",buyticket," was successfully modified.");
       else Print("Order ",buyticket," was NOT successfully modified.",GetLastError());
    
    Need brackets. All lines must be inside the if. If it is not time, then buyticket is not changed (still zero,) but you change TimeSent anyway. So nothing ever opens.

  4. Why are you modifying TimeSent if an order was not opened?

  5. If you had checked your return codes for the OrderSend error (and printed an error message including& _LastError, you would know why; that you are not calling OrderSend at all. What are Function return values ? How do I use them ? - MQL4 and MetaTrader 4 - MQL4 programming forum
    Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles

  6. You can not use any Trade Functions until you select an order.

  7. Code breaks on 4 digit brokers, exotics (e.g. USDZAR where spread is over 500 points,) and metals. Compute what a pip is and use it, not points.How to manage JPY pairs with parameters? - MQL4 and MetaTrader 4 - MQL4 programming forum

  8. NULL is not a valid price.
    • You can use NULL in place of _Symbol only in those calls that the documentation specially says you can. iHigh does, MarketInfo does not. OrderSend does not.
    • Don't use NULL (except for pointers where you explicitly check for it.) Use _Symbol and _Period, that is minimalist as possible and more efficient.
    • Zero is the same as PERIOD_CURRENT which means _Period.
    • No need for a function call with iHigh(NULL,0,s) just use the predefined arrays, i.e. High[].

  9. for(int i=OrdersTotal()-1; i >= 0; i--) if(
       OrderSelect(i,SELECT_BY_POS,MODE_TRADES)
    && OrderSymbol()== pair) total++;
    
    Using OrdersTotal directly and/or no Magic number filtering on your OrderSelect loop means your code is incompatible with every EA (including itself on other charts and manual trading.) Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 and MetaTrader 4 - MQL4 programming forum

  10. if(OpenOrdersThisPair(Symbol())<=5)
    :
    for(int i=OrdersTotal()-1; i >= 0; i--) if(
            OrderSelect(i,SELECT_BY_POS,MODE_TRADES)
    &&      OrderType()==OP_BUY)
    
    In the presence of multiple orders (one EA multiple charts, multiple EAs, manual trading,) because while you are waiting for the current operation (closing, deleting, modifying) to complete, any number of other operations on other orders could have concurrently happened and changed the position indexing:
    1. For non-FIFO (US brokers,) (or the EA only opens one order per symbol,) you can simply count down in a position loop, and you won't miss orders. Get in the habit of always counting down. Loops and Closing or Deleting Orders - MQL4 and MetaTrader 4 - MQL4 programming forum

    2. For FIFO (US brokers,) and you (potentially) process multiple orders per symbol, you must count up and on a successful operation, reprocess all positions (set index to -1 before continuing.)
    3. and check OrderSelect. What are Function return values ? How do I use them ? - MQL4 and MetaTrader 4 - MQL4 programming forum
      Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles
    4. and if you (potentially) process multiple orders, must call RefreshRates() after server calls if you want to use the Predefined Variables (Bid/Ask) or OrderClosePrice() instead, on the next order/server call.
  11. if (OrderClose(OrderTicket(),LotSize,High[0],3,CLR_NONE))
    
    You can not close at the High or Low. Only at the current market. Use OrderClosePrice and OrderLots. Adjust slippage (item 7.) RefreshRates (item 9.4.)
  12. else Print("Buy order",OrderTicket(), "was NOT closed successfully");
    
    Print _LastError to find out why (item 4.)
 

Thanks for the info whroeder.

I have it working the way I want it to trade now. Learning MQL4 has been challenging with no prior programming knowledge, but have got a few basic EA's up and running through trial and error. Now to thoroughly investigate an error 130

Reason: