- Llamada a una función
- Traspaso de parámetros
- Sobrecarga de funciones
- Sobrecarga de operaciones
- Descripción de funciones externas
- Exportación de funciones
- Funciones de procesamiento de eventos
Funciones de procesamiento de eventos
En el lenguaje MQL5 está previsto el procesamiento de algunos eventos predefinidos. Las funciones que manejan estos eventos tienen que ser definidos en el programa MQL5; el nombre de la función, el tipo de valor devuelto, composición de parámetros (si éstos existen) y sus tipos tienen que corresponder estrictamente a la descripción de la función de procesamiento de eventos.
El manejador de eventos del terminal de cliente identifica las funciones, que procesan uno u otro evento, precisamente por el tipo de valor devuelto y por los tipos de parámetros. La función no se usa para manejar los eventos, si en ésta están indicados otros parámetros que no corresponden a las descripciones siguientes, o está indicado otro tipo de valor devuelto.
OnStart #
La función OnStart() es manejador de evento Start, que se genera automáticamente sólo para los scripts a ser ejecutados. Esta función debe ser del tipo void, sin tener parámetros:
void OnStart(); |
Para la función OnStart() se admite especificar el tipo de valor devuelto int.
OnInit #
La función OnInit() es el manejador de evento Init. Puede tener el tipo void o int, no tiene parámetros:
void OnInit(); |
El evento Init se genera justo después de haberse cargado un Asesor Experto o un indicador; este evento no se genera para los scripts. La función OnInit() se usa para la inicialización. Si OnInit() tiene el valor devuelto del tipo int, entonces el código no nulo de la devolución significa una inicialización fallida y genera el evento Deinit con el código de la causa de deinicialización REASON_INITFAILED.
Para la optimización de los parámetros de entrada del EA se recomienda utilizar los valores de la enumeración ENUM_INIT_RETCODE como el código de devolución. Estos valores sirven para organizar el control del proceso de optimización, incluyendo la selección de los agentes de pruebas más apropiados. Durante la inicialización del EA, antes de iniciar el mismo proceso de simulación, se puede solicitar la información sobre la configuración y los recursos del agente (número de núcleos, volumen de la memoria libre, etc.) utilizando la función TerminalInfoInteger(). Y basándose en la información recibida permitir el uso de este agente, o bien rechazarlo para la optimización de este EA.
Identificador |
Descripción |
---|---|
INIT_SUCCEEDED |
La inicialización se ha finalizado con éxito. Se puede seguir con la simulación del EA. Este código significa lo mismo que el valor nulo - la inicialización del EA en el Probador ha pasado con éxito. |
INIT_FAILED |
Inicialización fallida. No merece la pena continuar la simulación debido a los errores insuperables. Por ejemplo, no se ha podido crear el indicador necesario para el funcionamiento del EA. La devolución de este valor significa lo mismo que la devolución de un valor distinto del cero. Significa que la inicialización del EA en el Probador no ha tenido éxito. |
INIT_PARAMETERS_INCORRECT |
Se utiliza por el programador para marcar un conjunto incorrecto de parámetros de entrada. La cadena del resultado que contiene este código de retorno se colorea con el rojo en la tabla general de optimización. La simulación para este conjunto de parámetros del EA no va a llevarse a cabo, el agente está disponible para recibir una nueva tarea. Cuando el Probador de Estrategias recibe este valor, nunca va a pasar esta tarea a otros agentes para que vuelvan a ejecutarlo. |
INIT_AGENT_NOT_SUITABLE |
Durante la inicialización no ha surgido ningún error en el funcionamiento del programa, pero por alguna razón este agente no vale para hacer la prueba. Por ejemplo, no hay suficiente memoria operativa, no hay soporte OpenCL, etc. Después de la devolución de este código, el agente ya no va a recibir tareas hasta que se finalice esta optimización. |
La función OnInit() del tipo void siempre indica a una inicialización exitosa.
OnDeinit #
La función OnDeinit() se llama durante la deinicialización y juega papel de manejador de evento Deinit. Tiene que ser declarada con el tipo void y tener un parámetro del tipo const int que contiene el código de la causa de deinicialización. Si está declarado otro tipo, el compilador lanzará un aviso pero la función no será invocada. Para los scripts el evento Deinit no se genera, y por tanto, en éstos no se puede usar la función OnDeinit().
void OnDeinit(const int reason); |
El evento Deinit se genera para los Asesores Expertos e indicadores en las siguientes ocasiones:
- antes de la reinicialización debido al cambio de símbolo o período del gráfico al cual el programa mql5 es atado;
- antes de la reinicialización debido al cambio de los parámetros de entrada;
- antes de descargar un programa mql5.
OnTick #
El evento NewTick se genera únicamente para los Asesores Expertos cuando se recibe un nuevo tick para el símbolo, al diagrama del cual está atado el Asesor. Es inútil determinar la función OnTick() en un indicador personalizado o en un script, porque para ellos el evento Tick no se genera.
El evento NewTick se genera sólo para los Asesores Expertos pero esto no significa que ellos tienen que tener la función OnTick() de una forma obligatoria, porque para los Asesores se generan no sólo los eventos NewTick, sino también los eventos Timer, BookEvent y ChartEvent. Tiene que ser declarada con el tipo void, no tiene parámetros:
void OnTick(); |
OnTimer #
La función OnTimer() se llama cuando se inicia el evento Timer que se genera por el temporizador del sistema sólo para los asesores e indicadores; no se puede usarla en los scripts. La frecuencia del inicio de este evento se establece cuando la función EventSetTimer() efectua la suscripción para obtener avisos sobre el evento Timer.
Para dar de baja dicha suscripción a recibir los eventos del temporizador para un Asesor en concreto se utiliza la función EventKillTimer(). La función tiene que ser declarada con el tipo void, no tiene parámetros:
void OnTimer(); |
Se recomienda llamar a la función EventSetTimer() una sola vez en la función OnInit(), y también una sola vez EventKillTimer() en OnDeinit().
Cada Asesor Experto y cada indicador trabaja con su propio temporizador y recibe eventos sólo de él. Una vez terminada la sesión del programa mql5, el temporizador se elimina de una manera forzosa, si ha sido creado pero no ha sido desactivado por la función EventKillTimer().
OnTrade #
La función se llama cuando se inicia el evento Trade, que aparece si se cambia la lista de las órdenes presentadas y posiciones abiertas, historial de órdenes y historial de transacciones. Cuando cualquier operación comercial (presentación de orden pendiente, apertura/cierre de posición, establecimiento de stops, accionamiento de órdenes pendientes, etc.) se efectua de una manera correspondiente, el historial de órdenes y transacciones y/o la lista de posiciones y órdenes corrientes se cambian.
void OnTrade(); |
Al recibir este evento (si esto requieren las condiciones de la estrategia comercial), el mismo usuario debe comprobar en el código el estado de la cuenta. Si la llamada a la función OrderSend() se ha realizado con éxito y ha devuelto el valor true, esto significa que el servidor comercial ha colocado la orden en la cola para ser ejecutado y le ha asignado un número de ticket. En cuanto el servidor procese esta orden, el evento Trade será generado. Y si el usuario ha memorizado el valor del ticket, durante el procesamiento de evento OnTrade() podrá averiguar con su ayuda qué es lo que haya pasado exactamente con la orden.
OnTradeTransaction #
Como resultado de ejecución de ciertas acciones con la cuenta de trading su estado se cambia. A estas acciones les pertenecen:
- El envío de una solicitud comercial por parte de cualquier aplicación MQL5 en el terminal de cliente utilizando la función OrderSend y OrderSendAsync, con su posterior ejecución;
- El envío de una solicitud comercial a través de la interfaz gráfica del terminal y su posterior ejecución;
- El accionamiento de órdenes pendientes y órdenes Stop en el servidor;
- La ejecución de operaciones en el servidor de trading.
Como resultado de estas acciones, para la cuenta se ejecutan las transacciones comerciales:
- tramitación de la solicitud comercial;
- cambio de órdenes abiertas;
- cambio del historial de órdenes;
- cambio del historial de operaciones;
- cambio de posiciones.
Por ejemplo, al enviar una orden de compra, ésta se tramita, para la cuenta se crea una orden de compra correspondiente, se realiza la ejecución de la orden, su eliminación de la lista de las abiertas, se agrega al historial de órdenes, luego la operación correspondiente se agrega al historial, y se crea una posición nueva. Pues todas estas acciones son transacciones comerciales. La llegada de cada una de estas transacciones al terminal es el evento TradeTransaction. Este evento llama al manejador OnTradeTransaction
void OnTradeTransaction( |
El manejador contiene tres parámetros:
- trans - este parámetro obtiene la estructura MqlTradeTransaction que describe la transacción comercial aplicada a la cuenta de trading;
- request - este parámetro obtiene la estructura MqlTradeRequest que describe la solicitud comercial;
- result - este parámetro obtiene la estructura MqlTradeResult que describe el resultado de ejecución de la solicitud comercial.
Los dos últimos parámetros request y result se llenan con los valores sólo para la transacción del tipo TRADE_TRANSACTION_REQUEST, la información sobre el parámetro se puede obtener del parámetro type de la variable trans. Fíjense que en este caso el campo request_id en la variable result contiene el identificador de la solicitud comercial request cuya ejecución ha provocado la aparición de la transacción comercial descrita en la variable trans. La presencia del identificador de la solicitud permite vincular la acción ejecutada (llamada a la función OrderSend o OrderSendAsync) con el resultado de esta acción que se traspasa en OnTradeTransaction().
Una solicitud comercial enviada desde el terminal manualmente o a través de las funciones de trading OrderSend()/OrderSendAsync() puede ocasionar en el servidor de trading varias transacciones consecutivas. Entendiéndose que el orden de llegada de estas transacciones al terminal no se garantiza, por eso no se puede construir su algoritmo de trading esperando la llegada de unas transacciones comerciales tras la llegada de otras.
|
Una vez aplicadas las transacciones comerciales a la cuenta de cliente, ellas se colocan sucesivamente a la cola de transacciones comerciales del terminal, de donde se pasan sucesivamente al punto de entrada OnTradeTransaction en orden de su llegada al terminal.
Mientras que el EA procese las transacciones comerciales con el manejador OnTradeTransaction, el terminal sigue procesando las transacciones que vayan llegando. De esta manera, el estado de la cuenta de trading ya puede cambiarse durante el proceso de trabajo del OnTradeTransaction. Por ejemplo, mientras que el programa MQL5 esté procesando el evento de agregación de una orden nueva, ésta puede ser ejecutada, eliminada de la lista de las abiertas y pasada al historial. A continuación, el programa será avisado sobre todos estos eventos.
La longitud de la cola de transacciones es de 1024 elementos. Si OnTradeTransaction va a tardar en procesar la transacción de turno, las transacciones antiguas pueden ser expulsadas por las nuevas.
|
OnTester #
La función OnTester() es el manejador del evento Tester que se genera automáticamente una vez terminado el chequeo histórico del Asesor Experto en el intervalo de datos especificado. La función tiene que ser declarada con el tipo double, no tiene parámetros:
double OnTester(); |
La función se invoca justamente antes de la llamada a la función OnDeinit() y tiene el tipo del valor devuelto double. La función OnTester() puede ser usada solamente en los Asesores Expertos durante el chequeo. En primer lugar está destinada para el cálculo de un valor que se usa como criterio Custom max durante la optimización genética de los parámetros de entrada.
Durante la optimización genética la selección de resultados dentro de una generación se realiza en orden descendiente. Es decir, desde el punto de vista del criterio de optimización, los mejores resultados son los que tienen el mayor valor (para el criterio de optimización Custom max se toman en cuenta los valores devueltos por la función OnTester). Con este tipo de selección los peores valores se colocan al final, y luego no toman parte en la formación de la siguiente generación.
OnTesterInit #
La función OnTesterInit() es el manejador del evento TesterInit que se genera automáticamente antes de iniciar la optimización del EA en el Probador de Estrategias. La función tiene que ser definida con el tipo void. No tiene parámetros:
void OnTesterInit(); |
El EA que cuenta con el manejador OnTesterDeinit() o OnTesterPass(), al iniciarse la optimización, se carga automáticamente en un gráfico separado con el símbolo y período especificados en el Probador y recibe el evento TesterInit. Esta función se utiliza para inicializar el EA antes del inicio de la optimización para el posterior procesamiento de los resultados de la optimización.
OnTesterPass #
La función OnTesterPass() es el manejador del evento TesterPass que se genera automáticamente cuando llega un frame durante la optimización del EA en el Probador de Estrategias. La función tiene que ser definida con el tipo void. No tiene parámetros:
void OnTesterPass(); |
El EA con el manejador OnTesterPass() se carga automáticamente en un gráfico nuevo del terminal con el símbolo/período especificados para la simulación, y recibe durante la optimización los eventos TesterPass cuando llegue un frame. La función está destinada para el procesamiento dinámico de los resultados de la optimización directamente "al vuelo", sin esperar su finalización. La agregación de los frames se realiza por la función FrameAdd(), que puede ser invocada cuando se finaliza el repaso único en el manejador OnTester().
OnTesterDeinit #
La función OnTesterDeinit() es el manejador del evento TesterDeinit que se genera automáticamente tras finalizarse la optimización del EA en el Probador de Estrategias. La función tiene que ser definida con el tipo void. No tiene parámetros:
void OnTesterDeinit(); |
El EA con el manejador TesterDeinit() se carga automáticamente en el gráfico al iniciarse la optimización, y recibe el evento TesterDeinit tras su finalización. Esta función está destinada para el procesamiento final de todos los resultados de la optimización.
OnBookEvent #
La función OnBookEvent() es manejador de evento BookEvent. El evento BookEvent se genera sólo para los Asesores e indicadores si se cambia el estado de la profundidad de mercado (Depth of Market). Debe tener el tipo void y un parámetro del tipo string:
void OnBookEvent (const string& symbol); |
Para recibir los eventos BookEvent por cualquier símbolo, es suficiente suscribirse previamente a la recepción de estos eventos para este símbolo mediante la función MarketBookAdd(). Para dar de baja la recepción del evento BookEvent por un símbolo concreto, es necesario llamar a la función MarketBookRelease().
A diferencia de otros eventos, el evento BookEvent es de difusión. Eso significa que si un Asesor Experto se suscribe a la recepción del evento BookEvent a través de la función MarketBookAdd, todos los demás Asesores que tienen el manejador OnBookEvent() van a recibir este evento. Por eso es necesario analizar el nombre del símbolo que se traspasa al manejador en calidad del parámetro const string& symbol.
OnChartEvent #
OnChartEvent() es manejador del grupo de eventos ChartEvent:
- CHARTEVENT_KEYDOWN evento de pulsación de teclas del teclado cuando la ventana del gráfico está en el foco;
- CHARTEVENT_MOUSE_MOVE eventos de mover el ratón y pulsar botones del ratón (si para el gráfico está establecida la propiedad CHART_EVENT_MOUSE_MOVE=true);
- CHARTEVENT_OBJECT_CREATE evento de creación de un objeto gráfico (si para el gráfico está establecida la propiedad CHART_EVENT_OBJECT_CREATE=true);
- CHARTEVENT_OBJECT_CHANGE evento de cambio de propiedades de un objeto a través del diálogo de propiedades;
- CHARTEVENT_OBJECT_DELETE evento de eliminación de un objeto gráfico (si para el gráfico está establecida la propiedad CHART_EVENT_OBJECT_DELETE=true);
- CHARTEVENT_OBJECT_CLICK evento de cliqueo con el ratón sobre el gráfico;
- CHARTEVENT_OBJECT_DRAG evento de movimiento de un objeto gráfico mediante el ratón;
- CHARTEVENT_OBJECT_ENDEDIT evento del fin de edición de texto en el campo de introducción de un objeto gráfico LabelEdit;
- CHARTEVENT_CHART_CHANGE evento de modificación del gráfico;
- CHARTEVENT_CUSTOM+n identificador del evento de usuario donde la n se encuentra en el rango de 0 a 65535.
- CHARTEVENT_CUSTOM_LAST el último identificador aceptable del evento de usuario (CHARTEVENT_CUSTOM+65535).
La función puede invocarse sólo en los Asesores e indicadores. Tiene que poseer el tipo void y 4 parámetros:
void OnChartEvent(const int id, // identificador de evento |
Para cada tipo de evento, los parámetros de entrada de la función OnChartEvent() tienen los determinados valores que son necesarios para procesar este evento. En la tabla de abajo se enumeran los eventos y valores pasados como parámetros.
Evento |
Valor del parámetro id |
Valor del parámetro lparam |
Valor del parámetro dparam |
Valor del parámetro sparam |
---|---|---|---|---|
Evento de un teclazo |
CHARTEVENT_KEYDOWN |
código de la tecla pulsada |
Número de pulsaciones de la tecla generadas mientras ésta se mantenía en estado pulsado |
Valor literal de la máscara de bits que describe el estatus de las teclas del teclado |
Eventos del ratón (si para el gráfico está establecida la propiedad CHART_EVENT_MOUSE_MOVE=true) |
CHARTEVENT_MOUSE_MOVE |
coordinada X |
coordinada Y |
Valor literal de la máscara de bits que describe el estatus de los botones del ratón |
Evento de creación de un objeto gráfico (si para el gráfico está establecida la propiedad CHART_EVENT_OBJECT_CREATE=true) |
CHARTEVENT_OBJECT_CREATE |
|
|
Nombre del objeto gráfico creado |
Evento de cambio de propiedades de un objeto a través del diálogo de propiedades |
CHARTEVENT_OBJECT_CHANGE |
|
|
Nombre del objeto gráfico modificado |
Evento de eliminación de un objeto gráfico (si para el gráfico está establecida la propiedad CHART_EVENT_OBJECT_DELETE=true) |
CHARTEVENT_OBJECT_DELETE |
|
|
Nombre del objeto gráfico eliminado |
Evento de cliquear sobre un gráfico |
CHARTEVENT_CLICK |
coordenada X |
coordenada Y |
|
Evento de cliquear sobre un objeto gráfico |
CHARTEVENT_OBJECT_CLICK |
coordenada X |
coordenada Y |
Nombre del objeto gráfico en el que ha ocurrido el evento |
Evento de mover un objeto gráfico con el ratón |
CHARTEVENT_OBJECT_DRAG |
|
|
Nombre del objeto gráfico desplazado |
Evento del fin de edición del texto en el campo de introducción del objeto gráfico |
CHARTEVENT_OBJECT_ENDEDIT |
|
|
Nombre del objeto gráfico "Campo de texto" donde se ha finalizado la introducción del texto |
Evento de modificación del gráfico |
CHARTEVENT_CHART_CHANGE |
|
|
|
Identificador del evento de usuario |
CHARTEVENT_CUSTOM+N |
Valor determinado por la función EventChartCustom() |
Valor determinado por la función EventChartCustom() |
Valor determinado por la función EventChartCustom() |
OnCalculate #
La función OnCalculate() se invoca sólo en los indicadores si surge la necesidad de calcular los valores de indicador por evento Calculate. Habitualmente eso ocurre cuando se recibe un nuevo tick por símbolo para el que se calcula el indicador. Además, no es obligatorio que el indicador esté anclado a un gráfico de precio del dicho símbolo.
La función OnCalculate() debe tener el tipo de valor devuelto int. Existen dos posibilidades de definición. No se puede usar las dos opciones de la función dentro un indicador.
La primera forma de la llamada está destinada para los indicadores que pueden ser calculados sobre un buffer de datos. El ejemplo de este indicador es Custom Moving Average.
int OnCalculate (const int rates_total, // tamaño del array price[] |
Como array price[] puede ser pasada una de las series temporales de precios o calculado el búfer de algún indicador. Para determinar la dirección de indexación en el array price[] es necesario invocar la función ArrayGetAsSeries(). Para no depender de los valores predefinidos es necesario invocar incondicionalmente la función ArraySetAsSeries() para los arrays con los que se prevé trabajar.
La elección del indicador o serie temporal apropiados en calidad del array price[] se realiza por el usuario a la hora de iniciar el indicador en la pestaña "Parameters". Para eso se necesita indicar el elemento necesario en la lista desplegable del campo "Apply to".
Par obtener valores del indicador personalizado desde otros programas mql5, se usa la función iCustom() que devuelve el manejador (handle) del indicador para la siguiente operación. Con eso también se puede indicar el array necesario price[] o manejador (handle) de otro indicador. Este parámetro tiene que ser pasado el último en la lista de las variables de entrada del indicador personalizado.
Ejemplo:
void OnStart() |
En este ejemplo el último parámetro pasa el valor PRICE_TYPICAL (desde la enumeración ENUM_APPLIED_PRICE ) que indica que el indicador personalizado va a ser construido por los precios típicos recibidos como (High+Low+Close)/3. Si el parámetro no se indica, el indicador se construye por los valores PRICE_CLOSE, es decir, por los precios de cierre de cada barra.
Otro ejemplo que demuestra el traspaso del manejador (handle) de indicador por el último parámetro para especificar el array price[], se muestra en la descripción de la función iCustom().
La segunda forma de la llamada sirve para todos los demás indicadores en los cuales para el cálculo se utiliza más de una serie temporal.
int OnCalculate (const int rates_total, // tamaño de series temporales de entrada |
Los parámetros open[], high[], low[] y close[] contienen los arrays con los precios de apertura, precio máximo, mínimo y precios de cierre del período en curso. El parámetro time[] contiene el array con valores de apertura, el parámetro spread[] es el array que contiene el historial de spreads (si spread está previsto para este instrumento comercial). Los parámetros volume[] y tick_volume[] contienen respectivamente el historial del volumen comercial y del volumen de tick.
Para determinar la dirección de indexación dentro de los arrays time[], open[], high[], low[], close[], tick_volume[], volume[] y spread[] es necesario llamar a la función ArrayGetAsSeries(). Para no depender de los valores predefinidos es necesario invocar incondicionalmente la función ArraySetAsSeries() para los arrays con los que se prevé trabajar.
El primer parámetro rates_total contiene la cantidad de barras disponibles para el indicador para ser calculados, y corresponde a la cantidad de barras disponibles en el gráfico.
Cabe destacar el vínculo entre el valor de la función devuelta OnCalculate() y el segundo parámetro de entrada prev_calculated. Cuando se invoca la función el parámetro prev_calculated contiene el valor que la función OnCalculate() ha devuelto durante la llamada anterior. Esto permite realizar los algoritmos económicos de cálculo del indicador personalizado con el fin de evitar los cálculos repetidos para las barras que no se hayan cambiado desde el arranque anterior de esta función.
Para eso es suficiente devolver el valor del parámetro rates_total que contiene la cantidad de barras durante la corriente llamada a la función. Si desde la última llamada a la función OnCalculate() los datos de precios han sido cambiados (se ha cargado un historial más profunda o los blancos en el historial han sido llenados), el mismo terminal pondrá el valor cero al parámetro entrante prev_calculated.
Nota: si la función OnCalculate devuelve el valor cero, los valores del indicador no se mostrarán en la ventana DataWindow del terminal de cliente.
Para el mejor entendimiento, será útil iniciar el indicador cuyo código se encuentra más abajo.
Ejemplo de indicador:
#property indicator_chart_window |
Véase también
Ejecución del programa, Eventos del terminal de usuario, Trabajo con eventos