//
// "00-CLV_v100.mq4" -- Close Location Value
//
//    Ver. 1.00  2009/02/15(Sun)  initial version
//
//
#property  copyright "00"
#property  link      "http://www.mql4.com/"

//---- defines

//---- indicator settings
#property  indicator_separate_window

#property  indicator_buffers  2

#property  indicator_maximum  1.2
#property  indicator_minimum  -1.2

#property  indicator_color1  MediumOrchid
#property  indicator_color2  MediumOrchid

#property  indicator_width1  1
#property  indicator_width2  1

#property  indicator_style1  STYLE_SOLID
#property  indicator_style2  STYLE_DOT

#property indicator_level1  0.0
#property indicator_level2  -1.0
#property indicator_level3  1.0

//---- indicator parameters
extern int timeFrame   = 0;     // time frame
extern int nPeriod     = 27;    // CLV period
extern int nSmooth     = 7;     // smooth length
extern int maMethod    = 0;     // 0: SMA, 1: EMA, 2: SMMA, 3: LWMA
extern int nMaxBars    = 2000;  // maximum number of bars to calculate, 0: no limit

//---- indicator buffers
double BufferClv[];     // 0: CLV
double BufferSmooth[];  // 1: CLV, smoothed

//---- vars
string    sIndicatorName;
string    sIndSelf  = "00-CLV_v100";
datetime  tAlertLast;

//----------------------------------------------------------------------
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()
{
    if (timeFrame == 0) {
	timeFrame = Period();
    }
    
    string tf = TimeFrameToStr(timeFrame);
    sIndicatorName = sIndSelf + "(" + tf + "," + nPeriod + "," + nSmooth + ")";
    
    IndicatorShortName(sIndicatorName);
    
    SetIndexBuffer(0, BufferClv);
    SetIndexBuffer(1, BufferSmooth);
    
    SetIndexLabel(0, "CLV");
    SetIndexLabel(1, "CLV, smoothed");
    
    SetIndexStyle(0, DRAW_LINE);
    SetIndexStyle(1, DRAW_LINE);
    
    SetIndexDrawBegin(0, nPeriod);
    SetIndexDrawBegin(1, nPeriod + nSmooth);
}

//----------------------------------------------------------------------
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--) {
	BufferClv[i] = EMPTY_VALUE;
	BufferSmooth[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]);
	    BufferClv[i]    = iCustom(NULL, timeFrame, nPeriod, nSmooth, maMethod, nMaxBars, 0, x);
	    BufferSmooth[i] = iCustom(NULL, timeFrame, nPeriod, nSmooth, maMethod, nMaxBars, 1, x);
	}
	
	return;
    }
    
    // timeFrame == Period()
    for (i = limit - 1; i >= 0; i--) {
	double hi = High[iHighest(NULL, 0, MODE_HIGH, nPeriod, i)];
	double lo = Low[iLowest(NULL, 0, MODE_LOW, nPeriod, i)];
	double close = Close[i];
	double clv = 0;
	if (hi != lo) {
	    clv = ((close - lo) - (hi - close)) / (hi - lo);
	}
	BufferClv[i] = clv;
    }
    
    for (i = limit - 1; i >= 0; i--) {
	BufferSmooth[i] = iMAOnArray(BufferClv, 0, nSmooth, 0, maMethod, i);
    }
}
