Navigation´╝ÜHome > Content >

00-VolumeStat_v101.mq4

Time: 2016-10-04 | Download file:00-VolumeStat_v101.mq4

//
// "00-VolumeStat_v101.mq4" -- volume statisics on each bars, daily/weekly
//
//    Ver. 1.00  2008/10/20(Mon)  initial version
//    Ver. 1.01  2009/03/10(Tue)  add upper/lower predict lines
//
//
#property  copyright "00 - [email protected]"
#property  link      "http://www.mql4.com/"

//---- indicator settings
#property  indicator_separate_window

#property  indicator_buffers  4

#property indicator_minimum  0

#property  indicator_color1  LimeGreen
#property  indicator_color2  Gold
#property  indicator_color3  Orange
#property  indicator_color4  Orange

#property  indicator_width1  1
#property  indicator_width2  1
#property  indicator_width3  1
#property  indicator_width4  1

#property  indicator_style1  STYLE_SOLID
#property  indicator_style2  STYLE_SOLID
#property  indicator_style3  STYLE_DOT
#property  indicator_style4  STYLE_DOT

//---- defines

//---- indicator parameters
extern int    nDays       = 10;         // number of days
extern double sigma       = 2.0;        // sigma of upper/lower bounds
extern bool   bHistogram  = true;       // draw volume histogram or line
extern bool   bWeekly     = true;       // stat on daily or weekly
extern bool   bNormalize  = true;       // normalize volumes by total volume of D1/W1
extern int    hAfter      = 24;         // hours to draw average lines after Time[0]
extern color  colAfter    = FireBrick;  // color of average lines after Time[0]

//---- indicator buffers
double BufferVol[];    // 0: current volume
double BufferAve[];    // 1: average of volumes on same time (daily/weekly)
double BufferUpper[];  // 2: +sigma*SD line
double BufferLower[];  // 3: -sigma*SD line

//---- vars
string sIndicatorName  = "00-VolumeStat_v101";
string sPrefix;
int    g_window;
int    secDay;
int    secWeek;

//----------------------------------------------------------------------
void init()
{
    sIndicatorName = sIndicatorName + "(" + nDays + ")";
    sPrefix = sIndicatorName;
    
    IndicatorShortName(sIndicatorName);
    
    SetIndexBuffer(0, BufferVol);
    SetIndexBuffer(1, BufferAve);
    SetIndexBuffer(2, BufferUpper);
    SetIndexBuffer(3, BufferLower);
    
    SetIndexLabel(0, "Volume");
    SetIndexLabel(1, "Average");
    SetIndexLabel(2, "Upper, +SD*" + sigma);
    SetIndexLabel(3, "Lower, -SD*" + sigma);
    
    if (bHistogram) {
	SetIndexStyle(0, DRAW_HISTOGRAM);
    } else {
	SetIndexStyle(0, DRAW_LINE);
    }
    
    int nOffset = 24 * 60 / Period();
    
    SetIndexDrawBegin(0, nOffset);
    SetIndexDrawBegin(1, nOffset);
    SetIndexDrawBegin(2, nOffset);
    SetIndexDrawBegin(3, nOffset);
    
    secDay = 24 * 60 * 60;
    secWeek = 7 * 24 * 60 * 60;
}

//----------------------------------------------------------------------
void deinit()
{
    int n = ObjectsTotal();
    for (int i = n - 1; i >= 0; i--) {
	string sName = ObjectName(i);
	if (StringFind(sName, sPrefix) == 0) {
	    ObjectDelete(sName);
	}
    }
}

//----------------------------------------------------------------------
void checkData()
{
    datetime t0 = Time[WindowFirstVisibleBar()];
    if (bWeekly) {
	t0 -= nDays * secWeek;
    } else {
	t0 -= nDays * secDay;
    }
    if (iBarShift(NULL, 0, t0, true) < 0) {
	Print("Warning: no data, period= ", Period(), ", t= ", TimeToStr(t0));
    }
}

//----------------------------------------------------------------------
void objLine(string sName, datetime ts, double ps, datetime te, double pe, color col, int style = STYLE_SOLID, bool ray = false)
{
    sName = sPrefix + sName;
    
    ObjectCreate(sName, OBJ_TREND, g_window, 0, 0);
    ObjectSet(sName, OBJPROP_TIME1, ts);
    ObjectSet(sName, OBJPROP_PRICE1, ps);
    ObjectSet(sName, OBJPROP_TIME2, te);
    ObjectSet(sName, OBJPROP_PRICE2, pe);
    ObjectSet(sName, OBJPROP_COLOR, col);
    ObjectSet(sName, OBJPROP_STYLE, style);
    ObjectSet(sName, OBJPROP_RAY, ray);
}

//----------------------------------------------------------------------
void start()
{
    g_window = WindowFind(sIndicatorName);
    if (g_window < 0) {
	g_window = 1;
    }
    
    int i;
    int limit;
    int counted_bars = IndicatorCounted();
    
    if (counted_bars > 0) {
	counted_bars--;
    }
    
    limit = Bars - counted_bars;

    double vol[];
    ArrayResize(vol, nDays);
    
    checkData();
    
    int nAfter = hAfter * 60 / Period();
    double aveLast1 = 0;
    double aveLast2 = 0;
    double sdLast1 = 0;
    double sdLast2 = 0;
    
    for (i = limit - 1; i >= -nAfter; i--) {
	datetime time;
	if (i >= 0) {
	    time = Time[i];
	} else {
	    time = Time[0] - Period() * i * 60;
	    if (bWeekly) {
		time -= secWeek;
	    } else {
		time -= secDay;
		if (TimeDayOfWeek(time) == 0) {
		    time -= secDay * 2;
		}
	    }
	}
	for (int d = 0; d < nDays; d++) {
	    double vol0 = 1.0;
	    if (bNormalize) {
		double vv;
		if (bWeekly) {
		    if (iBarShift(NULL, PERIOD_M1, time, true) < 0) {
			Print("Warning: no data, PERIOD_M5, t= ", TimeToStr(time));
		    }
		    vv = iVolume(NULL, PERIOD_W1, MathMax(iBarShift(NULL, PERIOD_M5, time), 1));
		} else {
		    if (iBarShift(NULL, PERIOD_D1, time, true) < 0) {
			Print("Warning: no data, PERIOD_M1, t= ", TimeToStr(time));
		    }
		    vv = iVolume(NULL, PERIOD_D1, MathMax(iBarShift(NULL, PERIOD_M1, time), 1));
		}
		if (vv > 0) {
		    vol0 = 1.0 / vv;
		}
	    }
	    
	    int ibar = iBarShift(NULL, 0, time);
	    vol[d] = Volume[ibar] * vol0;
	    if (bWeekly) {
		time -= secWeek;
	    } else {
		time -= secDay;
		if (TimeDayOfWeek(time) == 0) {
		    // Sunday
		    time -= secDay * 2;
		}
	    }
	}
	
	double ave = iMAOnArray(vol, 0, nDays, 0, MODE_SMA, 0);
	double sd = iStdDevOnArray(vol, 0, nDays, 0, MODE_SMA, 0);
	
	if (i >= 0) {
	    BufferVol[i] = vol[0];
	    BufferAve[i] = ave;
	    BufferUpper[i] = ave + sd * sigma;
	    BufferLower[i] = ave - sd * sigma;
	} else {
	    datetime ts = Time[0] - Period() * i * 60;
	    datetime te = ts - Period() * 60;
	    double psAve = ave;
	    double peAve = aveLast1;
	    if (i == -1) {
		te -= Period() * 60;
		peAve = aveLast2;
	    }
	    objLine("line ave" + i,   ts, psAve, te, peAve, colAfter);
	    
	    ts = Time[0] - Period() * i * 60;
	    te = ts - Period() * 60;
	    double psSd = psAve + sd * sigma;
	    double peSd = sdLast1;
	    if (i == -1) {
		te -= Period() * 60;
		peSd = sdLast2;
	    }
	    objLine("line upper" + i, ts, psSd, te, peSd, colAfter, STYLE_DOT);
	}
	
	aveLast2 = aveLast1;
	aveLast1 = ave;

	sdLast2 = sdLast1;
	sdLast1 = ave + sd * sigma;
    }
    
    WindowRedraw();
}

Recommend