//
// "00-MTFizer_v103.mq4" -- make single time frame indicator work on MTF
//
//    Ver. 1.00  2009/04/19(Sun)  initial version
//    Ver. 1.01  2009/09/20(Sun)  default for ADXm
//                                max buffers/params 4 -> 8
//    Ver. 1.02  2009/10/27(Tue)  relative timeframe
//    Ver. 1.03  2010/01/15(Fri)  arrow style
//
//
#property  copyright "00mql4@gmail.com"
#property  link      "http://www.mql4.com/"

//---- defines

//---- indicator settings
#property  indicator_separate_window

#property  indicator_buffers  8

#property  indicator_color1  LightSlateGray
#property  indicator_color2  DodgerBlue
#property  indicator_color3  SandyBrown
#property  indicator_color4  Lavender
#property  indicator_color5  Lavender
#property  indicator_color6  -1
#property  indicator_color7  -1
#property  indicator_color8  -1

#property  indicator_style1  STYLE_SOLID
#property  indicator_style2  STYLE_SOLID
#property  indicator_style3  STYLE_SOLID
#property  indicator_style4  STYLE_DOT
#property  indicator_style5  STYLE_DOT
#property  indicator_style6  STYLE_SOLID
#property  indicator_style7  STYLE_SOLID
#property  indicator_style8  STYLE_SOLID

#property  indicator_width1  1
#property  indicator_width2  2
#property  indicator_width3  2
#property  indicator_width4  1
#property  indicator_width5  1
#property  indicator_width6  1
#property  indicator_width7  1
#property  indicator_width8  1

//---- indicator parameters
extern int     timeFrame    = 0;            // time frame
extern string  sIndicator   = "ADXm";       // indicator name to be MTFized
extern int     nBuffer      = 5;            // number of buffers sIndicator uses
//
extern int     shapeStyle0  = DRAW_LINE;    // shape style for buffer 0
extern int     shapeStyle1  = DRAW_LINE;    // shape style for buffer 1
extern int     shapeStyle2  = DRAW_LINE;    // shape style for buffer 2
extern int     shapeStyle3  = DRAW_LINE;    // shape style for buffer 3
extern int     shapeStyle4  = DRAW_LINE;    // shape style for buffer 4
extern int     shapeStyle5  = DRAW_LINE;    // shape style for buffer 5
extern int     shapeStyle6  = DRAW_LINE;    // shape style for buffer 6
extern int     shapeStyle7  = DRAW_LINE;    // shape style for buffer 7
//
extern int     emptyValue0  = EMPTY_VALUE;  // empty value for buffer 0
extern int     emptyValue1  = EMPTY_VALUE;  // empty value for buffer 1
extern int     emptyValue2  = 0;            // empty value for buffer 2
extern int     emptyValue3  = EMPTY_VALUE;  // empty value for buffer 3
extern int     emptyValue4  = EMPTY_VALUE;  // empty value for buffer 4
extern int     emptyValue5  = EMPTY_VALUE;  // empty value for buffer 5
extern int     emptyValue6  = EMPTY_VALUE;  // empty value for buffer 6
extern int     emptyValue7  = EMPTY_VALUE;  // empty value for buffer 7
//
extern int     nArgs        = 2;            // number of args of sIndicator
extern double  arg0         = 14;           // 1st arg for sIndicator
extern double  arg1         = 25;           // 2nd arg for sIndicator
extern double  arg2         = 0;            // 3rd arg for sIndicator
extern double  arg3         = 0;            // 4th arg for sIndicator
extern double  arg4         = 0;            // 5th arg for sIndicator
extern double  arg5         = 0;            // 6th arg for sIndicator
extern double  arg6         = 0;            // 7th arg for sIndicator
extern double  arg7         = 0;            // 8th arg for sIndicator
//
extern int     arrow0       = 159;          // symbol for DRAW_ARROW 0
extern int     arrow1       = 159;          // symbol for DRAW_ARROW 1
extern int     arrow2       = 159;          // symbol for DRAW_ARROW 2
extern int     arrow3       = 159;          // symbol for DRAW_ARROW 3
extern int     arrow4       = 159;          // symbol for DRAW_ARROW 4
extern int     arrow5       = 159;          // symbol for DRAW_ARROW 5
extern int     arrow6       = 159;          // symbol for DRAW_ARROW 6
extern int     arrow7       = 159;          // symbol for DRAW_ARROW 7
//
extern int     nMaxBars     = 20000;        // maximum number of bars to calculate, 0: no limit

//---- indicator buffers
double Buffer0[];  // Buffer 0
double Buffer1[];  // Buffer 1
double Buffer2[];  // Buffer 2
double Buffer3[];  // Buffer 3
double Buffer4[];  // Buffer 4
double Buffer5[];  // Buffer 5
double Buffer6[];  // Buffer 6
double Buffer7[];  // Buffer 7

//---- vars
string sIndicatorName;
string sIndSelf  = "00-MTFizer_v103";

//----------------------------------------------------------------------
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("??");
}

//----------------------------------------------------------------------
void test_WPR_T3()
{
    sIndicator   = "WPR_T3";
    nBuffer      = 3;
    
    shapeStyle0  = DRAW_ARROW;
    shapeStyle1  = DRAW_ARROW;
    
    emptyValue2  = EMPTY_VALUE;
    
    nArgs        = 4;
    arg0         = 14;
    arg1         = 4;
    arg2         = 10;
    arg3         = 0.7;
}

//----------------------------------------------------------------------
void init()
{
    //test_WPR_T3();
    
    if (timeFrame == 0) {
	timeFrame = Period();
    }
    
    string sTf = TimeFrameToStr(timeFrame);
    
    string sArg;
    if (nArgs >= 1) sArg = DoubleToStr(arg0, 2);
    if (nArgs >= 2) sArg = sArg + "," + DoubleToStr(arg1, 2);
    if (nArgs >= 3) sArg = sArg + "," + DoubleToStr(arg2, 2);
    if (nArgs >= 4) sArg = sArg + "," + DoubleToStr(arg3, 2);
    if (nArgs >= 5) sArg = sArg + "," + DoubleToStr(arg4, 2);
    if (nArgs >= 6) sArg = sArg + "," + DoubleToStr(arg5, 2);
    if (nArgs >= 7) sArg = sArg + "," + DoubleToStr(arg6, 2);
    if (nArgs >= 8) sArg = sArg + "," + DoubleToStr(arg7, 2);
    
    sIndicatorName = sIndSelf + "(" + sTf + "," + sIndicator + "," + sArg + ")";
    
    IndicatorBuffers(nBuffer);
    
    IndicatorShortName(sIndicatorName);
    
    SetIndexBuffer(0, Buffer0);
    SetIndexBuffer(1, Buffer1);
    SetIndexBuffer(2, Buffer2);
    SetIndexBuffer(3, Buffer3);
    SetIndexBuffer(4, Buffer4);
    SetIndexBuffer(5, Buffer5);
    SetIndexBuffer(6, Buffer6);
    SetIndexBuffer(7, Buffer7);
    
    SetIndexLabel(0, "Buffer 0");
    SetIndexLabel(1, "Buffer 1");
    SetIndexLabel(2, "Buffer 2");
    SetIndexLabel(3, "Buffer 3");
    SetIndexLabel(4, "Buffer 4");
    SetIndexLabel(5, "Buffer 5");
    SetIndexLabel(6, "Buffer 6");
    SetIndexLabel(7, "Buffer 7");
    
    SetIndexStyle(0, shapeStyle0);
    SetIndexStyle(1, shapeStyle1);
    SetIndexStyle(2, shapeStyle2);
    SetIndexStyle(3, shapeStyle3);
    SetIndexStyle(4, shapeStyle4);
    SetIndexStyle(5, shapeStyle5);
    SetIndexStyle(6, shapeStyle6);
    SetIndexStyle(7, shapeStyle7);
    
    SetIndexEmptyValue(0, emptyValue0);
    SetIndexEmptyValue(1, emptyValue1);
    SetIndexEmptyValue(2, emptyValue2);
    SetIndexEmptyValue(3, emptyValue3);
    SetIndexEmptyValue(4, emptyValue4);
    SetIndexEmptyValue(5, emptyValue5);
    SetIndexEmptyValue(6, emptyValue6);
    SetIndexEmptyValue(7, emptyValue7);
    
    SetIndexArrow(0, arrow0);
    SetIndexArrow(1, arrow1);
    SetIndexArrow(2, arrow2);
    SetIndexArrow(3, arrow3);
    SetIndexArrow(4, arrow4);
    SetIndexArrow(5, arrow5);
    SetIndexArrow(6, arrow6);
    SetIndexArrow(7, arrow7);
}

//----------------------------------------------------------------------
int NextTimeFrame(int timeFrame)
{
    switch (timeFrame) {
    case PERIOD_M1:  return(PERIOD_M5);
    case PERIOD_M5:  return(PERIOD_M15);
    case PERIOD_M15: return(PERIOD_M30);
    case PERIOD_M30: return(PERIOD_H1);
    case PERIOD_H1:  return(PERIOD_H4);
    case PERIOD_H4:  return(PERIOD_D1);
    case PERIOD_D1:  return(PERIOD_W1);
    case PERIOD_W1:  return(PERIOD_MN1);
    case PERIOD_MN1: return(PERIOD_MN1);
    }
    
    return(NextTimeFrame(Period()));
}

//----------------------------------------------------------------------
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--) {
	Buffer0[i]  = EMPTY_VALUE;
	Buffer1[i]  = EMPTY_VALUE;
	Buffer2[i]  = EMPTY_VALUE;
	Buffer3[i]  = EMPTY_VALUE;
	Buffer4[i]  = EMPTY_VALUE;
	Buffer5[i]  = EMPTY_VALUE;
	Buffer6[i]  = EMPTY_VALUE;
	Buffer7[i]  = EMPTY_VALUE;
    }
    
    if (timeFrame != Period()) {
	// MTF
	if (timeFrame < 0) {
	    i = timeFrame;
	    timeFrame = Period();
	    for (; i < 0; i++) {
		timeFrame = NextTimeFrame(timeFrame);
	    }
	}
	limit = MathMax(limit, timeFrame / Period());
	for (i = limit - 1; i >= 0; i--) {
	    int x = iBarShift(NULL, timeFrame, Time[i]);
	    
	    double value[8];
	    for (int mode = 0; mode < nBuffer; mode++) {
		value[mode] = iCustom(NULL, timeFrame, sIndSelf,
				      0, sIndicator, nBuffer,
				      shapeStyle0, shapeStyle1, shapeStyle2, shapeStyle3, shapeStyle4, shapeStyle5, shapeStyle6, shapeStyle7,
				      emptyValue0, emptyValue1, emptyValue2, emptyValue3, emptyValue4, emptyValue5, emptyValue6, emptyValue7,
				      nArgs, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
				      arrow0, arrow1, arrow2, arrow3, arrow4, arrow5, arrow6, arrow7,
				      nMaxBars, mode, x);
	    }
	    
	    if (nBuffer > 0) Buffer0[i] = value[0];
	    if (nBuffer > 1) Buffer1[i] = value[1];
	    if (nBuffer > 2) Buffer2[i] = value[2];
	    if (nBuffer > 3) Buffer3[i] = value[3];
	    if (nBuffer > 4) Buffer4[i] = value[4];
	    if (nBuffer > 5) Buffer5[i] = value[5];
	    if (nBuffer > 6) Buffer6[i] = value[6];
	    if (nBuffer > 7) Buffer7[i] = value[7];
	}
	
	return;
    }
    
    // timeFrame == Period()
    for (i = limit - 1; i >= 0; i--) {
	for (mode = 0; mode < nBuffer; mode++) {
	
	    switch (nArgs) {
	    
	    case 0: value[mode] = iCustom(NULL, 0, sIndicator, mode, i); break;
	    case 1: value[mode] = iCustom(NULL, 0, sIndicator, arg0, mode, i); break;
	    case 2: value[mode] = iCustom(NULL, 0, sIndicator, arg0, arg1, mode, i); break;
	    case 3: value[mode] = iCustom(NULL, 0, sIndicator, arg0, arg1, arg2, mode, i); break;
	    case 4: value[mode] = iCustom(NULL, 0, sIndicator, arg0, arg1, arg2, arg3, mode, i); break;
	    case 5: value[mode] = iCustom(NULL, 0, sIndicator, arg0, arg1, arg2, arg3, arg4, mode, i); break;
	    case 6: value[mode] = iCustom(NULL, 0, sIndicator, arg0, arg1, arg2, arg3, arg4, arg5, mode, i); break;
	    case 7: value[mode] = iCustom(NULL, 0, sIndicator, arg0, arg1, arg2, arg3, arg4, arg5, arg6, mode, i); break;
	    case 8: value[mode] = iCustom(NULL, 0, sIndicator, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, mode, i); break;
	    
	    default:
		// not supported
		break;
	    }
	}
	
	if (nBuffer > 0) Buffer0[i] = value[0];
	if (nBuffer > 1) Buffer1[i] = value[1];
	if (nBuffer > 2) Buffer2[i] = value[2];
	if (nBuffer > 3) Buffer3[i] = value[3];
	if (nBuffer > 4) Buffer4[i] = value[4];
	if (nBuffer > 5) Buffer5[i] = value[5];
	if (nBuffer > 6) Buffer6[i] = value[6];
	if (nBuffer > 7) Buffer7[i] = value[7];
    }
}
