Indicadores: SuperTrend

 

SuperTrend:

Indicador SuperTrend trend.

Indicador Super Trend

Autor: Nikolay Kositsin

 

Nikolay! ¿Cuál de tus cerebros con menos retardo y menor número de señales falsas (si, por supuesto, esto se puede determinar en absoluto)

 
Makser:

Nikolay! ¿Cuál de sus cerebros tiene el menor retraso y el menor número de señales falsas (si, por supuesto, esto se puede determinar en absoluto).

Aquí hay una pregunta, por lo que la pregunta. Yo uso JFatlSpeed en los cruces, y últimamente en todo lo demás. Pero sólo en los de cuatro horas. Y capto rebotes en operaciones de cinco minutos en X2MA_BBx9.
 

Así que ese no es en absoluto mi estilo de programación.

No se puede ver el bosque por los árboles = no se puede ver el código por todos los comentarios.

Además, el parámetro de entrada 'shift' no se utiliza en absoluto.

He reprogramado esto en mi estilo, tal vez los 'super programadores' pueden tomar una hoja de mi libro.

//+------------------------------------------------------------------+
//|Supertrend.mq5
//| Código original encontrado en https://www.mql5.com/es/code/527 | 
//| Código original de Jason Robinson, reescrito por Nikolay Kositsin.
//| Mejorado por Ing. Otto Pauser alias Kronenchakra |
//+------------------------------------------------------------------+ 

//--- inckudes
#include <Utils.mqh>

//--- propiedades generales
#property copyright COPY 
#property link      LINK 
#property version   "1.00"

//--- propiedades del indicador
#property indicator_chart_window
#property indicator_buffers 4 
#property indicator_plots   4

//--- parámetros de entrada
input int CCIPeriod  =  50;   // Período del indicador CCI 
input int ATRPeriod  =   5;   // Período del indicador ATR
input int Level      =   0;   // Nivel de activación de la CCI

//---- tampones indicadores
double   ATR[],
         CCI[];
double   TrendUp[],
         TrendDn[];
double   SignUp[],
         SignDn[];
         
//---- variables globales
int      min_rates_total;
int      ATR_Handle,
         CCI_Handle;

//+------------------------------------------------------------------+
//| Función de inicialización del indicador personalizada |
//+------------------------------------------------------------------+
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);
}

//+------------------------------------------------------------------+
//| Función de iteración del indicador personalizada |
//+------------------------------------------------------------------+
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                                                    // comprobar
      (
          BarsCalculated(CCI_Handle)<rates_total ||      // comprobar indicador CCI
          BarsCalculated(ATR_Handle)<rates_total ||      // comprobar indicador ATR
          rates_total<min_rates_total                    // comprobar si hay suficientes barras
      )
          return(0);                                     // intenta el siguiente tick

   int limit,to_copy,bar;

   ArraySetAsSeries(high,true);                          // debe establecerse AsSeries en cada tick
   ArraySetAsSeries(low ,true);

   if(prev_calculated>rates_total || prev_calculated<=0) // comprobación del primer inicio del cálculo del indicador
      limit=rates_total-min_rates_total;                 // índice inicial para el cálculo de todas las barras
   else
      limit=rates_total-prev_calculated;                 // índice inicial para el cálculo de nuevas barras

   to_copy=limit+1;                                      // copia los datos ATR en el búfer
   if(CopyBuffer(ATR_Handle,0,0,to_copy,ATR)<=0) return(0);

   to_copy++;                                            // copiar CCI-Data al buffer
   if(CopyBuffer(CCI_Handle,0,0,to_copy,CCI)<=0) return(0);

   for(bar=limit; bar>=0; bar--)                         // cálculo bucle principal
     {
      TrendUp[bar]=NULL;                                 // borrar todos los buffers
      TrendDn[bar]=NULL;
      SignUp [bar]=NULL;
      SignDn [bar]=NULL;
                                                         // calcular las líneas
      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];  // comprobar señal UP
      if(TrendUp[bar+1]!=0.0 && TrendDn[bar]!=0.0) SignDn[bar]=TrendDn[bar];  // comprobar señal DOWN
     }
    
   return(rates_total);
}
//+------------------------------------------------------------------+
//|Utils.mqh
//| Copyright © 2018, Ing. Otto Pauser || 
//| https://www.mql5.com/es/users/kronenchakra | 
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| definiciones|
//+------------------------------------------------------------------+

#define  COPY   "Copyright © 2018, Ing. Otto Pauser"
#define  LINK   "https://www.mql5.com/es/users/kronenchakra"
#define  SPACER "---------------------" 

//+------------------------------------------------------------------+
//| abreviaturas|
//+------------------------------------------------------------------+

#define  PRICE ENUM_APPLIED_PRICE
#define  TIMEF ENUM_TIMEFRAMES

//+------------------------------------------------------------------+
//| Funciones 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 bufferindex a 0
   SetIndexBuffer     (idx,_buffer);                  // inicializar el búfer
   ArrayInitialize    (_buffer ,NULL);                // inicializar el búfer
   ArraySetAsSeries   (_buffer ,_series);             // set AsSeries
                                                      // establecer propiedades
   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 bufferindex para la siguiente llamada
}

bool InvalidHandle(int _handle, string _msg)
{
   if(_handle==INVALID_HANDLE)                     // comprobar asa
      Alert("*ERROR* creating "+_msg+" handle.");  // info
   return(_handle==INVALID_HANDLE);                // devolver true si no es vá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+")");
}

//+------------------------------------------------------------------+
//| Funciones 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);        // comprobar posición

   for(i=0;i<period;i++)                           // calcualte StdDev
      StdDev_dTmp+=MathPow(price[position-i]-MAprice[position],2);

   StdDev_dTmp=MathSqrt(StdDev_dTmp/period);

   return(StdDev_dTmp);                            // devolver el valor calculado
}

Se ve bastante claro de inmediato.

Tal vez MetaQutes también podría aprender algo, por ejemplo, cómo definir buffers de trazado en una sola línea.

Archivos adjuntos:
supertrend.mq5  11 kb
Utils.mqh  7 kb
 

Otto,

eso

      TrendUp[bar]=NULL;                                 // borrar todos los buffers
      TrendDn[bar]=NULL;
      SignUp [bar]=NULL;
      SignDn [bar]=NULL;

es peligroso. NULL es de tipo'void'. Mas adelante, para hacer MT5 aun mas rapido, quizas no se podria asignar nada (entonces se quedaria lo antiguo) o se crearia un valor aleatorio cuando cambie la posicion de memoria.

Imho sería mejor utilizar _symbol para el símbolo y EMPTY_VALUE o 0 directamente para los valores. De esa manera le das a la nada un ser ;)

 
¿Cómo puedo conseguir
 
Quiero utilizar este indicador
 
ka03ht8096:
¿Cómo puedo conseguirlo?

Paso 1:

Paso 2:

 
¿Qué entrada es Multiplicador y valor ATR?
 

¿tiene esto para mt4