- Manejadores y contadores de propietarios de indicadores
- Una forma sencilla de crear instancias de indicadores: iCustom
- Comprobación del número de barras calculadas: BarsCalculated
- Obtención de datos de series temporales a partir de un indicador: CopyBuffer
- Soporte para múltiples símbolos y marcos temporales
- Visión general de los indicadores integrados
- Utilización de los indicadores integrados
- Forma avanzada de crear indicadores: IndicatorCreate
- Creación flexible de indicadores con IndicatorCreate
- Visión general de las funciones de gestión de indicadores en el gráfico
- Combinar salida a ventanas principal y auxiliar
- Leer datos de gráficos que tienen un desplazamiento
- Borrar instancias de indicadores: IndicatorRelease
- Obtener la configuración del indicador por su manejador
- Definir la fuente de datos de un indicador
Una forma sencilla de crear instancias de indicadores: iCustom
MQL5 proporciona dos funciones para crear instancias de indicadores a partir de programas: iCustom y IndicatorCreate. La primera función consiste en pasar una lista de parámetros, que deben conocerse en el momento de compilar el programa. La segunda permite formar dinámicamente un array con los parámetros del indicador llamado durante la ejecución del programa. Este modo avanzado se abordará en la sección Forma avanzada de crear indicadores:IndicatorCreate.
int iCustom(const string symbol, ENUM_TIMEFRAMES timeframe, const string pathname, ...)
La función crea un indicador para el símbolo y el marco temporal especificados. NULL en el parámetro symbol puede utilizarse para indicar el símbolo del gráfico actual, mientras que 0 en el parámetro timeframe establece el periodo actual.
En el parámetro pathname, especifique el nombre del indicador (el nombre del archivo ex5 sin extensión) y, opcionalmente, la ruta. A continuación se ofrecen más detalles sobre la ruta.
El indicador referenciado por pathname debe compilarse.
La función devuelve un manejador de indicador o INVALID_HANDLE en caso de error. El manejador será necesario para llamar a otras funciones descritas en este capítulo e incluidas en el grupo de control del programa indicador. El manejador es un número entero que describe de forma única la instancia del indicador creado dentro del programa de llamada.
La elipsis en el prototipo de función iCustom indica una lista de parámetros reales para el indicador. Sus tipos y orden deben corresponder a los parámetros formales (en el código del indicador). No obstante, se permite omitir valores a partir del final de la lista de parámetros. Para tales parámetros no especificados en el código de llamada, el indicador creado utilizará los valores por defecto de los correspondientes inputs.
Por ejemplo, si el indicador toma dos variables de entrada: periodo (input int WorkPeriod = 14) y tipo de precio (input ENUM_APPLIED_PRICE WorkPrice = PRICE_CLOSE), entonces puede llamar a iCustom con distintos grados de detalle:
- iCustom(_Symbol, _Period, 21, PRICE_TYPICAL): establecer valores para toda la lista de parámetros.
- iCustom(_Symbol, _Period, 21): al establecer el primer parámetro, el segundo se omite y recibirá el valor PRICE_CLOSE.
- iCustom(_Symbol, _Period): se omiten ambos parámetros y se obtendrán los valores 14 y PRICE_CLOSE.
No puede omitir un parámetro al principio o en medio de la lista de parámetros.
Si el indicador que se está creando tiene una forma abreviada de OnCalculate, entonces el último parámetro adicional (además de la lista de variables de entrada descritas dentro del indicador) puede ser el tipo de precio utilizado para construir el indicador. Es como una lista desplegable Apply to en el cuadro de diálogo de propiedades del indicador. Además, en este parámetro adicional, puede pasar un manejador a otro indicador creado previamente (véase un ejemplo más abajo). En este caso, el indicador recién creado se calculará utilizando el primer búfer de indicador con el manejador especificado. En otras palabras: el programador puede establecer el cálculo de un indicador a partir de otro.
MQL5 no proporciona medios programáticos para averiguar si un indicador de terceros específico se implementa utilizando la forma corta o la forma larga de OnCalculate, es decir, si se permite pasar un manejador adicional al crearlo a través de iCustom. Además, MQL5 no permite seleccionar el número de búfer si el indicador identificado por el manejador adicional tiene varios búferes.
Volvamos al parámetro pathname.
Una ruta es una cadena que contiene al menos una barra invertida ('\') o una barra diagonal ('/'), que es un carácter especial utilizado en el sistema de archivos como separador en la jerarquía de carpetas y archivos. Puede utilizar una barra diagonal o una barra invertida, pero esta última requiere «escape», lo que significa que debe escribirse dos veces. Esto se debe a que la barra invertida es un carácter de control que forma muchos códigos de servicio, como tabulación ('\t'), nueva línea ('\n'), etc. (véase la sección Tipos de caracteres).
Si la ruta comienza con una barra, se llama absoluta, y su carpeta raíz es el directorio de todos los códigos fuente MQL5. Por ejemplo, si se especifica la cadena «/MiIndicador» en el parámetro pathname se buscará el archivo MQL5/MyIndicator.ex5, y la ruta más larga con el directorio «/Ejercicio/MiIndicador» hará referencia a MQL5/Exercise/MyIndicator.ex5.
Si el parámetro pathname contiene una o varias barras pero no empieza por una, la ruta se denomina relativa porque entonces se considera relativa a una de las dos ubicaciones predefinidas. En primer lugar, el archivo del indicador se busca en relación con la carpeta donde se encuentra el programa MQL de llamada. Si no se encuentra allí, la búsqueda continúa dentro de la carpeta común de indicadores MQL5/Indicators.
En una línea con barras, el fragmento situado a la derecha de la barra más a la derecha se trata como el nombre del archivo, y todos los anteriores describen la jerarquía de carpetas. Por ejemplo, la ruta «Carpeta/Subcarpeta/NombreDeArchivo» coincide con dos subcarpetas: SubFolder dentro de Folder, y el archivo Filename dentro de SubFolder.
El caso más sencillo es cuando pathname no contiene barras. De este modo, sólo se especifica el nombre del archivo. También se considera en el contexto de los dos puntos de partida de la búsqueda mencionados anteriormente.
Por ejemplo, el Asesor Experto MyExpert.ex5 se encuentra en la carpeta MQL5/Experts/Examples, y contiene la llamada de iCustom(_Symbol, _Period, "MyIndicator"). Aquí la ruta relativa está degenerada (vacía) y sólo aparece el nombre del archivo. Así, la búsqueda del indicador parte de la carpeta MQL5/Experts/Examples/ y el nombre MyIndicator, lo que da MQL5/Experts/Examples/MyIndicator.ex5. Si no se encuentra un indicador de este tipo en este directorio, la búsqueda continuará en la carpeta raíz de los indicadores, es decir, por la ruta conectada y el nombre MQL5/Indicators/MyIndicator.ex5.
Si el indicador no se encuentra en ambos lugares, la función devolverá INVALID_HANDLE y establecerá el código de error 4802 (ERR_INDICATOR_CANNOT_CREATE) en _LastError.
Un caso más difícil es si pathname contiene no sólo el nombre, sino también el directorio, por ejemplo «SeñalesTrading/MiIndicador». La ruta especificada se añade a la carpeta del programa de llamada, lo que da como resultado el siguiente objetivo de búsqueda:MQL5/Experts/Examples/TradeSignals/MyIndicator.ex5. A continuación, en caso de fallo, se añade la misma ruta a MQL5/Indicators, es decir, se busca en el archivo MQL5/Indicators/TradeSignals/MyIndicator.ex5. Tenga en cuenta que si utiliza una barra invertida como separador, no debe olvidar escribirla dos veces, por ejemplo, iCustom(_Symbol, _Period, "TradeSignals\\MyIndicator").
Para liberar la memoria del ordenador de un indicador que ya no se utiliza, utilice la función IndicatorRelease pasándole el manejador de este indicador.
Debe prestarse especial atención a la comprobación de un programa que utilice indicadores. Si el parámetro pathname de la llamada a iCustom se especifica como una cadena constante, el compilador detecta automáticamente el indicador requerido correspondiente y lo pasa al comprobador junto con el programa que se está probando. De lo contrario, si el parámetro se calcula en una expresión o se obtiene del exterior (por ejemplo, a través de input desde el usuario), deberá especificar la propiedad en el código fuente #property tester_indicator:
#property tester_indicator "indicator_name.ex5" |
Esto significa que sólo los indicadores personalizados previamente conocidos pueden probarse en los programas.
Consideremos el ejemplo de un nuevo indicador UseWPR1.mq5, que, dentro de su manejador OnInit, estará creando un manejador del indicador IndWPR que discutimos en el capítulo anterior (no olvide compilar IndWPR porque iCustom descarga archivos ex5). El manejador recibido en UseWPR1 no se utiliza de ninguna manera todavía, ya que sólo estudiaremos la posibilidad en sí y comprobaremos la indicación de éxito. Por lo tanto, no necesitamos búferes en el nuevo indicador.
#property indicator_separate_window
|
El indicador creará una subventana vacía pero aún no mostrará nada en ella. Este es un comportamiento normal.
Vamos a comprobar varias opciones para obtener un descriptor, con distintos valores de pathname:
- Una ruta absoluta que comienza con una barra y por lo tanto incluye toda la jerarquía de carpetas (a partir de MQL5) con ejemplos de indicadores del capítulo 5, es decir, «/Indicadores/MQL5Book/p5/IndWPR»
- Sólo el nombre «IndWPR» para buscar en la misma carpeta donde se encuentra el indicador de llamada UseWPR1.mq5 (ambos indicadores se proporcionan en la misma carpeta).
- Ruta con jerarquía de carpetas de ejemplos de indicadores relativa al directorio estándar MQL5/Indicators, es decir, «MQL5Book/p5/IndWPR» (tenga en cuenta que no hay barra al principio).
- Sólo el nombre como en el punto 2 pero para el indicador inexistente «IndWPR NonExistent».
- Ruta absoluta como en el punto 1 pero con barras invertidas sin evitarlas, es decir, «\Indicadores\MQL5Book\p5\IndWPR»
- Copia íntegra del punto 2.
int OnInit()
|
Dado que las variables del manejador no se utilizan, se declaran locales. Vamos a explicar de forma específica que, aunque las variables locales handle se borran al salir de OnInit, esto no afecta a los manejadores, que siguen existiendo mientras se ejecute el indicador «padre» UseWPR. Simplemente perdemos los valores de estos manejadores en nuestro código, lo que sin embargo no es ningún problema, porque no se utilizan en ninguna parte aquí. En los ejemplos de indicadores reales que consideraremos más adelante, los manejadores, por supuesto, se almacenan (normalmente en variables globales) y se utilizan.
No se preocupe tampoco por las fugas de recursos: al eliminar el indicador UseWPR del gráfico, todos los manejadores creados por él serán borrados automáticamente por el terminal. Los principios y la necesidad de una liberación explícita de los manejadores se describirán con más detalle en la sección sobre borrar instancias de indicadores: utilizando IndicatorRelease.
El código OnInit anterior genera las siguientes entradas de registro:
iCustom(_Symbol,_Period,/Indicators/MQL5Book/p5/IndWPR)=10 / ok
|
Como podemos ver, los manejadores significativos 10, 11, 12 y 13 se reciben en todos los casos excepto en el 4º, con un indicador de llamada inexistente. El valor del manejador es -1 (INVALID_HANDLE).
Observe también que la 5ª línea genera varias advertencias de «secuencia de escape de caracteres no reconocida» al compilar. Esto es consecuencia del hecho de que no escapamos la barra invertida. Y también tuvimos suerte de que la instrucción se ejecutara correctamente, porque si el nombre de cualquier carpeta o archivo empezara por una de las letras de las secuencias de escape admitidas, la interpretación de la secuencia violaría la lectura esperada del nombre. Por ejemplo, si tuviéramos un indicador llamado «test» en la misma carpeta e intentáramos crearlo a través de la ruta «MQL5Book\p5\test», obtendríamos INVALID_HANDLE y el error 4802. Esto se debe a que '\t' es un carácter de tabulación, por lo que el terminal buscaría «MQL5Book\p5<nbsp> est». La entrada correcta debe ser «MQL5Book\p5\\test». Por lo tanto, es más fácil utilizar una barra diagonal.
También es importante tener en cuenta que, aunque todas las variaciones de éxito se refieren al mismo indicador MQL5/Indicators/MQL5Book/p5/IndWPR.ex5, y de hecho las rutas 1, 2, 3 y 5 son equivalentes, el terminal las trata como cadenas diferentes, que es la razón por la que obtenemos valores de descriptor distintos. Y sólo la opción 6, que duplica completamente la opción 2, devuelve un descriptor idéntico: 11.
¿Por qué la numeración de los manejadores empieza por 10? Los valores más pequeños se reservan para el sistema. Como se mencionó anteriormente, para los indicadores con una forma abreviada de OnCalculate, el último parámetro se puede utilizar para pasar el tipo de precio o un manejador de otro indicador, cuyo búfer se utilizará para calcular la nueva instancia creada. Dado que los elementos de la enumeración ENUM_APPLIED_PRICE tienen sus propios valores constantes, ocupan el área inferior a 10. Para más información, consulte Definir la fuente de datos de un indicador.
En el siguiente ejemplo de UseWPR2.mq5 implementaremos un indicador que creará una instancia de IndWPR y comprobará el progreso de su cálculo utilizando el manejador. Pero para ello es necesario familiarizarse con la nueva función BarsCalculated.