//+------------------------------------------------------------------+
//|                                                  rsi extreme.mq4 |
//|                                           Author: LordoftheMoney |
//|                                Expert advisor is in the codebase |
//|                                                    (Easiest RSI) |
//+------------------------------------------------------------------+
//+Updated for trends and CCI look-forward 27 Jan.-------------------+

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_width1 1
#property indicator_width2 1
#property indicator_color1 Red
#property indicator_color2 Red

//---- input parameters

extern string t = "--LAGUERRE TREND--";
extern double gamma=0.85;
extern string t0 = "----CCI TREND----";
extern int FastCCI=14;
extern int cciBars=40;

extern string t1 = "--BARS HISTORY--";
extern int    historyBarStandard=10;
extern int    historyBarLag=20;
extern int    startBar=1;

extern string t2 = "--SPAN LEVELS--";
extern double upLevelSpan = 0.45;
extern double downLevelSpan = 0.45;

extern string t3 = "--RSI & MIN & MAX--";
extern int    rsiperiod = 14;
extern double buyFlag = 40.0;
extern double selFlag = 60.0;

double buffy1[];
double buffy2[];
int cb=0;int bar;int cciSearch=0;
int iTrendB=0;int iTrendS=0;

double L0 = 0;
double L1 = 0;
double L2 = 0;
double L3 = 0;
double L0A = 0;
double L1A = 0;
double L2A = 0;
double L3A = 0;
double LRSI = 0;
double CU = 0;
double CD = 0;

double RSI[10000];
double barStd[10];
double barLong[50];
double s14;
double s21;
double v8, v08, v9, v09, v09b, v9b;
double counted_bars;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   int  draw=0;
   SetIndexStyle(0,DRAW_ARROW);
   //SetIndexArrow(0, 108);
   SetIndexArrow(0,233);
   SetIndexStyle(1,DRAW_ARROW);
   //SetIndexArrow(1, 108);
   SetIndexArrow(1,234);
   SetIndexEmptyValue(0,0.0);
   SetIndexLabel(0,"buy");
   SetIndexLabel(1,"sell");
   SetIndexDrawBegin(0,draw);
   SetIndexDrawBegin(1,draw);
   SetIndexBuffer(0,buffy1);
   SetIndexBuffer(1,buffy2);
   return(0);
  }
//+------------------------------------------------------------------+
int deinit()
  {
   ObjectsDeleteAll(0,OBJ_ARROW);

   for(int i = ObjectsTotal() - 1; i >= 0; i--){
   string label = ObjectName(i);
   if(StringSubstr(label, 0, 3) != "vli")continue; ObjectDelete(label);
   if(StringSubstr(label, 0, 3) != "BMC")continue; ObjectDelete(label);
   }
   return(0);
  }
//+------------------------------------------------------------------+
int start()
  {
   int iCounted  = 5000;
//+------------------------------------------------------------------+
   while(iCounted>=0)
   {
   //**** Laguerre .85.
   //**** Slope
   L0A = L0;
   L1A = L1;
   L2A = L2;
   L3A = L3;
   L0 = (1 - gamma)*Close[iCounted] + gamma*L0A;
   L1 = - gamma *L0 + L0A + gamma *L1A;
   L2 = - gamma *L1 + L1A + gamma *L2A;
   L3 = - gamma *L2 + L2A + gamma *L3A;

   CU = 0;
   CD = 0;

   if (L0 >= L1) CU = L0 - L1; else CD = L1 - L0;
   if (L1 >= L2) CU = CU + L1 - L2; else CD = CD + L2 - L1;
   if (L2 >= L3) CU = CU + L2 - L3; else CD = CD + L3 - L2;

   if (CU + CD != 0) LRSI = CU / (CU + CD); {RSI[iCounted] = LRSI; }

   iCounted--; }

//+------------------------------------------------------------------+
//+Set Variables-----------------------------------------------------+

   // if on the chart there are not enough bars the indicator is not calculate
   if(Bars <= 38) return(0);
   // amount not changed after last call of the indicator of bars
   int counted_bars = IndicatorCounted();
   if(counted_bars < 0) return(-1);
   // last counted bar will be counted
   if(counted_bars > 0) counted_bars--;
   iCounted = Bars - counted_bars;
   if ((iCounted + historyBarLag) >= Bars)
         iCounted = Bars - historyBarLag; //padding for slope calc

   while(iCounted >= 0)
   {
   v8    = RSI[iCounted+startBar];
   v9    = RSI[iCounted+historyBarStandard];
   v9b   = RSI[iCounted+historyBarLag];

   v08   =GlobalVariableSet("iTrend1",v8);
   v09   =GlobalVariableSet("iTrend10",v9);
   v09b  =GlobalVariableSet("iTrend10b",v9b);

   double lSlope  = v8;
   double hSlope  = v9;
   double hSlopeb = v9b;

   ArrayInitialize(barStd,0.45);
   ArrayInitialize(barLong,0.45);
   ArrayCopy(barStd,RSI,0,iCounted,historyBarStandard+1);
   ArrayCopy(barLong,RSI,0,iCounted,historyBarLag+1);

   int maxStdLevel   = ArrayMaximum(barStd,historyBarStandard,0);
   int minStdLevel   = ArrayMinimum(barStd,historyBarStandard,0);
   int maxLongLevel  = ArrayMaximum(barLong,historyBarStandard,0);
   int minLongLevel  = ArrayMinimum(barLong,historyBarStandard,0);

   if (lSlope > upLevelSpan && barStd[minStdLevel] > 0.45) int iTrend = +1; else
      if (lSlope < downLevelSpan && barStd[maxStdLevel] < 0.45) iTrend = -1; else iTrend=0;
      //barStd[minStdLevel]
      switch(iTrend) {
      case -1 : string l2 = "Down trend";break;
      case +1 : l2 = "Up trend";break;
      default : l2 = "No trade"; }

   if (lSlope > upLevelSpan && barLong[minLongLevel] > 0.45) int iTrendL = +1; else
      if (lSlope < downLevelSpan && barLong[maxLongLevel] < 0.45) iTrendL = -1; else iTrendL=0;
      //barLong[minLongLevel]
      switch(iTrendL) {
      case -1 : string l2b = "Down trend"; break;
      case +1 : l2b = "Up trend"; break;
      default : l2b = "No trade"; } //Print("open price - "+(iOpen(NULL,0,startBar),0));

      objc("vline2" + TimeToStr(TimeCurrent(),TIME_DATE),0,800,425,
         l2 + " Std  " + startBar+ " - ("+historyBarStandard+") Levels:  " + DoubleToStr(barStd[historyBarStandard],2) + " & " + DoubleToStr(barStd[maxLongLevel],2));
      objc("vline3" + TimeToStr(TimeCurrent(),TIME_DATE),0,800,450,
         l2b + " Hist " + startBar+ " - ("+historyBarLag+") Levels:  " + DoubleToStr(barLong[minLongLevel],2) + " & " + DoubleToStr(barLong[maxLongLevel],2));

   string name="vline4"+DoubleToStr(startBar,0);
   ObjectCreate(name,OBJ_ARROW,0,iTime(Symbol(),0,historyBarStandard),iOpen(Symbol(),0,historyBarStandard));
   ObjectSet(name,OBJPROP_ARROWCODE,159);
   ObjectSet(name, OBJPROP_COLOR, MediumSlateBlue);

   string name1="vline"+DoubleToStr(startBar,0);
   ObjectCreate(name1,OBJ_HLINE,0,0,iOpen(Symbol(),0,historyBarStandard));
   ObjectSet(name1, OBJPROP_STYLE, STYLE_DASHDOTDOT);
   ObjectSet(name1, OBJPROP_COLOR, DarkSlateGray);

   string name2="vline3"+DoubleToStr(historyBarStandard,0);
   ObjectCreate(name2,OBJ_VLINE,0,iTime(Symbol(),0,startBar),0);
   ObjectSet(name2, OBJPROP_STYLE, STYLE_DASHDOTDOT);
   ObjectSet(name2, OBJPROP_COLOR, DarkSlateGray);

   string name3="vline2"+DoubleToStr(historyBarStandard,0);
   ObjectCreate(name3,OBJ_VLINE,0,iTime(Symbol(),0,historyBarStandard),0);
   ObjectSet(name3, OBJPROP_STYLE, STYLE_DASHDOTDOT);
   ObjectSet(name3, OBJPROP_COLOR, DarkSlateGray);

   string name4="vline1"+DoubleToStr(historyBarLag,0);
   ObjectCreate(name4,OBJ_VLINE,0,iTime(Symbol(),0,historyBarLag),0);
   ObjectSet(name4, OBJPROP_STYLE, STYLE_DASHDOTDOT);
   ObjectSet(name4, OBJPROP_COLOR, DarkSlateGray);

//+------------------------------------------------------------------+
// here if flag false ---------- off cciSearch => FALSE--------------+

   if (cciSearch == 0)
   {
   double r1 = iRSI(NULL,0,rsiperiod,PRICE_CLOSE,iCounted);
   double r2 = iRSI(NULL,0,rsiperiod,PRICE_CLOSE,iCounted+1);

   if (iTrend>0) { //up trend - present is gt 30 history less 30
   if (r1 > buyFlag && r2 < buyFlag) {cciSearch = 1; iTrendB = 1; }}

   if (iTrend<0) { //down trend - present is less 70 history gt 70
   if (r1 < selFlag && r2 > selFlag) {cciSearch = 1; iTrendS = 1; }}
   }
//+------------------------------------------------------------------+
// here if flag true ---------- on cciSearch => TRUE-----------------+

   if (cciSearch >= 1) {
   for (cciSearch = 1; cciSearch <= cciBars && (iCounted-cciSearch) >=0; cciSearch++ )
   {
      double bar1CCI = iCCI(NULL, 0, FastCCI, PRICE_TYPICAL, iCounted-cciSearch+3);
      double bar2CCI = iCCI(NULL, 0, FastCCI, PRICE_TYPICAL, iCounted-cciSearch+2);
      double bar3CCI = iCCI(NULL, 0, FastCCI, PRICE_TYPICAL, iCounted-cciSearch+1);

      string BUY="false"; string SELL="false";
      if ((bar1CCI <= -70.0 && bar2CCI > -70.0 && bar3CCI > -70.0)) BUY="true";
      if ((bar1CCI >= +70.0 && bar2CCI < +70.0 && bar3CCI < +70.0)) SELL="true";

      if (iTrendB == 1)
      {  //look for buy
         if (BUY =="true" || cciSearch == cciBars)
         {
            Print (bar1CCI+"  "+bar2CCI+"  "+bar3CCI);
            buffy1[iCounted-cciSearch+2] = Low[iCounted-cciSearch+2]-15*Point;
            bar=Time[cciSearch+iCounted+1]; string name8="vline7";
            ObjectCreate(name8,OBJ_VLINE,0,iTime(Symbol(),0,iCounted-cciSearch+2),0);
            ObjectSet(name8, OBJPROP_STYLE, STYLE_DASHDOTDOT);
            ObjectSet(name8, OBJPROP_COLOR, DarkSlateGray);
            Print (l2+" "+cciSearch+iCounted+" "+BUY +" Buy "+  cciSearch);iTrendB = 0;
            }
      }
      if (iTrendS == 1)
      {  //look for sell
          if (SELL=="true" || cciSearch == cciBars)
          {
            buffy2[cciSearch+iCounted+1] = High[iCounted-cciSearch+2]+15*Point;
            bar=Time[cciSearch+iCounted+1]; string name9="vline7";
            ObjectCreate(name9,OBJ_VLINE,0,iTime(Symbol(),0,cciSearch+iCounted),0);
            ObjectSet(name9, OBJPROP_STYLE, STYLE_DASHDOTDOT);
            ObjectSet(name9, OBJPROP_COLOR, DarkSlateGray);
            Print (l2+" "+cciSearch+iCounted+" "+SELL +" Sell "+  cciSearch);iTrendS = 0;
            }
      }}  //cciSearch+=1;        //add to loop

      //else {
         cciSearch = 0;
         iTrendB = 0; iTrendB = 0; } //}
                           //flags off
                           //<= loop for cciSearch
   iCounted--; }

   RefreshRates();
   return(0);
  }

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
   void objc(string name,int winPos, int x,int y, string descr)
   {
   ObjectCreate(name,OBJ_LABEL,winPos,0,0,0,0,0,0);
   ObjectSet(name, OBJPROP_XDISTANCE, x);
   ObjectSet(name, OBJPROP_YDISTANCE, y);
   ObjectSetText(name,descr,12,"Consolas",DodgerBlue);
   }