Using RVI to filter/entry tops and bottoms - page 3

 

RVI Extremum detection - indicator for MetaTrader 5

RVI Extremum detection - indicator for MetaTrader 5

The idea of the indicator was born when developing an advisor based on iRVI (Relative Vigor Index, RVI) - the advisor was looking for indicator extremes. And I wanted to somehow visualize the moments of finding the extrema - there was an idea that tops are different - with a sharp inflection or smoother. In general, this is how the indicator was born.

[Deleted]  

I made EA code based on OP condition and backtested. performance is bad. i added extra MA filter to improve it. 


//+------------------------------------------------------------------+
//|                  RVI 13 + Shifted RVI EA                         |
//+------------------------------------------------------------------+
#property strict

extern int     RVI_Period      = 13;
extern int     RVI_Shift       = 13;

// ---------------- ENTRY MODE ----------------
extern int     EntryMode       = 1;     // 1 = Set A, 2 = Set B

// ---------------- STOP LOSS TYPE ----------------
extern int     SL_Mode         = 1;     // 1 = Fractal SL, 2 = Fixed SL
extern double  FixedSL_Pips    = 30;

// ---------------- TAKE PROFIT TYPE ----------------
extern int     TP_Mode         = 1;     // 1=Opp RVI Cross, 2=Fixed, 3=None, 4=RR
extern double  FixedTP_Pips    = 50;
extern double  RR_Ratio        = 2.0;

// ---------------- MA FILTER ----------------
extern bool    UseMAFilter     = false;
extern int     MA_Period       = 200;
extern int     MA_Shift        = 0;

//+------------------------------------------------------------------+
double RVI(int mode, int shift)
{
   return iRVI(_Symbol, _Period, RVI_Period, mode, shift);
}

bool IsUpSlope(double v1, double v2){ return v1 > v2; }
bool IsDnSlope(double v1, double v2){ return v1 < v2; }

//+------------------------------------------------------------------+
bool MA_Filter_BUY()
{
   if(!UseMAFilter) return true;
   double ma = iMA(_Symbol, _Period, MA_Period, MA_Shift, MODE_SMA, PRICE_CLOSE, 0);
   return Close[0] > ma;
}

bool MA_Filter_SELL()
{
   if(!UseMAFilter) return true;
   double ma = iMA(_Symbol, _Period, MA_Period, MA_Shift, MODE_SMA, PRICE_CLOSE, 0);
   return Close[0] < ma;
}

//+------------------------------------------------------------------+
// CHECK FIRST CLASS BUY (Set A)
bool FirstClassBUY()
{
   double rvi_now      = RVI(MODE_MAIN,0);
   double rvi_prev     = RVI(MODE_MAIN,1);
   double sig_now      = RVI(MODE_SIGNAL,0);
   double sig_prev     = RVI(MODE_SIGNAL,1);

   if(!(rvi_prev < sig_prev && rvi_now > sig_now)) return false;

   double rvi_shift    = RVI(MODE_MAIN, RVI_Shift);
   double rvi_shift1   = RVI(MODE_MAIN, RVI_Shift+1);

   if(rvi_shift <= 0) return false;
   if(!IsUpSlope(rvi_shift, rvi_shift1)) return false;

   return true;
}

// CHECK FIRST CLASS SELL (Set A)
bool FirstClassSELL()
{
   double rvi_now      = RVI(MODE_MAIN,0);
   double rvi_prev     = RVI(MODE_MAIN,1);
   double sig_now      = RVI(MODE_SIGNAL,0);
   double sig_prev     = RVI(MODE_SIGNAL,1);

   if(!(rvi_prev > sig_prev && rvi_now < sig_now)) return false;

   double rvi_shift    = RVI(MODE_MAIN, RVI_Shift);
   double rvi_shift1   = RVI(MODE_MAIN, RVI_Shift+1);

   if(rvi_shift >= 0) return false;
   if(!IsDnSlope(rvi_shift, rvi_shift1)) return false;

   return true;
}

//+------------------------------------------------------------------+
// CHECK SECOND CLASS BUY (Set B)
bool SecondClassBUY()
{
   double rvi_now      = RVI(MODE_MAIN,0);
   double rvi_prev     = RVI(MODE_MAIN,1);
   double sig_now      = RVI(MODE_SIGNAL,0);
   double sig_prev     = RVI(MODE_SIGNAL,1);

   if(!(rvi_prev < sig_prev && rvi_now > sig_now)) return false;

   double rvi_shift    = RVI(MODE_MAIN, RVI_Shift);

   return (rvi_shift > 0);
}

bool SecondClassSELL()
{
   double rvi_now      = RVI(MODE_MAIN,0);
   double rvi_prev     = RVI(MODE_MAIN,1);
   double sig_now      = RVI(MODE_SIGNAL,0);
   double sig_prev     = RVI(MODE_SIGNAL,1);

   if(!(rvi_prev > sig_prev && rvi_now < sig_now)) return false;

   double rvi_shift    = RVI(MODE_MAIN, RVI_Shift);

   return (rvi_shift < 0);
}

//+------------------------------------------------------------------+
double GetFractalSL(int type)
{
   int shift = type==OP_BUY ? iLowest(NULL,0,MODE_LOW,5,1) 
                            : iHighest(NULL,0,MODE_HIGH,5,1);
   return type==OP_BUY ? Low[shift] : High[shift];
}

double PipToPrice(double p)
{
   return p * Point;
}

// EXIT BASED ON OPPOSITE RVI CROSS
bool ExitBUY_OnRVICross()
{
   double rvi = RVI(MODE_MAIN,0), rvi1 = RVI(MODE_MAIN,1);
   double sig = RVI(MODE_SIGNAL,0), sig1= RVI(MODE_SIGNAL,1);
   return (rvi1 > sig1 && rvi < sig);
}

bool ExitSELL_OnRVICross()
{
   double rvi = RVI(MODE_MAIN,0), rvi1 = RVI(MODE_MAIN,1);
   double sig = RVI(MODE_SIGNAL,0), sig1= RVI(MODE_SIGNAL,1);
   return (rvi1 < sig1 && rvi > sig);
}

//+------------------------------------------------------------------+
void OnTick()
{
   if(OrdersTotal()==0)
   {
      bool buy=false, sell=false;

      if(EntryMode==1) // Set A
      {
         buy  = FirstClassBUY();
         sell = FirstClassSELL();
      }
      else // Set B
      {
         buy  = SecondClassBUY();
         sell = SecondClassSELL();
      }

      if(buy && MA_Filter_BUY())
      {
         double sl,tp;

         if(SL_Mode==1) sl = GetFractalSL(OP_BUY);
         else sl = Bid - PipToPrice(FixedSL_Pips);

         if(TP_Mode==2) tp = Bid + PipToPrice(FixedTP_Pips);
         else if(TP_Mode==4) tp = Bid + (MathAbs(Bid - sl) * RR_Ratio);
         else tp = 0;

         OrderSend(_Symbol,OP_BUY,0.1,Ask,3,sl,tp,"RVI BUY",0,0,clrGreen);
      }

      if(sell && MA_Filter_SELL())
      {
         double sl,tp;

         if(SL_Mode==1) sl = GetFractalSL(OP_SELL);
         else sl = Ask + PipToPrice(FixedSL_Pips);

         if(TP_Mode==2) tp = Ask - PipToPrice(FixedTP_Pips);
         else if(TP_Mode==4) tp = Ask - (MathAbs(Ask - sl) * RR_Ratio);
         else tp = 0;

         OrderSend(_Symbol,OP_SELL,0.1,Bid,3,sl,tp,"RVI SELL",0,0,clrRed);
      }
   }
   else
   {
      // Manage open trades
      for(int i=OrdersTotal()-1;i>=0;i--)
      {
         if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;

         if(OrderType()==OP_BUY)
         {
            if(TP_Mode==1 && ExitBUY_OnRVICross())
               OrderClose(OrderTicket(),OrderLots(),Bid,3,clrBlue);
         }

         if(OrderType()==OP_SELL)
         {
            if(TP_Mode==1 && ExitSELL_OnRVICross())
               OrderClose(OrderTicket(),OrderLots(),Ask,3,clrBlue);
         }
      }
   }
}
//+------------------------------------------------------------------+