Event Handling Functions
The MQL5 language provides processing of some predefined events. Functions for handling these events must be defined in the a MQL5 program; function name, return type, composition of parameters (if there are any) and their types must strictly conform to the description of the event handler function.
The event handler of the client terminal identifies functions, handling this or that event, by the type of return value and type of parameters. If other parameters, not corresponding to below descriptions, are specified for a corresponding function, or another return type is indicated for it, such a function will not be used as an event handler.
The OnStart() function is the Start event handler, which is automatically generated only for running scripts. It must be of void type, with no parameters:
void OnStart(); |
For the OnStart() function, the int return type can be specified.
The OnInit() function is the Init event handler. It must be of void or int type, with no parameters:
void OnInit(); |
The Init event is generated immediately after an Expert Advisor or an indicator is downloaded; this event is not generated for scripts. The OnInit() function is used for initialization. If OnInit() has the int type of the return value, the non-zero return code means unsuccessful initialization, and it generates the Deinit event with the code of deinitialization reason REASON_INITFAILED.
The OnInit() function of the void type always denotes successful initialization.
The OnDeinit() function is called during deinitialization and is the Deinit event handler. It must be declared as the void type and should have one parameter of the const int type, which contains the code of deinitialization reason. If a different type is declared, the compiler will generate a warning, but the function will not be called. For scripts the Deinit event is not generated and therefore the OnDeinit() function can't be used in scripts.
void OnDeinit(const int reason); |
The Deinit event is generated for Expert Advisors and indicators in the following cases:
The NewTick event is generated for Expert Advisors only when a new tick for a symbol is received, to the chart of which the Expert Advisor is attached. It's useless to define the OnTick() function in a custom indicator or script, because the Tick event is not generated for them.
The Tick event is generated only for Expert Advisors, but this does not mean that Expert Advisors required the OnTick() function, since not only Tick events are generated for Expert Advisors, but also events of Timer, BookEvent and ChartEvent are generated. It must be declared as the void type, with no parameters:
void OnTick(); |
The OnTimer() function is called when the Timer event occurs, which is generated by the system timer only for Expert Advisors - it can't be used in scripts or indicators. The frequency of the event occurrence is set when subscribing to notifications about this event to be received by the EventSetTimer() function.
You can unsubscribe from receiving timer events for a particular Expert Advisor using the EventKillTimer() function. The function must be defined with the void type, with no parameters:
void OnTimer(); |
It is recommended to call the EventSetTimer() function once in the OnInit() function, and the EventKillTimer() function should be called once in OnDeinit().
Every Expert Advisor, as well as every indicator works with its own timer and receives events only from it. As soon as a mql5 program stops operating, the timer is destroyed forcibly if it was created but hasn't been disabled by the EventKillTimer() function.
The function is called upon the occurrence of Trade, which appears when you change the list of placed orders and open positions, the history of orders and history of deals. When a trade activity is performed pending order opening, position opening/closing, stops setting, pending order triggering, etc.) the history of orders and trades and/or list of positions and current orders is changed accordingly.
void OnTrade(); |
Users must independently implement in the code the verification of a trade account state when such an event is received (if this is required by the trade strategy conditions). If the OrderSend() function call has been completed successfully and returned a value of true, this means that the trading server has put the order into the queue for execution and assigned a ticket number to it. As soon as the server processes this order. the Trade event will be generated. And if the user remembers the ticket value, during OnTrade() event handling he/she will be able to find out what happened to the order using this value.
The OnBookEvent() function is the BookEvent handler. BookEvent is generated for Expert Advisors only when Depth of Market changes. It must be of the void type and have one parameter of the string type:
void OnBookEvent (const string& symbol); |
To receive BookEvent events for any symbol, you just need to pre-subscribe to receive these events for this symbol using the MarketBookAdd() function. In order to unsubscribe from receiving the BookEvent events for a particular symbol, call MarketBookRelease().
Unlike other events, the BookEvent event is broadcast. This means that if one Expert Advisor subscribes to receiving BookEvent events using MarketBookAdd, all the other Experts Advisors that have the OnBookEvent() handler will receive this event. It is therefore necessary to analyze the name of the symbol, which is passed to the handler as the const string& symbol parameter.
OnChartEvent() is the handler of a group of ChartEvent events:
The function can be called only in Expert Advisors and indicators. The function should be of void type with 4 parameters:
void OnChartEvent(const int id, // Event ID |
The OnCalculate() function is called only in custom indicators when it's necessary to calculate the indicator values by the Calculate event. This usually happens when a new tick is received for the symbol, for which the indicator is calculated. This indicator is not required to be attached to any price chart of this symbol.
The OnCalculate() function must have a return type int. There are two possible definitions. Within one indicator you cannot use both versions of the function.
The first form is intended for those indicators that can be calculated on a single data buffer. An example of such an indicator is Custom Moving Average.
int OnCalculate (const int rates_total, // size of the price[] array |
As the price[] array, one of timeseries or a calculated buffer of some indicator can be passed. To determine the direction of indexing in the price[] array, call ArrayGetAsSeries(). In order not to depend on the default values, you must unconditionally call the ArraySetAsSeries() function for those arrays, that are expected to work with.
The appropriate timeseries or indicator as the price[] array is selected by the user when starting the indicator in the "Parameters" tab. To do this you must specify the necessary item in the drop-down list of the "Apply to" field.

To receive values of a custom indicator from other mql5 programs, the iCustom() function is used, which returns the indicator handle for nest operations. You can also specify the appropriate price[] array or the handle of another indicator. This parameter should be transmitted last in the list of input variables of the custom indicator.
Example:
void OnStart() |
In this example, the last parameter passed is the PRICE_TYPICAL value (from the ENUM_APPLIED_PRICE enumeration), which indicates that the custom indicator will be built on typical prices obtained as (High+Low+Close)/3. If this parameter is not specified, the indicator is built based on PRICE_CLOSE values, i.e. closing prices of each bar.
Another example that shows passing of the indicator handler as the last parameter to specify the price[] array, is given in the description of the iCustom() function.
The second form is intended for all other indicators, in which more than one timeseries is used for calculations.
int OnCalculate (const int rates_total, // size of input timeseries |
Parameters of open[], high[], low[] and close[] contain arrays with open prices, high and low prices and close prices of the current timeframe.The time[] parameter contains an array with open time values, the spread[] parameter has an array containing the history of spreads (if any spread is provided for the traded security). The parameters of volume[] and tick_volume[] contain the history of trade and tick volume, respectively.
To determine the indexing direction of time[], open[], high[], low[], close[], tick_volume[], volume[] and spread[], call ArrayGetAsSeries(). In order not to depend on default values, you should unconditionally call the ArraySetAsSeries() function for those arrays, which are expected to work with.
The first rates_total parameter contains the number of bars, available to the indicator for calculation, and corresponds to the number of bars available in the chart.
We should noted the connection between the return value of OnCalculate() and the second input parameter prev_calculated. During the function call, the prev_calculated parameter contains a value returned by OnCalculate() during previous call. This allows for economical algorithms for calculating the custom indicator in order to avoid repeated calculations for those bars that haven't changed since the previous run of this function.
For this, it is usually enough to return the value of the rates_total parameter, which contains the number of bars in the current function call. If since the last call of OnCalculate() price data has changed (a deeper history downloaded or history blanks filled), the value of the input parameter prev_calculated will be set to zero by the terminal.
Note: if OnCalculate returns zero, then the indicator values are not shown in the DataWindow of the client terminal.
To understand it better, it would be useful to start the indicator, whose code is attached below.
Indicator Example:
#property indicator_chart_window |
See also
Running Programs, Client Terminal Events, Working with Events
© 2000-2010, MetaQuotes Software Corp.
