{*************************************************************************** * * Indicator: Trend StdDev * Gary Fritz 1/7/99 * 7/20/99: Minor fixes and improvements * * Computes the standard deviation of Nlengs different lengths of * price action: C-C[1], C-C[3], C-C[8], C-C[15], etc. * In a pure Random Walk, the N^2-length sample will have a StdDev * of N times the StdDev of the 1-length sample. If a particular * price example shows larger-than-expected StdDevs it indicates * a trending market; if the StdDevs are smaller than the expected * values it indicates an anti-trending (reversing) market. * * Doesn't start recording data until 100 bars are available. * Needs a lot of bars to compute valid data anyway, so just apply it * to a long chart. * * StdDev values are printed to the Print Log. * * References: * TASC Aug 95, Alex Saitta, Trending on a Historical Basis * TASC Jan 92, E. Michael Poulos, Futures According to Trend Tendency * (Thanks to Dave Chamness for the pointer & explanation!) * * Inputs: Price Price point used in SD calculations * PlotStD If true, plots StdDev for 4 sample lengths * (Probably not very useful) * ***************************************************************************} Inputs: Price(Close), PlotStD(False); { Plot Std Devs of 9, 25, 49, 81-long samples } Vars: Nlengs(10); { Compute stddev for lengths 1:Nlengs^2 } Vars: Nbars(0), Index(0), Barsback(0), Diff(0), Mean(0), Sigma(0), SD1(0); Arrays: BarSum[20](0), BarSum2[20](0); if (currentBar = 1) then begin for Index = 1 to Nlengs begin Nbars = 0; BarSum[Index] = 0; BarSum2[Index] = 0; end; end; { On each bar, add up sums & sum-of-squares, for lookback lengths of Index^2 } if (currentBar > Nlengs*Nlengs) then begin Nbars = Nbars+1; for Index = 1 to Nlengs begin if (Index = 1) then Diff = (Price - Price[1]) / Price[1] else Diff = (Price - Price[Index*Index-1]) / Price[Index*Index-1]; BarSum[Index] = BarSum[Index] + Diff; BarSum2[Index] = BarSum2[Index] + Diff*Diff; end; end; if LastBarOnChart and (Nbars > 1) then begin print("Trend data for ",GetSymbolName,":"); if (DataCompression = 4) then print(" Monthly bars") else if (DataCompression = 3) then print(" Weekly bars") else if (DataCompression = 2) then print(" Daily bars") else if (DataCompression = 1) then print(" ",BarInterval:3:0,"-minute bars"); print(Nbars:5:0," samples"); { An N^2 day test, with a perfect random walk, is expected to have a standard deviation N times larger than a 1-day test. So the "Expected" column is N, and the "Actual" column is N^2-day_StdDev / 1-day_StdDev. } print("Bars StdDev Expected Actual"); for Index = 1 to Nlengs begin Mean = BarSum[Index] / Nbars; Sigma = SquareRoot((BarSum2[Index]-Nbars*Mean*Mean)/(Nbars-1)); if (Index = 1) then SD1 = Sigma; print(Index*Index:4:0," ",Sigma:2:5," ",Index:2:0," ",Sigma/SD1:2:5); end; end; { If desired, plot 4 of the SD's. I'm not sure this is useful but I thought somebody might like to see it. The repeated code is not very pretty, but EL's limits made it a pain to do it via looping. } if PlotStD and (Nbars > 10) then begin Mean = BarSum[3] / Nbars; Sigma = SquareRoot((BarSum2[3]-Nbars*Mean*Mean)/(Nbars-1)); plot1(Sigma, "StD3"); Mean = BarSum[5] / Nbars; Sigma = SquareRoot((BarSum2[5]-Nbars*Mean*Mean)/(Nbars-1)); plot2(Sigma, "StD5"); Mean = BarSum[7] / Nbars; Sigma = SquareRoot((BarSum2[7]-Nbars*Mean*Mean)/(Nbars-1)); plot3(Sigma, "StD7"); Mean = BarSum[9] / Nbars; Sigma = SquareRoot((BarSum2[9]-Nbars*Mean*Mean)/(Nbars-1)); plot4(Sigma, "StD9"); end;