{
Function: _StdDevMeanArray (Standard Deviation of array values )
Purpose: Calculate the mean and standard deviation in single function using an alternative
algorithm to calculation standard deviation described in Wikipedia.
Discussion: The TS standard deviation functions do not ouput the mean used in calculating the
standard deviation. Therefore, in many custom routines that use both mean and
standard deviation, such as Bollinger Bands and Z-Score, there is duplication of
the mean calculation.
This routine returns both the mean and the standard deviation in a single function
and therefore avoids the necessity of performing a repeat calculation of the mean.
Source: Casey (TS forums) found this method, described in Wikipedia. It is encorporated in
this routine for use with arrays.
Author: MarkSanDiego
Updated: 08/28/08 original version
02/19/09 alternative method of calculating standard deviation implemented
02/21/09 documentation improved
09/13/09 converted _StdDevMean routine for use with arrays (_StdDevMeanArray)
09/17/09 original version saved as Series Function by mistake. Now recompiled as Simple Function.
04/06/10 made Divisor intrabarpersist, since may be initialized during BarStatus(1) <> 2
Usage: Put the following in the calling routine:
______________________________________________________________________________________________________________________
inputs:
Price(Close),
Length(100), { length used to measure average and standard deviation }
DataType(1), { = 1 for Variance and standard deviation of entire population; }
{ = 2 for Variance and standard deviation of sample of population }
vars:
oMean(0), { average price; oAvg = Average(Price, Length) }
oStdDev(0); { standard deviation of price; oSD = StandardDev(Price, Length) }
value1 = _StdDevMeanFC(Price, Length, DataType, oMean, oStdDev);
_______________________________________________________________________________________________________________________
}
inputs:
Price[nn](NumericArrayRef), { array containing values for standard deviation calculation. Element 0 not used. }
Length(NumericSimple), { number of recent elements used to calculate average and standard deviation }
{ this technique allows one to calculate a running standard deviation or average
without increasing MaxBarsBack for an indicator or strategy }
DataType(NumericSimple), { = 1 for Variance and standard deviation of entire population }
{ = 2 for Variance and standard deviation of sample of population }
{ outputs: }
oMean(NumericRef), { average price; oMean = Average(Price, Length) }
oStdDev(NumericRef); { standard deviation of price series; oSD = StandardDev(Price), Length) }
variables:
j(0),
x(0),
rLen(1/Length),
intrabarpersist Divisor(0), { divisor used for variance of entire/sample population }
{ must be intrabarpersist since initialization may occur when BarStatus(1) <> 2 }
rDiv(0), { inverse of divisor to allow faster multiplication }
Sum(0), { sum used to calculate Mean }
SumSq(0), { sum of squares of (Price - oMean) }
MeanSq(0);
{ INLINE CODE STARTS HERE: Function _StdDevMean }
{ uncomment this section when extracting this function for in-line code }
{
inputs:
Length(100), { length used to measure average and standard deviation }
DataType(1), { = 1 for Variance and standard deviation of entire population; }
{ = 2 for Variance and standard deviation of sample of population }
vars:
oMean(0), { average price; oAvg = Average(Price, Length) }
oStdDev(0); { standard deviation of price; oSD = StandardDev(Price, Length) }
arrays:
PriceArray[1000](0);
value1 = _StdDevMeanArray(DoCalc, PriceArray, Length, DataType, oMean, oStdDev);
}
once begin
if DataType = 1 then begin
Divisor = Length;
if Length < 1 then RaiseRunTimeError("_StdDevMean: StdDev of entire population requires Length >= 1");
end else begin
Divisor = Length - 1;
if Length < 2 then RaiseRunTimeError("_StdDevMean: StdDev of sample of population requires Length >= 2");
end;
rDiv = 1/Divisor;
end;
if CurrentBar >= Length then begin
Sum = 0;
SumSq = 0;
for j = 1 to Length begin
x = Price[j];
Sum = Sum + x;
SumSq = SumSq + x * x;
end;
oMean = Sum * rLen;
MeanSq = SumSq * rLen;
x = MeanSq - oMean * oMean;
if x > 0 then
oStdDev = SquareRoot( x )
else
oStdDev = 0;
{ INLINE CODE STOPS HERE }
_StdDevMeanArray = oStdDev;
end;