Most of the functionality and syntax between MQL4 and MQL5 are similar. However, some core functions and code structures may vary. This is, for example, the case for executing trade operations. MQL4 and MQL5 OrderSend() function do not share the same properties. In this article, we will highlight the difference between both languages and how to place a trade with MQL4 and MQL5.
Before we deep dive into the code, let us define the various types of basic trade operations that can be performed on MetaTrader. There are four types of operations:
- Market order, which is a buy or sell order placed immediately at the current market price.
- Pending order, which is an order to buy or sell at a different price than the current market price, for instance, BUY STOP, SELL LIMIT, BUY LIMIT and SELL STOP.
- Modifying or removing a non-executed pending order.
- Closing, adding, partial close of a position.
The four basic types of trade operations
The four basic types of trade operations are performed with the function OrderSend(). The type of trade operations is defined by ENUM_ORDER_TYPE properties in MQL5 and by the order properties OP_BUY, OP_SELL, OP_BUYLIMIT, OP_SELLLIMIT, OP_BUYSTOP, OP_SELLSTOP in MQL4.
MQL4 | MQL5 |
|
ENUM_ORDER_TYPE
|
The four type of pending orders (Fig.94):
- BUY STOP: Buy stop is an order placed above the current market price. It is designed to enter a long position at the specified level once the market price crosses the defined threshold.
- BUY LIMIT: Buy limit, on the other hand, will open a long position if the market price crosses the threshold and moves back above the defined level. Buy limit is a pending order placed below market price.
- SELL LIMIT: Sell limit is a pending order that is placed above market price and triggers a short position once the price has moved beyond the defined level and moves back down, crossing the threshold.
- SELL STOP: Sell stop is an order placed below the market price and designed to execute a short position once the defined level has been crossed downward.
The concept of magic number
MetaTrader and by extent, MQL4 and MQL5 robots are using a defined number to identify which trade belongs to which expert advisor. This unique number is what we name “magic number.” It is a unique number to track open positions and to allow multiple expert advisors to run in parallel without affecting each other’s operations. The magic number is declared and defined as a global variable. Some practical example of the use of magic number:
- You have two different trading strategies provided by two expert advisors. Both expert advisors are trading on the EUR/USD pair. One of the expert advisors will close all EUR/USD opened positions with the condition that the market price crosses the 20-day moving average. The second expert advisor condition is to close the trade once it reaches a predefined target price of 100 pips. The use of a magic number to differentiate each of the expert advisor’s trading positions will avoid mistakenly closing another expert advisor’s trade.
- You have a trading strategy that operates on two different time frames but on the same currency pair. One of the strategies is a one-hour timeframe moving average crossover strategy, and the other is a daily time frame pivot point trading. Each strategy belongs to one expert advisor. The first strategy will open and close GBP/USD positions according to the price action on the one-hour chart. The second strategy will open GBP/USD positions at the beginning of the day and close trades according to the pivot points. In this case, two different magic numbers will be used to differentiate which trade belongs to which strategy.
Note:
- Magic numbers are defined as global variables.
- More than one magic number can be defined in an expert advisor to organize and segregate strategies.
- Magic number is an integer; hence only a series of numbers can be assigned.
OrderSend() function parameters
Trade requests are executed with the function OrderSend(). The function OrderSend() is designed to manage all the functionality to manage trading operations, from opening trade at market price, set pending order, modification of stop loss, and take profit level and closing positions. The function OrderSend() does exactly the same thing; however, the structure of the function differs. In MQL4, OrderSend() requires eleven parameters and returns an integer, as a result, while in MQL5, OrderSend() requires only two parameters and returns a Boolean as a result (Fig.95).
MQL4 | MQL5 |
Fig.95 OrderSend() function in MQL4 and MQL5 language
OrderSend() Parameters | |
MQL4 | MQL5 |
Symbol (EURUSD, GBPUSD, Symbol() ) | MqlTradeRequest | request |
cmd (OP_BUY, OP_SELL, OP_BUYLIMIT, OP_SELLLIMIT, OP_BUYSTOP, OP_SELLSTOP) | MqlTradeResult | result |
Volume (Lot size: 0.1, 0.01, 1.0) | |
Price (Entry price: 1.30, Ask, Bid) | |
Slippage (Maximum price slippage to enter) | |
Stoploss (Stop loss level) | |
Takeprofit (Take profit level) | |
Comment=NULL (Order comment text) | |
Magic (Order magic number) | |
Expiration (We recommend leaving this parameter to 0 to avoid some errors from some brokers which do not support this function) | |
arrow_color=clrNONE (The color of the arrow that is displayed on the chart) |
MqlTradeRequest and MqlTradeResult are a structure that is specific to MQL5. MQL4 use a set of parameters to define an order while MQL5 regroups type into a predefined structure which is defined as follows:
MQL5 Request Structure | |
MqlTradeRequest | MqlTradeResult |
action; //Trade operation type (*1)
magic; //Expert Advisor ID (magic order; //Order ticket symbol; //Trade symbol volume; //Requested volume for a deal in price; //Price stoplimit; //StopLimit level of the order sl; //Stop Loss level of the order tp; //Take Profit level of the order deviation; //Maximal possible deviation type; //Order type (*2) type_filling; //Order execution type type_time; //Order expiration type expiration; //Order expiration time (for the comment; //Order comment position; //Position ticket position_by; //The ticket of opposite position |
retcode; //Operation return code
deal; //Deal ticket, if it is performed order; //Order ticket, if it is placed volume; //Deal volume, confirmed by broker price; //Deal price, confirmed by broker bid; //Current Bid price ask; //Current Ask price comment; //Broker comment to operation request_id; //Request ID set by the terminal retcode_external; //External return code |
MQL5 MqlTradeRequest type | |
action (*1) | type (*2) |
TRADE_ACTION_DEAL
Place a trade order for immediate execution with the specified parameters (market order). TRADE_ACTION_PENDING Place a trade order for the execution under specified conditions (pending order). TRADE_ACTION_SLTP Modify Stop Loss and Take Profit values of an opened position. TRADE_ACTION_MODIFY Modify the parameters of the order placed previously. TRADE_ACTION_REMOVE Delete the pending order placed previously. TRADE_ACTION_CLOSE_BY Close a position by an opposite one. |
ORDER_TYPE_BUY
Market Buy order ORDER_TYPE_SELL Market Sell order ORDER_TYPE_BUY_LIMIT Buy Limit pending order. ORDER_TYPE_SELL_LIMIT Sell Limit pending order. ORDER_TYPE_BUY_STOP Buy Stop pending order. ORDER_TYPE_SELL_STOP Sell Stop pending order. ORDER_TYPE_BUY_STOP_LIMIT Upon reaching the order price, a pending Buy Limit order is placed at the StopLimit price. ORDER_TYPE_SELL_STOP_LIMIT Upon reaching the order price, a pending Sell Limit order is placed at the StopLimit price. ORDER_TYPE_CLOSE_BY Order to close a position by an opposite one |
Retrieve market price function and properties for MQL4 and MQL5 |
SymbolInfoDouble(Symbol(), SYMBOL_BID);
SymbolInfoDouble(Symbol(), SYMBOL_ASK); |
Coding tips:
- Use the function Symbol() to get the symbol from which you are attaching your expert advisor.
- For the parameter “Price,” you can either enter the entry price by providing the price or use the predefined property SYMBOL_ASK, SYMBOL_BID in MQL5.
How to open a buy or sell at market price?
MQL4
Line 97: Define a return status for the OrderSend() function. If OrderSend() successfully performs a position on the market, it will return the value of the status to the variable ticket. If -1 is returned, then MetaTrader fails to place the trade. Line 98: Check the ticket value returned by OrderSend(). Line 97: Note that the second parameter from OrderSend() differentiates the buy from the sell with the property OP_BUY and OP_SELL. |
Buy |
Sell |
Fig.96 Open a buy or sell market order with MQL4
MQL5
MQL5 approach to OrderSend() differs from MQL4. MQL5 approach to OrderSend() is only through two parameters, MqlTradeRequest and MqlTradeResult. These two parameters regroup type-specific to trade order. Line 90 -91: Declare and initialize MqlTradeRequest and MqlTradeResult structure. Line 93 – 99: Define parameters. Line 93: Note that for market orders, the action type is defined as TRADE_ACTION_DEAL. Line 96: Define the type of order, ORDER_TYPE_BUY or ORDER_TYPE_SELL. Line 102: Conditional check of the OrderSend() function with the provided parameters. OrderSend() returns true if an error occurred during the process. Line 103: With the function GetLastError(), you can get the error code to facilitate troubleshooting and debugging. Use PrintFormat() to display the error message in the log. |
Buy |
Sell |
Fig.97 Open a buy or sell market order with MQL5
How to open a pending buy or sell stop order?
MQL4
Line 97: Send order buy stop as specified by OP_BUYSTOP, the second parameter from the function OrderSend(). Variable ticket collects the returned code from the function OrderSend(). Line 98 – 100: Check the value of the variable ticket and if the returned value is less than 0, print an error message in the log. Line 114: Send order sell stop as specified by OP_SELLSTOP, the second parameter from the function OrderSend(). |
Buy stop |
Sell stop |
Fig.98 Open a pending buy stop or pending sell stop with MQL4
MQL5
Line 61 – 62: Declare structure MqlTradeRequest and MqlTradeResult and assign request and result. Line 64 – 72: Define trade order parameters. Line 64: Note that for pending order, the type is TRADE_ACTION_PENDING. Line 65: Define the type of order: ORDER_TYPE_BUY_STOP or ORDER_TYPE_SELL_STOP. Line 74: OrderSend() execute the order and return a code that determines if it succeeds. The if statement checks the returned logical value. If the value is false, the error code is printed in the log as per the function GetLastError() (Line 76). |
Buy stop |
Sell stop |
Fig.99 Open a pending buy stop or pending sell stop with MQL5
How to open a pending buy or sell limit order?
MQL4
Line 97: Note the second parameter of the function OrderSend(), which defines a buy limit order with OP_BUYLIMIT. OrderSend() returns a status value, -1 if it fails to place the trade order. Line 98: If statement that checks the value of the variable ticket that contains the returned status value from OrderSend(). Line 114: The second parameter from the function OrderSend() defines the type of order, which is a sell limit with OP_SELLLIMIT. |
Buy limit |
Sell limit |
Fig.100 Open a pending buy limit or pending sell limit with MQL4
MQL5
Line 61 – 62: Declare MqlTradeRequest and MqlTradeResult, which are structures that contain specific parameters for the trade order. Line 64 – 72: Define parameters of the trade order. Line 64 – 65: Define the type of trade. Note that a buy limit or a sell limit is a pending order which corresponds to the type of TRADE_ACTION_PENDING. Specify the type of trade with ORDER_TYPE_BUY_LIMIT for a buy limit or ORDER_TYPE_SELL_LIMIT for a sell limit. Line 74: Execute the order with OrderSend(). Note that OrderSend() returns a status value of the trade execution. In case an error occurred during the process, OrderSend() will return false. |
Buy limit |
Sell limit |
Fig.101 Open a pending buy limit or pending sell limit with MQL5
Coding tips:
- Use function and properties instead of input value or manually defined values. For instance, to retrieve the symbol to trade, instead of providing “EUR/USD” as the symbol, use the function Symbol(). As for price as well, use a dynamic price allocation such as Ask +2, Bid -5, instead of providing a fixed price such as 1.3503. Using properties and functions allow you more flexibility and code reusability.
- Instead of calling multiple time OrderSend() for each criterion, implement a function to manage and facilitate your algorithm logic.