Nikolay, qual de suas criações tem o menor atraso e o menor número de sinais falsos (se, é claro, isso puder ser determinado)?
Nikolay, qual de suas criações tem o menor atraso e o menor número de sinais falsos (se, é claro, isso puder ser determinado).
Portanto, esse não é meu estilo de programação.
Você não consegue ver a floresta pelas árvores = você não consegue ver o código por todos os comentários.
Além disso, o parâmetro de entrada "shift" não é usado de forma alguma.
Reprogramei isso em meu estilo, talvez os "superprogramadores" possam tirar uma folha do meu livro.
//+------------------------------------------------------------------+ //|Supertendência.mq5 //| Código original encontrado em https://www.mql5.com/pt/code/527 //| Código original de Jason Robinson, reescrito por Nikolay Kositsin //| Aprimorado pelo engenheiro Otto Pauser, conhecido como Kronenchakra //+------------------------------------------------------------------+ //--- inckudes #include <Utils.mqh> //--- propriedades gerais #property copyright COPY #property link LINK #property version "1.00" //--- propriedades do indicador #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 4 //--- parâmetros de entrada input int CCIPeriod = 50; // Período do indicador CCI input int ATRPeriod = 5; // Período do indicador ATR input int Level = 0; // Nível de ativação da CCI //---- buffers de indicadores double ATR[], CCI[]; double TrendUp[], TrendDn[]; double SignUp[], SignDn[]; //---- variáveis globais int min_rates_total; int ATR_Handle, CCI_Handle; //+------------------------------------------------------------------+ //| Função de inicialização do indicador personalizado //+------------------------------------------------------------------+ int OnInit() { min_rates_total=MathMax(CCIPeriod,ATRPeriod); CCI_Handle=iCCI(NULL,0,CCIPeriod,PRICE_TYPICAL); if(InvalidHandle(CCI_Handle,"iCCI")) return(INIT_FAILED); ATR_Handle=iATR(NULL,0,ATRPeriod); if(InvalidHandle(ATR_Handle,"iATR")) return(INIT_FAILED); string shortname=IndiShortName("Supertrend",CCIPeriod,ATRPeriod); IndicatorSetString(INDICATOR_SHORTNAME,shortname); IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1); InitBuffer(TrendUp,DRAW_LINE ,"Supertrend Up" ,clrLime,min_rates_total,0 ,2,true); InitBuffer(TrendDn,DRAW_LINE ,"Supertrend Down" ,clrRed ,min_rates_total,0 ,2,true); InitBuffer(SignUp ,DRAW_ARROW,"Supertrend signal Buy" ,clrLime,min_rates_total,108,1,true); InitBuffer(SignDn ,DRAW_ARROW,"Supertrend signal Sell",clrRed ,min_rates_total,108,1,true); ArraySetAsSeries(ATR,true); ArraySetAsSeries(CCI,true); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 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[]) { if // verificar ( BarsCalculated(CCI_Handle)<rates_total || // verificar o indicador CCI BarsCalculated(ATR_Handle)<rates_total || // verificar o indicador ATR rates_total<min_rates_total // verificar se há barras suficientes ) return(0); // tente o próximo tique int limit,to_copy,bar; ArraySetAsSeries(high,true); // precisa ser definido como AsSeries a cada tick ArraySetAsSeries(low ,true); if(prev_calculated>rates_total || prev_calculated<=0) // verificação do primeiro início do cálculo do indicador limit=rates_total-min_rates_total; // índice inicial para o cálculo de todas as barras else limit=rates_total-prev_calculated; // índice inicial para o cálculo de novas barras to_copy=limit+1; // copiar dados ATR para o buffer if(CopyBuffer(ATR_Handle,0,0,to_copy,ATR)<=0) return(0); to_copy++; // copiar dados da CCI para o buffer if(CopyBuffer(CCI_Handle,0,0,to_copy,CCI)<=0) return(0); for(bar=limit; bar>=0; bar--) // loop principal de cálculo { TrendUp[bar]=NULL; // limpar todos os buffers TrendDn[bar]=NULL; SignUp [bar]=NULL; SignDn [bar]=NULL; // calcular as linhas if(CCI[bar]>=Level && CCI[bar+1]<Level) TrendUp[bar]=TrendDn[bar+1]; if(CCI[bar]<=Level && CCI[bar+1]>Level) TrendDn[bar]=TrendUp[bar+1]; if(CCI[bar]>Level) { TrendUp[bar]=low[bar]-ATR[bar]; if(TrendUp[bar]<TrendUp[bar+1] && CCI[bar+1]>=Level) TrendUp[bar]=TrendUp[bar+1]; } if(CCI[bar]<Level) { TrendDn[bar]=high[bar]+ATR[bar]; if(TrendDn[bar]>TrendDn[bar+1] && CCI[bar+1]<=Level) TrendDn[bar]=TrendDn[bar+1]; } if(TrendDn[bar+1]!=0.0 && TrendUp[bar]!=0.0) SignUp[bar]=TrendUp[bar]; // verificar o sinal UP if(TrendUp[bar+1]!=0.0 && TrendDn[bar]!=0.0) SignDn[bar]=TrendDn[bar]; // verificar sinal DOWN } return(rates_total); }
//+------------------------------------------------------------------+ //|Utils.mqh //| Copyright © 2018, Ing. Otto Pauser //| https://www.mql5.com/pt/users/kronenchakra | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| definições| //+------------------------------------------------------------------+ #define COPY "Copyright © 2018, Ing. Otto Pauser" #define LINK "https://www.mql5.com/pt/users/kronenchakra" #define SPACER "---------------------" //+------------------------------------------------------------------+ //| abreviações| //+------------------------------------------------------------------+ #define PRICE ENUM_APPLIED_PRICE #define TIMEF ENUM_TIMEFRAMES //+------------------------------------------------------------------+ //| Funções auxiliares| //+------------------------------------------------------------------+ void InitBuffer(double &_buffer[], ENUM_DRAW_TYPE _type, string _label, color _color, int _begin, int _arrow=159, int _width=1, bool _series=false) { static int idx=0; // inicializar o bufferindex em 0 SetIndexBuffer (idx,_buffer); // inicializar o buffer ArrayInitialize (_buffer ,NULL); // inicializar o buffer ArraySetAsSeries (_buffer ,_series); // definir AsSeries // definir propriedades PlotIndexSetInteger(idx,PLOT_DRAW_TYPE ,_type ); PlotIndexSetInteger(idx,PLOT_LINE_COLOR ,_color); PlotIndexSetInteger(idx,PLOT_LINE_WIDTH ,_width); PlotIndexSetInteger(idx,PLOT_DRAW_BEGIN ,_begin); PlotIndexSetInteger(idx,PLOT_ARROW ,_arrow); PlotIndexSetString (idx,PLOT_LABEL ,_label); PlotIndexSetDouble (idx,PLOT_EMPTY_VALUE,NULL ); idx++; // incrementar o bufferindex para a próxima chamada } bool InvalidHandle(int _handle, string _msg) { if(_handle==INVALID_HANDLE) // verificar a alça Alert("*ERROR* creating "+_msg+" handle."); // informações return(_handle==INVALID_HANDLE); // retorna true se for inválido } string IndiShortName(string _name, int val_1, int val_2=NULL, int val_3=NULL) { string result=_name+"("+IntegerToString(val_1); if(val_2!=NULL) result=result+","+IntegerToString(val_2); if(val_3!=NULL) result=result+","+IntegerToString(val_3); return(result+")"); } //+------------------------------------------------------------------+ //| Funções de cálculo| //+------------------------------------------------------------------+ double StdDeviation(int position,const double &price[],const double &MAprice[],int period) { int i; double StdDev_dTmp=0.0; if(position<period) return(StdDev_dTmp); // verificar a posição for(i=0;i<period;i++) // calcular o StdDev StdDev_dTmp+=MathPow(price[position-i]-MAprice[position],2); StdDev_dTmp=MathSqrt(StdDev_dTmp/period); return(StdDev_dTmp); // retorna o valor calculado }
Parece bem claro logo de cara.
Talvez o MetaQutes também possa aprender algo, por exemplo, como definir buffers de plotagem em apenas uma linha.
Otto,
isso:
TrendUp[bar]=NULL; // limpar todos os buffers TrendDn[bar]=NULL; SignUp [bar]=NULL; SignDn [bar]=NULL;
é perigoso. NULL é do tipo'void'. Algum tempo depois, para tornar o MT5 ainda mais rápido, talvez nada pudesse ser realmente atribuído (então o antigo permaneceria) ou um valor aleatório seria criado quando o local da memória fosse alterado.
Na minha opinião, seria melhor usar _symbol para o símbolo e EMPTY_VALUE ou 0 diretamente para os valores. Dessa forma, você dá um ser ao nada ;)
Como posso obter
Etapa 1: 
Etapa 2: 
Você tem isso para o mt4?
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
SuperTrend:
Este indicador é considerado como de tendência única e o seu princípio de funcionamento é muito simples: assim que indicador muda a sua cor para verde, isto significa que o início de uma tendência de alta, se a cor mudou para vermelho, uma tendência de baixa começa. O indicador tem uma desvantagem - atrasa muitas vezes, no entanto é bastante popular entre os traders. Para melhores resultados, o indicador deve ser usada com uma confirmação para a entrada no mercado.
Autor: Nikolay Kositsin