Reglas de asignación de búferes y gráficos

Cuando se registran diagramas utilizando PlotIndexSetInteger(i, PLOT_DRAW_TYPE, type), cada llamada asigna secuencialmente un cierto número de búferes al i-ésimo diagrama de acuerdo con su número requerido para la renderización type (véase la tabla ENUM_DRAW_TYPE en la sección anterior). Por lo tanto, este número de búferes no se tiene en cuenta al vincular los búferes a los diagramas siguientes (durante las próximas llamadas a PlotIndexSetInteger).

Por ejemplo, si el primer trazado (bajo el índice 0) es DRAW_CANDLES, que requiere 4 búferes de indicadores, se le asociará exactamente este número. Por lo tanto, los búferes indexados del 0 al 3 inclusive se vincularán, y el siguiente búfer libre que se vinculará será el búfer indexado 4.

Si a continuación se registra un gráfico lineal simple DRAW_LINE (su índice en la secuencia de gráficos es 1), sólo ocupará 1 búfer, justo en el índice 4.

Si además se configura un gráfico DRAW_ZIGZAG (el siguiente índice del gráfico es 2), entonces, como utiliza dos búferes, los búferes con índices 5 y 6 irán a él.

Por supuesto, el número de búferes debe ser suficiente para todos los trazados registrados. El ejemplo anterior se ilustra en la siguiente tabla. Sólo tiene 7 búferes y 3 trazados (diagramas).

Índice del búfer en SetIndexBuffer

0

1

2

3

4

5

6

Índice gráfico in PlotIndexSetInteger

0

1

2

Tipo de renderizado

DRAW_CANDLES

DRAW
__LINE__

DRAW_ZIGZAG

La indexación del búfer y del gráfico es independiente, es decir, el índice del búfer no tiene por qué ser el mismo que el del gráfico. Al mismo tiempo, a medida que aumentan los índices de los gráficos, aumentan los índices de los búferes vinculados a ellos, y la discrepancia en la indexación puede hacerse cada vez mayor si se utilizan tipos de renderización que toman más de un búfer para sí mismos.

Aunque es habitual llamar a las funciones SetIndexBuffer antes que a PlotIndexSetInteger, esto no es obligatorio. Lo único importante es la correspondencia correcta de los índices de los búferes y los índices de los diagramas. Cuando se utilizan directivas (véase la sección siguiente), que son una alternativa a la llamada a PlotIndexSetInteger, las directivas se ejecutan en cualquier caso antes que el manejador OnInit.

Para demostrar la diferencia entre el búfer y la indexación de gráficos, considere un ejemplo sencillo de IndHighLowClose.mq5. En este archivo, dibujaremos el rango de cada vela entre High y Low en forma de histograma del tipo DRAW_HISTOGRAM2 y subrayaremos el precio de Close con una línea simple DRAW_LINE. Para acceder a series temporales de precios de distintos tipos, también tenemos que cambiar la forma OnCalculate de simplificada a completa.

Como el histograma requiere 2 búferes, entonces, junto con el búfer para la línea Close, deberíamos describir tres búferes.

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 2
   
double highs[];
double lows[];
double closes[];

Regístrelos en OnInit por orden de prioridad.

int OnInit()
{
   // arrays for buffers for 3 price types
   SetIndexBuffer(0highs);
   SetIndexBuffer(1lows);
   SetIndexBuffer(2closes);
   
   // drawing a histogram between the High and Low candles under index 0
   PlotIndexSetInteger(0PLOT_DRAW_TYPEDRAW_HISTOGRAM2);
   PlotIndexSetInteger(0PLOT_LINE_WIDTH5);
   PlotIndexSetInteger(0PLOT_LINE_COLORclrBlue);
   
   // drawing the line Close at index 1
   PlotIndexSetInteger(1PLOT_DRAW_TYPEDRAW_LINE);
   PlotIndexSetInteger(1PLOT_LINE_WIDTH2);
   PlotIndexSetInteger(1PLOT_LINE_COLORclrRed);
   
   return INIT_SUCCEEDED;
}

Por el camino, la anchura del histograma se fija en 5 píxeles, y la anchura de la línea en 2. Los estilos no se asignan explícitamente, y por defecto son STYLE_SOLID.

Veamos ahora la función OnCalculate.

int OnCalculate(const int rates_total
                const int prev_calculated
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   // on each new bar or set of bars (including the first calculation)
   if(prev_calculated != rates_total)
   {
      // fill in all new bars
      ArrayCopy(highshighprev_calculatedprev_calculated);
      ArrayCopy(lowslowprev_calculatedprev_calculated);
      ArrayCopy(closescloseprev_calculatedprev_calculated);
   }
   else // ticks on the current bar
   {
      // update the last bar
      highs[rates_total - 1] = high[rates_total - 1];
      lows[rates_total - 1] = low[rates_total - 1];
      closes[rates_total - 1] = close[rates_total - 1];
   }
   // return the number of processed bars for the next call
   return rates_total;
}

El resultado de este indicador se muestra en la siguiente imagen:

Histograma alto-bajo y línea de cierre

Histograma alto-bajo y línea de cierre

Preste atención a un punto importante: los diagramas se representan en el gráfico en el orden correspondiente a sus índices, por lo que algunos son visualmente más altos que otros (se superponen). En este caso, primero se dibuja un histograma con índice 0 y, a continuación, una línea con índice 1. A veces tiene sentido cambiar el orden de registro de los gráficos para proporcionar una mejor visibilidad de las construcciones gráficas más pequeñas, que pueden quedar cubiertas por trazados más grandes (más anchos).

El establecimiento de estas prioridades a lo largo del eje Z imaginario, adentrándose en la pantalla (perpendicular a la pantalla) se denomina orden Z. Volveremos a encontrarnos con esta técnica al estudiar objetos gráficos.

Además, recuerde que, por defecto, los indicadores se muestran encima del gráfico de precios, pero este comportamiento se puede cambiar en la configuración: cuadro de diálogo Chart Properties, pestaña Common, opción Chart on foreground. Existe una opción similar en la interfaz del software (ChartSetInteger(CHART_FOREGROUND), véase la sección Modos de visualización de gráficos).