Saturday, 9 February 2013

How To Write a Close All Script in MQL4? (2 of 4)

MQL4 contains a simple way to differentiate between different types of orders. The order types that are of most concern when attempting to close all open trades are open buy and sell orders, represented by the OP_BUY and OP_SELL constants used in the OrderType() function. The OrderType() function simply returns the type of order that is currently selected. Returning back to the code, it is possible to create a Close All routine that only closes buy (or long) orders as follows:

for (int i = OrdersTotal(); i >=0; i--) {
    OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
    if (OrderType() == OP_BUY) {
        bool closed = OrderClose( OrderTicket(), OrderLots(), Bid, 5, White);
    }
}
In the MQL4 code above "closed" is a boolean (true/false) variable that is defined to accept the return value from the OrderClose() function. By selecting the orders with the OrderSelect() function, it is possible to make use of several other built-in MQL4 functions that make the job of closing an order much simpler.

The OrderClose() function defined in the code above takes the following variables:
    ticket - Refers to the order index number selected, in this case it will be i, but to keep the code generalizable it is best to use the OrderTicket() function.

    lots - May be referenced by the OrderLots() function which returns the number of lots open for a given ticket number.

    Bid - Refers to the current symbol's bid price. Unfortunately in the code sample provided, does not distinguish between the orders that refer to the current symbol and the orders that belong to other symbols so using the Bid price of the current symbol will often lead to errors due to prices not matching. 

    5 - Refers to the number of pips (or pippettes for 3/5 digit symbols) of slippage you are willing to allow.

    White - refers to a color that will be used to show the exit on the chart. Any valid color constant will work here. CLR_NONE may be used to instruct Metatrader not to draw a close object on the screen.

To make sure the code works for a single symbol you need to add an additional condition to the code as follows:
for (int i = OrdersTotal(); i >=0; i--) {
    OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
    if (OrderType() == OP_BUY && Symbol() == OrderSymbol()) {
        bool closed = OrderClose( OrderTicket(), OrderLots(), Bid, 5, White);
    }
}

By specifying that Symbol() == OrderSymbol() you are requiring the current chart's symbol be equal to the symbol with the currently selected open order. Open orders of other symbols will not be closed in this manner. The code can be made to close both buy and sell orders as follows:
int Slippage = 5;
for (int i = OrdersTotal(); i >=0; i--) {
    OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
    if (OrderType() == OP_BUY && Symbol() == OrderSymbol()) {
        bool closed = OrderClose( OrderTicket(), OrderLots(), Bid, Slippage, White);
    }
    if (OrderType() == OP_SELL && Symbol() == OrderSymbol()) {
        bool closed = OrderClose( OrderTicket(), OrderLots(), Ask, Slippage, White);
    }
}
Additionally, a variable has been created for Slippage for reuse purposes. Note that the Ask price is used as the exiting price for sell orders as open sell orders must be bought back at the ask price in order to close. Likewise, open buy orders must be sold back at the bid price to close.

MT4 has some gotchas with regards to order placement that need to be taken into account. Often times the above code will cause MT4 to kick out errors when the program isn't expecting an order to be submitted due to the trade context being busy, or due to stale prices.

No comments:

Post a Comment