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

[GT] SVN Commit r569 - trunk/GT/Indicators



Author: ras
Date: 2008-03-17 19:39:13 +0100 (Mon, 17 Mar 2008)
New Revision: 569

Modified:
   trunk/GT/Indicators/BPCorrelation.pm
   trunk/GT/Indicators/EVWMA.pm
   trunk/GT/Indicators/KirshenbaumBands.pm
   trunk/GT/Indicators/LinearRegression.pm
   trunk/GT/Indicators/MaxDrawDown.pm
   trunk/GT/Indicators/RSquare.pm
   trunk/GT/Indicators/StandardError.pm
Log:
overlooked patches from thomas weigert 2005
along with some more recent improvements


Modified: trunk/GT/Indicators/BPCorrelation.pm
===================================================================
--- trunk/GT/Indicators/BPCorrelation.pm	2008-03-12 05:51:36 UTC (rev 568)
+++ trunk/GT/Indicators/BPCorrelation.pm	2008-03-17 18:39:13 UTC (rev 569)
@@ -1,55 +1,90 @@
 package GT::Indicators::BPCorrelation;
 
-# Copyright 2000-2002 Rapha�Hertzog, Fabien Fulhaber
+# Copyright 2000-2002 Rapha�Hertzog, Fabien Fulhaber, Oliver Bossert
+# standards upgrade Copyright 2005 Thomas Weigert
 # This file is distributed under the terms of the General Public License
 # version 2 or (at your option) any later version.
 
+# includes ras hack to protect against division by zero
+# detection of missing or invalid arguments
+# $Id$
+
+# Standards-Version: 1.0
+
 use strict;
 use vars qw(@ISA @NAMES);
 
 use GT::Indicators;
 
 @ISA = qw(GT::Indicators);
-
AT
NAMES = ("BPCorrelation[#1]");
+
AT
NAMES = ("BPCorrelation[#1,#2,#3]");
 
-=head2 GT::Indicators::Correlation
+=head2 GT::Indicators::BPCorrelation (Bravais-Pearson Correlation Coefficient)
 
 This function will calculate the Bravais-Pearson Correlation Coefficient.
 Correlation analysis measures the relationship between two items and shows
 if changes in one item will result in changes in the other item.
 
-=cut
-sub new {
-    my $type = shift;
-    my $class = ref($type) || $type;
-    my ($args, $key, $f1, $f2) = @_;
-    my $self = { 'args' => defined($args) ? $args : [] };
+this indicator requires three arguments, and provides no default values
+for any of them.
 
-    if (defined($f1)) {
-	$self->{'_f1'} = $f1;
-    }
-    if (defined($f2)) {
-        $self->{'_f2'} = $f2;
-    }
+the first argument is the number of intervals in the period,
+it can be a constant or a data series. the period is used as
+the number of data values used in each computation
 
-    return manage_object(\
AT
NAMES, $self, $class, $self->{'args'}, $key);
-}
+the second and third arguments must be functions (e.g. data series
+or data objects?)
 
+the indicator will validate that the arguments are provided and are
+of the correct type.
+
+=head2 examples (display_indicator)
+ 
+ %   display_indicator.pl I:BPCorrelation 13000 \
+ '20 {I:Prices OPEN} {I:Prices CLOSE}'
+
+ %   display_indicator.pl I:BPCorrelation 13000 \
+ '14 {I:G:Cum 1} {I:Prices CLOSE}'
+ 
+
+=cut
 sub initialize {
     my ($self) = @_;
 
+    if ($self->{'args'}->is_constant(1)) {
+        $self->add_prices_dependency($self->{'args'}->get_arg_constant(1));
+    } else {
     $self->add_prices_dependency(20);
 }
 
+    # indicator requires 3 arguments
+    my $err = 0;
+    ( my $msg_n = $NAMES[0] ) =~ s/^(.*)\[.*/$1/;
+    my $msg = "$msg_n: argument error\n";
+    if ( ! defined($self->{'args'}[1]) ) {
+    $msg .= join "", "\targ #1 must not be null\n";
+      ++$err;
+    }
+    # indicator requires functions for 2nd and 3rd arguments
+    # skip self and first
+    for ( my $i = 2; $i <= 3; ++$i ) {
+      if ( ! defined($self->{'args'}[$i])
+       ||  $self->{'args'}->is_constant($i)) {
+        my $msg_txt = "must be a function (series)\n";
+        $msg .= join "", "\targ #$i \"$self->{'args'}[$i]\" $msg_txt";
+        ++$err;
+      }
+    }
+    die "$msg" if ( $err );
+}
+
 =head2 GT::Indicators::Correlation::calculate($calc, $day)
 
 =cut
 sub calculate {
     my ($self, $calc, $i) = @_;
-    my $getvalue1 = $self->{'_f1'};
-    my $getvalue2 = $self->{'_f2'};
     my $name = $self->get_name;
-    my $period = $self->{'args'}[0];
+    my $period = $self->{'args'}->get_arg_constant(1);
     my $average_x = 0;
     my $average_y = 0;
     my $sum_y = 0;
@@ -57,6 +92,11 @@
     my $sum_xy = 0;
     
     return if ($calc->indicators->is_available($name, $i));
+
+    $self->remove_volatile_dependencies();
+    $self->add_volatile_arg_dependency(2, $period);
+    $self->add_volatile_arg_dependency(3, $period);
+
     return if (! $self->check_dependencies($calc, $i));
     return if (defined($period) && ($i + 1 < $period));
 
@@ -66,22 +106,24 @@
     
     for(my $n = $i - $period + 1; $n <= $i; $n++) {
 
-	$average_x += &$getvalue1($calc, $n);
-	$average_y += &$getvalue2($calc, $n);
+        $average_x += $self->{'args'}->get_arg_values($calc, $n, 2);
+        $average_y += $self->{'args'}->get_arg_values($calc, $n, 3);
     }
     
     $average_x /= $period;
     $average_y /= $period;
     
     for(my $n = $i - $period + 1; $n <= $i; $n++) {
-	$sum_x += (&$getvalue1($calc, $n) - $average_x) ** 2;
-	$sum_y += (&$getvalue2($calc, $n) - $average_y) ** 2;
-	$sum_xy += (&$getvalue1($calc, $n) - $average_x) *
-		   (&$getvalue2($calc, $n) - $average_y);
+        $sum_x += ($self->{'args'}->get_arg_values($calc, $n, 2) - $average_x) ** 2;    
+        $sum_y += ($self->{'args'}->get_arg_values($calc, $n, 3) - $average_y) ** 2;    
+        $sum_xy += ($self->{'args'}->get_arg_values($calc, $n, 2) - $average_x)
+          * ($self->{'args'}->get_arg_values($calc, $n, 3) - $average_y);
     }
 
     # Calculate the Bravais-Pearson Correlation Coefficient
-    my $correlation = $sum_xy / ( ($sum_x * $sum_y) ** (1/2) );
+    # protect against division by zero
+    my $den = ($sum_x * $sum_y) ** 0.5 || 0.0000001;
+    my $correlation = $sum_xy / $den;
     
     # Return the result
     $calc->indicators->set($name, $i, $correlation);

Modified: trunk/GT/Indicators/EVWMA.pm
===================================================================
--- trunk/GT/Indicators/EVWMA.pm	2008-03-12 05:51:36 UTC (rev 568)
+++ trunk/GT/Indicators/EVWMA.pm	2008-03-17 18:39:13 UTC (rev 569)
@@ -1,9 +1,16 @@
  package GT::Indicators::EVWMA;
 
 # Copyright 2000-2002 Rapha�Hertzog, Fabien Fulhaber
+# standards upgrade Copyright 2005 Thomas Weigert
 # This file is distributed under the terms of the General Public License
 # version 2 or (at your option) any later version.
 
+# ras hack based on version dated 24apr05 2780 bytes
+# includes patches thru 9mar07
+# $Id$
+
+# Standards-Version: 1.0
+
 use strict;
 use vars qw(@ISA @NAMES @DEFAULT_ARGS);
 
@@ -14,22 +21,41 @@
 @NAMES = ("EVWMA");
 @DEFAULT_ARGS = ("{I:Prices CLOSE}");
 
-=head1 GT::Indicators::EVWMA
+=head1 GT::Indicators::EVWMA (Elastic Volume Weighted Moving Average)
 
 =head2 Overview
 
-The Elastic Volume Weighted Moving Average (eVWMA) differs from usual average in that :
+The Elastic Volume Weighted Moving Average (eVWMA) differs from usual
+average in that :
 
-- It does not refer to any underlying averaging time period (for example, 20 days, 50 days, 200 days). Instead, eVWMA uses share volume to define the period of the averaging.
+- It does not refer to any underlying averaging time period (for
+example, 20 days, 50 days, 200 days). Instead, eVWMA uses share volume
+to define the period of the averaging.
 
-- It incorporates information about volume (and possibly time) in a natural and logical way
+- It incorporates information about volume (and possibly time) in a
+natural and logical way
 
-- It can be derived from, and seen as an approximation to, a statistical measure and thus has a solid mathematical justification.
+- It can be derived from, and seen as an approximation to, a statistical
+measure and thus has a solid mathematical justification.
 
+=head2 =====>>>>>   SIGNIFICANT USAGE ISSUE   <<<<<=====
+
+to use I:EVWMA one must have a database containing the number of
+shares floating for each security being analyzed. this shares_float
+database is only searched for in an xml file at /bourse/metainfo/"$code".xml
+
+currently the beancounter database doesn't store this security attribute,
+nor does beancounter fetch this value in the course of a normal daily update.
+
+yahoo does provide the attribute via 'f6', but how one might create the
+required xml file based database is not described.
+
 =head2 Calculation
 
 eVWMA(0) = Today's Close
-eVWMA(i) = ((Number of shares floating - Today's Volume) * eVWMA(i-1) + Today's Volume * Today's Close) / Number of shares floating
+eVWMA(i) = ( (Number of shares floating - Today's Volume) \
+         * eVWMA(i-1) + Today's Volume * Today's Close ) \
+         / Number of shares floating
 
 =head2 Example
 
@@ -71,7 +97,12 @@
 	} else {
 
 	    # Calculate the following eVWMA
-	    $evwma = (($floating_shares - $prices->at($n)->[$VOLUME]) * $self->{'args'}->get_arg_values($calc, $i, $n - 1) + ($prices->at($n)->[$VOLUME] * $self->{'args'}->get_arg_values($calc, $i, $n))) / $floating_shares;
+            $evwma = (($floating_shares - $prices->at($n)->[$VOLUME])
+             * $self->{'args'}->get_arg_values($calc, $i, $n - 1)
+             + ($prices->at($n)->[$VOLUME]
+             * $self->{'args'}->get_arg_values($calc, $i, $n)))
+             / $floating_shares;
+            
 	}
         $calc->indicators->set($evwma_name, $i, $evwma);
     }

Modified: trunk/GT/Indicators/KirshenbaumBands.pm
===================================================================
--- trunk/GT/Indicators/KirshenbaumBands.pm	2008-03-12 05:51:36 UTC (rev 568)
+++ trunk/GT/Indicators/KirshenbaumBands.pm	2008-03-17 18:39:13 UTC (rev 569)
@@ -1,9 +1,15 @@
 package GT::Indicators::KirshenbaumBands;
 
 # Copyright 2000-2002 Rapha�Hertzog, Fabien Fulhaber
+# standards upgrade Copyright 2005 Thomas Weigert
 # This file is distributed under the terms of the General Public License
 # version 2 or (at your option) any later version.
 
+# original base date 24 Apr 2005 3206 bytes
+# $Id$
+
+# Standards-Version: 1.0
+
 use strict;
 use vars qw(@ISA @NAMES @DEFAULT_ARGS);
 
@@ -20,7 +26,12 @@
 
 =head2 Overview
 
-Kirshenbaum Bands are similar to Bollinger Bands, in that they measure market volatility. However, rather than use Standard Deviation of a moving average for band with, they use Standard Error of linear regression lines of the Close. This has the effect of measuring volatility around the current trend, instead of measuring volatility for changes in trend.
+Kirshenbaum Bands are similar to Bollinger Bands, in that they measure
+market volatility. However, rather than use Standard Deviation of
+a moving average for band with, they use Standard Error of linear
+regression lines of the Close. This has the effect of measuring
+volatility around the current trend, instead of measuring volatility for
+changes in trend.
 
 =head2 Author
 

Modified: trunk/GT/Indicators/LinearRegression.pm
===================================================================
--- trunk/GT/Indicators/LinearRegression.pm	2008-03-12 05:51:36 UTC (rev 568)
+++ trunk/GT/Indicators/LinearRegression.pm	2008-03-17 18:39:13 UTC (rev 569)
@@ -1,16 +1,21 @@
 package GT::Indicators::LinearRegression;
 
 # Copyright 2000-2002 Rapha�Hertzog, Fabien Fulhaber
+# standards upgrade Copyright 2005 Thomas Weigert
 # This file is distributed under the terms of the General Public License
 # version 2 or (at your option) any later version.
 
+# $Id$
+
+# Standards-Version: 1.0
+
 use strict;
 use vars qw(@ISA @NAMES);
 
 use GT::Indicators;
 
 @ISA = qw(GT::Indicators);
-
AT
NAMES = ("LinearRegressionLine[#1]","LinearRegressionCoefficientA[#1]","LinearRegressionCoefficientB[#1]");
+
AT
NAMES = ("LinearRegressionLine[#1,#2,#3]","LinearRegressionCoefficientA[#1,#2,#3]","LinearRegressionCoefficientB[#1,#2,#3]");
 
 =head1 GT::Indicators::LinearRegression
 
@@ -22,56 +27,45 @@
 are also provided by the indicator if you want to calculate the value of
 the linear regression for other days.
 
-=head2 GT::Indicators::LinearRegression->new([$length], $key, $func1, $func2)
+=head2 Parameters
 
-Create a new LinearRegression indicator. Please note that the key must
-be unique for the combination of both data series ($func1 and $func2)
-so that the generated name of the indicator is unique. It is highly
-recommended to use a key such as "serie1_name,serie2_name".
+Takes 2 or 3 parameters. The first is the period over which the regression
+is calculated. The following parameters indicate the series that are being
+compared. If there is only a second parameter, this parameter forms the
+dependent variables, while the numerical sequence is the independent
+parameter. If there are both a second and a third parameter, the former is
+the independent and the latter the dependent parameter.
     
 =cut
 
-sub new {
-    my $type = shift;
-    my $class = ref($type) || $type;
-    my ($args, $key, $f1, $f2) = @_;
+sub initialize {
+    my ($self) = @_;
+
     # No default value for the first arg on purpose
     # It means use all the values for the regression and not only the XX
     # latest
-    my $self = { 'args' => defined($args) ? $args : [] };
-
-    if (defined($f1)) {
-	$self->{'_f1'} = $f1;
-    } else { die "Missing data serie.\n"; }
-    if (defined($f2)) {
-        $self->{'_f2'} = $f2;
-    } else { die "Missing data serie.\n"; }
-
-    return manage_object(\
AT
NAMES, $self, $class, $self->{'args'}, $key);
-}
-
-sub initialize {
-    my ($self) = @_;
-
     if (defined $self->{'args'}[0]) {
-	$self->add_prices_dependency($self->{'args'}[0]);
+        $self->add_prices_dependency($self->{'args'}->get_arg_constant(1));
     }
 }
 
 sub calculate {
     my ($self, $calc, $i) = @_;
-    my $getvalue1 = $self->{'_f1'};
-    my $getvalue2 = $self->{'_f2'};
     my $linear_regression_line_name = $self->get_name(0);
     my $linear_regression_coefficient_a_name = $self->get_name(1);
     my $linear_regression_coefficient_b_name = $self->get_name(2);
-    my $period = $self->{'args'}[0];
+    my $period = $self->{'args'}->get_arg_values($calc, $i, 1);
     my ($sum_x, $sum_y, $sum_xy) = 0;
     my ($variance_x, $variance_y) = 0;
     
     return if ($calc->indicators->is_available($linear_regression_line_name, $i) &&
                $calc->indicators->is_available($linear_regression_coefficient_a_name, $i) &&
 	       $calc->indicators->is_available($linear_regression_coefficient_b_name, $i));
+
+    $self->remove_volatile_dependencies();
+    $self->add_volatile_arg_dependency(2, $period);
+    $self->add_volatile_arg_dependency(3, $period);
+
     return if (! $self->check_dependencies($calc, $i));
 
     # Initialize $period to $i if nothing was previously defined
@@ -82,9 +76,18 @@
     # Calculate the average of (x), (y) and (xy)
     for(my $n = $i - $period + 1; $n <= $i; $n++) {
 
-	$sum_x += &$getvalue1($calc, $n);
-	$sum_y += &$getvalue2($calc, $n);
-	$sum_xy += (&$getvalue1($calc, $n) * &$getvalue2($calc, $n));
+        my $x = $self->{'args'}->get_arg_values($calc, $n, 2);
+        my $y;
+        if ( defined( $self->{'args'}->get_arg_object(3) ) ) {
+          my $y = $self->{'args'}->get_arg_values($calc, $n, 3);
+        } else {
+          $y = $x;
+          $x = $n;
+        }
+
+        $sum_x += $x;
+        $sum_y += $y;
+        $sum_xy += ($x * $y);
     }
     
     my $average_x = $sum_x / $period;
@@ -94,8 +97,17 @@
     # Calculate the variance of (x) and (y)
     for(my $n = $i - $period + 1; $n <= $i; $n++) {
 
-	$variance_x += ((&$getvalue1($calc, $n) - $average_x) ** 2);
-	$variance_y += ((&$getvalue2($calc, $n) - $average_y) ** 2);
+        my $x = $self->{'args'}->get_arg_values($calc, $n, 2);
+        my $y;
+        if ( defined( $self->{'args'}->get_arg_object(3) ) ) {
+          my $y = $self->{'args'}->get_arg_values($calc, $n, 3);
+        } else {
+          $y = $x;
+          $x = $n;
+        }
+
+        $variance_x += (($x - $average_x) ** 2);
+        $variance_y += (($y - $average_y) ** 2);
     }
     $variance_x /= $period;
     $variance_y /= $period;

Modified: trunk/GT/Indicators/MaxDrawDown.pm
===================================================================
--- trunk/GT/Indicators/MaxDrawDown.pm	2008-03-12 05:51:36 UTC (rev 568)
+++ trunk/GT/Indicators/MaxDrawDown.pm	2008-03-17 18:39:13 UTC (rev 569)
@@ -1,16 +1,22 @@
 package GT::Indicators::MaxDrawDown;
 
 # Copyright 2000-2002 Rapha�Hertzog, Fabien Fulhaber
+# standards upgrade Copyright 2005 Thomas Weigert
 # This file is distributed under the terms of the General Public License
 # version 2 or (at your option) any later version.
 
+# $Id$
+
+# Standards-Version: 1.0
+
 use strict;
-use vars qw(@ISA @NAMES);
+use vars qw(@ISA @NAMES @DEFAULT_ARGS);
 
 use GT::Indicators;
 
 @ISA = qw(GT::Indicators);
-
AT
NAMES = ("MaxDrawDown");
+
AT
NAMES = ("MaxDrawDown[#1]");
+
AT
DEFAULT_ARGS = ("{I:Prices CLOSE}");
 
 =pod
 
@@ -22,22 +28,6 @@
 
 =cut
 
-sub new {
-    my $type = shift;
-    my $class = ref($type) || $type;
-    my ($args, $key, $func) = @_;
-    my $self = { 'args' => defined($args) ? $args : [] };
-    
-    if (defined($func)) {
-	$self->{'_func'} = $func;
-    } else {
-	$self->{'_func'} = $GET_LAST;
-	$key = 'LAST';
-    }
-
-    return manage_object(\
AT
NAMES, $self, $class, $self->{'args'}, $key);
-}
-
 sub initialize {
     my ($self) = @_;
 
@@ -46,22 +36,20 @@
 
 sub calculate {
     my ($self, $calc, $i) = @_;
-    my $nb = $self->{'args'}[0];
-    my $getvalue = $self->{'_func'};
     my $name = $self->get_name;
     my $current_draw_down = 0;
     my $max_draw_down = 0;
     
     return if (! $self->check_dependencies($calc, $i));
 
-    my $high = &$getvalue($calc, 0);
+    my $high = $self->{'args'}->get_arg_values($calc, 0, 1);
     
     for (my $n = 0; $n <= $i; $n++) {
 	
-	if (&$getvalue($calc, $n) > $high) {
-	    $high = &$getvalue($calc, $n);
+        if ($self->{'args'}->get_arg_values($calc, $n, 1) > $high) {
+            $high = $self->{'args'}->get_arg_values($calc, $n, 1);
 	} else {
-	    $current_draw_down = ($high - &$getvalue($calc, $n)) * 100 / $high;
+            $current_draw_down = ($high - $self->{'args'}->get_arg_values($calc, $n, 1)) * 100 / $high;
 	}
 	if ($current_draw_down > $max_draw_down) {
 	    $max_draw_down = $current_draw_down;

Modified: trunk/GT/Indicators/RSquare.pm
===================================================================
--- trunk/GT/Indicators/RSquare.pm	2008-03-12 05:51:36 UTC (rev 568)
+++ trunk/GT/Indicators/RSquare.pm	2008-03-17 18:39:13 UTC (rev 569)
@@ -1,18 +1,24 @@
 package GT::Indicators::RSquare;
 
 # Copyright 2000-2002 Rapha�Hertzog, Fabien Fulhaber
+# standards upgrade and major corrections Copyright 2008 Thomas Weigert
 # This file is distributed under the terms of the General Public License
 # version 2 or (at your option) any later version.
 
+# $Id$
+
+# Standards-Version: 1.0
+
 use strict;
-use vars qw(@ISA @NAMES);
+use vars qw(@ISA @NAMES @DEFAULT_ARGS);
 
 use GT::Indicators;
 use GT::Indicators::BPCorrelation;
 use GT::Prices;
 
 @ISA = qw(GT::Indicators);
-
AT
NAMES = ("RSquare[#1]");
+
AT
NAMES = ("RSquare[#1, #2]");
+
AT
DEFAULT_ARGS = (14, "{I:Prices CLOSE}");
 
 =pod
 
@@ -28,21 +34,13 @@
  
 =cut
 
-sub new {
-    my $type = shift;
-    my $class = ref($type) || $type;
-    my ($args) = @_;
-    my $self = { 'args' => defined($args) ? $args : [ 14 ] };
-
-    $args->[0] = 14 if (! defined($args->[0]));
-       
-    return manage_object(\
AT
NAMES, $self, $class, $self->{'args'}, "");
-}
-
 sub initialize {
     my $self = shift;
 
-    $self->{'correlation'} = GT::Indicators::BPCorrelation->new([ $self->{'args'}[0] ], "i,Close", sub { return $_[1] + 1 }, sub { return $_[0]->prices->at($_[1])->[$LAST] } );
+    $self->{'correlation'} = GT::Indicators::BPCorrelation->new([ 
+                                 $self->{'args'}->get_arg_constant(1),
+                                 '{I:Generic:Cum 1 }',
+                                 $self->{'args'}->get_arg_names(2) ]);
 
     $self->add_indicator_dependency($self->{'correlation'}, 1);
     $self->add_prices_dependency(2);
@@ -58,7 +56,7 @@
     my ($self, $calc, $i) = @_;
     my $indic = $calc->indicators;
     my $prices = $calc->prices;
-    my $period = $self->{'args'}[0];
+    my $period = $self->{'args'}->get_arg_constant(1);
     my $correlation_name = $self->{'correlation'}->get_name;
     my $name = $self->get_name;
 

Modified: trunk/GT/Indicators/StandardError.pm
===================================================================
--- trunk/GT/Indicators/StandardError.pm	2008-03-12 05:51:36 UTC (rev 568)
+++ trunk/GT/Indicators/StandardError.pm	2008-03-17 18:39:13 UTC (rev 569)
@@ -1,18 +1,25 @@
 package GT::Indicators::StandardError;
 
 # Copyright 2000-2002 Rapha�Hertzog, Fabien Fulhaber
+# standards upgrade Copyright 2005 Thomas Weigert
 # This file is distributed under the terms of the General Public License
 # version 2 or (at your option) any later version.
 
+# requires Thomas Weigert revision to GT::Indicators::LinearRegression
+# $Id$
+
+# Standards-Version: 1.0
+
 use strict;
-use vars qw(@ISA @NAMES);
+use vars qw(@ISA @NAMES @DEFAULT_ARGS);
 
 use GT::Indicators;
 use GT::Indicators::LinearRegression;
 use GT::Prices;
 
 @ISA = qw(GT::Indicators);
-
AT
NAMES = ("StandardError[#1]");
+
AT
NAMES = ("StandardError[#1, #2]");
+
AT
DEFAULT_ARGS = (20, "{I:Prices CLOSE}");
 
 =pod
 
@@ -40,38 +47,27 @@
 
 =cut
 
-sub new {
-    my $type = shift;
-    my $class = ref($type) || $type;
-    my ($args, $key, $func) = @_;
-    my $self = { 'args' => defined($args) ? $args : [ 20 ] };
-
-    $args->[0] = 20 if (! defined($args->[0]));
-    
-    if (defined($func)) {
-	$self->{'_func'} = $func;
-    } else {
-	$self->{'_func'} = $GET_LAST;
-	$key = 'LAST';
-    }
-						
-    return manage_object(\
AT
NAMES, $self, $class, $args, $key);
-}
-
 sub initialize {
     my $self = shift;
 
-    $self->{'linear_regression_line'} = GT::Indicators::LinearRegression->new([ $self->{'args'}[0] ], $self->{'key'}, sub { return $_[1] }, sub { $self->{'_func'}(@_) } );
+    # Linear regression of the CLOSE against the sequence number
+    $self->{'linear_regression_line'} = GT::Indicators::LinearRegression->new([
+     $self->{'args'}->get_arg_names(1), $self->{'args'}->get_arg_names(2) ]);
+#   # What are the arguments to the linear regression?
+#   $self->{'linear_regression_line'} = GT::Indicators::LinearRegression->new([
+#    $self->{'args'}->get_arg_names(1),
+#    $self->{'args'}->get_arg_names(2),
+#    $self->{'args'}->get_arg_names(2)]);
 
-    $self->add_indicator_dependency($self->{'linear_regression_line'}, $self->{'args'}[0]);
-    $self->add_prices_dependency($self->{'args'}[0]);
+    $self->add_indicator_dependency($self->{'linear_regression_line'},
+     $self->{'args'}->get_arg_constant(1));
+    $self->add_prices_dependency($self->{'args'}->get_arg_constant(1));
 }
 
 sub calculate {
     my ($self, $calc, $i) = @_;
     my $indic = $calc->indicators;
-    my $period = $self->{'args'}[0];
-    my $getvalue = $self->{'_func'};
+    my $period = $self->{'args'}->get_arg_constant(1);
     my $linear_regression_coefficient_a_name = $self->{'linear_regression_line'}->get_name(1);
     my $linear_regression_coefficient_b_name = $self->{'linear_regression_line'}->get_name(2);
     my $standard_error_name = $self->get_name;
@@ -91,7 +87,9 @@
 	my $linear_regression_line_value = $a * $n + $b;
 	
 	# Calculate the distance from the linear regression line
-	my $d = &$getvalue($calc, $n) - $linear_regression_line_value;
+        my $d = $self->{'args'}->get_arg_values($calc, $n, 2)
+              - $linear_regression_line_value;
+#       my $d = $get_arg_values($calc, $n, 2) - $linear_regression_line_value;
 
 	# Calculate the sum of the squared errors
 	$sum_of_the_squared_errors += ($d ** 2);