//+------------------------------------------------------------------+
//|                                           MTF Moving Average.mq4 |
//|													2007, Christof Risch (iya)	|
//| Moving average from any timeframe.											|
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers	18
#property indicator_color1		Red
#property indicator_color2		LightSalmon
#property indicator_color3		Red
#property indicator_color4		Red
#property indicator_color5		Red
#property indicator_color6		Red
#property indicator_color7		Red
#property indicator_color8		Red
#property indicator_color9		Red
#property indicator_color10	Red
#property indicator_color11	Red
#property indicator_color12	Red
#property indicator_color13	Red
#property indicator_color14	Red
#property indicator_color15	Red
#property indicator_color16	Red
#property indicator_color17	Red
#property indicator_color18	Red
#property strict


extern ENUM_TIMEFRAMES	   TimeFrame	   = PERIOD_CURRENT;		//	{1=M1, 5=M5, 15=M15, ..., 1440=D1, 10080=W1, 43200=MN1}
extern int                 PERIOD		   = 14;
extern ENUM_MA_METHOD      Method		   = 0;		//	{0=SMA, 1=EMA, 2=SMMA, 3=LWMA}
extern ENUM_APPLIED_PRICE  AppliedPrice   = 0;		//	{0=Close,1=Open,2=High,3=Low,4=Median,5=Typical,6=Weighted}
extern double              level_1        = 20;    // Upper level start
extern double              level_2        = 30;
extern double              level_3        = 40;
extern double              level_4        = 50;
extern double              level_5        = 60;
extern double              level_6        = 70;
extern double              level_7        = 80;
extern double              level_8        = 90;
extern double              level_9        = 20;    // Lower level start
extern double              level_10       = 30;
extern double              level_11       = 40;
extern double              level_12       = 50;
extern double              level_13       = 60;
extern double              level_14       = 70;
extern double              level_15       = 80;
extern double              level_16       = 90;
extern bool                Interpolate    = true;            // Interpolate in multi time frame mode?

//---- indicator buffers
double		Buffer[],BufferCurrent[];
double      buffer_level_1[];
double      buffer_level_2[];
double      buffer_level_3[];
double      buffer_level_4[];
double      buffer_level_5[];
double      buffer_level_6[];
double      buffer_level_7[];
double      buffer_level_8[];
double      buffer_level_9[];
double      buffer_level_10[];
double      buffer_level_11[];
double      buffer_level_12[];
double      buffer_level_13[];
double      buffer_level_14[];
double      buffer_level_15[];
double      buffer_level_16[],count[];
string indicatorFileName;
#define _mtfCall(_buff,_y) iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,PERIOD,Method,AppliedPrice,level_1,level_2,level_3,level_4,level_5,level_6,level_7,level_8,level_9,level_10,level_11,level_12,level_13,level_14,level_15,level_16,_buff,_y)


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{

   IndicatorBuffers(19);
	SetIndexBuffer(0,Buffer);          SetIndexStyle(0,DRAW_LINE);
	SetIndexBuffer(1,BufferCurrent);   SetIndexStyle(1,DRAW_LINE);
	SetIndexBuffer(2,buffer_level_1);  SetIndexStyle(2,DRAW_LINE);
	SetIndexBuffer(3,buffer_level_2);  SetIndexStyle(3,DRAW_LINE);
	SetIndexBuffer(4,buffer_level_3);  SetIndexStyle(4,DRAW_LINE);
	SetIndexBuffer(5,buffer_level_4);  SetIndexStyle(5,DRAW_LINE);
	SetIndexBuffer(6,buffer_level_5);  SetIndexStyle(6,DRAW_LINE);
	SetIndexBuffer(7,buffer_level_6);  SetIndexStyle(7,DRAW_LINE);
	SetIndexBuffer(8,buffer_level_7);  SetIndexStyle(8,DRAW_LINE);
	SetIndexBuffer(9,buffer_level_8);  SetIndexStyle(9,DRAW_LINE);
	SetIndexBuffer(10,buffer_level_9); SetIndexStyle(10,DRAW_LINE);
	SetIndexBuffer(11,buffer_level_10);SetIndexStyle(11,DRAW_LINE);
	SetIndexBuffer(12,buffer_level_11);SetIndexStyle(12,DRAW_LINE);
	SetIndexBuffer(13,buffer_level_12);SetIndexStyle(13,DRAW_LINE);
	SetIndexBuffer(14,buffer_level_13);SetIndexStyle(14,DRAW_LINE);
	SetIndexBuffer(15,buffer_level_14);SetIndexStyle(15,DRAW_LINE);
	SetIndexBuffer(16,buffer_level_15);SetIndexStyle(16,DRAW_LINE);
	SetIndexBuffer(17,buffer_level_16);SetIndexStyle(17,DRAW_LINE);
	SetIndexBuffer(18,count);
	indicatorFileName = WindowExpertName();
   TimeFrame         = MathMax(TimeFrame,_Period);  
return(0);
}


//+------------------------------------------------------------------+
//| MTF Moving Average                                               |
//+------------------------------------------------------------------+
int start()
{
   int i,counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
         int limit = fmin(Bars-counted_bars,Bars-1); count[0]=limit;
            if (TimeFrame!=_Period)
            {
               limit = (int)fmax(limit,fmin(Bars-1,_mtfCall(18,0)*TimeFrame/_Period));
               for (i=limit;i>=0 && !_StopFlag; i--)
               {
                  int y = iBarShift(NULL,TimeFrame,Time[i]);
                     Buffer[i]          = _mtfCall(0,y);
                     BufferCurrent[i]   = _mtfCall(1,y);
                     buffer_level_1[i]  = _mtfCall(2,y);
                     buffer_level_2[i]  = _mtfCall(3,y);
                     buffer_level_3[i]  = _mtfCall(4,y);
                     buffer_level_4[i]  = _mtfCall(5,y);
                     buffer_level_5[i]  = _mtfCall(6,y);
                     buffer_level_6[i]  = _mtfCall(7,y);
                     buffer_level_7[i]  = _mtfCall(8,y);
                     buffer_level_8[i]  = _mtfCall(9,y);
                     buffer_level_9[i]  = _mtfCall(10,y);
                     buffer_level_10[i] = _mtfCall(11,y);
                     buffer_level_11[i] = _mtfCall(12,y);
                     buffer_level_12[i] = _mtfCall(13,y);
                     buffer_level_13[i] = _mtfCall(14,y);
                     buffer_level_14[i] = _mtfCall(15,y);
                     buffer_level_15[i] = _mtfCall(16,y);
                     buffer_level_16[i] = _mtfCall(17,y);
                 
                     //
                     //
                     //
                     //
                     //
                     
                     if (!Interpolate || (i>0 && y==iBarShift(NULL,TimeFrame,Time[i-1]))) continue;
                        #define _interpolate(buff) buff[i+k] = buff[i]+(buff[i+n]-buff[i])*k/n
                        int n,k; datetime time = iTime(NULL,TimeFrame,y);
                           for(n = 1; (i+n)<Bars && Time[i+n] >= time; n++) continue;	
                           for(k = 1; k<n && (i+n)<Bars && (i+k)<Bars; k++)  
                           {
                              _interpolate(Buffer);
                              _interpolate(BufferCurrent);
                              _interpolate(buffer_level_1);
                              _interpolate(buffer_level_2);
                              _interpolate(buffer_level_3);
                              _interpolate(buffer_level_4);
                              _interpolate(buffer_level_5);
                              _interpolate(buffer_level_6);
                              _interpolate(buffer_level_7);
                              _interpolate(buffer_level_8);
                              _interpolate(buffer_level_9);
                              _interpolate(buffer_level_10);
                              _interpolate(buffer_level_11);
                              _interpolate(buffer_level_12);
                              _interpolate(buffer_level_13);
                              _interpolate(buffer_level_14);
                              _interpolate(buffer_level_15); 
                              _interpolate(buffer_level_16);
                            }                                      
              }             
   return(0);
   }
   
   //
   //
   //
   //
   //
   
   for (i=limit;i>=0;i--)
   { 
     if (i<Bars-1)
     { 
	    BufferCurrent[i] = iMA(NULL,0,PERIOD,0,Method,AppliedPrice,i);
	    Buffer[i] = BufferCurrent[i+1];
       if(level_1>0) buffer_level_1[i]   = Buffer[i] + level_1*_Point*pow(10,_Digits%2);
       if(level_2>0) buffer_level_2[i]   = Buffer[i] + level_2*_Point*pow(10,_Digits%2);
       if(level_3>0) buffer_level_3[i]   = Buffer[i] + level_3*_Point*pow(10,_Digits%2);
       if(level_4>0) buffer_level_4[i]   = Buffer[i] + level_4*_Point*pow(10,_Digits%2);
       if(level_5>0) buffer_level_5[i]   = Buffer[i] + level_5*_Point*pow(10,_Digits%2);
       if(level_6>0) buffer_level_6[i]   = Buffer[i] + level_6*_Point*pow(10,_Digits%2);
       if(level_7>0) buffer_level_7[i]   = Buffer[i] + level_7*_Point*pow(10,_Digits%2);
       if(level_8>0) buffer_level_8[i]   = Buffer[i] + level_8*_Point*pow(10,_Digits%2);
       if(level_9>0) buffer_level_9[i]   = Buffer[i] - level_9*_Point*pow(10,_Digits%2);
       if(level_10>0) buffer_level_10[i] = Buffer[i] - level_10*_Point*pow(10,_Digits%2);
       if(level_11>0) buffer_level_11[i] = Buffer[i] - level_11*_Point*pow(10,_Digits%2);
       if(level_12>0) buffer_level_12[i] = Buffer[i] - level_12*_Point*pow(10,_Digits%2);
       if(level_13>0) buffer_level_13[i] = Buffer[i] - level_13*_Point*pow(10,_Digits%2);
       if(level_14>0) buffer_level_14[i] = Buffer[i] - level_14*_Point*pow(10,_Digits%2);
       if(level_15>0) buffer_level_15[i] = Buffer[i] - level_15*_Point*pow(10,_Digits%2);
       if(level_16>0) buffer_level_16[i] = Buffer[i] - level_16*_Point*pow(10,_Digits%2);
     }
   }
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("");
}


