//+------------------------------------------------------------------+ //| Demo_iADX.mq5 | //| Copyright 2011, 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 "O indicador demonstra como obter dados" #property description "dos buffers do indicador para o indicador técnico iADX." #property description "Um símbolo e o prazo utilizado para o cálculo do indicador," #property description "são definidos pelos parâmetros de símbolo e período." #property description "O método de criação do manipulador é definido através do parâmetro "type" (tipo de função)." #property indicator_separate_window #property indicator_buffers 3 #property indicator_plots 3 //--- plotar ADX #property indicator_label1 "ADX" #property indicator_type1 DRAW_LINE #property indicator_color1 clrLightSeaGreen #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plotar DI_plus #property indicator_label2 "DI_plus" #property indicator_type2 DRAW_LINE #property indicator_color2 clrYellowGreen #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- plotar DI_minus #property indicator_label3 "DI_minus" #property indicator_type3 DRAW_LINE #property indicator_color3 clrWheat #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //+------------------------------------------------------------------+ //| Enumerador dos métodos de criação do manipulador | //+------------------------------------------------------------------+ enum Creation { Call_iADX, // usar iADX Call_IndicatorCreate // usar IndicatorCreate }; //--- parâmetros de entrada input Creation type=Call_iADX; // tipo da função input int adx_period=14; // cálculo do período input string symbol=" "; // símbolo input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe //--- buffers do indicador double ADXBuffer[]; double DI_plusBuffer[]; double DI_minusBuffer[]; //--- variável para armazenar o manipulador do indicador iADX int handle; //--- variável para armazenamento string name=symbol; //--- nome do indicador num gráfico string short_name; //--- manteremos o número de valores no indicador Average Directional Movement Index int bars_calculated=0; //+------------------------------------------------------------------+ //| Função de inicialização do indicador customizado | //+------------------------------------------------------------------+ int OnInit() { //--- atribuição de arrays para buffers do indicador SetIndexBuffer(0,ADXBuffer,INDICATOR_DATA); SetIndexBuffer(1,DI_plusBuffer,INDICATOR_DATA); SetIndexBuffer(2,DI_minusBuffer,INDICATOR_DATA); //--- determinar o símbolo do indicador, é desenhado para name=symbol; //--- excluir os espaços à direita e à esquerda StringTrimRight(name); StringTrimLeft(name); //--- se resulta em comprimento zero da string do 'name' if(StringLen(name)==0) { //--- tomar o símbolo do gráfico, o indicador está anexado para name=_Symbol; } //--- criar manipulador do indicador if(type==Call_iADX) handle=iADX(name,period,adx_period); else { //--- preencher a estrutura com os parâmetros do indicador MqlParam pars[1]; pars[0].type=TYPE_INT; pars[0].integer_value=adx_period; handle=IndicatorCreate(name,period,IND_ADX,1,pars); } //--- se o manipulador não é criado if(handle==INVALID_HANDLE) { //--- mensagem sobre a falha e a saída do código de erro PrintFormat("Falha ao criar o manipulador do indicador iADX para o símbolo %s/%s, código de erro %d", name, EnumToString(period), GetLastError()); //--- o indicador é interrompido precocemente return(INIT_FAILED); } //--- mostrar o símbolo/prazo, o indicador de Average Directional Movement Index é calculado para short_name=StringFormat("iADX(%s/%s period=%d)",name,EnumToString(period),adx_period); IndicatorSetString(INDICATOR_SHORTNAME,short_name); //--- inicialização normal do indicador 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[]) { //--- número de valores copiados a partir do indicador iADX int values_to_copy; //--- determinar o número de valores calculados no indicador int calculated=BarsCalculated(handle); if(calculated<=0) { PrintFormat("BarsCalculated() retornando %d, código de erro %d",calculated,GetLastError()); return(0); } //--- se for o primeiro arranque do cálculo do indicador, ou se o número de valores em que o indicador iADX foi alterado //--- ou se é necessário cálculo do indicador para duas ou mais barras (isso significa que algo mudou no histórico do preço) if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1) { //--- se o array iADXBuffer é maior do que o número de valores no indicador iADX para símbolo/período, então não copiamos tudo //--- caso contrário, copiamos menor do que o tamanho dos buffers do indicador if(calculated>rates_total) values_to_copy=rates_total; else values_to_copy=calculated; } else { //--- isso significa que não é a primeira vez do cálculo do indicador, é desde a última chamada de OnCalculate()) //--- para o cálculo não mais do que uma barra é adicionada values_to_copy=(rates_total-prev_calculated)+1; } //--- preencher o array com valores do indicador Average Directional Movement Index //--- se FillArraysFromBuffer retorna falso, isto significa que a informação ainda não está pronta, sair da operação if(!FillArraysFromBuffers(ADXBuffer,DI_plusBuffer,DI_minusBuffer,handle,values_to_copy)) return(0); //--- formar a mensagem string comm=StringFormat("%s ==> Valor atualizado no indicador %s: %d", TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS), short_name, values_to_copy); //--- exibir a mensagem de serviço no gráfico Comment(comm); //--- memorizar o número de valores no indicador Average Directional Movement Index bars_calculated=calculated; //--- retorna o valor prev_calculated para a próxima chamada return(rates_total); } //+------------------------------------------------------------------+ //| Preenchendo buffers do indicador a partir do indicador iADX | //+------------------------------------------------------------------+ bool FillArraysFromBuffers(double &adx_values[], // buffer do indicador da linha ADX double &DIplus_values[], // buffer do indicador para DI+ double &DIminus_values[], // buffer do indicador para DI- int ind_handle, // manipulador do indicador iADXWilder int amount // número dos valores copiados ) { //--- redefinir o código de erro ResetLastError(); //--- preencher uma parte do array iADXBuffer com valores a partir do buffer do indicador que tem índice 0 (zero) if(CopyBuffer(ind_handle,0,0,amount,adx_values)<0) { //--- Se a cópia falhar, informe o código de erro PrintFormat("Falha ao copiar dados a partir do indicador iADX, código de erro %d",GetLastError()); //--- parar com resultado zero - significa que indicador é considerado como não calculado return(false); } //--- preencher uma parte do array DI_plusBuffer com valores a partir do buffer do indicador que tem índice 1 (um) if(CopyBuffer(ind_handle,1,0,amount,DIplus_values)<0) { //--- Se a cópia falhar, informe o código de erro PrintFormat("Falha ao copiar dados a partir do indicador iADX, código de erro %d",GetLastError()); //--- parar com resultado zero - significa que indicador é considerado como não calculado return(false); } //--- preencher uma parte do array DI_plusBuffer com valores a partir do buffer do indicador que tem o índice 2 (dois) if(CopyBuffer(ind_handle,2,0,amount,DIminus_values)<0) { //--- Se a cópia falhar, informe o código de erro PrintFormat("Falha ao copiar dados a partir do indicador iADX, código de erro %d",GetLastError()); //--- parar com resultado zero - significa que indicador é considerado como não calculado return(false); } //--- está tudo bem return(true); } //+------------------------------------------------------------------+ //| Função de desinicialização do indicador | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(handle!=INVALID_HANDLE) IndicatorRelease(handle); //--- limpar o gráfico após excluir o indicador Comment(""); } |