Início Indicador técnico Postagem

Painel Gráfico: Mostre a Tendência Atual em Todos os Tempos no MetaTrader 4

Anexo
15620.zip (2.17 KB, Baixar 0 vezes)

Se você é um trader que gosta de ter uma visão clara do mercado, este indicador gráfico é para você! Ele se baseia no famoso indicador de Slope-Direction-Trend e traz uma novidade: agora você pode visualizar todas as tendências em um único painel gráfico na sua tela.

Embora já existam várias versões desse indicador, nenhuma delas exibia todos os tempos em um só lugar. Você pode conferir mais resultados no link.

Eu peguei o indicador original e fiz algumas modificações. A principal delas é que agora você pode escolher o método da média móvel para suavizar os dados. O código original utilizava a média ponderada linear, que pode tornar o indicador muito reativo, gerando leituras falsas sobre a tendência atual. Ao optar pela média simples como o segundo método de suavização, conseguimos uma tendência que reflete melhor para onde o preço está indo.

Outra alteração importante é que agora não apenas conseguimos identificar a direção da tendência (alta, baixa ou neutra), mas também obter o seu valor. Vou aprofundar isso em um próximo artigo onde falarei sobre como usar um indicador de double SlopeDirection para criar um Expert Advisor.

SlopeDirection

Mas por enquanto, vamos dar uma olhada no código. Primeiro, definimos todos os nomes dos objetos que vamos usar. Essa é uma boa prática porque, ao colocar um nome de objeto entre aspas, o programa reserva espaço para ele. Se você defini-los uma única vez (usando uma declaração define), economiza espaço no seu código.

// Definindo direções de tendência
#define     UPTREND           1
#define     DOWNTREND         -1
#define     FLATTREND         0

// Definindo Objetos
#define     TrendPanel        "TrendPanel"
#define     InfoLine1         "InfoLine1"
#define     InfoLine2         "InfoLine2"
#define     TrendLabel        "Tendência:  M1  M5  M15  M30  H1  H4  D1  W1  MN"
#define     TrendUp           "\233"
#define     TrendDown         "\234"
#define     TrendFlat         "\232"
#define     TrendUnknown      "\251"
#define     StatObjectError   "%s(%d) Falha ao criar '%s'.  Erro = %d"

Em seguida, defino dois arrays. Um com a posição em pixels para cada um dos 9 tempos e o segundo com os próprios tempos. Esses são definidos como variáveis globais.

// Definindo variáveis globais
int      TrendPosition[] = { 44, 64, 88, 114, 136, 156, 174, 194, 216 };
int      TrendPeriods[] = { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4, PERIOD_D1, PERIOD_W1, PERIOD_MN1 };

A função OnInit() do nosso indicador chama uma função para criar o painel e os objetos dentro dele. Ela também faz uma verificação rápida sobre as barras usadas para calcular a tendência. Menos de 3 barras não faz sentido.

//+------------------------------------------------------------------+
//| Função de inicialização do indicador customizado                         |
//+------------------------------------------------------------------+
int   OnInit()
{
   // Criar objetos para o painel do indicador
   if(Create_Panel() && BarCount >= 3)
      return(INIT_SUCCEEDED);
   else
      return(INIT_FAILED);
}

Não vou entrar em detalhes sobre como a função GetTrend() realmente funciona, já existe uma boa documentação sobre isso. Vamos apenas dar uma olhada na função gráfica DisplayTrend().

//+------------------------------------------------------------------+
//| Exibe a tendência atual para todos os tempos
//+------------------------------------------------------------------+
void  DisplayTrend(void)
{
   int      i, cntr, Trend, LastTrend;
   string   str;
   
   for(i=1; i<10; i++)
   {
      str = "Trend" + DoubleToStr(i, 0);
      Trend = (int)GetTrend(TrendPeriods[i-1], BarCount, Method);
      if(Trend == FLATTREND)
      {
         // Estou neutro, encontre a última direção da tendência
         cntr = 1;
         do 
         { 
            LastTrend = (int)GetTrend(TrendPeriods[i-1], BarCount, Method, false, cntr++);
         } while(LastTrend == Trend);
         ObjectSetText(str, TrendFlat, 8, "WingDings", (LastTrend == UPTREND ? Green : Red));
         ObjectSetInteger(0, str, OBJPROP_YDISTANCE, 6);
      }
      else
      {
         ObjectSetText(str, (Trend == UPTREND ? TrendUp : TrendDown), 8, "WingDings", (Trend == UPTREND ? Green : Red));
         ObjectSetInteger(0, str, OBJPROP_YDISTANCE, 5 + (Trend == UPTREND ? 1 : -1));
      }
   }
}

Básicamente, percorremos o array TrendPeriods[] (para obter todos os tempos) e definimos a seta da tendência de acordo com a direção da tendência daquele tempo. Se a tendência for neutra, encontramos a primeira direção que não é neutra para saber de onde a tendência estava vindo, assim conseguimos exibir a seta lateral na cor daquela direção.

A função Create_Panel() em nosso OnInit() cria os objetos ancorados na parte inferior esquerda da tela, utilizando TrendPosition[] para colocar as setas nos lugares corretos.

//+------------------------------------------------------------------+
//| Cria o painel de tendência no canto inferior esquerdo da tela
//+------------------------------------------------------------------+
bool  Create_Panel(void)
{

   int      i;
   string   str;
   
   // Criar a janela do indicador de tendência
   if(ObjectCreate(TrendPanel, OBJ_RECTANGLE_LABEL, 0, 0, 0))
   {
      ObjectSetInteger(0, TrendPanel, OBJPROP_XDISTANCE, 1);
      ObjectSetInteger(0, TrendPanel, OBJPROP_YDISTANCE, 29);
      ObjectSetInteger(0, TrendPanel, OBJPROP_XSIZE, 240);
      ObjectSetInteger(0, TrendPanel, OBJPROP_YSIZE, 26);
      ObjectSetInteger(0, TrendPanel, OBJPROP_BGCOLOR, White);
      ObjectSetInteger(0, TrendPanel, OBJPROP_BORDER_TYPE, 0);
      ObjectSetInteger(0, TrendPanel, OBJPROP_CORNER, CORNER_LEFT_LOWER);
      ObjectSetInteger(0, TrendPanel, OBJPROP_COLOR, Red);
      ObjectSetInteger(0, TrendPanel, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSetInteger(0, TrendPanel, OBJPROP_WIDTH, 2);
      ObjectSetInteger(0, TrendPanel, OBJPROP_BACK, false);
      ObjectSetInteger(0, TrendPanel, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, TrendPanel, OBJPROP_SELECTED, false);
      ObjectSetInteger(0, TrendPanel, OBJPROP_HIDDEN, true);
      ObjectSetString(0, TrendPanel, OBJPROP_TOOLTIP, "\n");
   }
   else
   { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, TrendPanel, GetLastError()); return(false); }

   if(ObjectCreate(InfoLine1, OBJ_LABEL, 0, 0, 0))
   {
      ObjectSet(InfoLine1, OBJPROP_CORNER, CORNER_LEFT_LOWER);
      ObjectSet(InfoLine1, OBJPROP_XDISTANCE, 6);
      ObjectSet(InfoLine1, OBJPROP_YDISTANCE, 15);
      ObjectSetInteger(0, InfoLine1, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, InfoLine1, OBJPROP_HIDDEN, true);
      ObjectSetString(0, InfoLine1, OBJPROP_TOOLTIP, "\n");
      ObjectSetText(InfoLine1, TrendLabel, 8, "Arial", Black);
   }
   else
   { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, InfoLine1, GetLastError()); return(false); }
   
   if(ObjectCreate(InfoLine2, OBJ_LABEL, 0, 0, 0))
   {
      ObjectSet(InfoLine2, OBJPROP_CORNER, CORNER_LEFT_LOWER);
      ObjectSet(InfoLine2, OBJPROP_XDISTANCE, 6);
      ObjectSet(InfoLine2, OBJPROP_YDISTANCE, 5);
      ObjectSetInteger(0, InfoLine2, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, InfoLine2, OBJPROP_HIDDEN, true);
      ObjectSetString(0, InfoLine2, OBJPROP_TOOLTIP, "\n");
      ObjectSetText(InfoLine2, " " + DoubleToStr(BarCount, 0) + " / " + DoubleToStr(Method, 0), 8, "Arial", Black);
   }
   else
   { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, InfoLine2, GetLastError()); return(false); }

   // Criar objeto de tendência e exibir a tendência atual    
   for(i=1; i<10; i++)
   {
      str = "Trend" + DoubleToStr(i, 0);
      if(ObjectCreate(str, OBJ_LABEL, 0, 0, 0))
      {
         ObjectSet(str, OBJPROP_CORNER, CORNER_LEFT_LOWER);
         ObjectSet(str, OBJPROP_XDISTANCE, TrendPosition[i-1]);
         ObjectSet(str, OBJPROP_YDISTANCE, 5);
         ObjectSetInteger(0, str, OBJPROP_SELECTABLE, false);
         ObjectSetInteger(0, str, OBJPROP_HIDDEN, true);
         ObjectSetString(0, str, OBJPROP_TOOLTIP, "\n");
      }
      else
      { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, str, GetLastError()); return(false); }
   }

   // Exibir a tendência atual
   DisplayTrend();
      
   // Tudo certo
   return(true);
}

Essa função retornará TRUE se conseguir criar todos os objetos, ou retornará FALSE se ocorrer um erro na criação de um objeto. O legal é que o indicador exibirá na aba EXPERT do seu console o código do erro e a linha do código onde ocorreu.

Precisamos também atualizar o indicador de tendência para cada novo tick que recebemos. Isso é feito chamando DisplayTrend() na nossa função start().

//+------------------------------------------------------------------+
//| Função de iteração do indicador customizado                              |
//+------------------------------------------------------------------+
int   start()
{
   // Exibir a tendência atual para todos os tempos
   DisplayTrend();   

   return(0);
}

Por último, destruímos todos os objetos criados pelo indicador quando fechamos o indicador.

//+------------------------------------------------------------------+
//| Função de desinicialização                                        |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Deletar os objetos do indicador
   if(ObjectFind(TrendPanel) >= 0) ObjectDelete(TrendPanel);
   if(ObjectFind(InfoLine1) >= 0) ObjectDelete(InfoLine1);
   if(ObjectFind(InfoLine2) >= 0) ObjectDelete(InfoLine2);
   for(int i=1; i<10; i++)
      if(ObjectFind("Trend"+DoubleToStr(i, 0)) >= 0) ObjectDelete("Trend"+DoubleToStr(i, 0));
}

É basicamente isso. Agora você tem um painel de indicador bacana mostrando a tendência atual para todos os tempos na parte inferior esquerda da sua tela.

Aproveite!


Publicações relacionadas

Comentário (0)