//
// "00-MA_v101.mq4" -- Moving Average
//
//    Ver. 1.00  2009/01/03(Sat)  initial version
//    Ver. 1.01  2010/01/03(Sun)  rewrote
//
//
#property  copyright "00mql4@gmail.com"
#property  link      "http://www.mql4.com/"

//---- defines

//---- indicator settings
#property  indicator_chart_window

#property  indicator_buffers  3

#property  indicator_color1  Silver
#property  indicator_color2  DodgerBlue
#property  indicator_color3  Crimson

#property  indicator_width1  1
#property  indicator_width2  1
#property  indicator_width3  1

#property  indicator_style1  STYLE_SOLID
#property  indicator_style2  STYLE_SOLID
#property  indicator_style3  STYLE_SOLID

//---- indicator parameters
extern int  timeFrame     = 0;         // time frame
extern int  period        = 20;        // period
extern int  maShift       = 0;         // shift
extern int  maMethod      = MODE_SMA;  // 0:SMA 1:EMA 2:SMMA 3:LWMA
extern int  appliedPrice  = 0;         // 0:CLOSE 1:OPEN 2:HIGH 3:LOW 4:MEDIAN 5:TYPICAL 6:WEIGHTED
extern bool bColorize     = true;      // up/down colorize
extern int  nMaxBars      = 20000;     // maximum number of bars to calculate, 0: no limit

//---- indicator buffers
double BufferMa[];    // 0: MA
double BufferUp[];    // 1: up
double BufferDown[];  // 2: down

//---- vars
string   sIndicatorName   = "";
string   sIndSelf         = "00-MA_v101";

//----------------------------------------------------------------------
string TimeFrameToStr(int timeFrame)
{
    switch (timeFrame) {
    case 1:     return("M1");
    case 5:     return("M5");
    case 15:    return("M15");
    case 30:    return("M30");
    case 60:    return("H1");
    case 240:   return("H4");
    case 1440:  return("D1");
    case 10080: return("W1");
    case 43200: return("MN");
    }
    
    return("??");
}

//----------------------------------------------------------------------
string MethodToStr(int maMethod)
{
    switch (maMethod) {
    case MODE_SMA:  return("SMA");
    case MODE_EMA:  return("EMA");
    case MODE_SMMA: return("SMMA");
    case MODE_LWMA: return("LWMA");
    }
    
    return("??");
}

//----------------------------------------------------------------------
void init()
{
    if (timeFrame == 0) {
	timeFrame = Period();
    }
    
    string tf = TimeFrameToStr(timeFrame);
    sIndicatorName = sIndSelf + "(" + tf + "," + period + "," + MethodToStr(maMethod) + ")";
    
    IndicatorShortName(sIndicatorName);
    
    SetIndexBuffer(0, BufferMa);
    SetIndexBuffer(1, BufferUp);
    SetIndexBuffer(2, BufferDown);
    
    SetIndexLabel(0, "MA");
    SetIndexLabel(1, "Up");
    SetIndexLabel(2, "Down");
    
    SetIndexStyle(0, DRAW_LINE);
    SetIndexStyle(1, DRAW_LINE);
    SetIndexStyle(2, DRAW_LINE);
    
    int n = period;
    if (maMethod != MODE_SMA) {
	n *= 4;
    }
    SetIndexDrawBegin(0, n);
    SetIndexDrawBegin(1, n);
    SetIndexDrawBegin(2, n);
}

//----------------------------------------------------------------------
void start()
{
    int limit;
    int counted_bars = IndicatorCounted();
    
    if (counted_bars > 0) {
	counted_bars--;
    }
    
    limit = Bars - counted_bars;
    int limit0 = limit;
    if (nMaxBars > 0) {
	limit = MathMin(limit, nMaxBars);
    }
    
    // clear beyond limits
    for (int i = limit0 - 1; i >= limit; i--) {
	BufferMa[i]   = 0;
	BufferUp[i]   = EMPTY_VALUE;
	BufferDown[i] = EMPTY_VALUE;
    }
    
    if (timeFrame != Period()) {
	// MTF
	limit = MathMax(limit, timeFrame / Period());
	for (i = limit - 1; i >= 0; i--) {
	    int x = iBarShift(NULL, timeFrame, Time[i]);
	    BufferMa[i]   = iCustom(NULL, timeFrame, sIndSelf, 0, period, maShift, maMethod, appliedPrice, bColorize, nMaxBars, 0, x);
	    BufferUp[i]   = iCustom(NULL, timeFrame, sIndSelf, 0, period, maShift, maMethod, appliedPrice, bColorize, nMaxBars, 1, x);
	    BufferDown[i] = iCustom(NULL, timeFrame, sIndSelf, 0, period, maShift, maMethod, appliedPrice, bColorize, nMaxBars, 2, x);
	}
	
	return;
    }
    
    // timeFrame == Period()
    for (i = limit - 1; i >= 0; i--) {
	double ave0 = iMA(NULL, 0, period, maShift, maMethod, appliedPrice, i);
	BufferMa[i] = ave0;
	
	BufferUp[i] = EMPTY_VALUE;
	BufferDown[i] = EMPTY_VALUE;
	
	if (bColorize) {
	    double ave1 = BufferMa[i + 1];
	    if (ave0 > ave1) {
		BufferUp[i + 1] = ave1;
		BufferUp[i] = ave0;
	    } else if (ave0 < ave1) {
		BufferDown[i + 1] = ave1;
		BufferDown[i] = ave0;
	    }
	}
    }
}
