[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sve.lr function



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;