Closing a Trade Using OrderClose
In the last module we built a basic, but complete, Expert Advisor. If you’d like to review that module, click here: Trade Managing Using OrderSelect.
This is the start of a new course – Building and Running Expert Advisors. We are going to continue adding advanced functionality to our EA in an effort to cover the essential MetaTrader functions.
We left off with an EA that opened a single trade based on the value of the iRSI function. The EA did not explicitly close the trade. We allowed the stoploss or the takeprofit to close the trade. In this module we are going to use the MQL function OrderClose to close our trade based on an indicator value.
This is the OrderClose function:
| bool OrderClose( | int ticket, double lots, double price, int slippage, color Color=CLR_NONE) | 
The ticket parameter is the ticket number used to identify the trade.
The lots parameter is the number of lots you’d like to close. It does not need to be the entire position, but in this example we will close the full position. We’ll cover partial closing in a later module.
The price parameter is the preferred price to close the position at. I’ve found that for Buy orders it should be Bid and for Sell orders it should be Ask.
The slippage parameter is the number of points the price can move and still allow the order to be closed.
The color parameter defines the color of the arrow drawn on the chart when the order is closed.
We will use the OrderTicket and OrderLots functions for the ticket and lots parameters, respectively. We are able to use these (only) because we used OrderSelect to select the order!
This is the MQL programming code for a complete EA, including an explicit close using OrderClose.
// these are all externs so they can be changed when the EA is attached to a chart
// the values set are default values
extern int stoploss=200;
extern int takeprofit=200;
extern double lots = 1.0;
extern int magic_number=12345;
extern int rsi_period=12;
extern double rsi_buy_level=75.0;
extern double rsi_sell_level=25.0;
int start()
{
 // get the rsi value
 double rsi_value = iRSI(Symbol(), Period(), rsi_period, PRICE_CLOSE, 0);
 // this variable will hold the number of trades open for this EA (as defined by magic number)
 int my_trades=0;
 // this variable will holds the total number of trades for the entire account
 int all_trades=OrdersTotal();
 // use a for loop to cycle through all of the trades, from 0 up to all_trades
 for( int cnt=0;cnt<all_trades;cnt++ )
 {
 // use OrderSelect to get the info for each trade, cnt=0 the first time, then 1, 2, .., etc
 // if OrderSelect fails it returns false, so we just continue
 if( OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES) == false ) 
 continue;
 // compare the magic_number of our EA (as passed in as an input parameter) to the order’s magic number
 // if they are equal, increment my_trades 
 if( magic_number == OrderMagicNumber() )
 {
 my_trades++;
 if( OrderType() == OP_BUY )
 {
 // this is the explicit close logic for a buy order
 if(rsi_value < rsi_sell_level)
 {
 // use the ticket info to close
 // note: the price should be Bid for a Buy order
 // using OrderLots()will close the entire order 
 OrderClose(OrderTicket(), OrderLots(), Bid, 3, Green);
 }
 }
 if( OrderType() == OP_SELL )
 {
 // this is the explicit close logic for a sell order
 if(rsi_value > rsi_buy_level)
 {
 // use the ticket info to close
 // note: the price should be Ask for a Sell order
 // using OrderLots()will close the entire order 
 OrderClose(OrderTicket(), OrderLots(), Ask, 3, Green);
 }
 }
 }
 }
 // my_trades should either be 1 or 0. if it is greater than zero, then we just exit
 if( my_trades > 0 )
 return(0);
 // if the rsi_value is larger than rsi_buy_level, we open a buy
 if(rsi_value > rsi_buy_level)
 {
 int status = 
 OrderSend( Symbol(), // the synbol for this chart
 OP_BUY, // a buy order
 lots, // number of lots
 Ask, // use the ask price for a BUY
 3, // allow the price up to move 3 points
 Ask – (stoploss*Point), // stop
 Bid + (takeprofit*Point), // limit
 “My Simple EA”, // comment to see in Terminal
 magic_number, // a unique # to id this trade
 0, // expiration, doesn’t work 
 Blue // a blue arrow
 );
 if( status < 0 )
 Comment(“OrderSend Failed!! Error=”, GetLastError());
 // exit after trying to open a trade 
 return(0); 
 }
 // if the rsi_value is larger than rsi_buy_level, we open a buy
 if(rsi_value < rsi_sell_level)
 {
 status = 
 OrderSend( Symbol(), // the synbol for this chart
 OP_SELL, // a buy order
 lots, // number of lots
 Bid, // use the ask price for a BUY
 3, // allow the price up to move 3 points
 Bid + (stoploss*Point), // stop
 Ask – (takeprofit*Point), // limit
 “My Simple EA”, // comment to see in Terminal
 magic_number, // a unique # to id this trade
 0, // expiration, doesn’t work 
 Red // a blue arrow
 );
 if( status < 0 )
 Comment(“OrderSend Failed!! Error=”, GetLastError());
 // exit after trying to open a trade 
    return(0); 
  }
return(0); 
}
Copy and paste this code into your MetaEditor and play around with it. (Remember, the MQL code will look better and be easier to read in the MetaEditor.)
Next module we’ll introduce functions to make our EA’s easier to read (and write!).
 
									


