PureBytes Links
Trading Reference Links
|
At 10:26 AM 7/3/2004, Alex Matulich wrote:
>A much faster version that uses no loops (except for initialization) can
>be found at
>
>http://unicorn.us.com/trading/src/_LinRegSlopeSFC.txt
That version assumes the X axis = CurrentBar. His version did not make that
assumption.
Below is listed my function for doing this. It uses all the tricks I know of
to improve accuracy and speed. It also returns the standard error value in
addition to the slope and intercept. I have tested it on TS 8 but not on
TS2000i.
Bob Fulks
{ *******************************************************************
Function : LinearRegXY.bf
Written : 3/8/03
Last Edit : 7/3/04 - Comments added
Provided By : Bob Fulks
Description : This function calculates the linear regression
coefficients between two price series. It uses the standard
formulas with three enhancements to improve speed and accuracy.
> It offsets each price input by a constant so that the
difference calculations will not be subtracting two
large near-equal numbers.
> It uses the fast calculation of simple moving averages
to eliminate loops to greatly speed up the calculations.
> It repeated the exact calculation every 100 bars to
eliminate any build-up of numerical errors.
Inputs:
DepPrice: The dependent price series.
IndPrice: The independent price series.
Length: The number of bars used in the calculation.
Outputs returned through calls by reference:
Intercept: The value of the intercept.
Slope: The slope of the linear regression line.
StdErr: The standard error
Output of function call:
+1 if no errors
-1 if errors
© 2004 Bob Fulks, All rights reserved.
********************************************************************}
Input: DepPrice(NumericSeries), {Y axis price}
IndPrice(NumericSeries), {X axis price}
Length(NumericSimple), {Number of bars}
Intercept(NumericRef),
Slope(NumericRef),
StdErr(NumericRef);
Vars: Yo(0), Xo(0), Dep(0), Ind(0), DepL(0), IndL(0),
AveX(0), AveY(0), AveXY(0), AveXsq(0), AveYsq(0),
SumX(0), SumY(0), SumXY(0), SumXsq(0), SumYsq(0),
Denom(0), Num(0), j(0);
if Mod(CurrentBar, 100) = 1 then begin
SumXY = 0;
SumXsq = 0;
SumYsq = 0;
SumX = 0;
SumY = 0;
Yo = DepPrice; {Y Price offset}
Xo = IndPrice; {X Price offset}
for j = 0 to Length - 1 begin
Dep = DepPrice[j]-Yo; {Offset prices}
Ind = IndPrice[j]-Xo;
SumXY = SumXY + Ind * Dep;
SumXsq = SumXsq + Square(Ind);
SumYsq = SumYsq + Square(Dep);
SumX = SumX + Ind;
SumY = SumY + Dep;
end;
AveXY = SumXY / Length;
AveXsq = SumXsq / Length;
AveYsq = SumYsq / Length;
AveX = SumX / Length;
AveY = SumY / Length;
end else begin {Fast calculation of averages}
Dep = DepPrice - Yo;
Ind = IndPrice - Xo;
DepL = DepPrice[Length] - Yo;
IndL = IndPrice[Length] - Xo;
AveXY = AveXY[1] + (Ind * Dep - IndL * DepL) / Length;
AveXsq = AveXsq[1] + (Square(Ind) - Square(IndL)) / Length;
AveYsq = AveYsq[1] + (Square(Dep) - Square(DepL)) / Length;
AveX = AveX[1] + (Ind - IndL) / Length;
AveY = AveY[1] + (Dep - DepL) / Length;
end;
LinearRegXY.bf = +1;
Denom = AveXsq - Square(AveX);
if Denom <> 0
then begin
Slope = (AveXY - AveX * AveY) / Denom;
Num = (AveYsq - Square(AveY) - (Square(AveXY - AveX * AveY)) / Denom);
end
else begin
Print("LinearRegXY.bf ", Date:7:0, " Div by 0 ", IndPrice:8:2, DepPrice:8:2,
AveXsq:12:2, Square(AveX):12:2, Denom:12:2, Num:12:0);
LinearRegXY.bf = -1;
end;
Intercept = (AveY + Yo) - Slope * (AveX + Xo);
if Num > 0
then begin
StdErr = SquareRoot(Num * Length / (Length - 2));
end else begin
Print("LinearRegXY.bf ", Date:7:0, " Sqrt Num < 0", IndPrice:8:2, DepPrice:8:2,
AveXsq:12:2, Square(AveX):12:2, Denom:12:2, Num:12:0);
LinearRegXY.bf = -1;
end;
--------------------------------------------------------------------------------
{Indicator to display values}
Input: PriceX(Close data1), PriceY(Close data2), Length(20), IMode(1);
Vars: Intercept(0), Slope(0), StdErr(0);
Value1 = LinearRegXY.bf(PriceY, PriceX, Length, Intercept, Slope, StdErr);
if IMode = 1 then begin
Plot1(Slope, "1");
if FALSE then Plot2(0, "2");
if FALSE then Plot3(0, "3");
if FALSE then Plot4(0, "4");
end;
if IMode = 2 then begin
Plot1(Intercept, "1");
if FALSE then Plot2(0, "2");
if FALSE then Plot3(0, "3");
if FALSE then Plot4(0, "4");
end;
if IMode = 3 then begin
Plot1(StdErr, "1");
if FALSE then Plot2(0, "2");
if FALSE then Plot3(0, "3");
if FALSE then Plot4(0, "4");
end;
|