#property copyright "Copyright 2014, Murad Ismayilov" #property link "http://www.mql4.com/ru/users/wmlab" #property version "1.00" #property strict #property indicator_separate_window #property indicator_minimum 0 #property indicator_maximum 1 #property indicator_buffers 2 #property indicator_color1 clrRed #property indicator_color2 clrGreen #property indicator_width1 2 #property indicator_width2 2 #property indicator_style1 STYLE_SOLID #property indicator_style2 STYLE_SOLID double BufLowVol[]; double BufHighVol[]; double barVols[1]; double avgVol; int OnInit() { int barsInDay = 1440 / (PeriodSeconds() / 60); if (barsInDay == 0) return(INIT_FAILED); SetIndexBuffer(0, BufLowVol); SetIndexBuffer(1, BufHighVol); SetIndexStyle(0, DRAW_HISTOGRAM); SetIndexStyle(1, DRAW_HISTOGRAM); SetIndexShift(0, barsInDay); SetIndexShift(1, barsInDay); ArrayResize(barVols, barsInDay); int barCounts[1]; ArrayResize(barCounts, barsInDay); for (int i = 0; i < barsInDay; i++) { barVols[i] = 0.0; barCounts[i] = 0; } for (int iBar = 1; iBar <= Bars; iBar++) { int barOfDay = iBarOfDay(iTime(NULL, 0, iBar)); barVols[barOfDay] += GetVol(iBar); barCounts[barOfDay]++; } for (int i = 0; i < barsInDay; i++) { if (barCounts[i] != 0) barVols[i] /= barCounts[i]; } double minVol = barVols[ArrayMinimum(barVols)]; double maxVol = barVols[ArrayMaximum(barVols)]; avgVol = 0.0; for (int i = 0; i < barsInDay; i++) { if (maxVol > minVol) barVols[i] = (barVols[i] - minVol) / (maxVol - minVol); avgVol += barVols[i]; } avgVol /= barsInDay; /* Для отладки Print("PeriodSeconds() = ", PeriodSeconds()); Print("barsInDay = ", barsInDay); Print("iBarOfDay(D'2014.02.25 00:00:00') = ", iBarOfDay(D'2014.02.25 00:00:00')); Print("iBarOfDay(D'2014.02.25 00:01:00') = ", iBarOfDay(D'2014.02.25 00:01:00')); Print("iBarOfDay(D'2014.02.25 01:00:00') = ", iBarOfDay(D'2014.02.25 01:00:00')); Print("iBarOfDay(D'2014.02.25 23:59:30') = ", iBarOfDay(D'2014.02.25 23:59:30')); Print("Bars = ", Bars); Print("barVols[0] = ", barVols[0], " barCounts[0] = ", barCounts[0]); Print("barVols[M] = ", barVols[barsInDay / 2], " barCounts[M] = ", barCounts[barsInDay / 2]); Print("minVolIndex = ", ArrayMinimum(barVols), " maxVolIndex = ", ArrayMaximum(barVols)); Print("minVol = ", minVol, " maxVol = ", maxVol, " avgVol = ", avgVol); for (int i = 0; i < barsInDay; i++) Print("barVols[", i , "] = ", barVols[i]); */ return(INIT_SUCCEEDED); } int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { int limit = rates_total - prev_calculated; if (prev_calculated > 0) limit++; for(int iBar = 0; iBar < limit; iBar++) { int barOfDay = iBarOfDay(iTime(NULL, 0, iBar)); double vol = barVols[barOfDay]; if (vol >= avgVol) { BufLowVol[iBar] = EMPTY_VALUE; BufHighVol[iBar] = vol; } else { BufLowVol[iBar] = vol; BufHighVol[iBar] = EMPTY_VALUE; } } return(rates_total); } int iBarOfDay(datetime timeOpenBar) { int minutesInPeriod = PeriodSeconds() / 60; double minutesSinceMidnight = MathMod(timeOpenBar / 60, 1440); int barsSinceMidnight = (int)MathFloor(minutesSinceMidnight / minutesInPeriod); return (barsSinceMidnight); } double GetVol(int iBar) { return (iHigh(NULL, 0, iBar) - iLow(NULL, 0, iBar)); }