- Expert Advisors main event: OnTick
- Basic principles and concepts: order, deal, and position
- Types of trading operations
- Order types
- Order execution modes by price and volume
- Pending order expiration dates
- Margin calculation for a future order: OrderCalcMargin
- Estimating the profit of a trading operation: OrderCalcProfit
- MqlTradeRequest structure
- MqlTradeCheckResult structure
- Request validation: OrderCheck
- Request sending result: MqlTradeResult structure
- Sending a trade request: OrderSend and OrderSendAsync
- Buying and selling operations
- Modying Stop Loss and/or Take Profit levels of a position
- Trailing stop
- Closing a position: full and partial
- Closing opposite positions: fill and partial
- Placing a pending order
- Modifying a pending order
- Deleting a pending order
- Getting a list of active orders
- Order properties (active and historical)
- Functions for reading properties of active orders
- Selecting orders by properties
- Getting the list of positions
- Position properties
- Functions for reading position properties
- Deal properties
- Selecting orders and deals from history
- Functions for reading order properties from history
- Functions for reading deal properties from history
- Types of trading transactions
- OnTradeTransaction event
- Synchronous and asynchronous requests
- OnTrade event
- Monitoring trading environment changes
- Creating multi-symbol Expert Advisors
- Limitations and benefits of Expert Advisors
- Creating Expert Advisors in the MQL Wizard
MqlTradeRequest structure
MQL5 API trading functions, in particular OrderCheck and OrderSend, operate on several built-in structures. Therefore, we will have to consider these structures before moving on to the functions themselves.
Let's start with the MqlTradeRequest structure which contains all the fields required for executing trades.
struct MqlTradeRequest
|
You should not be afraid of a large number of fields: the structure is designed to serve absolutely all possible types of trade requests, however, in each specific case, only a few fields are usually used.
Before filling in the fields, it is recommended to nullify the structure either by explicit initialization in its definition or by calling the ZeroMemory function.
MqlTradeRequest request = {};
|
This way it will avoid potential errors and side effects from passing random values to the API functions in those fields that were not explicitly assigned.
The following table provides a brief description of the fields. We will see how to fill them when describing trading operations.
Field |
Description |
---|---|
action |
Trading operation type from ENUM_TRADE_REQUEST_ACTIONS |
magic |
Expert ID (optional) |
order |
Pending order ticket for which modification is requested |
symbol |
Trading instrument name |
volume |
Requested trade volume in lots |
price |
The price at which the order must be executed |
stoplimit |
The price where a limit order will be placed when the ORDER_TYPE_BUY_STOP_LIMIT and ORDER_TYPE_SELL_STOP_LIMIT orders are activated |
sl |
Price at which Stop Loss order will be triggered when the price moves in an unfavorable direction |
tp |
Price at which Take Profit order will be triggered when the price moves in a favorable direction |
deviation |
Maximum acceptable deviation from the asked price, in points |
type |
Order type from ENUM_ORDER_TYPE |
type_filling |
Order filling type from ENUM_ORDER_TYPE_FILLING |
type_time |
Pending order expiration type from ENUM_ORDER_TYPE_TIME |
expiration |
Pending order expiration date |
comment |
Comment to the order |
position |
Position ticket |
position_by |
Opposite position ticket for the TRADE_ACTION_CLOSE_BY operation |
To send orders for trading operations, it is necessary to fill in a different set of fields, depending on the nature of the operation. Some fields are required, and some are optional (can be omitted when filling out). Next, we'll take a closer look at the field requirements in the context of specific actions.
The program can check a formed MqlTradeRequest structure for correctness using the OrderCheck function or send it to the server using the OrderSend function. If successful, the requested operation will be performed.
The action field is the only one required for all trading activities.
A unique number in the magic field is usually indicated only for market buy/sell requests or when creating a new pending order. This leads to the subsequent marking of completed transactions and positions with this number, which allows for organizing the analytical processing of trading actions. When modifying the price levels of a position or pending orders, as well as deleting them, this field has no effect.
When manually performing trading operations from the MetaTrader 5 interface, the magic identifier cannot be set, and therefore it is equal to zero. This provides a popular but not entirely reliable way to distinguish between manual and automated trading when analyzing history. In fact, Expert Advisors can also use a zero identifier. Therefore, to find out who and how performed specific trading actions, use the corresponding properties of orders (ORDER_REASON), deals (DEAL_REASON), and positions (POSITION_REASON).
Each Expert Advisor can set its own unique ID or even use several IDs for different purposes (broken down by trading strategies, signals, etc.). The magic number of the position corresponds to the magic number of the last deal involved in the formation of the position.
Symbol name in the symbol field is important only for opening or increasing positions, as well as when placing pending orders. In cases of modifying and closing orders and positions, it will be ignored, but there is a small exception here. Since only one position can exist on netting accounts for each symbol, the symbol field can be used to identify a position in a request to change its protective price levels (Stop Loss and Take Profit).
The volume field is used in the same way: it is needed in immediate buy/sell orders or when creating pending orders. It should be taken into account that the actual volume in the operation will depend on the execution mode and may differ from what is requested.
The price field also has some limitations: when sending market orders (TRADE_ACTION_DEAL in the action) for instruments with execution mode SYMBOL_TRADE_EXECUTION_MARKET or SYMBOL_TRADE_EXECUTION_EXCHANGE, this field is ignored.
The stoplimit field makes sense only when setting stop-limit orders, i.e., when the type field contains ORDER_TYPE_BUY_STOP_LIMIT or ORDER_TYPE_SELL_STOP_LIMIT. It specifies the price at which a pending limit order will be placed when the price reaches the price value (this fact is tracked by the MetaTrader 5 server, and until this moment a pending order is not displayed in the trading system).
When placing pending orders, their expiration rules are set in a pair of fields: type_time and expiration. The latter contains a value of type datetime, which is taken into account only if type_time is equal to ORDER_TIME_SPECIFIED or ORDER_TIME_SPECIFIED_DAY.
Finally, the last couple of fields are related to the identification of positions in queries. Each new position created on the basis of orders (manually or programmatically) gets a ticket assigned by the system, a unique number. As a rule, it corresponds to the ticket of the order, as a result of which the position is opened, but may change subject to service operations on the server, for example, accrual of swaps by reopening a position.
We will talk about obtaining the properties of positions, deals, and orders in separate sections. Here, for now, it is important for us that the position field should be filled in when changing and closing a position in order to unambiguously identify it. In theory, on netting accounts, it is enough to indicate the position symbol in the symbol field, but for the unification of algorithms, it is better to leave the position field in work.
The position_by field is used for closing opposite positions (TRADE_ACTION_CLOSE_BY). It should indicate a position opened for the same symbol but in the opposite direction in relation to position (this is only possible on hedging accounts).
The deviation field affects the execution of market orders only in the Instant Execution and Request Execution modes.
Examples of filling in the structure for trading operations of each type will be given in the relevant sections.