OnCalculate

Se llama en los indicadores al suceder el evento Calculate para el procesamiento del cambio en los datos de precio. Existen dos variantes de la función, no debemos usar ambas dentro de los límites de un mismo indicador.

Cálculo basado en la matriz de datos

int  OnCalculate(
   const int        rates_total,       // tamaño de la matriz price[]
   const int        prev_calculated,   // número de barras procesadas en la llamada anterior
   const int        begin,             // número de índice en la matriz price[] desde el que comienzan los datos significativos
   const double&    price[]            // matriz de valores para el cálculo
   );

Cálculos basados en las series temporales del marco temporal actual

int  OnCalculate(
   const int        rates_total,       // tamaño de la series de datos de entrada
   const int        prev_calculated,   // número de barras procesadas en la llamada anterior
   const datetime&  time[],            // matriz Time
   const double&    open[],            // matriz Open
   const double&    high[],            // matriz High
   const double&    low[],             // matriz Low
   const double&    close[],           // matriz Close
   const long&      tick_volume[],     // matriz Tick Volume
   const long&      volume[],          // matriz Real Volume
   const int&       spread[]           // matriz Spread
   );

Parámetros

rates_total

[in]  Tamaño de la matriz price[] o de las series temporales de entrada, disponibles para el indicador para el cálculo. En la segunda variante de la función, el valor del parámetro se corresponde con el número de barras en el gráfico en el que está iniciado.

prev_calculated

[in]  Contiene el valor que ha retornado la función OnCalculate() en la llamada anterior. Ha sido pensado para omitir en los cálculos aquellas barras que no han cambiado desde el anterior inicio de esta función.

begin

[in]  Valor del índice en la matriz price[], desde el cual comienzan los datos significativos. Permite omitir en los cálculos los datos ausentes o iniciales para los cuales no hay valores correctos.

price[]

[in]  Matriz de valores para realizar los cálculos. En calidad de matriz price[] se puede transmitir una de las series temporales de precio, o bien el búfer calculado de algún indicador. El tipo de los datos que han sido transmitidos para el cálculo, se puede conocer con la ayuda de la variable predeterminada _AppliedTo.

time{}

[in]  matriz con los valores de tiempo de apertura de las barras.

open[]

[in]  Matriz con los valores de los precios de apertura.

high[]

[in]  Matriz con los valores de los precios máximos.

low[]

[in]  Matriz con los valores de los precios mínimos.

close[]

[in]  Matriz con los valores de los precios de cierre.

tick_volume[]

[in]  Matriz con los valores de los volúmenes de ticks.

volume[]

[in]  Matriz con los valores de los volúmenes comerciales.

spread[]

[in]  Matriz con los valores de spread para las barras.

Valor retornado

Valor del tipo int que se transmitirá como parámetro prev_calculated en las posteriores llamadas a la función.

Observación

Si la función OnCalculate() retorna un valor cero, en la ventana DataWindow del terminal de cliente no se mostrarán los valores del indicador.

Si desde el momento de la última llamada de la función OnCalculate() han cambiado los datos de precio (se ha cargado una historia más profunda o se han rellanado los huecos de la historia), el valor del parámetro necesario prev_calculated será establecido como valor cero por el propio terminal.

Para determinar la dirección de la indexación en las matrices time[], open[], high[], low[], close[], tick_volume[], volume[] y spread[], es necesario llamar la función ArrayGetAsSeries(). Para no depender de las características por defecto, es sin duda necesario llamar a ArraySetAsSeries() para aquellas matrices con las que se supone que debemos trabajar.

Al usar la primera variante de la función, el usuario elige la serie temporal o indicador necesarios como matriz price[] en la pestaña Parameters al iniciar el indicador. Para ello, se deberá indicar el elemento necesario en la lista desplegable del campo "Apply to".

Para obtener los valores del indicador personalizado de otros programas mql5, se usa la función iCustom(), que retorna el manejador del indicador para las operaciones sucesivas. En este caso, además, podemos indicar la matriz price[] necesaria o el manejador de otro indicador. Este parámetro debe ser transmitido en último lugar en la lista de variables de entrada del indicador personalizado.

Es necesario utilizar la vinculación entre el valor retornado por la función OnCalculate() y el segundo parámetro de entrada prev_calculated. El parámetro prev_calculated, al llamarse la función, contiene el valor que ha retornado la función OnCalculate() en la llamada anterior. Esto permite implementar algoritmos ahorrativos para calcular el indicador personalizado, evitando así los cálculos repetidos de aquellas barras que no han cambiado desde el anterior inicio de esta función.

 

Ejemplo de indicador

//+------------------------------------------------------------------+
//|                                           OnCalculate_Sample.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "Ejemplo de cálculo del indicador Momentum"
 
//---- indicator settings
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  Blue
//---- parámetros de entrada
input int MomentumPeriod=14; // Periodo para el cálculo
//---- búfer de indicador
double    MomentumBuffer[];
//--- variable global para guardar el periodo de los cálculos
int       IntPeriod;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- comprobamos el parámetro de entrada
   if(MomentumPeriod<0)
     {
      IntPeriod=14;
      Print("el parámetro Periodo tiene un valor incorrecto. Para los cálculos se usará el valor ",IntPeriod);
     }
   else
      IntPeriod=MomentumPeriod;
//---- búferes  
   SetIndexBuffer(0,MomentumBuffer,INDICATOR_DATA);
//---- nombre del indicador para mostrar en DataWindows y en la subventana
   IndicatorSetString(INDICATOR_SHORTNAME,"Momentum"+"("+string(IntPeriod)+")");
//--- esteblecemos el número de barra desde el que comenzará el dibujado
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,IntPeriod-1);
//--- establecemos 0.0 como valor vacío, es decir, que no se dibuja
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//--- con qué precisión mostrar los valores del indicador
   IndicatorSetInteger(INDICATOR_DIGITS,2);
  }
//+------------------------------------------------------------------+
//|  Cálculo del indicador Momentum                                  |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,     // tamaño de la matriz price[] 
                const int prev_calculated, // cuántas barras se han procesado anteriormente
                const int begin,           // desde dónde comienzan los datos significativos 
                const double &price[])     // matriz del valor para el procesamiento
  {
//--- posición inicial para los cálculos
   int StartCalcPosition=(IntPeriod-1)+begin;
//---- si no hay datos suficientes para el cálculo
   if(rates_total<StartCalcPosition)
      return(0);  // salimos con un valor cero, el indicador no ha sido calculado
//--- correct draw begin
   if(begin>0)
      PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,StartCalcPosition+(IntPeriod-1));
//--- comenzamos los cálculos, calculamos la posición de inicio
   int pos=prev_calculated-1;
   if(pos<StartCalcPosition)
      pos=begin+IntPeriod;
//--- ciclo principal de cálculo
   for(int i=pos;i<rates_total && !IsStopped();i++)
      MomentumBuffer[i]=price[i]*100/price[i-IntPeriod];
//--- la ejecución de OnCalculate ha finalizado. Retornamos el nuevo valor de prev_calculated para la llamada posterior
   return(rates_total);
  }

Ver también

ArrayGetAsSeries, ArraySetAsSeries, iCustom, funciones de procesamiento de eventos, Ejecución de programas, Eventos del terminal de cliente, Acceso a las series temporales e indicadores