MetaTrader MQL Course. Module 6: Closing a Trade Using OrderClose

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!).