//+------------------------------------------------------------------+
//|                    MTF_RSI_Orest_v1.0.mq4                    |
//|                                                                  |
//+------------------------------------------------------------------+

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Blue
#property indicator_color2 Orange
#property indicator_color3 Blue
#property indicator_color4 Orange

double CrossUp[];
double CrossDown[];
double StarUp[];
double StarDown[];

extern int RSI_Period = 5;
extern int Number_Of_Alerts = 1;

int H1_Period  = 60;
int M15_Period = 15;
int H4_Period  = 240;
int D1_Period  = 1440;


int chartBarsCount;
datetime LastAlert = 0;
datetime LastAlert_CT = 0;


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0, DRAW_ARROW, EMPTY,2);
   SetIndexArrow(0, 233);
   SetIndexBuffer(0, CrossUp);
   SetIndexStyle(1, DRAW_ARROW, EMPTY,2);
   SetIndexArrow(1, 234);
   SetIndexBuffer(1, CrossDown);

   SetIndexStyle(2, DRAW_ARROW, EMPTY,2);
   SetIndexArrow(2, 241);
   SetIndexBuffer(2, StarUp);
   SetIndexStyle(3, DRAW_ARROW, EMPTY,2);
   SetIndexArrow(3, 242);
   SetIndexBuffer(3, StarDown);

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start() {
   int limit, i, counter;
   double fasterEMAnow, slowerEMAnow, fasterEMAprevious, slowerEMAprevious, fasterEMAafter, slowerEMAafter;
   double Range, AvgRange;
   
   int counted_bars = IndicatorCounted();
   if(counted_bars < 0) 
       return(-1);
   if(counted_bars > 0) 
       counted_bars--;
   limit = Bars - counted_bars; 

   int ii = 0;

   //for(i = chartBarsCount - countedBars; i >= 0; i--) {
   for(i = 0; i < limit ; i++) {
   
      counter=i;
      Range=0;
      AvgRange=0;
      for (counter=i ;counter<=i+9;counter++)
      {
         AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]);
      }
      Range=AvgRange/10;
       
      int trend = Signal(i);
    
      if (trend==1) {
         CrossUp[i] = Low[i] - Range*0.75;
         if (LastAlert != iTime(NULL,0,0) && i<1) {
            for(ii = 0; ii < Number_Of_Alerts; ii++) {
             Alert("Buy Signal:", TimeToStr(TimeCurrent()));
             PlaySound("alert.wav");

             Sleep(3000); 
            }
            LastAlert = iTime(NULL,0,0);
         }             
      }
      else if (trend==-1) {
         CrossDown[i] = High[i] + Range*0.75;
         if (LastAlert != iTime(NULL,0,0) && i<1) {
            for(ii = 0; ii < Number_Of_Alerts; ii++) {
               Alert("Sell Signal:", TimeToStr(TimeCurrent()));
               PlaySound("alert.wav");

               Sleep(3000); 
            }
            LastAlert = iTime(NULL,0,0);
         }                        
      }

   }
   return(0);
}

int Signal(int shift)
{

   int signal = 0;

   datetime ti = iTime(NULL,0, shift);
   int bar_h1  = iBarShift(NULL,PERIOD_H1,ti)+1; 
   int bar_m15 = iBarShift(NULL,PERIOD_M15,ti)+1; 
   int bar_h4  = iBarShift(NULL,PERIOD_H4,ti); 
   int bar_d1  = iBarShift(NULL,PERIOD_D1,ti); 

  
   double RSI_H1  = iRSI(NULL,PERIOD_H1,RSI_Period,PRICE_CLOSE,bar_h1);
   double RSI_M15 = iRSI(NULL,PERIOD_M15,RSI_Period,PRICE_CLOSE,bar_m15);
   double RSI_M15_prev = iRSI(NULL,PERIOD_M15,RSI_Period,PRICE_CLOSE,bar_m15+1);
   double RSI_M15_prev1 = iRSI(NULL,PERIOD_M15,RSI_Period,PRICE_CLOSE,bar_m15+2);

double upslopehistobuf_h4[];
double downslopehistobuf_h4[];
double uplimitbuf_h4[];
double medlimitbuf_h4[];
double downlimitbuf_h4[];
double pricealertbuf_h4[];
double rcslope_h4;

double upslopehistobuf_d1[];
double downslopehistobuf_d1[];
double uplimitbuf_d1[];
double medlimitbuf_d1[];
double downlimitbuf_d1[];
double pricealertbuf_d1[];
double rcslope_d1;

  
SHIChannels(PERIOD_H4, bar_h4, 240, upslopehistobuf_h4, downslopehistobuf_h4, uplimitbuf_h4, medlimitbuf_h4,
 downlimitbuf_h4, pricealertbuf_h4, rcslope_h4, 0, 0);

SHIChannels(PERIOD_D1, bar_d1, 240, upslopehistobuf_d1, downslopehistobuf_d1, uplimitbuf_d1, medlimitbuf_d1,
 downlimitbuf_d1, pricealertbuf_d1, rcslope_d1, 0, 0);

//Print(rcslope_h4, rcslope_d1);

   if (/*rcslope_h4>0 && rcslope_d1>0 &&*/ RSI_H1<30 && RSI_M15_prev<30 && RSI_M15_prev1<30 && /*RSI_M15_prev<RSI_M15_prev1 && RSI_M15>RSI_M15_prev &&*/ RSI_M15>=30)
       signal = 1;
   else if (/*rcslope_h4<0 && rcslope_d1<0 &&*/ RSI_H1>70 && RSI_M15_prev>70 && RSI_M15_prev1>70 &&/*RSI_M15_prev>RSI_M15_prev1 && RSI_M15<RSI_M15_prev &&*/ RSI_M15<=70)
            signal = -1; 


   return (signal);      
 }


//+------------------------------------------------------------------+
//| SHI Channels (by shimodax, based on shurka&kevin, based on slavic|
//+------------------------------------------------------------------+
int SHIChannels(int period, int offset, int howmany, double &upslopehistobuf[], double &downslopehistobuf[], 
                           double &uplimitbuf[], double &medlimitbuf[], double &downlimitbuf[], double &pricealertbuf[], 
                           double &rcslope, int barsfofr, int lazyness)
{
   // by Shimodax, based on  "SHI_Channel.mq4 by Shurka & Kevin"
   // original link ""
   int currentbar= 0, startbar;
   double step=0, slope;
   int b1=-1, b2=-1;
   int updown=0, barsforfract= 0; // fractal (reverse point) size
   double p1=0, p2=0, pp=0, px, llow, hhigh, p1lower, p1upper;
   int i=0, lastbar= 300, ishift=0, inspectwidth;
   double iprice=0;

   rcslope= 0;
   
   // lazyness (how many fresh bars will be ignored when determining the trend)
   if (lazyness<2)
      lazyness= 2;

	if ((howmany==0) || (Bars<offset+howmany)) 
	  lastbar= Bars; 
	else 
	  lastbar= offset+howmany;   //lastbar-?????????? ????????????? ?????
	
	if (barsfofr>0) {
		barsforfract= barsfofr; 
   }
	else {
		switch (period) {
			case 1: barsforfract=12; break;
			case 5: barsforfract=48; break;
			case 15: barsforfract=24; break;
			case 30: barsforfract=24; break;
			case 60: barsforfract=12; break;
			case 240: barsforfract=15; break;
			case 1440: barsforfract=10; break;
			case 10080: barsforfract=6; break;
			default: return(-1); break;
		}
	}
	

	startbar= offset + lazyness;
	b1=-1; b2=-1; 
	updown=0;
	
	currentbar= startbar; 
	while(((b1==-1) || (b2==-1)) && (currentbar<lastbar))
	{
      //UpDown=1 means the 1st fractal has been found on top,
      //UpDown=-1 means the 1st fractal has been found at the bottom,
      //UpDown=0 means a fractal has not yet been found
      //B1 & B2 - base line fractal bars
      //P1 & P2 - prices for this line
      
      
      inspectwidth= MathMax(currentbar-barsforfract, startbar);  // avoid negative indices (beyond zero-bar)
                                                                 // or looking further than startbar
                                                                 // (bug found by Shahin)
      
      llow= Lowest(NULL,period, MODE_LOW, barsforfract*2+1, inspectwidth);
		if(updown<1 && currentbar==llow) 
		{
			if(updown==0) { updown=-1; b1=currentbar; p1=iLow(NULL, period, b1); }
			else { b2=currentbar; p2=iLow(NULL, period, b2);}
		}
		
		hhigh= Highest(NULL,period, MODE_HIGH, barsforfract*2+1, inspectwidth);
		if(updown>-1 && (currentbar==hhigh)) 
		{
			if(updown==0) { updown=1; b1=currentbar; p1=iHigh(NULL, period, b1); }
			else { b2=currentbar; p2=iHigh(NULL, period, b2); }
		}
		currentbar++;
	}

	if((b1==-1) || (b2==-1)) {
  
      return(-1);    // ?????? ?? ????? ????????? ????? 300 ????? 8-)
                     // No fractals have been found in 300 bar range 8-)
	}
	
	step= (p2-p1)/(b2-b1);                 // slope (price diff)/(time diff)
	                                       // (if positive then the channel is descending)
	                                       
	p1= p1-(b1-offset)*step; b1= offset;   // extend right side of channel up to the right side of 
	                                       // the requested area (usually end of chart, bar= 0)
	

   //
	// determine other sides channel border 
	//
	ishift=0; iprice=0;
	if(updown==1) { 
	
		pp= 99999; // too high to survive low-tests
		
		for (i= offset+lazyness; i<=b2; i++) {    // find lowest low matching slope
			pp= MathMin(pp, iLow(NULL, period, i) - step*(i-offset)); 
		}
	
	   // swap to make pp upper and p1 lower Point
	   p1upper= p1;
	   p1lower= pp;
	} 
	else { 
		pp= -1; // too low to surive high tests
		
		for (i= offset+lazyness; i<=b2; i++) {    // find highest high matching slope
			pp= MathMax(pp, iHigh(NULL, period, i) - step*(i-offset));
		}
		
	   p1upper= pp;
	   p1lower= p1;
	}

   // now the lower trend channel slopes back from b1/p1, the upper channel from b1/pp
   
   //
	// determine range braks (upper/lower channel)
	//
	for (i= 0; i<lazyness; i++) {
	  if (iLow(NULL, period,offset+i) < p1lower+step*i) { 
	     ishift= offset+i; 
	     iprice= p1lower + step*i; 
	  }  
	  if (iHigh(NULL, period,offset+i)> p1upper+step*i) { 
	     ishift= offset+1; 
	     iprice= p1upper + step*i; 
	   }
	}

   if (iprice!=0) 
      pricealertbuf[ishift]= iprice; // 0 (zero) means the channel line remains intact, dot means the channel is broken
     

   //
   // fill buffers for the in-chart channel borders
   //
   for (i= lastbar; i>=offset; i--) {
      downlimitbuf[i]= p1lower + (step * (i-b1));
      medlimitbuf[i]= ((p1lower + p1upper)/2) + (step * (i-b1));
      uplimitbuf[i]= p1upper + (step * (i-b1));
   }

   //
   // fill buffers for use with the slope histogram
   //
   slope= -step/Point;

   //
   // fill in the slope into the slop buffers 
   // 

   if (slope>0) {
      upslopehistobuf[offset]= slope;
      downslopehistobuf[offset]= 0;
   }
   else {
      downslopehistobuf[offset]= slope;
      upslopehistobuf[offset]= 0;
   }
   
   rcslope= slope;
       
   return(0);
}




