Indicadores: Reversal - página 2

 
Christian:

¡Aquí prevalecen la cría y el orden! :-)

... que era suave como la mantequilla con encanto prenavideño ... al menos eso pensé

;)
 

Cogí este Indi y lo reprogramé.

Lo destilé de 286 líneas confusas a sólo 151 líneas claras, y también puede hacer más.

Ahora es un indicador muy simple que tiene mucho potencial en conjunción con, por ejemplo, una EMA 50 (la línea de compra/venta de Steven Primo) y una salida adecuada.

//+------------------------------------------------------------------+
//|Reversal_V2.0.mq5
//| Copyright © 2019, Ing. Otto Pauser |
//| https://www.mql5.com/es/users/kronenchakra |
//| encontrado en https://www.mql5.com/es/code/19605 |
//+------------------------------------------------------------------+
#property copyright     "Copyright © 2019, Ing. Otto Pauser"
#property link          "https://www.mql5.com/es/users/kronenchakra"
#property version       "2.00"

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2

//+------------------------------------------------------------------+
//| parámetros de entrada|
//+------------------------------------------------------------------+
input int   inp_PeriodBack    =      10;  // Períodos lookback
input int   inp_ArrowCodeDN   =     242;  // ArrowCode vender
input int   inp_ArrowCodeUP   =     241;  // ArrowCode comprar
input color inp_ArrowColorDN  =  clrRed;  // ArrowColor vender
input color inp_ArrowColorUP  = clrLime;  // ArrowColor comprar
input int   inp_ArrowSize     =       3;  // ArrowSize
input int   inp_ArrowOffs     =      30;  // ArrowOffset
input bool  inp_DrawRange     =    true;  // Dibujar el rango comprobado
input bool  inp_SendMail      =   false;  // Enviar correo a la señal

//+------------------------------------------------------------------+
//| búferes indicadores|
//+------------------------------------------------------------------+
double buDN[];    // buffer Flechas abajo
double buUP[];    // buffer Flechas arriba

//+------------------------------------------------------------------+
//| Función de inicialización del indicador personalizada |
//+------------------------------------------------------------------+
int OnInit()
{
   InitArrows(buDN,inp_ArrowCodeDN,inp_ArrowColorDN,inp_ArrowSize,-inp_ArrowOffs,"Sell");
   InitArrows(buUP,inp_ArrowCodeUP,inp_ArrowColorUP,inp_ArrowSize,+inp_ArrowOffs,"Buy" );
   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[])
{
   ArraySetAsSeries(high ,true);
   ArraySetAsSeries(close,true);
   ArraySetAsSeries(open ,true);
   ArraySetAsSeries(low  ,true);
   ArraySetAsSeries(time ,true);

   int limit=(prev_calculated==0)?0:rates_total-prev_calculated-1;

   for(int i=limit; i>=0; i--)
      {
         buDN[i]=NULL;
         buUP[i]=NULL;
         
         if(i>=MathMin(5000-1,rates_total-1-50)) continue; //con algunos tipos antiguos para evitar "Array fuera de rango" o cálculos lentos

                                                      //Hacia abajo
         if(high[1+i]==HH(high,inp_PeriodBack))       //Candlestick High es igual a Resistencia
            if(close[1+i]<open[1+i])                  //Candlestick Close < Candlestick Open (barra bajista)
               {
                  buDN[i]=high[i];                    //Establecer el valor del indicador en el Candlestick High
                  if(i==1) 
                     myAlert(time[1],"Sell");         //Alerta en el próximo bar abierto
               }
                                                      //Arriba
         if(low[1+i]==LL(low,inp_PeriodBack))         //Candlestick Low es igual a Soporte
            if(close[1+i]>open[1+i])                  //Candlestick Cierre > Candlestick Apertura (barra alcista)
               {
                  buUP[i]=low[i];                     //Establecer el valor del indicador en el mínimo de la vela
                  if(i==1) 
                     myAlert(time[1],"Buy");          //Alerta en el próximo bar abierto
               }
      }

   if(inp_DrawRange)
      DrawRange("Range",time[inp_PeriodBack],HH(high,inp_PeriodBack),time[0],LL(low,inp_PeriodBack));

   return(rates_total);
}

//+------------------------------------------------------------------+
void myAlert(datetime aTime, string aMsg)    // Función de alerta
{
   static datetime lastTime=NULL;
   if(aTime!=lastTime)
      {
         aMsg="Reversal_V2.9 @ "+_Symbol+","+PeriodShortStr(_Period)+" -> "+aMsg;
         Print(aMsg);
         if(inp_SendMail) 
            SendMail("Reversal_V2.9", aMsg);
         lastTime=aTime;
      }
}

string PeriodShortStr(ENUM_TIMEFRAMES _tf)            // corta el 'PERIOD_' inicial / devuelve 'M1', 'M10', .... 
{
   return(StringSubstr(EnumToString(_tf),7));
}

//+------------------------------------------------------------------+
double HH(const double &aBuffer[], int aPeriBack)     // máximo de un periodo hacia atrás
{
   return(aBuffer[ArrayMaximum(aBuffer,0,aPeriBack)]);
}

double LL(const double &aBuffer[], int aPeriBack)     // mínimo más bajo de un período hacia atrás
{
   return(aBuffer[ArrayMinimum(aBuffer,0,aPeriBack)]);
}

void DrawRange(string aName, datetime aBegin, double aHigh, datetime aEnd, double aLow)
{
   if(ObjectFind   (0,aName)==0) 
      ObjectDelete (0,aName);
   ObjectCreate    (0,aName,OBJ_RECTANGLE,0,aBegin,aHigh,aEnd,aLow);
   ObjectSetInteger(0,aName,OBJPROP_STYLE,STYLE_DASHDOT);
}
//+------------------------------------------------------------------+
//| init indicatorbuffer with arrows|
//+------------------------------------------------------------------+
void InitArrows(double &aBuffer[], int aArrowCode, color aArrowColor, int aArrowSize, int aArrowOffs, string aPlotLabel)
{
   static int idx=0;
   SetIndexBuffer(idx,aBuffer,INDICATOR_DATA);
   PlotIndexSetInteger(idx,PLOT_DRAW_TYPE  ,DRAW_ARROW);
   PlotIndexSetInteger(idx,PLOT_ARROW      ,aArrowCode);
   PlotIndexSetInteger(idx,PLOT_LINE_COLOR ,aArrowColor);
   PlotIndexSetInteger(idx,PLOT_LINE_WIDTH ,aArrowSize);
   PlotIndexSetInteger(idx,PLOT_ARROW_SHIFT,aArrowOffs);
   PlotIndexSetString (idx,PLOT_LABEL      ,aPlotLabel);
   PlotIndexSetDouble (idx,PLOT_EMPTY_VALUE,NULL);
   ArrayInitialize    (aBuffer,NULL);
   ArraySetAsSeries   (aBuffer,true);
   idx++;
}

Este indicador es un buen candidato para mi página web, que estará en línea a principios del próximo año.

Archivos adjuntos:
 
Otto Pauser:

Tomé este Indi y lo reprogramé.

Destilado de 286 líneas confusas a sólo 151 líneas claras, y puede hacer más.

Ahora es un indicador muy simple que, en conjunción con una EMA 50 (línea de compra/venta de Steven Primo) y una salida adecuada, por ejemplo, definitivamente tiene potencial.

Este indicador es un buen candidato para mi página web, que estará en línea a principios del próximo año.

Muy amable. Lo he probado enseguida y funciona perfectamente. Muchas gracias.

 
no funciona
 
no funciona
 
hay errores en la compilación en meta editor. por favor, arreglar si es posible. gracias por la oferta gratuita de tal concepto potencialmente gran indicador
 
Joseph Kisakye #:
hay errores en la compilacion en el editor meta. por favor, arreglar si es posible. gracias por la oferta gratuita de un gran concepto potencial indicador de tales

este es el código modificado para no error..


//+------------------------------------------------------------------+
//|Indicador: inversión.mq5
//||
//||
//+------------------------------------------------------------------+
#property copyright "Sergey Vradiy"
#property version   "1.00"
#property description ""

//--- configuración del indicador
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2

#property indicator_type1 DRAW_ARROW
#property indicator_width1 3
#property indicator_color1 0x0000FF
#property indicator_label1 "Sell"

#property indicator_type2 DRAW_ARROW
#property indicator_width2 3
#property indicator_color2 0xFFAA00
#property indicator_label2 "Buy"

//--- tampones indicadores
double Buffer1[];
double Buffer2[];

input int Interval=10;
datetime time_alert;     //utilizado al enviar la alerta
input bool Send_Email=true;
double myPoint; //inicializado en OnInit

//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
void myAlert(string type,string message)
{
   if(type=="print")
      Print(message);
   else if(type=="error")
   {
      Print(type+" | reversal @ "+Symbol()+","+(string)Period()+" | "+message);
   }
   else if(type=="indicator")
   {
      if(Send_Email)
         SendMail("reversal",type+" | reversal @ "+Symbol()+","+(string)Period()+" | "+message);
   }
}
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
void DrawLine(string objname,double price,int count,int start_index) //crea o modifica el objeto existente si es necesario
{
   if((price<0) && ObjectFind(0,objname)>=0)
   {
      ObjectDelete(0,objname);
   }
   else if(ObjectFind(0,objname)>=0 && ObjectGetInteger(0,objname,OBJPROP_TYPE)==OBJ_TREND)
   {
      datetime Time[];
      ArraySetAsSeries(Time,true);
      CopyTime(Symbol(),Period(),0,start_index+count,Time);
      ObjectSetInteger(0,objname,OBJPROP_TIME,Time[start_index]);
      ObjectSetDouble(0,objname,OBJPROP_PRICE,price);
      ObjectSetInteger(0,objname,OBJPROP_TIME,1,Time[start_index+count-1]);
      ObjectSetDouble(0,objname,OBJPROP_PRICE,1,price);
   }
   else
   {
      datetime Time[];
      ArraySetAsSeries(Time,true);
      CopyTime(Symbol(),Period(),0,start_index+count,Time);
      ObjectCreate(0,objname,OBJ_TREND,0,Time[start_index],price,Time[start_index+count-1],price);
      ObjectSetInteger(0,objname,OBJPROP_RAY_LEFT,0);
      ObjectSetInteger(0,objname,OBJPROP_RAY_RIGHT,0);
      ObjectSetInteger(0,objname,OBJPROP_COLOR,C'0x00,0x00,0xFF');
      ObjectSetInteger(0,objname,OBJPROP_STYLE,STYLE_SOLID);
      ObjectSetInteger(0,objname,OBJPROP_WIDTH,2);
   }
}
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
double Support(int time_interval,bool fixed_tod,int hh,int mm,bool draw,int shift)
{
   int start_index=shift;
   int count=time_interval/PeriodSeconds();
   if(fixed_tod)
   {
      datetime start_time;
      datetime Time[];
      ArraySetAsSeries(Time,true);
      CopyTime(Symbol(),Period(),0,Bars(Symbol(),Period())-count,Time);
      if(shift==0)
         start_time=TimeCurrent();
      else
         start_time=Time[shift-1];
      datetime dt=StringToTime(TimeToString(start_time,TIME_DATE)+" "+(string)hh+":"+(string)mm); //hora más cercana hh:mm
      if(dt>start_time)
         dt-=86400; //vuelve 24 horas atrás
      int dt_index = iBarShift(Symbol(), Period(), dt, true);
      datetime dt2 = dt;
      while(dt_index<0 && dt>Time[Bars(Symbol(),Period())-1-count]) //barra no encontrada => mirar hace unos días
      {
         dt-=86400; //vuelve 24 horas atrás
         dt_index=iBarShift(Symbol(),Period(),dt,true);
      }
      if(dt_index<0) //sigue sin encontrar => buscar el bar más cercano
         dt_index =iBarShift(Symbol(), Period(), dt2, false);
      start_index=dt_index+1; //barra después de que el S/R se abra en dt
   }
   double _Low[];
   ArraySetAsSeries(_Low,true);
   CopyLow(Symbol(),Period(),start_index,count,_Low);
   double ret=_Low[ArrayMinimum(_Low,0,count)];
   if(draw) DrawLine("Support",ret,count,start_index);
   return(ret);
}
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
double Resistance(int time_interval,bool fixed_tod,int hh,int mm,bool draw,int shift)
{
   int start_index=shift;
   int count=time_interval/PeriodSeconds();
   if(fixed_tod)
   {
      datetime start_time;
      datetime Time[];
      ArraySetAsSeries(Time,true);
      CopyTime(Symbol(),Period(),0,Bars(Symbol(),Period())-count,Time);
      if(shift==0)
         start_time=TimeCurrent();
      else
         start_time=Time[shift-1];
      datetime dt=StringToTime(TimeToString(start_time,TIME_DATE)+" "+(string)hh+":"+(string)mm); //hora más cercana hh:mm
      if(dt>start_time)
         dt-=86400; //vuelve 24 horas atrás
      int dt_index = iBarShift(Symbol(), Period(), dt, true);
      datetime dt2 = dt;
      while(dt_index<0 && dt>Time[Bars(Symbol(),Period())-1-count]) //barra no encontrada => mirar hace unos días
      {
         dt-=86400; //vuelve 24 horas atrás
         dt_index=iBarShift(Symbol(),Period(),dt,true);
      }
      if(dt_index<0) //sigue sin encontrar => buscar el bar más cercano
         dt_index =iBarShift(Symbol(), Period(), dt2, false);
      start_index=dt_index+1; //barra después de que el S/R se abra en dt
   }
   double _High[];
   ArraySetAsSeries(_High,true);
   CopyHigh(Symbol(),Period(),start_index,count,_High);
   double ret=_High[ArrayMaximum(_High,0,count)];
   if(draw) DrawLine("Resistance",ret,count,start_index);
   return(ret);
}
//+------------------------------------------------------------------+
//| Función de inicialización del indicador personalizada |
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0,Buffer1);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
   PlotIndexSetInteger(0,PLOT_ARROW,242);
   SetIndexBuffer(1,Buffer2);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);
   PlotIndexSetInteger(1,PLOT_ARROW,241);

   //inicializar miPunto
   myPoint=Point();
   if(Digits()==5 || Digits()==3)
   {
      myPoint*=10;
   }
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Función personalizada de iteración del indicador|
//+------------------------------------------------------------------+
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 limit=rates_total-prev_calculated;
   if(limit<=0) return(rates_total);

//--- contando de 0 a rates_total
   ArraySetAsSeries(Buffer1,true);
   ArraySetAsSeries(Buffer2,true);

   //--- cero inicial
   if(prev_calculated<1)
   {
      ArrayInitialize(Buffer1,0);
      ArrayInitialize(Buffer2,0);
   }
   else
      limit++;

   //--- bucle principal
   for(int i=limit-1; i>=0; i--)
   {
      if(i>=MathMin(5000-1,rates_total-1-50)) continue; //omitir tarifas antiguas

      //Indicador Buffer 1 (Vender)
      if(high[i]==Resistance(Interval*PeriodSeconds(),false,00,00,false,i)
         && close[i]<open[i]) //Condición de venta
      {
         Buffer1[i]=high[i]; //Establecer el valor del indicador en el Candlestick High
         if(i==1 && time[1]!=time_alert)
            myAlert("indicator","Sell"); //Alerta en el próximo bar abierto
         time_alert=time[1];
      }
      else
      {
         Buffer1[i]=0;
      }

      //Indicator Buffer 2 (Comprar)
      if(low[i]==Support(Interval*PeriodSeconds(),false,00,00,false,i)
         && close[i]>open[i]) //Condición de compra
      {
         Buffer2[i]=low[i]; //Establecer el valor del indicador en el mínimo de la vela
         if(i==1 && time[1]!=time_alert)
            myAlert("indicator","Buy"); //Alerta en el próximo bar abierto
         time_alert=time[1];
      }
      else
      {
         Buffer2[i]=0;
      }
   }
   return(rates_total);
}
//+------------------------------------------------------------------+



 
bitcoin razak #:

este es el código modificado para no error..




Gracias Razak, el código actualizado se ha compilado correctamente. Permítanme probarlo y ver si funciona como se explica en su introducción.

He backtested el indicador utilizando la configuración por defecto, pero no veo ninguna flechas de compra y venta en el gráfico. Por favor, revise el código si se confirma este error. Gracias