- Principales características de los indicadores
- Evento indicador principal: OnCalculate
- Dos tipos de indicadores: para la ventana principal y para la subventana
- Ajuste del número de buffers y gráficos
- Asignación de un array como buffer: SetIndexBuffer
- Configuración de plot: PlotIndexSetInteger
- Reglas de asignación de buffers y gráficos
- Aplicación de directivas para personalizar plots
- Configuración de nombres de plots
- Visualización de las carencias de datos (elementos vacíos)
- Indicadores de subventanas independientes: tamaños y niveles
- Propiedades generales de los indicadores: precisión del título y del valor
- Coloreado de gráficos por elementos
- Omitir dibujo en barras iniciales
- Esperar datos y gestionar la visibilidad (DRAW_NONE)
- Indicadores multidivisa y multitemporal
- Seguimiento de formación de barras
- Comprobación de indicadores
- Limitaciones y ventajas de los indicadores
- Crear un borrador de indicador en el Asistente MQL
Asignación de un array como búfer: SetIndexBuffer
La función de los búferes de indicadores puede ser desempeñada por cualquier array dinámico del tipo double a lo largo de la vida útil desde el inicio del programa hasta su finalización. La forma más habitual de definir un array de este tipo es a nivel global, pero en algunos casos es más conveniente establecer arrays como miembros de clases y luego crear objetos globales con arrays. Examinaremos ejemplos de este tipo de enfoque al aplicar un indicador multidivisa (véase el ejemplo IndUnityPercent.mq5 en la sección Indicadores multidivisa y de marco temporal múltiple) e indicador de volumen delta (véase IndDeltaVolume.mq5 en la sección Esperar datos y gestionar la visibilidad).
Así pues, vamos a describir un array dinámico buffer a nivel global (sin dimensionamiento).
double buffer[]; |
Puede registrarse como búfer mediante la función especial SetIndexBuffer del terminal. Por regla general, se llama en el manejador OnInit, como muchas otras funciones para configurar el indicador, que comentaremos más adelante.
bool SetIndexBuffer(int index, double buffer[],
ENUM_INDEXBUFFER_TYPE mode = INDICATOR_DATA)
La función enlaza el búfer de indicador especificado por index con el array dinámico buffer. El valor de index debe estar comprendido entre 0 y N - 1, donde N es el número de búferes especificado por la directiva #property indicator_buffers.
Inmediatamente después de la vinculación, el array aún no está listo para trabajar con datos y ni siquiera cambia su tamaño, por lo que la inicialización y todos los cálculos deben realizarse en la función OnCalculate. No se puede modificar el tamaño de un array dinámico después de haberlo asignado como un búfer de indicador. En el caso de los búferes de indicadores, todas las operaciones de redimensionamiento las realiza el propio terminal.
La dirección de indexación tras enlazar un array con un búfer de indicador se establece por defecto como en los arrays ordinarios. Si es necesario, puede modificarse mediante la función ArraySetAsSeries.
La función SetIndexBuffer devuelve true en caso de éxito y false en caso de error.
El parámetro opcional mode indica al sistema cómo se utilizará el búfer. Los valores posibles se proporcionan en el enum ENUM_INDEXBUFFER_TYPE.
Identificador |
Descripción |
---|---|
INDICATOR_DATA |
Datos para procesar |
INDICATOR_COLOR_INDEX |
Colores de renderizado |
INDICATOR_CALCULATIONS |
Resultados internos de los cálculos intermedios |
Por defecto, el búfer de indicador está destinado a los datos de dibujo (INDICATOR_DATA). Este valor tiene otro efecto además de mostrar el array en el gráfico: el valor de cada búfer para la barra bajo el cursor del ratón se muestra en la Data window. Sin embargo, este comportamiento puede modificarse mediante algunos ajustes del indicador (véase la propiedad PLOT_SHOW_DATA en la sección Ajuste de trazado gráfico). La mayoría de los ejemplos de este capítulo se refieren al modo INDICATOR_DATA.
Si el cálculo del indicador requiere almacenar resultados intermedios para cada barra, se puede asignar un búfer auxiliar no visualizado (INDICATOR_CALCULATIONS) para ellos. Esto es más práctico que utilizar un array ordinario para el mismo propósito, ya que entonces el programador debe controlar independientemente su tamaño. En este capítulo se presentan dos ejemplos con INDICATOR_CALCULATIONS: IndTripleEMA.mq5 (véase Omitir dibujo en barras iniciales) y IndSubChartSimple.mq5 (véase Indicadores multidivisa y de marco temporal múltiple).
Algunas construcciones permiten establecer el color de visualización de cada barra. Los búferes de color (INDICATOR_COLOR_INDEX) se utilizan para almacenar información sobre el color. El color se representa mediante el tipo entero color, pero todos los búferes de indicadores deben tener el tipo double, y en este caso almacenan el número de color de una paleta especial establecida por el desarrollador (véase la sección Coloreado de diagramas elemento por elemento e indicador de ejemplo IndColorWPR.mq5 en él).
Los valores del color y del búfer auxiliar no se muestran en Data window, y no pueden obtenerse utilizando la función CopyBuffer que exploraremos más adelante en el capítulo sobre Uso de indicadores integrados y personalizados desde MQL5.
El búfer de indicador no se inicializa con ningún valor. Si algunos de sus elementos no se calculan por una razón u otra (por ejemplo, en la configuración del indicador hay un límite en el número máximo de barras o la propia construcción gráfica implica elementos significativos raros entre los que debería haber huecos, como entre los vértices de zigzag), entonces deben rellenarse explícitamente con un valor especial «vacío». El valor vacío no aparece en el gráfico ni en Data Window. Por defecto, existe una constante EMPTY_VALUE (DBL_MAX) para ello, pero si es necesario se puede sustituir por cualquier otra, por ejemplo, por 0. Para ello se utiliza la función PlotIndexSetDouble.
Dado el nuevo conocimiento sobre la función SetIndexBuffer, vamos a completar nuestro siguiente ejemplo IndReplica1.mq5, que empezamos en la sección anterior. En concreto, necesitamos el manejador OnInit.
#property indicator_chart_window
|
El número de búferes está definido por la directiva igual a 1, por lo que la asignación de arrays para un solo búfer utiliza el índice 0 (el primer parámetro SetIndexBuffer). La segunda llamada a la función es errónea y sólo se añade para demostrar el problema: dado que el índice 1 implica dos búferes declarados, genera un error BUFFERS_WRONG_INDEX (4602).
Al principio de la función OnCalculate, vamos a imprimir de nuevo el tamaño del array. En este lugar, se distribuirá ya de acuerdo con el número de barras.
int OnCalculate(const int rates_total,
|
Pasemos ahora a la cuestión de qué calculará nuestro indicador. Como ya se ha mencionado, no pondremos fórmulas complejas en él todavía, sino que simplemente intentaremos copiar las series temporales pasadas desde el parámetro data al búfer. Esto se refleja en el nombre del indicador.
...
|
Ahora el indicador se compila sin advertencias. Podemos ejecutarlo en el gráfico, y con la configuración por defecto, debería duplicar los valores de los precios de cierre de las barras en el búfer. Esto se debe a la forma abreviada de OnCalculate; hemos analizado este aspecto en la sección Evento indicador principal: OnCalculate.
Sin embargo, hay algo extraño: nuestro búfer se muestra en Data window y contiene los valores correctos, pero no hay ninguna línea en el gráfico. Esto es consecuencia del hecho de que las construcciones gráficas, y no los búferes, son responsables de la visualización. En la versión actual del indicador hemos configurado sólo el búfer. En la siguiente sección, crearemos una nueva versión IndReplica2.mq5 y la completaremos con las instrucciones necesarias.
Al mismo tiempo, el efecto descrito puede ser útil para crear indicadores «ocultos» que no muestren sus líneas en el gráfico pero que estén disponibles para su lectura programática desde otros programas MQL. Si lo desea, el desarrollador podrá ocultar incluso la mención de los búferes de indicadores de Data windows (véase PLOT_SHOW_DATA en la sección siguiente).
Abordaremos cómo gestionar indicadores desde el código MQL5 en el capítulo siguiente.