ArrayCopy

Esta función copia un array al otro.

int  ArrayCopy(
   void&        dst_array[],         // array de destino
   const void&  src_array[],         // array de origen
   int          dst_start=0,         // índice inicial para copiar desde el array de origen
   int          src_start=0,         // primer índice del array de destino
   int          count=WHOLE_ARRAY    // número de elementos
   );

Parámetros

dst_array[]

[out]  Array de destino.

src_array[]

[in]  Array de origen.

dst_start=0

[in]  Índice inicial para el array de destino. Por defecto, índice inicial - 0.

src_start=0

[in]  Índice inicial para el array de origen. Por defecto, índice inicial - 0.

count=WHOLE_ARRAY

[in]  Número de elementos que hay que copiar. Por defecto, se copia el array entero (count=WHOLE_ARRAY).

Valor devuelto

Devuelve el número de elementos copiados.

Nota

Si count<0 o count>src_size-src_start, entonces se copia toda la parte restante del array. Los arrays se copian de izquierda a derecha. Para los arrays de serie, la posición de inicio se redefine correctamente tomando en cuenta el copiado de izquierda a derecha.

Si los arrays son de tipos diferentes, durante el copiado se intenta la transformación de cada elemento del array de origen en el tipo del array de destino. Los arrays literales se puede copiar sólo a los arrays literales. Los arrays de clases y estructuras que contienen los objetos que requieren la inicialización no se copian. Un array de estructuras puede ser copiado sólo a un array del mismo tipo.

Para los arrays dinámicos con la indexación como en las series temporales se realiza el aumento der array receptor hasta la cantidad de los datos copiados (si la cantidad de los datos copiados supera su tamaño). La reducción automática del tamaño del array receptor no se hace.

Ejemplo:

#property description "El indicador colorea las velas que son"
#property description "máximos y mínimos locales. La distancia del intervalo para buscar"
#property description "los valores extremos se puede establecer a través del parámetro de entrada."
//--- ajustes del indicador
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots   1
//---- plot
#property indicator_label1  "Extremums"
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_color1  clrLightSteelBlue,clrRed,clrBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- constante predefinida
#define INDICATOR_EMPTY_VALUE 0.0
//--- parámetros de entrada
input int InpNum=4; // Longitud de la mitad del intervalo
//--- búfers indicadores
double ExtOpen[];
double ExtHigh[];
double ExtLow[];
double ExtClose[];
double ExtColor[];
//--- variables globales
int    ExtStart=0; // índice de la primera vela que no es un extremo
int    ExtCount=0; // número de velas no- extremos en este intervalo
//+------------------------------------------------------------------+
//| Coloreado de velas no- extremos                                  |
//+------------------------------------------------------------------+
void FillCandles(const double &open[],const double &high[],
                 const double &low[],const double &close[])
  {
//--- coloreamos velas
   ArrayCopy(ExtOpen,open,ExtStart,ExtStart,ExtCount);
   ArrayCopy(ExtHigh,high,ExtStart,ExtStart,ExtCount);
   ArrayCopy(ExtLow,low,ExtStart,ExtStart,ExtCount);
   ArrayCopy(ExtClose,close,ExtStart,ExtStart,ExtCount);
  }
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtOpen);
   SetIndexBuffer(1,ExtHigh);
   SetIndexBuffer(2,ExtLow);
   SetIndexBuffer(3,ExtClose);
   SetIndexBuffer(4,ExtColor,INDICATOR_COLOR_INDEX);
//--- especificamos el valor que no va a mostrarse
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,INDICATOR_EMPTY_VALUE);
//--- especificamos los nombres de los búfers indicadores para mostrar en la ventana de datos
   PlotIndexSetString(0,PLOT_LABEL,"Open;High;Low;Close");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//--- establecemos la indexación directa en las series temporales
   ArraySetAsSeries(open,false);
   ArraySetAsSeries(high,false);
   ArraySetAsSeries(low,false);
   ArraySetAsSeries(close,false);
//--- variable de inicio para el cálculo de las barras
   int start=prev_calculated;
//--- para las primeras barras InpNum*2 no realizamos el cálculo
   if(start==0)
     {
      start+=InpNum*2;
      ExtStart=0;
      ExtCount=0;
     }
//--- si la barra acaba de formarse, comprobamos el siguiente extremo potencial
   if(rates_total-start==1)
      start--;
//--- índice de la barra cuyo extremo vamos a comprobar
   int ext;
//--- ciclo de cálculo de los valores del indicador
   for(int i=start;i<rates_total-1;i++)
     {
      //--- inicialmente en la barra i sin dibujar
      ExtOpen[i]=0;
      ExtHigh[i]=0;
      ExtLow[i]=0;
      ExtClose[i]=0;
      //--- índice del extremo a chequear
      ext=i-InpNum;
      //--- comprobación del máximo local
      if(IsMax(high,ext))
        {
         //--- coloreamos la vela extremo
         ExtOpen[ext]=open[ext];
         ExtHigh[ext]=high[ext];
         ExtLow[ext]=low[ext];
         ExtClose[ext]=close[ext];
         ExtColor[ext]=1;
         //--- las demás velas hasta el extremo marcamos con color neutral
         FillCandles(open,high,low,close);
         //--- cambiamos los valores de variables
         ExtStart=ext+1;
         ExtCount=0;
         //--- pasamos a la siguiente iteración
         continue;
        }
      //--- comprobación del mínimo local
      if(IsMin(low,ext))
        {
         //--- coloreamos la vela extremo
         ExtOpen[ext]=open[ext];
         ExtHigh[ext]=high[ext];
         ExtLow[ext]=low[ext];
         ExtClose[ext]=close[ext];
         ExtColor[ext]=2;
         //--- las demás velas hasta el extremo marcamos con color neutral
         FillCandles(open,high,low,close);
         //--- cambiamos los valores de variables
         ExtStart=ext+1;
         ExtCount=0;
         //--- pasamos a la siguiente iteración
         continue;
        }
      //--- incrementamos el número de no-extremos en este intervalo
      ExtCount++;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Comprobamos si el elemento actual del array es un máximo local   |
//+------------------------------------------------------------------+
bool IsMax(const double &price[],const int ind)
  {
//--- variable del inicio del intervalo
   int i=ind-InpNum;
//--- variable del fin del intervalo
   int finish=ind+InpNum+1;
//--- chequeo para la primera mitad del intervalo
   for(;i<ind;i++)
     {
      if(price[ind]<=price[i])
         return(false);
     }
//--- chequeo para la segunda mitad del intervalo
   for(i=ind+1;i<finish;i++)
     {
      if(price[ind]<=price[i])
         return(false);
     }
//--- es un extremo
   return(true);
  }
//+------------------------------------------------------------------+
//| Comprobamos si el elemento actual del array es un mínimo local   |
//+------------------------------------------------------------------+
bool IsMin(const double &price[],const int ind)
  {
//--- variable del inicio del intervalo
   int i=ind-InpNum;
//--- variable del fin del intervalo
   int finish=ind+InpNum+1;
//--- chequeo para la primera mitad del intervalo
   for(;i<ind;i++)
     {
      if(price[ind]>=price[i])
         return(false);
     }
//--- chequeo para la segunda mitad del intervalo
   for(i=ind+1;i<finish;i++)
     {
      if(price[ind]>=price[i])
         return(false);
     }
//--- es un extremo
   return(true);
  }