How to place (and close correctly) multiple orders in an EA

 
Hi,

I would like to create an EA that I could run on multiple currency pairs for the same account. However, I don't know how to get around the standard 1 order-at-a-time restriction. Can someone help me with the code to allow me to place multiple concurrent orders (and close them all correctly) on a single account? I believe this has something to do with the OrderSend "magic" parameter, but that's as far as my very limited knowledge of MQL4 has gotten me...

Any help would be great!

Thanks,

Ian
 
//+------------------------------------------------------------------+ //| CloseAll.mq4 | //| Copyright © 2006, MetaQuotes Software Corp. | //| https://www.metaquotes.net/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2006, MetaQuotes Software Corp." #property link "https://www.metaquotes.net/" //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { bool flag; //---- for(int cnt=OrdersTotal()-1; cnt>=0; cnt--) { flag=false; if(OrderSelect(cnt,SELECT_BY_POS) && OrderSymbol()==Symbol()) { if(OrderType()==OP_SELL) { flag=true; OrderClose(OrderTicket(),OrderLots(),Ask,3); } if(OrderType()==OP_BUY) { flag=true; OrderClose(OrderTicket(),OrderLots(),Bid,3); } if(flag) { Sleep(1000); RefreshRates(); } } } //---- return(0); } //+------------------------------------------------------------------+
 
For example:

void CloseOrders(int type) { int cnt = OrdersTotal(); for (int i=cnt-1; i>=0; i--) { if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; if (OrderSymbol() != Symbol()) continue; if (OrderMagicNumber() != Magic) continue; if (OrderType() != type) continue; if (type == OP_BUY) CloseOrder(OrderTicket(), OrderLots(), Bid, Slippage); if (type == OP_SELL) CloseOrder(OrderTicket(), OrderLots(), Ask, Slippage); } } int SleepOk = 2000; int SleepErr = 6000; bool CloseOrder(int ticket, double lot, double price, int slip) { RefreshRates(); int dig = MarketInfo(OrderSymbol(), MODE_DIGITS); string _lot = DoubleToStr(lot, 1); string _price = DoubleToStr(price, dig); Print("CloseOrder ", ticket, ", ", _lot, ", ", _price, ", ", slip); bool res = OrderClose(ticket, lot, price, slip); if (res) { Sleep(SleepOk); return (res); } int code = GetLastError(); Print("CloseOrder failed: ", ErrorDescription(code), " (", code, ")"); Sleep(SleepErr); return (false);
 
RickD:
For example:

void CloseOrders(int type) { int cnt = OrdersTotal(); for (int i=cnt-1; i>=0; i--) { if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; if (OrderSymbol() != Symbol()) continue; if (OrderMagicNumber() != Magic) continue; if (OrderType() != type) continue; if (type == OP_BUY) CloseOrder(OrderTicket(), OrderLots(), Bid, Slippage); if (type == OP_SELL) CloseOrder(OrderTicket(), OrderLots(), Ask, Slippage); } } int SleepOk = 2000; int SleepErr = 6000; bool CloseOrder(int ticket, double lot, double price, int slip) { RefreshRates(); int dig = MarketInfo(OrderSymbol(), MODE_DIGITS); string _lot = DoubleToStr(lot, 1); string _price = DoubleToStr(price, dig); Print("CloseOrder ", ticket, ", ", _lot, ", ", _price, ", ", slip); bool res = OrderClose(ticket, lot, price, slip); if (res) { Sleep(SleepOk); return (res); } int code = GetLastError(); Print("CloseOrder failed: ", ErrorDescription(code), " (", code, ")"); Sleep(SleepErr); return (false);
Thanks to both you and Stringo for your help on this. I'm incorporating this code into my EA, so wish me luck...

- Ian
 
stringo:
//+------------------------------------------------------------------+
//|                                                     CloseAll.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/"
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
   bool flag;
//----
   for(int cnt=OrdersTotal()-1; cnt>=0; cnt--)
     {
      flag=false;
      if(OrderSelect(cnt,SELECT_BY_POS) && OrderSymbol()==Symbol())
        {
         if(OrderType()==OP_SELL) { flag=true; OrderClose(OrderTicket(),OrderLots(),Ask,3); }
         if(OrderType()==OP_BUY)  { flag=true; OrderClose(OrderTicket(),OrderLots(),Bid,3); }
         if(flag)
           {
            Sleep(1000);
            RefreshRates();
           }
        }
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+

I'm sorry. I've been trying to figure out how to let my program do multiple buys and sells in one currency and I don't understand what you've written.

I'd appreciate it if anyone could answer my questions and/or give me an example with the simple "moving average" code.

1) Is the above Start function also taking the place of the traditional deinitialization section of code (check for close order conditions) or does that have to still be included)?
2) How does the rest of the code need to be changed because of the start being changed?
2) What is flag? I gather flag for the op_buy and sell are the buy and sell close orders- but what about the other flags- bool flag, flag=false, if(flag)

Here's the generic moving average code: Thanks!
//+------------------------------------------------------------------+
//| Moving Average. mq4 |
//| Copyright © 2005, MetaQuotes Software Corp. |
//| https://www.metaquotes.net// |
//+------------------------------------------------------------------+
#define MAGICMA 20050610

extern double MATrendPeriod=21;
extern double Lots = 0.1;
extern double MaximumRisk = 0.02;
extern double DecreaseFactor = 3;
extern double MovingPeriod = 12;
extern double MovingShift = 6;
//+------------------------------------------------------------------+
//| Calculate open positions |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
{
int buys=0,sells=0;
//----
for(int i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
{
if(OrderType()==OP_BUY) buys++;
if(OrderType()==OP_SELL) sells++;
}
}
//---- return orders volume
if(buys>0) return(buys);
else return(-sells);
}
//+------------------------------------------------------------------+
//| Calculate optimal lot size |
//+------------------------------------------------------------------+
double LotsOptimized()
{
double lot=Lots;
int orders=HistoryTotal(); // history orders total
int losses=0; // number of losses orders without a break
//---- select lot size
lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);
//---- calcuulate number of losses orders without a break
if(DecreaseFactor>0)
{
for(int i=orders-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS, MODE_HISTORY)==false) { Print("Error in history!"); break; }
if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;
//----
if(OrderProfit()>0) break;
if(OrderProfit()<0) losses++;
}
if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor, 1);
}
//---- return lot size
if(lot<0.1) lot=0.1;
return(lot);
}
//+------------------------------------------------------------------+
//| Check for open order conditions |
//+------------------------------------------------------------------+
void CheckForOpen()
{
double ma;
int res;
//---- go trading only for first tiks of new bar
if(Volume[0]>1) return;
//---- get Moving Average
ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
//---- sell conditions
if(I'll insert sell conditions here)
{
res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid, 3, 0,0,"", MAGICMA, 0,Red);
return;
}
//---- buy conditions
if(I'll insert buy conditions here)
{
res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask, 3,0, 0,"", MAGICMA, 0,Blue);
return;
}
//----
}
//+------------------------------------------------------------------+
//| Check for close order conditions |
//+------------------------------------------------------------------+
void CheckForClose()
{
double ma;
//---- go trading only for first tiks of new bar
if(Volume[0]>1) return;
//---- get Moving Average
ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
//----
for(int i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
//---- check order type
if(OrderType()==OP_BUY)
{
if(I'll insert close buy conditions here) OrderClose(OrderTicket(), OrderLots(), Bid,3,White);
break;
}
if(OrderType()==OP_SELL)
{
if(I'll insert close sell conditions here) OrderClose(OrderTicket(), OrderLots(), Ask,3,White);
break;
}
}
//----
}
//+------------------------------------------------------------------+
//| Start function |
//+------------------------------------------------------------------+
void start()
{
//---- check for history and trading
if(Bars<100 || IsTradeAllowed()==false) return;
//---- calculate open orders by current symbol
if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
else CheckForClose();
//----
}
//+------------------------------------------------------------------+
Reason: