//+------------------------------------------------------------------+
//|                                           MTF Moving Average.mq4 |
//|													2007, Christof Risch (iya)	|
//| Moving average from any timeframe.											|
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers	2
#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

//---- input parameters
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 bool                Backtesting	   = false;	// Check to avoid problems in the visual backtesting mode.

extern double              level_1        = 20;
extern double              level_2        = 0;
extern double              level_3        = 0;
extern double              level_4        = 0;
extern double              level_5        = 0;
extern double              level_6        = 0;
extern double              level_7        = 0;
extern double              level_8        = 0;
extern double              level_9        = 0;
extern double              level_10       = 0;
extern double              level_11       = 0;
extern double              level_12       = 0;
extern double              level_13       = 0;
extern double              level_14       = 0;
extern double              level_15       = 0;
extern double              level_16       = 0;

//---- 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[];

//----
string	IndicatorName = "";

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
//---- name for DataWindow and indicator subwindow label

   IndicatorName = EnumToString(TimeFrame);

	switch(Method)
	{
		case MODE_SMA:		IndicatorName = IndicatorName+" SMA("+PERIOD+")";	break;
		case MODE_EMA:		IndicatorName = IndicatorName+" EMA("+PERIOD+")";	break;
		case MODE_SMMA:	IndicatorName = IndicatorName+" SMMA("+PERIOD+")";	break;
		case MODE_LWMA:	IndicatorName = IndicatorName+" LWMA("+PERIOD+")";	break;
		default:			  {Method = MODE_SMA; return(init());}
	}

	IndicatorShortName(IndicatorName);
	SetIndexBuffer(0,Buffer);
	SetIndexBuffer(1,BufferCurrent);
	SetIndexStyle(0,DRAW_LINE);
	SetIndexStyle(1,DRAW_LINE);
	SetIndexLabel(0,IndicatorName);
	SetIndexLabel(1,IndicatorName+" Current Candle");
	
	IndicatorBuffers(18);
	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);

}


//+------------------------------------------------------------------+
//| MTF Moving Average                                               |
//+------------------------------------------------------------------+
int start()
{
//----
//	counted bars from indicator time frame
	static int countedBars1 = 0;

//----
//	Comment(TimeFrame+" Time[0] = "+iTime(NULL,TimeFrame,0));

//----
//	counted bars from display time frame
	if(Bars-1-IndicatorCounted() > 1 && countedBars1!=0)
		countedBars1 = 0;

	int bars1 = iBars(NULL,TimeFrame),
		 start1 = bars1-1-countedBars1,
		 limit1 = iBarShift(NULL,TimeFrame,Time[Bars-1]);

	if(countedBars1 != bars1-1)
	{
		if(!Backtesting)
			countedBars1  = bars1-1;

		ArrayInitialize(BufferCurrent,EMPTY_VALUE);
	}


	if(start1 > limit1 && limit1 != -1)
		start1 = limit1;

//----
//	3... 2... 1... GO!
	for(int i = start1; i >= 0; i--)
	{
		int shift1 = i;

		if(TimeFrame < Period())
			shift1 = iBarShift(NULL,TimeFrame,Time[i]);

		int time1  = iTime    (NULL,TimeFrame,shift1),
			 shift2 = iBarShift(NULL,0,time1);

		double ma = iMA(NULL,TimeFrame,PERIOD,0,Method,AppliedPrice,shift1);

	//----
	//	old (closed) candles
		if(shift1>=1)
		{
			Buffer[shift2] = ma;
		}

	//----
	//	current candle
		if((TimeFrame >=Period() && shift1<=1)
		|| (TimeFrame < Period() &&(shift1==0||shift2==1)))
		{
			BufferCurrent[shift2] = ma;
		}

	//----
	//	linear interpolatior for the number of intermediate bars, between two higher timeframe candles.
		int n = 1;
		if(TimeFrame > Period())
		{
			int shift2prev = iBarShift(NULL,0,iTime(NULL,TimeFrame,shift1+1));

			if(shift2prev!=-1 && shift2prev!=shift2)
				n = shift2prev - shift2;
		}

	//----
	//	apply interpolation
		double factor = 1.0 / n;
		if(shift1>=1)
		if(Buffer[shift2+n]!=EMPTY_VALUE && Buffer[shift2]!=EMPTY_VALUE)
		{
			for(int k = 1; k < n; k++)
			{
				Buffer[shift2+k] = k*factor*Buffer[shift2+n] + (1.0-k*factor)*Buffer[shift2];
			}
		}

	//----
	//	current candle
		if(shift1==0)
		if(BufferCurrent[shift2+n]!=EMPTY_VALUE && BufferCurrent[shift2]!=EMPTY_VALUE)
		{
			for(k = 1; k < n; k++)
			{
				BufferCurrent[shift2+k] = k*factor*BufferCurrent[shift2+n] + (1.0-k*factor)*BufferCurrent[shift2];
			}
		}
		
	}

	for(i = Bars-1; i >= 0; i--) {
      if(level_1>0) buffer_level_1[i] = Buffer[i] + level_1*_Point;
      if(level_2>0) buffer_level_2[i] = Buffer[i] + level_2*_Point;
      if(level_3>0) buffer_level_3[i] = Buffer[i] + level_3*_Point;
      if(level_4>0) buffer_level_4[i] = Buffer[i] + level_4*_Point;
      if(level_5>0) buffer_level_5[i] = Buffer[i] + level_5*_Point;
      if(level_6>0) buffer_level_6[i] = Buffer[i] + level_6*_Point;
      if(level_7>0) buffer_level_7[i] = Buffer[i] + level_7*_Point;
      if(level_8>0) buffer_level_8[i] = Buffer[i] + level_8*_Point;
      if(level_9>0) buffer_level_9[i] = Buffer[i] + level_9*_Point;
      if(level_10>0) buffer_level_10[i] = Buffer[i] + level_10*_Point;
      if(level_11>0) buffer_level_11[i] = Buffer[i] + level_11*_Point;
      if(level_12>0) buffer_level_12[i] = Buffer[i] + level_12*_Point;
      if(level_13>0) buffer_level_13[i] = Buffer[i] + level_13*_Point;
      if(level_14>0) buffer_level_14[i] = Buffer[i] + level_14*_Point;
      if(level_15>0) buffer_level_15[i] = Buffer[i] + level_15*_Point;
      if(level_16>0) buffer_level_16[i] = Buffer[i] + level_16*_Point;
   }


	if(Backtesting && Period()!=TimeFrame)
	{
		Buffer[0]			= EMPTY_VALUE;
		BufferCurrent[0]	= EMPTY_VALUE;
	}

	return(0);
}


