Comprobación del número de barras calculadas: BarsCalculated

Cuando creamos un indicador de terceros llamando a iCustom o a otras funciones que veremos más adelante en este capítulo, se requiere algún tiempo para hacer el cálculo. Como sabemos, la principal medida de la disponibilidad de datos del indicador es el número de barras calculadas, que devuelve desde su función OnCalculate. Podemos averiguar este número dado que tenemos el manejador del indicador.

int BarsCalculated(int handle)

La función devuelve el número de barras cuyos datos se calculan en el indicador especificado por handle. En caso de error, obtenemos -1.

Mientras no se hayan calculado los datos, el resultado es 0. Posteriormente, este número debe compararse con el tamaño de la serie temporal (por ejemplo, con rates_total si el indicador que llama comprueba BarsCalculated en el contexto de su propia función OnCalculate) para analizar el procesamiento de nuevas barras por parte del indicador.

En el indicador UseWPR2.mq5, intentaremos crear IndWPR mientras cambiamos el periodo WPR en el argumento de entrada.

input int WPRPeriod = 0;

Su valor por defecto es 0, que es un valor no válido. Se propone de forma intencionada para demostrar una situación anormal. Recordemos que en el código fuente IndWPR.mq5 hay comprobaciones en OnInit y en OnCalculate.

// IndWPR.mq5
void OnInit()
{
   if(WPRPeriod < 1)
   {
      Alert(StringFormat("Incorrect Period value (%d). Should be 1 or larger",
         WPRPeriod));
   }
   ...
}
   
int OnCalculate(ON_CALCULATE_STD_FULL_PARAM_LIST)
{
   if(rates_total < WPRPeriod || WPRPeriod < 1return 0;
   ...
}

Así, en el periodo cero, deberíamos recibir un mensaje de error, y BarsCalculated debería devolver siempre 0. Una vez que hemos introducido un valor positivo para el periodo, el indicador auxiliar debería empezar a calcular normalmente (y dada la facilidad de cálculo de WPR, casi inmediatamente), y BarsCalculated debería devolver el número total de barras.

Ahora vamos a presentar el código fuente para la creación de un manejador en UseWPR2.mq5.

// UseWPR2.mq5
int handle// handle to global variable
   
int OnInit()
{
   // passing name and parameter
   handle = PRTF(iCustom(_Symbol_Period"IndWPR"WPRPeriod));
   // next check is useless here because you have to wait,
   // when the indicator is loaded, run and calculate
   // (here it is for demonstration purposes only)
   PRTF(BarsCalculated(handle));
   // successful initialization depends on the descriptor
   return handle == INVALID_HANDLE ? INIT_FAILED : INIT_SUCCEEDED;
}

En OnCalculate sólo registramos los valores BarsCalculated y rates_total.

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &data[])
{
   // wait until the slave indicator is calculated on all bars
   if(PRTF(BarsCalculated(handle)) != PRTF(rates_total))
   {
      return prev_calculated;
   }
   
   // ... here is usually further work using handle
   
   return rates_total;
}

Compile y ejecute UseWPR2, primero con el parámetro 0, y después con algún valor válido, por ejemplo, 21. Aquí están las entradas de registro para el período cero.

iCustom(_Symbol,_Period,IndWPR,WPRPeriod)=10 / ok
BarsCalculated(handle)=-1 / INDICATOR_DATA_NOT_FOUND(4806)
Alert: Incorrect Period value (0). Should be 1 or larger
BarsCalculated(handle)=0 / ok
rates_total=20000 / ok
...

Inmediatamente después de la creación del manejador, los datos aún no están disponibles, por lo que se muestra el error INDICATOR_DATA_NOT_FOUND(4806), y el resultado BarsCalculated es igual a -1. A continuación aparece una notificación sobre un parámetro de entrada incorrecto que confirma la carga y el inicio correctos del indicador IndWPR. En el siguiente segmento obtenemos el valor BarsCalculated igual a 0.

Para que se calcule el indicador, introduciremos el parámetro de entrada correcto. En este caso, BarsCalculated es igual a rates_total.

iCustom(_Symbol,_Period,IndWPR,WPRPeriod)=10 / ok
BarsCalculated(handle)=-1 / INDICATOR_DATA_NOT_FOUND(4806)
BarsCalculated(handle)=20000 / ok
rates_total=20000 / ok
...

Después de haber dominado la comprobación de la disponibilidad de un indicador esclavo, podemos empezar a leer sus datos. Hagámoslo en el siguiente ejemplo UseWPR3.mq5, donde nos familiarizaremos con la función CopyBuffer.