{ 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;