CopyBuffer

Obtém dados de um buffer especificado de um certo indicador na quantidade necessária.

copyBuffer

A contagem de elementos de dados copiados (buffer de indicador com o índice buffer_num) da posição de início é realizada do presente para o passado, isto é, posição de início 0 significa a barra corrente (valor do indicador para a barra corrente).

Ao copiar uma quantidade ainda desconhecida de dados, é recomendado usar um array dinâmico como um buffer[] recipiente, porque a função CopyBuffer() tenta alocar o tamanho do array receptor ao tamanho dos dados copiados. Se um buffer de indicador (array que é pré-alocado para armazenar valores de um indicador através da função SetIndexBufer()) for usado como um array recipiente buffer[], uma copia parcial é permitida. Um exemplo pode ser encontrado no indicador customizado Awesome_Oscillator.mql5 no pacote padrão do terminal.

Se você precisar fazer uma cópia parcial dos valores de um indicador em um outro array (um não buffer de indicador), você deve usar um array intermediário, para o qual o número desejado é copiado. Após isso, conduza uma cópia elemento a elemento do requerido número de valores para os lugares requeridos em um array de recepção a partir deste array intermediário.

Se você souber a quantidade de dados que você precisa para copiar, é melhor usar um buffer alocado estaticamente, a fim de evitar a alocação de memória excessiva.

Não importa qual seja a propriedade do array destino - como series=true ou como series=false. Os dados serão copiados de tal maneira que o elemento mais antigo será localizado no início da memória física alocada para o array. Exitem 3 variantes de chamada da função.

Chamar pela posição primeira e o número de elementos requeridos

int  CopyBuffer(
   int       indicator_handle,     // handle do indicador
   int       buffer_num,           // número do buffer do indicador
   int       start_pos,            // posição de início
   int       count,                // quantidade para copiar
   double    buffer[]              // array destino para copiar
   );

Chamar pela data de início e o número de elementos requeridos

int  CopyBuffer(
   int       indicator_handle,     // handle do indicador
   int       buffer_num,           // número do buffer do indicador
   datetime  start_time,           // data e hora de início
   int       count,                // quantidade para copiar
   double    buffer[]              // array destino para copiar
   );

Chamar pelas datas de início e término de um intervalo de tempo requerido

int  CopyBuffer(
   int       indicator_handle,     // handle do indicador
   int       buffer_num,           // número do buffer do indicador
   datetime  start_time,           // data e hora de início
   datetime  stop_time,            // data e hora de término
   double    buffer[]              // array destino para copiar
   );

Parâmetros

indicator_handle

[in]  O handle do indicador, retornado pela função do indicador correspondente.

buffer_num

[in]  O número do buffer do indicador.

start_pos

[in]  A posição do primeiro elemento para copiar.

count

[in]  Quantidade de dados para copiar.

start_time

[in]  Hora da barra, correspondente ao primeiro elemento.

stop_time

[in]  Hora da barra, correspondente ao último elemento.

buffer[]

[out]  Array de tipo double.

Valor do Retorno

Retorna a quantidade de dados copiados ou -1 no caso de um erro.

Observação

Ao solicitar dados de um indicador, se as séries de tempo solicitadas não estiverem ainda construídas ou elas precisarem serem baixadas do servidor, a função imediatamente retornará -1, mas o processo de download/construção será iniciado.

Ao solicitar dados de um Expert Advisor ou script, o download do servidor será iniciado se o terminal não tiver estes dados localmente, ou a construção da série de tempo solicitada iniciará, se os dados puderem ser construídas a partir do histórico local mas eles não estiverem prontos ainda. A função retornará a quantidade de dados que estará pronta no momento da expiração do tempo limite.

Exemplo:

//+------------------------------------------------------------------+
//|                                              TestCopyBuffer3.mq5 |
//|                         Copyright 2000-2024, MetaQuotes Ltd. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//---- plotar MA
#property indicator_label1  "MA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- parâmetros de entrada
input bool               AsSeries=true;
input int                period=15;
input ENUM_MA_METHOD     smootMode=MODE_EMA;
input ENUM_APPLIED_PRICE price=PRICE_CLOSE;
input int                shift=0;
//--- buffers do indicador
double                   MABuffer[];
int                      ma_handle;
//+------------------------------------------------------------------+
//| Função de inicialização do indicador customizado                 |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- mapeamento de buffers do indicador
   SetIndexBuffer(0,MABuffer,INDICATOR_DATA);
   Print("Parameter AsSeries = ",AsSeries);
   Print("Buffer do indicador após SetIndexBuffer() é timeseries = ",
         ArrayGetAsSeries(MABuffer));
//--- define o nome abreviado do indicador
   IndicatorSetString(INDICATOR_SHORTNAME,"MA("+period+")"+AsSeries);
//--- define AsSeries(depende do parâmetro de entrada)
   ArraySetAsSeries(MABuffer,AsSeries);
   Print("Buffer do indicador após ArraySetAsSeries(MABuffer,true); é timeseries = ",
         ArrayGetAsSeries(MABuffer));
//---
   ma_handle=iMA(Symbol(),0,period,shift,smootMode,price);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Função de iteração do indicador customizado                      |
//+------------------------------------------------------------------+
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[])
  {
//--- verifica se todos os dados estão calculados
   if(BarsCalculated(ma_handle)<rates_total) return(0);
//--- nós não podemos copiar todos os dados
   int to_copy;
   if(prev_calculated>rates_total || prev_calculated<=0) to_copy=rates_total;
   else
     {
      to_copy=rates_total-prev_calculated;
      //--- o último valor é sempre copiado
      to_copy++;
     }
//--- tenta copiar
   if(CopyBuffer(ma_handle,0,0,to_copy,MABuffer)<=0) return(0);
//--- valor retorno de prev_calculated para a próxima chamada
   return(rates_total);
  }
//+------------------------------------------------------------------+

O exemplo acima ilustra como um buffer de indicador é preenchido com os valores de um outro buffer de indicador a partir de um indicador sobre o mesmo ativo/período.

Veja uma exemplo detalhado de solicitação de dados históricos na seção Métodos de Vinculação de Objetos. O script disponível nesta seção mostra como obter os valores do indicador iFractals nas últimas 1000 barras e como exibir os últimos 10 fractais de alta e os últimos 10 fractais de baixa no gráfico. Uma técnica simular pode ser usada para todos os indicadores que têm dados faltantes e que são usualmente desenhados usando os seguintes estilos:

 

Também Veja

Propriedades de Indicadores Customizados, SetIndexBuffer