Indicators: Reversal - page 2

 
Christian:

Breeding and order prevail here! :-)

...that was buttery soft with pre-Christmas charm ..at least I thought so

;)
 

I took this Indi and reprogrammed it.

Distilled from 286 confusing lines to only 151 clear lines, and can also do more.

Now it is a very simple indicator that has a lot of potential in conjunction with, for example, an EMA 50 (Steven Primo's buy/sell line) and a suitable exit.

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

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2

//+------------------------------------------------------------------+
//| input parameters|
//+------------------------------------------------------------------+
input int   inp_PeriodBack    =      10;  // Periods lookback
input int   inp_ArrowCodeDN   =     242;  // ArrowCode sell
input int   inp_ArrowCodeUP   =     241;  // ArrowCode buy
input color inp_ArrowColorDN  =  clrRed;  // ArrowColor sell
input color inp_ArrowColorUP  = clrLime;  // ArrowColor buy
input int   inp_ArrowSize     =       3;  // ArrowSize
input int   inp_ArrowOffs     =      30;  // ArrowOffset
input bool  inp_DrawRange     =    true;  // Draw the checked range
input bool  inp_SendMail      =   false;  // Send mail on signal

//+------------------------------------------------------------------+
//| indicator buffers|
//+------------------------------------------------------------------+
double buDN[];    // buffer Arrows down
double buUP[];    // buffer Arrows up

//+------------------------------------------------------------------+
//| Custom indicator initialisation function |
//+------------------------------------------------------------------+
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);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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; //with some old rates to prevent "Array out of range" or slow calculation

                                                      //Arrows down
         if(high[1+i]==HH(high,inp_PeriodBack))       //Candlestick High is equal to Resistance
            if(close[1+i]<open[1+i])                  //Candlestick Close < Candlestick Open (bearish bar)
               {
                  buDN[i]=high[i];                    //Set indicator value at Candlestick High
                  if(i==1) 
                     myAlert(time[1],"Sell");         //Alert on next bar open
               }
                                                      //Arrows up
         if(low[1+i]==LL(low,inp_PeriodBack))         //Candlestick Low is equal to Support
            if(close[1+i]>open[1+i])                  //Candlestick Close > Candlestick Open (bullish bar)
               {
                  buUP[i]=low[i];                     //Set indicator value at Candlestick Low
                  if(i==1) 
                     myAlert(time[1],"Buy");          //Alert on next bar open
               }
      }

   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)    // Alert function
{
   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)            // cuts of leading 'PERIOD_' / returns 'M1', 'M10', .... 
{
   return(StringSubstr(EnumToString(_tf),7));
}

//+------------------------------------------------------------------+
double HH(const double &aBuffer[], int aPeriBack)     // highest high of a period backwards
{
   return(aBuffer[ArrayMaximum(aBuffer,0,aPeriBack)]);
}

double LL(const double &aBuffer[], int aPeriBack)     // lowest low of a period backwards
{
   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++;
}

This indicator is a good candidate for my homepage, which will go online at the beginning of next year.

Files:
 
Otto Pauser:

I took this Indi and reprogrammed it.

Distilled down from 286 confusing lines to just 151 clear lines, and can do more.

Now it is a very simple indicator which, in conjunction with an EMA 50 (Steven Primo's buy/sell line) and a suitable exit, for example, definitely has potential.

This indicator is a good candidate for my homepage, which will go online at the beginning of next year.

Super nice of you! I tried it out straight away and it works perfectly. Thank you very much!

 
not working
 
does not work
 
there are errors on compilation in meta editor. please fix if possible. thank you for the free offer of such a potentially great indicator concept
 
Joseph Kisakye #:
there are errors on compilation in meta editor. please fix if possible. thank you for the free offer of such a potentially great indicator concept

this is code modified for no error..  


//+------------------------------------------------------------------+
//|                                          Indicator: reversal.mq5 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Sergey Vradiy"
#property version   "1.00"
#property description ""

//--- indicator settings
#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"

//--- indicator buffers
double Buffer1[];
double Buffer2[];

input int Interval=10;
datetime time_alert;     //used when sending alert
input bool Send_Email=true;
double myPoint; //initialized in 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) //creates or modifies existing object if necessary
{
   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); //closest time hh:mm
      if(dt>start_time)
         dt-=86400; //go 24 hours back
      int dt_index = iBarShift(Symbol(), Period(), dt, true);
      datetime dt2 = dt;
      while(dt_index<0 && dt>Time[Bars(Symbol(),Period())-1-count]) //bar not found => look a few days back
      {
         dt-=86400; //go 24 hours back
         dt_index=iBarShift(Symbol(),Period(),dt,true);
      }
      if(dt_index<0) //still not found => find nearest bar
         dt_index =iBarShift(Symbol(), Period(), dt2, false);
      start_index=dt_index+1; //bar after S/R opens at 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); //closest time hh:mm
      if(dt>start_time)
         dt-=86400; //go 24 hours back
      int dt_index = iBarShift(Symbol(), Period(), dt, true);
      datetime dt2 = dt;
      while(dt_index<0 && dt>Time[Bars(Symbol(),Period())-1-count]) //bar not found => look a few days back
      {
         dt-=86400; //go 24 hours back
         dt_index=iBarShift(Symbol(),Period(),dt,true);
      }
      if(dt_index<0) //still not found => find nearest bar
         dt_index =iBarShift(Symbol(), Period(), dt2, false);
      start_index=dt_index+1; //bar after S/R opens at 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);
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
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);

   //initialize myPoint
   myPoint=Point();
   if(Digits()==5 || Digits()==3)
   {
      myPoint*=10;
   }
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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);

//--- counting from 0 to rates_total
   ArraySetAsSeries(Buffer1,true);
   ArraySetAsSeries(Buffer2,true);

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

   //--- main loop
   for(int i=limit-1; i>=0; i--)
   {
      if(i>=MathMin(5000-1,rates_total-1-50)) continue; //omit old rates

      //Indicator Buffer 1 (Sell)
      if(high[i]==Resistance(Interval*PeriodSeconds(),false,00,00,false,i)
         && close[i]<open[i]) //Condition for Sell
      {
         Buffer1[i]=high[i]; //Set indicator value at Candlestick High
         if(i==1 && time[1]!=time_alert)
            myAlert("indicator","Sell"); //Alert on next bar open
         time_alert=time[1];
      }
      else
      {
         Buffer1[i]=0;
      }

      //Indicator Buffer 2 (Buy)
      if(low[i]==Support(Interval*PeriodSeconds(),false,00,00,false,i)
         && close[i]>open[i]) //Condition for Buy
      {
         Buffer2[i]=low[i]; //Set indicator value at Candlestick Low
         if(i==1 && time[1]!=time_alert)
            myAlert("indicator","Buy"); //Alert on next bar open
         time_alert=time[1];
      }
      else
      {
         Buffer2[i]=0;
      }
   }
   return(rates_total);
}
//+------------------------------------------------------------------+



 
bitcoin razak #:

this is code modified for no error..  




Thank you Razak, the updated code has successfully compiled. Let me test it and see whether it functions as explained in your introduction.

I have backtested the indicator using the default settings but don't see any buy and sell arrows on the chart. Please review the code if this error is confirmed. Thank you