#property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #define OBJ_NAME "TestObjectGetDouble" // Nome do objeto #define WND 0 // Su0bjanela do gráfico #define EXT " (%$)" // String de formato para exibir os valores de preço nos níveis //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- identificador do gráfico atual, símbolo desse gráfico e Digits do símbolo long chart_id= ChartID(); string symbol = ChartSymbol(chart_id); int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); //--- construímos o objeto gráfico "Níveis de Fibonacci" nos preços máximo e mínimo do gráfico visível if(!CreateFibo(chart_id)) return; //--- quantidade de níveis do objeto int total=(int)ObjectGetInteger(chart_id, OBJ_NAME, OBJPROP_LEVELS); double value =0; double price0=0; double price1=0; //--- preços dos pontos de ancoragem price0=ObjectGetDouble(chart_id, OBJ_NAME, OBJPROP_PRICE, 0); price1=ObjectGetDouble(chart_id, OBJ_NAME, OBJPROP_PRICE, 1); //--- em laço pela quantidade de níveis do objeto for(int i=0; i<total; i++) { //--- obtemos o valor definido para o nível atual ResetLastError(); if(!ObjectGetDouble(chart_id, OBJ_NAME, OBJPROP_LEVELVALUE, i, value)) { Print("ObjectGetDouble() failed. Error ", GetLastError()); return; } //--- obtemos os preços máximo e mínimo de ancoragem do objeto e a distância entre eles em valor de preço double max=fmax(price0, price1); double min=fmin(price0, price1); double range=max-min; //--- calculamos o valor de preço para o nível atual do objeto double level_price=min+range*value; //--- definimos a cor para o nível de modo que seja visível tanto no fundo escuro quanto no fundo claro do gráfico ObjectSetInteger(chart_id, OBJ_NAME, OBJPROP_LEVELCOLOR, i, clrRed); //--- definimos para o nível a string de formato, para que junto com o valor do nível seja exibido também o seu valor de preço string level_text=ObjectGetString(chart_id, OBJ_NAME, OBJPROP_LEVELTEXT, i); if(StringFind(level_text, EXT)<0) { level_text+=EXT; ObjectSetString(chart_id, OBJ_NAME, OBJPROP_LEVELTEXT, i, level_text); } //--- imprimimos no log o número do nível e seus dados - o valor do nível e seu preço PrintFormat("Fibo level [%d] value: %.3f, price: %.*f", i, value, digits, level_price); } /* Resultado: Fibo level [0] value: 0.000, price: 0.61989 Fibo level [1] value: 0.236, price: 0.62533 Fibo level [2] value: 0.382, price: 0.62869 Fibo level [3] value: 0.500, price: 0.63140 Fibo level [4] value: 0.618, price: 0.63412 Fibo level [5] value: 1.000, price: 0.64292 Fibo level [6] value: 1.618, price: 0.65715 Fibo level [7] value: 2.618, price: 0.68018 Fibo level [8] value: 4.236, price: 0.71745 */ } //+------------------------------------------------------------------+ //| Cria o objeto gráfico Níveis de Fibonacci no gráfico especificado| //+------------------------------------------------------------------+ bool CreateFibo(const long chart_id) { //--- desenharemos os Níveis de Fibonacci do maior para o menor dos valores de preço visíveis no gráfico, obtemos esses valores double price_high=0, price_low=0; datetime time_high =0, time_low =0; if(!GetChartExtremums(chart_id, price_high, price_low, time_high, time_low)) return(false); //--- construiremos o objeto "Níveis de Fibonacci" nas coordenadas de preço/tempo encontradas if(!ObjectCreate(chart_id, OBJ_NAME, OBJ_FIBO, WND, time_high, price_high, time_low, price_low)) { PrintFormat("%s: ObjectCreate() failed. Error %d",__FUNCTION__, GetLastError()); return(false); } //--- tudo concluído com sucesso, atualizamos o gráfico e retornamos true ChartRedraw(); return(true); } //+------------------------------------------------------------------+ //| Retorna os preços máximo e mínimo no gráfico e seus tempos | //+------------------------------------------------------------------+ bool GetChartExtremums(const long chart_id, double &price_high, double &price_low, datetime &time_high, datetime &time_low) { //--- zeramos as variáveis price_high=price_low=0; time_high =time_low =0; //--- símbolo do gráfico string symbol = ChartSymbol(chart_id); //--- pelo número da primeira barra visível e pela quantidade de barras no gráfico calculamos o início do intervalo das séries temporais a copiar int first = (int)ChartGetInteger(chart_id, CHART_FIRST_VISIBLE_BAR); int count = (int)ChartGetInteger(chart_id, CHART_VISIBLE_BARS); int start = first+1-count; //--- arrays para onde serão copiadas as séries temporais double array_high[]; double array_low[]; datetime array_time[]; int index; //--- copiamos para os arrays três séries temporais na quantidade count e a partir de start ResetLastError(); if(CopySeries(symbol, PERIOD_CURRENT, start, count, COPY_RATES_TIME|COPY_RATES_HIGH|COPY_RATES_LOW, array_time, array_high, array_low)!=count) { PrintFormat("%s: CopySeries() failed. Error %d",__FUNCTION__, GetLastError()); return(false); } //--- buscamos o índice do preço máximo no array array_high index=ArrayMaximum(array_high); if(index<0) { PrintFormat("%s: ArrayMaximum() failed. Error %d",__FUNCTION__, GetLastError()); return(false); } //--- guardamos o preço mais alto no gráfico visível e o valor do tempo da barra no qual esse preço se encontra price_high=array_high[index]; time_high=array_time[index]; //--- buscamos o índice do preço mínimo no array array_low index=ArrayMinimum(array_low); if(index<0) { PrintFormat("%s: ArrayMinimum() failed. Error %d",__FUNCTION__, GetLastError()); return(false); } //--- guardamos o menor preço no gráfico visível e o valor do tempo da barra na qual esse preço se encontra price_low=array_low[index]; time_low=array_time[index]; //--- tudo concluído com sucesso return(true); } |