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.

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 globaisint 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, <:number>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, <:macro>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, <:macro>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 |//+------------------------------------------------------------------+voidOnDeinit(constint 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!

Comentário 0