//+------------------------------------------------------------------+
//|                                     Moving averages cross SR.mq4 |
//| coded after the idea of bulliz                                   |
//| so the credits go to him                                         |
//+------------------------------------------------------------------+

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1  clrDeepSkyBlue
#property indicator_color2  clrRed
#property indicator_color3  clrDeepSkyBlue
#property indicator_color4  clrRed
//#property strict

//
//
//
//
//

extern ENUM_TIMEFRAMES     TimeFrame         = PERIOD_CURRENT; // Time frame to use
extern int                 FastMaPeriod      = 20;             
extern ENUM_MA_METHOD      FastMaMethod      = MODE_EMA;
extern ENUM_APPLIED_PRICE  FastMaPrice       = PRICE_CLOSE;
extern int                 SlowMaPeriod      = 50;
extern ENUM_MA_METHOD      SlowMaMethod      = MODE_EMA;
extern ENUM_APPLIED_PRICE  SlowMaPrice       = PRICE_CLOSE;
extern bool                ShowAverages      = true;
extern bool                ShowTillChange    = true;
extern int                 BarForSRHighsLows = 0;
extern bool                ArrowOnFirst      = true;           // Arrow on first bars
extern bool                Interpolate       = true;           // Interpolate in multi time frame mode?

//
//
//
//
//

double fastMa[];
double slowMa[];
double resistance[];
double support[];
double trend[];
string indicatorFileName;
bool   returnBars;

//+------------------------------------------------------------------+
//|                                                                 
//+------------------------------------------------------------------+
//
//
//
//
//

int init()
{
   IndicatorBuffers(5);
   SetIndexBuffer(0,fastMa); if (ShowAverages) SetIndexStyle(0,DRAW_LINE); else SetIndexStyle(0,DRAW_NONE);
   SetIndexBuffer(1,slowMa); if (ShowAverages) SetIndexStyle(1,DRAW_LINE); else SetIndexStyle(1,DRAW_NONE);
   SetIndexBuffer(2,resistance);               SetIndexStyle(2,DRAW_ARROW); SetIndexArrow(2,159);
   SetIndexBuffer(3,support);                  SetIndexStyle(3,DRAW_ARROW); SetIndexArrow(3,159);
   SetIndexBuffer(4,trend);
   
      
   indicatorFileName = WindowExpertName();
   returnBars        = TimeFrame==-99;
   TimeFrame         = fmax(TimeFrame,_Period);   

   return(0);
}
int deinit() { return(0); }

//+------------------------------------------------------------------+
//|                                                                 
//+------------------------------------------------------------------+
//
//
//
//
//

int start()
{
   int counted_bars=IndicatorCounted();
   int i,limit;

   if (counted_bars<0) return(-1);
   if (counted_bars>0) counted_bars--;
          limit = MathMin(Bars-counted_bars,Bars-1);
          if (returnBars) { fastMa[0] = fmin(limit+1,Bars-1); return(0); }
            
   //
   //
   //
   //
   //
   
   if (TimeFrame == Period())
   {

     for (i=limit; i>=0; i--)
     {
        fastMa[i]     = iMA(NULL,0,FastMaPeriod,0,FastMaMethod,FastMaPrice,i);
        slowMa[i]     = iMA(NULL,0,SlowMaPeriod,0,SlowMaMethod,SlowMaPrice,i);
        resistance[i] = resistance[i+1];
        support[i]    = support[i+1];
        trend[i] = (i<Bars-1) ? (fastMa[i]>slowMa[i]) ? 1 : (fastMa[i]<slowMa[i]) ? -1 : trend[i+1] : 0;  
  
         //
         //
         //
         //
         //
         
         if (i<Bars-1)
         {
           if (trend[i]!=trend[i+1])
           {
            if (trend[i] == 1)
               {
                  resistance[i] = High[i+BarForSRHighsLows];
                  if (!ShowTillChange)
                     support[i] = EMPTY_VALUE;
               }                     
            else
               {
                  support[i] = Low[i+BarForSRHighsLows];
                  if (!ShowTillChange)
                     resistance[i] = EMPTY_VALUE;
               }                     
          }
        }
   }
   return(0);
   }
   
   //
   //
   //
   //
   //
      
   limit = (int)fmax(limit,fmin(Bars-1,iCustom(NULL,TimeFrame,indicatorFileName,-99,0,0)*TimeFrame/_Period));
   for(i=limit; i>=0; i--)
   {
      int y = iBarShift(NULL,TimeFrame,Time[i]);
      int x = y;
      if (ArrowOnFirst)
            {  if (i<Bars-1) x = iBarShift(NULL,TimeFrame,Time[i+1]);          }
      else  {  if (i>0) x = iBarShift(NULL,TimeFrame,Time[i-1]); else x = -1;  }
         fastMa[i]  = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,FastMaPeriod,FastMaMethod,FastMaPrice,SlowMaPeriod,SlowMaMethod,SlowMaPrice,ShowAverages,ShowTillChange,BarForSRHighsLows,ArrowOnFirst,0,y);
         slowMa[i]  = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,FastMaPeriod,FastMaMethod,FastMaPrice,SlowMaPeriod,SlowMaMethod,SlowMaPrice,ShowAverages,ShowTillChange,BarForSRHighsLows,ArrowOnFirst,1,y);
         resistance[i] = EMPTY_VALUE;
         support[i]    = EMPTY_VALUE;
         if (x!=y)
         {
            resistance[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,FastMaPeriod,FastMaMethod,FastMaPrice,SlowMaPeriod,SlowMaMethod,SlowMaPrice,ShowAverages,ShowTillChange,BarForSRHighsLows,ArrowOnFirst,2,y);
            support[i]    = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,FastMaPeriod,FastMaMethod,FastMaPrice,SlowMaPeriod,SlowMaMethod,SlowMaPrice,ShowAverages,ShowTillChange,BarForSRHighsLows,ArrowOnFirst,3,y);
         }
         if (!Interpolate || (i>0 && y==iBarShift(NULL,TimeFrame,Time[i-1]))) continue;
                  
         //
         //
         //
         //
         //
                  
         int n,j; datetime time = iTime(NULL,TimeFrame,y);
            for(n = 1; (i+n)<Bars && Time[i+n] >= time; n++) continue;	
            for(j = 1; j<n && (i+n)<Bars && (i+j)<Bars; j++)
            { 
               fastMa[i+j] = fastMa[i] + (fastMa[i+n] - fastMa[i])*j/n; 
               slowMa[i+j] = slowMa[i] + (slowMa[i+n] - slowMa[i])*j/n; 
            }          
   }
   return(0);
}

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
//
//
//
//
//

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}
 
