//+------------------------------------------------------------------+ //| Demo_iDeMarker.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 "de buffers do indicador para o indicador técnico iDeMarker." #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 1 #property indicator_plots 1 //--- plotar iDeMarker #property indicator_label1 "iDeMarker"\ #property indicator_type1 DRAW_LINE #property indicator_color1 clrLightSeaGreen #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- níveis horizontais na janela de indicador #property indicator_level1 0.3 #property indicator_level2 0.7 //+------------------------------------------------------------------+ //| Enumerador dos métodos de criação do manipulador | //+------------------------------------------------------------------+ enum Creation { Call_iDeMarker, // usar iDeMarker Call_IndicatorCreate // usar IndicatorCreate }; //--- parâmetros de entrada input Creation type=Call_iDeMarker; // tipo de função input int ma_period=14; // período de média móvel input string symbol=" "; // símbolo input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe //--- buffer do indicador double iDeMarkerBuffer[]; //--- variável para armazenar o manipulador do indicator iDeMarker 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 DeMarker int bars_calculated=0; //+------------------------------------------------------------------+ //| Função de inicialização do indicador customizado | //+------------------------------------------------------------------+ int OnInit() { //--- atribuição de array para buffer do indicador SetIndexBuffer(0,iDeMarkerBuffer,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_iDeMarker) handle=iDeMarker(name,period,ma_period); else { //--- preencher a estrutura com os parâmetros do indicador MqlParam pars[1]; //--- período de média móvel pars[0].type=TYPE_INT; pars[0].integer_value=ma_period; handle=IndicatorCreate(name,period,IND_DEMARKER,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 iDeMarker para o símbolo %s/%s, código de erro %d", name, EnumToString(period), GetLastError()); //--- o indicador é interrompido precocemente return(INIT_FAILED); } //--- mostra que o símbolo/prazo do indicador DeMarker é calculado para short_name=StringFormat("iDeMarker(%s/%s, period=%d)",name,EnumToString(period),ma_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 iDeMarker 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 princípio do cálculo do indicador, ou se o número de valores é modificado no indicador iDeMarker //--- 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 iDeMarkerBuffer é maior do que o número de valores no indicador iDeMarker para o 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 iDeMarkerBuffer com valores do indicador DeMarker //--- se FillArrayFromBuffer retorna falso, significa que a informação não está pronta ainda, sair da operação if(!FillArrayFromBuffer(iDeMarkerBuffer,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 DeMarker bars_calculated=calculated; //--- retorna o valor prev_calculated para a próxima chamada return(rates_total); } //+------------------------------------------------------------------+ //| Preencher buffers do indicador a partir do indicador iDeMarker | //+------------------------------------------------------------------+ bool FillArrayFromBuffer(double &values[], // buffer do indicator para valores do DeMarker int ind_handle, // manipulador do indicador iDeMarker int amount // número de valores copiados ) { //--- redefinir o código de erro ResetLastError(); //--- preencher uma parte do array iDeMarkerBuffer com valores do buffer do indicador que tem índice 0 (zero) if(CopyBuffer(ind_handle,0,0,amount,values)<0) { //--- Se a cópia falhar, informe o código de erro PrintFormat("Falha ao copiar dados do indicador iDeMarker, 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(""); } |