App-Chart

 view release on metacpan or  search on metacpan

lib/App/Chart/Series/Derived/Adjust.pm  view on Meta::CPAN

  my $factor = 1;
  my $post_close;
  for (my $t = $hi; $t >= $lo; $t--) {

    if ($p_opens->[$t])   { $s_opens->[$t]  = $p_opens->[$t]  * $factor; }
    if ($p_highs->[$t])   { $s_highs->[$t]  = $p_highs->[$t]  * $factor; }
    if ($p_lows->[$t])    { $s_lows->[$t]   = $p_lows->[$t]   * $factor; }
    if ($p_closes->[$t])  { $post_close     = $p_closes->[$t];
                            $s_closes->[$t] = $post_close     * $factor;
                          }
    if ($p_volumes->[$t]) { $s_volumes->[$t]  = $p_volumes->[$t]  / $factor;}
    if ($p_openints->[$t]){ $s_openints->[$t] = $p_openints->[$t] / $factor;}

    for ( ; $splits->[0]->{'date'} >= $t; shift @$splits) {
      $factor *= ($splits->[0]->{'old'} / $splits->[0]->{'new'});
      ### factor now: $factor
    }

    for ( ; $dividends->[0]->{'ex_date'} >= $t; shift @$dividends) {
      my $div = $dividends->[0]->{'amount'};
      Scalar::Util::looks_like_number ($div) or next;

      if ($self->{'adjust_imputation'}) {
        my $imp = $dividends->[0]->{'imputation'};
        if (Scalar::Util::looks_like_number ($imp)) { $div += $imp; }
      }
      if (defined $post_close) {
        # factor chosen so if prev=post+div then prev*factor==post
        $factor *= $post_close / ($post_close + $div);
        ### dividend: $div
        ### $post_close
        ### factor now: $factor
      }
    }
  }
}

sub dividends {
  my ($self) = @_;
  return $self->{'parent'}->dividends;
}
sub splits {
  my ($self) = @_;
  return $self->{'parent'}->splits;
}
sub annotations {
  my ($self) = @_;
  return $self->{'parent'}->annotations;
}

sub Alerts_arrayref {
  my ($self) = @_;
  my $parent = $self->{'parent'};
  if (my $func = $parent->can('Alerts_arrayref')) {
    return $parent->$func;
  } else {
    return [];
  }
}

# FIXME: Adjust endpoints per display
sub AnnLines_arrayref {
  my ($self) = @_;
  my $parent = $self->{'parent'};
  if (my $func = $parent->can('AnnLines_arrayref')) {
    return $parent->$func;
  } else {
    return [];
  }
}

1;
__END__


=head1 NAME

App::Chart::Series::Derived::Adjust -- series adjustments for dividends, splits, etc

=for test_synopsis my ($series)

=head1 SYNOPSIS

 use App::Chart::Series::Derived::Adjust;
 my $adj_series = App::Chart::Series::Derived::Adjust->derive
                      ($series, adjust_splits => 1);

=head1 DESCRIPTION

A C<App::Chart::Series::Derived::Adjust> series applies adjustments to an underlying
database series for stock splits, dividend reinvestment, etc.  The split
information etc is obtained from the database.

=head1 FUNCTIONS

=over 4

=item App::Chart::Series::Derived::Adjust->derive ($series, key=>value,...)

Create a new series which applies adjustments to C<$series>, for some or all
of dividends, splits, capital returns, etc.  C<$series> must be a
C<App::Chart::Series::Database> object.  The adjustments are controlled by
the following options arguments taken in key/value style

    adjust_splits        adjust for stock splits
    adjust_dividends     adjust for dividends (as reinvested)
    adjust_imputation    include imputation credits in dividends

For example

    my $db_series = App::Chart::Series::Database->new ('BHP.AX');

    my $adj_series = App::Chart::Series::Derived::Adjust->derive
      ($db_series, adjust_splits => 1,
                   adjust_dividends => 1);

If the options ask for no adjustments at all, or there's no splits etc in
the database for the C<$series> symbol then C<$series> is simply returned.

=back



( run in 0.572 second using v1.01-cache-2.11-cpan-39bf76dae61 )