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)
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).
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.
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 conseguirlo?
Paso 1: 
Paso 2: 
¿tiene esto para mt4
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso
SuperTrend:
Indicador SuperTrend trend.
Autor: Nikolay Kositsin