Obtener cotizaciones como un array de estructuras MqlRates

Para solicitar un array de cotizaciones que incluya todas las características de la barra, utilice la función CopyRates, que tiene múltiples sobrecargas.

int CopyRates(const string symbol, ENUM_TIMEFRAMES timeframe, int offset, int count, MqlRates &rates[])

int CopyRates(const string symbol, ENUM_TIMEFRAMES timeframe, datetime start, int count, MqlRates &rates[])

int CopyRates(const string symbol, ENUM_TIMEFRAMES timeframe, datetime start, datetime stop, MqlRates &rates[])

La función obtiene en el array rates datos históricos para los parámetros especificados: símbolo, marco temporal e intervalo temporal especificados mediante números de barra o valores start/stop del tipo datetime.

La función devuelve el número de elementos de array copiados, o -1 en caso de error, cuyo código puede encontrarse en _LastError. En concreto, se producirá un error si se especifica un símbolo inexistente, el intervalo no contiene datos en el servidor o supera el límite del número de barras del gráfico (TerminalInfoInteger(TERMINAL_MAXBARS)).

Los conceptos básicos para trabajar con esta función son comunes a todas las funciones de Copy y se han expuesto en la sección Visión general de las funciones Copy para obtener arrays de cotizaciones.

La estructura de tipos en línea MqlRates se describe del siguiente modo:

struct MqlRates
{
   datetime time;         // bar opening time
   double   open;         // opening price
   double   high;         // maximum price per bar
   double   low;          // minimum price per bar
   double   close;        // closing price
   long     tick_volume;  // tick volume per bar
   int      spread;       // minimum spread per bar in points
   long     real_volume;  // exchange volume per bar
};

Vamos a intentar aplicar la función para calcular el tamaño medio de las barras en el script SeriesStats.mq5. En las variables de entrada, ofreceremos la posibilidad de seleccionar un símbolo de trabajo, un marco temporal, el número de barras analizadas y el desplazamiento inicial hacia el pasado (0 significa análisis desde la barra actual).

input string WorkSymbol = NULL// Symbol (leave empty for current)
input ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT;
input int BarOffset = 0;
input int BarCount = 10000;
 
void OnStart()
{
   MqlRates rates[];
   double range = 0move = 0// calculate the range and price movement in bars
   
   PrintFormat("Requesting %d bars on %s %s"
      BarCountStringLen(WorkSymbol) > 0 ? WorkSymbol : _Symbol
      EnumToString(TimeFrame == PERIOD_CURRENT ? _Period : TimeFrame));
   
   // request all information about BarCount bars to the MqlRates array
   const int n = PRTF(CopyRates(WorkSymbolTimeFrameBarOffsetBarCountrates));
   
   // in the loop we calculate the average for the range and movement
   for(int i = 0i < n; ++i)
   {
      range += (rates[i].high - rates[i].low) / n;
      move += (fmax(rates[i].openrates[i].close)
             - fmin(rates[i].openrates[i].close)) / n;
   }
   
   PrintFormat("Stats per bar: range=%f, movement=%f"rangemove);
   PrintFormat("Dates: %s - %s"
      TimeToString(rates[0].time), TimeToString(rates[n - 1].time));
}

Habiendo lanzado el script en el gráfico EURUSD,H1, podemos obtener aproximadamente el siguiente resultado:

Requesting 100000 bars on EURUSD PERIOD_H1
CopyRates(WorkSymbol,TimeFrame,BarOffset,BarCount,rates)=20018 / ok
Stats per bar: range=0.001280, movement=0.000621
Dates: 2018.07.19 15:00 - 2021.10.11 17:00

Como el terminal tenía un límite de 20 000 barras, una petición de 100 000 barras sólo podía devolver 20 018 (el límite y las barras recién formadas tras el inicio de la sesión). El primer elemento del array (con índice 0) contiene una barra con la hora 2018.07.19 15:00, y el último, - 2021.10.11 17:00.

Según las estadísticas, el rango medio de la barra durante este tiempo fue de 128 puntos, y el movimiento entre la apertura y el cierre fue de 62 puntos.

Cuando solicite información utilizando una fecha de inicio y de fin (start/stop) tenga en cuenta que ambos límites se tratan de forma inclusiva. Por lo tanto, para establecer un intervalo correspondiente a cualquier barra de un marco temporal superior, hay que restar 1 segundo del borde derecho. Aplicaremos esta técnica en el ejemplo SeriesSpread.mq5 de la sección Lectura de precio, volumen, diferencial y hora por índice de barras.