Indicadores: AutoTrendLines - página 2

 
Show!
 
O Autotrendlines é um dos melhores indicadores gratuitos. Muito obrigado ao criador desse indicador. Mas ele tem um grande problema! Ele remove qualquer linha de tendência que o próprio usuário desenha. Estou esperando há muito tempo pela correção desse problema. Portanto, ficarei muito grato se esse problema for resolvido na nova atualização.
 
O Autotrendlines é um dos melhores indicadores gratuitos. Muito obrigado ao criador desse indicador. Mas ele tem um grande problema! Ele remove qualquer linha de tendência que o próprio usuário desenha. Estou esperando há muito tempo pela correção desse problema. Portanto, ficarei muito grato se esse problema for resolvido na nova atualização.
 
Aqui está a análise que exclui apenas a linha criada pelo indicador e deixa outra tendência no gráfico //+------------------------------------------------------------------+ //| AutoTrendLines.mq5 | //| Copyright 2012, Rone. | //| rone.sergey@gmail.com | //+------------------------------------------------------------------+ // https://www.mql5.com/pt/code/1220 //+------------------------------------------------------------------+ //| Linhas de tendência automáticas. | //| Tipo 1. Com dois extremos. | //| 1) A partir da barra atual, "vá" para a esquerda e procure o primeiro ponto extremo (direito) com as barras InpRightExmSide em ambos os lados. | //| 2) A partir do primeiro ponto, novamente "vá" para a esquerda e procure o segundo ponto extremo (esquerdo) com as barras InpLeftExmSide em ambos os lados. | 3) Desenhe uma linha de tendência. | //| | //| Tipo 2. Com extremum e delta. | 1) A partir da barra atual, "vá" para a esquerda e procure o segundo ponto extremo (esquerdo) com as barras InpLeftExmSide em ambos os lados. 2) Começando com a barra InpFromCurrent da barra atual e até o segundo ponto extremo, encontre a barra com o delta mínimo. | //| 3) Desenhe uma linha de tendência. | //| | //| OBSERVAÇÃO: | //| 1) As linhas são recalculadas somente quando uma nova barra aparece | //| 2) A barra atual não formada não é incluída nos cálculos| //| 3) O extremo significa uma barra, para a qual as barras esquerda e direita | //| N têm mínimos acima e máximos abaixo. | //+------------------------------------------------------------------+ #property copyright "Copyright 2012, Rone." #property link "rone.sergey@gmail.com" #property version "1.00" #property description "Automatic trend lines" //--- #property indicator_chart_window //--- string prefisso="AUTO_TRND"; enum ENUM_LINE_TYPE { EXM_EXM, // 1: Por 2 extremos EXM_DELTA // 2: Extremo e delta }; //+------------------------------------------------------------------+ //| Class CPoint | //+------------------------------------------------------------------+ class CPoint { private: double price; datetime time; public: CPoint(); CPoint(const double p, const datetime t); ~CPoint() {}; void setPoint(const double p, const datetime t); bool operator==(const CPoint &other) const; bool operator!=(const CPoint &other) const; void operator=(const CPoint &other); double getPrice() const; datetime getTime() const; }; //--- CPoint::CPoint(void) { price = 0; time = 0; } //--- CPoint::CPoint(const double p, const datetime t) { price = p; time = t; } //--- void CPoint::setPoint(const double p, const datetime t) { price = p; time = t; } //--- bool CPoint::operator==(const CPoint &other) const { return price == other.price && time == other.time; } //--- bool CPoint::operator!=(const CPoint &other) const { return !operator==(other); } //--- void CPoint::operator=(const CPoint &other) { price = other.price; time = other.time; } //--- double CPoint::getPrice(void) const { return(price); } //--- datetime CPoint::getTime(void) const { return(time); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CPoint curLeftSup, curRightSup, curLeftRes, curRightRes, nullPoint; //+------------------------------------------------------------------+ //| parâmetros de entrada | //+------------------------------------------------------------------+ input ENUM_LINE_TYPE InpLineType = EXM_DELTA;// Tipo de linha input int InpLeftExmSide = 10; // Lado extremo esquerdo (Tipo 1, 2) input int InpRightExmSide = 3; // Lado extremo direito (Tipo 1) input int InpFromCurrent = 3; // Deslocamento da barra atual (Tipo 2) input bool InpPrevExmBar = false; // Considera a barra antes do extremo (Tipo 2) //--- input int InpLinesWidth = 2; // largura das linhas input color InpSupColor = clrRed; // cor da linha de suporte input color InpResColor = clrBlue; // cor da linha de resistência //--- variáveis globais int minRequiredBars; //+------------------------------------------------------------------+ //| Função de inicialização do indicador personalizado | //+------------------------------------------------------------------+ int OnInit() { //--- minRequiredBars = InpLeftExmSide * 2 + MathMax(InpRightExmSide, InpFromCurrent) * 2; //--- mapeamento de buffers de indicador //--- return(0); } //+------------------------------------------------------------------+ //| Função de desinicialização de indicador personalizado | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- int obj_total = ObjectsTotal(0,0); for(int i=obj_total -1; i>=0; i--) { string name= ObjectName(0,i); if(StringFind(name,prefisso,0) == 0) ObjectDelete(0, name); } //--- } //+------------------------------------------------------------------+ //| Função de iteração de indicador personalizado | //+------------------------------------------------------------------+ 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[]) { //--- int leftIndex, rightIndex; double delta, tmpDelta; //--- if ( rates_total < minRequiredBars ) { Print("Not enough data to calculate"); return(0); } //--- if ( prev_calculated != rates_total ) { switch ( InpLineType ) { case EXM_DELTA: //--- Support Left Point leftIndex = rates_total - InpLeftExmSide - 2; for ( ; !isLowestLow(leftIndex, InpLeftExmSide, low) && leftIndex > minRequiredBars; leftIndex-- ); curLeftSup.setPoint(low[leftIndex], time[leftIndex]); //--- Ponto de apoio direito rightIndex = rates_total - InpFromCurrent - 2; delta = (low[rightIndex] - low[leftIndex]) / (rightIndex - leftIndex); if ( !InpPrevExmBar ) { leftIndex += 1; } for ( int tmpIndex = rightIndex - 1; tmpIndex > leftIndex; tmpIndex-- ) { tmpDelta = (low[tmpIndex] - curLeftSup.getPrice()) / (tmpIndex - leftIndex); if ( tmpDelta < delta ) { delta = tmpDelta; rightIndex = tmpIndex; } } curRightSup.setPoint(low[rightIndex], time[rightIndex]); //--- Ponto esquerdo de resistência leftIndex = rates_total - InpLeftExmSide - 2; for ( ; !isHighestHigh(leftIndex, InpLeftExmSide, high) && leftIndex > minRequiredBars; leftIndex-- ); curLeftRes.setPoint(high[leftIndex], time[leftIndex]); //--- Ponto direito de resistência rightIndex = rates_total - InpFromCurrent - 2; delta = (high[leftIndex] - high[rightIndex]) / (rightIndex - leftIndex); if ( !InpPrevExmBar ) { leftIndex += 1; } for ( int tmpIndex = rightIndex - 1; tmpIndex > leftIndex; tmpIndex-- ) { tmpDelta = (curLeftRes.getPrice() - high[tmpIndex]) / (tmpIndex - leftIndex); if ( tmpDelta < delta ) { delta = tmpDelta; rightIndex = tmpIndex; } } curRightRes.setPoint(high[rightIndex], time[rightIndex]); //--- break; case EXM_EXM: default: //--- Ponto de suporte à direita rightIndex = rates_total - InpRightExmSide - 2; for ( ; !isLowestLow(rightIndex, InpRightExmSide, low) && rightIndex > minRequiredBars; rightIndex-- ); curRightSup.setPoint(low[rightIndex], time[rightIndex]); //--- Support Left Point leftIndex = rightIndex - InpRightExmSide; for ( ; !isLowestLow(leftIndex, InpLeftExmSide, low) && leftIndex > minRequiredBars; leftIndex-- ); curLeftSup.setPoint(low[leftIndex], time[leftIndex]); //--- Resistência Ponto direito rightIndex = rates_total - InpRightExmSide - 2; for ( ; !isHighestHigh(rightIndex, InpRightExmSide, high) && rightIndex > minRequiredBars; rightIndex-- ); curRightRes.setPoint(high[rightIndex], time[rightIndex]); //--- Resistência Ponto esquerdo leftIndex = rightIndex - InpRightExmSide; for ( ; !isHighestHigh(leftIndex, InpLeftExmSide, high) && leftIndex > minRequiredBars; leftIndex-- ); curLeftRes.setPoint(high[leftIndex], time[leftIndex]); //--- break; } //--- Desenhe o suporte e a resistência if ( curLeftSup != nullPoint && curRightSup != nullPoint ) { drawLine(prefisso+"Current_Support", curRightSup, curLeftSup, InpSupColor); } if ( curLeftRes != nullPoint && curRightRes != nullPoint ) { drawLine(prefisso+"Current_Resistance", curRightRes, curLeftRes, InpResColor); } } //--- retorne o valor de prev_calculated para a próxima chamada return(rates_total); } //+------------------------------------------------------------------+ //| A função de busca Local Low | //+------------------------------------------------------------------+ bool isLowestLow(int bar, int side, const double &Low[]) { //--- for ( int i = 1; i <= side; i++ ) { if ( Low[bar] > Low[bar-i] || Low[bar] > Low[bar+i] ) { return(false); } //--- return(true); } } //--- return(true); } //+------------------------------------------------------------------+ //| The Local High search function | //+------------------------------------------------------------------+ bool isHighestHigh(int bar, int side, const double &High[]) { //--- for ( int i = 1; i <= side; i++ ) { if ( High[bar] < High[bar-i] || High[bar] < High[bar+i] ) { return(false); } } //--- return(true); } //+------------------------------------------------------------------+ //| Draw trend line function | //+------------------------------------------------------------------+ void drawLine(string name, CPoint &right, CPoint &left, color clr) { //--- ObjectDelete(0, name); //--- ObjectCreate(0, name, OBJ_TREND, 0, right.getTime(), right.getPrice(), left.getTime(), left.getPrice()); ObjectSetInteger(0, name, OBJPROP_WIDTH, InpLinesWidth); ObjectSetInteger(0, name, OBJPROP_COLOR, clr); ObjectSetInteger(0, name, OBJPROP_RAY_LEFT, true); ObjectSetInteger(0, name, OBJPROP_SELECTABLE, true); //--- } //+------------------------------------------------------------------+
 
Um bom código, mas a linha de tendência está se movendo com muita frequência e deveria ter uma inclinação negativa para a tendência de baixa e uma inclinação positiva para a tendência de alta.