//+------------------------------------------------------------------+
//|                                                   Volatility.mq4 |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 LimeGreen
#property indicator_level1 0.0

extern int		DataType				= 2,		// {0=Volume, 1=High-Low, 2=Volume/(High-Low)}
					AveragingMethod	= 0,		// {0=Arithmetic, 1=Geometric, 2=Median}
					AveragingPeriods	= 48;		// Averaging Periods
extern bool		UseMinuteData		= false;	// Collect data from M1 chart
extern int		BarsLimit			= 0;		// Limit history to be processed

//---- indicator buffers
double Buffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
double volume[];
//+------------------------------------------------------------------+
int init()
{
	ArrayResize(volume,AveragingPeriods);
//---- indicator line
   IndicatorBuffers(1);
   IndicatorShortName("Volatility("+AveragingPeriods+")");
   SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer(0,Buffer);
   SetIndexLabel(0,"Volatility("+AveragingPeriods+")");
//----
   return(0);
}

//+------------------------------------------------------------------+
double GetData(int i = 0, int timeframe = 0)
{
	switch(DataType)
	{
		case 0: return(iVolume(NULL,timeframe,i));
		case 1: return((iHigh(NULL,timeframe,i)-iLow(NULL,timeframe,i))/Point);
		case 2: double range = (iHigh(NULL,timeframe,i)-iLow(NULL,timeframe,i))/Point;
					if(range>0.0)	return(iVolume(NULL,timeframe,i)/range);
					else				return(0.0);
		default:return(0.0);
	}
}

//+------------------------------------------------------------------+
double GetVolume(int i = 0)
{
	for(int n = 0; n < AveragingPeriods; n++)
	{
		if(UseMinuteData)
		{
			volume[n] = 0.0;
			int shift = iBarShift(NULL,PERIOD_M1,Time[i+n]);
			for(int m = Period()-1; m >= 0; m--)
				volume[n] += GetData(shift-m,PERIOD_M1);
		}
		else
			volume[n] = GetData(i+n);
	}

	switch(AveragingMethod)
	{
		case 0:	// Arithmetic
			double vol = 0.0;
			for(n = ArraySize(volume); n >= 0; n--)
				vol += volume[n];
			return(vol/ArraySize(volume));

		case 1:	// Geometric
			vol = 0.0;
			for(n = ArraySize(volume); n >= 0; n--)
				vol += volume[n]*volume[n];
			return(MathSqrt(vol));

		case 2:	// Median
			ArraySort(volume);
			return(volume[(ArraySize(volume)-1)/2]);

		default:	return(0.0);
	}
}

//+------------------------------------------------------------------+
int start()
{
	int limit = Bars-1-AveragingPeriods-IndicatorCounted();
	if(BarsLimit>0 && limit>BarsLimit)
		limit = BarsLimit;

	for(int i = MathMax(limit,1); i>=0; i--)
	{
		Buffer[i] = GetVolume(i);

//		Buffer[i] /= 1.0*PERIOD;
//		Buffer[i] /= 0.01*Close[i+PERIOD];
	}

	return(0);	
}

