//
// "00-DropBars_v100.mq4" -- show dropped bar info
//
//    Ver. 1.00  2009/10/26(Mon)  initial version
//
//
#property  copyright "00"
#property  link      "http://www.mql4.com/"

//---- defines

//---- indicator settings
#property  indicator_chart_window

#property  indicator_buffers  8

#property  indicator_color1  MediumTurquoise
#property  indicator_color2  MediumTurquoise
#property  indicator_color3  Gold
#property  indicator_color4  Gold
#property  indicator_color5  Crimson
#property  indicator_color6  Crimson
#property  indicator_color7  White
#property  indicator_color8  White

#property  indicator_width1  1
#property  indicator_width2  1
#property  indicator_width3  1
#property  indicator_width4  1
#property  indicator_width5  1
#property  indicator_width6  1
#property  indicator_width7  1
#property  indicator_width8  1

#property  indicator_style1  STYLE_DASHDOT
#property  indicator_style2  STYLE_DASHDOT
#property  indicator_style3  STYLE_DASHDOT
#property  indicator_style4  STYLE_DASHDOT
#property  indicator_style5  STYLE_DASHDOT
#property  indicator_style6  STYLE_DASHDOT
#property  indicator_style7  STYLE_DOT
#property  indicator_style8  STYLE_DOT

//---- indicator parameters
extern int     nDropBars0   = 2;                // number of dropped bars
extern int     nDropBars1   = 5;                // number of dropped bars
extern int     nDropBars2   = 10;               // number of dropped bars
extern bool    bDrawUpper   = false;            // draw upper line
extern bool    bDrawLower   = true;             // draw lower line
extern bool    bAlert0      = false;            // alert for nDropBars0
extern bool    bAlert1      = false;            // alert for nDropBars1
extern bool    bAlert2      = false;            // alert for nDropBars2
extern double  yOffset      = 0.05;             // y offset for info
extern string  sHour        = "時間";           // hour suffix
extern string  sMinute      = "分";             // min suffix
extern string  defFontName  = "ＭＳ ゴシック";  // font name
extern int     defFontSize  = 10;               // font size
extern int     nMaxBars     = 20000;            // maximum number of bars to calculate, 0: no limit

//---- indicator buffers
double Buffer0Upper[];  // 0: nDropBars0
double Buffer0Lower[];  // 1: nDropBars0
double Buffer1Upper[];  // 2: nDropBars1
double Buffer1Lower[];  // 3: nDropBars1
double Buffer2Upper[];  // 4: nDropBars2
double Buffer2Lower[];  // 5: nDropBars2
double Buffer3Upper[];  // 6: weekly gap
double Buffer3Lower[];  // 7: weekly gap

//---- vars
string   sIndicatorName   = "";
string   sIndSelf         = "00-DropBars_v100";
string   sPrefix;
datetime tAlertLast;
double   windowPriceMax;

//----------------------------------------------------------------------
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 init()
{
    string tf = TimeFrameToStr(Period());
    sIndicatorName = sIndSelf + "(" + tf + "," + nDropBars0 + "," + nDropBars1 + "," + nDropBars2 + ")";
    sPrefix = sIndicatorName;
    
    IndicatorShortName(sIndicatorName);
    
    SetIndexBuffer(0, Buffer0Upper);
    SetIndexBuffer(1, Buffer0Lower);
    SetIndexBuffer(2, Buffer1Upper);
    SetIndexBuffer(3, Buffer1Lower);
    SetIndexBuffer(4, Buffer2Upper);
    SetIndexBuffer(5, Buffer2Lower);
    SetIndexBuffer(6, Buffer3Upper);
    SetIndexBuffer(7, Buffer3Lower);
    
    SetIndexLabel(0, "drop>=" + nDropBars0);
    SetIndexLabel(1, "drop>=" + nDropBars0);
    SetIndexLabel(2, "drop>=" + nDropBars1);
    SetIndexLabel(3, "drop>=" + nDropBars1);
    SetIndexLabel(4, "drop>=" + nDropBars2);
    SetIndexLabel(5, "drop>=" + nDropBars2);
    SetIndexLabel(6, "weekly");
    SetIndexLabel(7, "weekly");
    
    SetIndexStyle(0, DRAW_HISTOGRAM);
    SetIndexStyle(1, DRAW_HISTOGRAM);
    SetIndexStyle(2, DRAW_HISTOGRAM);
    SetIndexStyle(3, DRAW_HISTOGRAM);
    SetIndexStyle(4, DRAW_HISTOGRAM);
    SetIndexStyle(5, DRAW_HISTOGRAM);
    SetIndexStyle(6, DRAW_HISTOGRAM);
    SetIndexStyle(7, DRAW_HISTOGRAM);

    Print("INIT");
}

//----------------------------------------------------------------------
void deinit()
{
    objErase();
}

//----------------------------------------------------------------------
void objErase(string name = "")
{
    int i;
    int n = ObjectsTotal();
    
    for (i = n - 1; i >= 0; i--) {
	string sName = ObjectName(i);
	if (StringFind(sName, sPrefix + name) == 0) {
	    ObjectDelete(sName);
	}
    }
}

//----------------------------------------------------------------------
void objText(string sName, datetime t, double p, string text, color col, int fontSize = 0, string fontName = "")
{
    sName = sPrefix + sName;
    
    if (fontSize == 0) {
	fontSize = defFontSize;
    }
    if (fontName == "") {
	fontName = defFontName;
    }
    
    ObjectCreate(sName, OBJ_TEXT, 0, 0, 0);
    ObjectSetText(sName, text, fontSize, fontName, col);
    ObjectSet(sName, OBJPROP_TIME1, t);
    ObjectSet(sName, OBJPROP_PRICE1, p);
}

//----------------------------------------------------------------------
void start()
{
    int limit;
    int counted_bars = IndicatorCounted();
    
    if (counted_bars > 0) {
	counted_bars--;
    }
    
    if (WindowPriceMax() != windowPriceMax) {
	windowPriceMax = WindowPriceMax();
	counted_bars = 0;
	objErase();
    }
    
    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--) {
	Buffer0Upper[i] = EMPTY_VALUE;
	Buffer0Lower[i] = EMPTY_VALUE;
	Buffer1Upper[i] = EMPTY_VALUE;
	Buffer1Lower[i] = EMPTY_VALUE;
	Buffer2Upper[i] = EMPTY_VALUE;
	Buffer2Lower[i] = EMPTY_VALUE;
	Buffer3Upper[i] = EMPTY_VALUE;
	Buffer3Lower[i] = EMPTY_VALUE;
    }
    
    int period = Period() * 60;
    double ps, pe;
    bool bDrop0 = false;
    bool bDrop1 = false;
    bool bDrop2 = false;
    int nDrop = 0;
    int iDrop = 0;
    datetime t0, t1, tDiff = 0;
    
    for (i = limit - 1; i >= -1; i--) {
	t1 = Time[i + 1];
	if (i >= 0) {
	    t0 = Time[i];
	} else {
	    t0 = TimeCurrent();
	}
	tDiff = t0 - t1;
	if (tDiff > period) {
	    if (bDrawLower && !bDrawUpper) {
		ps = 0;
		pe = Low[i];
	    } else if (!bDrawLower && bDrawUpper) {
		ps = High[i];
		pe = 9999;
	    } else {
		ps = 0;
		pe = 9999;
	    }
	    
	    iDrop = i;
	    nDrop = MathCeil(tDiff / period);
	    bDrop0 = (nDrop > nDropBars0);
	    bDrop1 = (nDrop > nDropBars1);
	    bDrop2 = (nDrop > nDropBars2);
	    
	    if (TimeDayOfWeek(t0) < TimeDayOfWeek(t1)) {
		Buffer3Upper[i] = ps;
		Buffer3Lower[i] = pe;
	    } else if (bDrop2) {
		Buffer2Upper[i] = ps;
		Buffer2Lower[i] = pe;
	    } else if (bDrop1) {
		Buffer1Upper[i] = ps;
		Buffer1Lower[i] = pe;
	    } else if (bDrop0) {
		Buffer0Upper[i] = ps;
		Buffer0Lower[i] = pe;
	    }
	    
	    if (bDrop0) {
		double pmax = WindowPriceMax();
		double pmin = WindowPriceMin();
		double p = pmax - (pmax - pmin) * yOffset;
		int m = (tDiff + 59) / 60;
		int h = m / 60;
		m = m % 60;
		string sInfo = "";
		if (h > 0) {
		    sInfo = h + sHour;
		}
		sInfo = sInfo + m + sMinute;
		sInfo = "drop=" + nDrop + "(" + sInfo + ")";
		objText("text.drop" + t0, t0, p, sInfo, White);
	    }
	}
    }
    
    if (iDrop == -1) {
	if ((bAlert0 && bDrop0) || (bAlert1 && bDrop1) || (bAlert2 && bDrop2)) {
	    Alert("[" + sIndSelf + "] " + sInfo);
	}
    }
}
