Finance-ChartHist

 view release on metacpan or  search on metacpan

lib/Finance/ChartHist.pm  view on Meta::CPAN

##

sub _get_graph_data
{
  my $self = shift;
  my %graph_data;
  
  ## Get the data
  my $quote = new Finance::QuoteHist(symbols    => $self->{symbols},
                                     start_date => $self->{start_date},
                                     end_date   => $self->{end_date}
                                    );
                                    

  foreach my $row ($quote->quotes()) {
    my ($symbol, $date, $open, $high, $low, $close, $volume) = @$row;
    push @{ $graph_data{$symbol}[0] }, $date;
    push @{ $graph_data{$symbol}[1] }, $close;
    ##print "$symbol, $date, $close\n";
  }
  
  return \%graph_data;
}

sub _graph_single_symbol
{
  my $self = shift;
  my $graph_data = shift or die "No graph data!";

  ## Find the y range of the graph, normalised depending on the
  ## size of the range  
  my ($y_min, $y_max) = $self->_calculate_price_range($graph_data);
  
  ## Figure out how many days our chart will show  
  my $s_date = Date::Simple->new($self->{start_date}) or croak "Couldn't parse start_date";
  my $e_date = Date::Simple->new($self->{end_date}) or croak "Couldn't parse end_date";
  my $date_count = $e_date - $s_date;
  ## Figure out how many x values exist in the chart
  my $tick_count = scalar @{ $graph_data->{$self->{symbols}}[0] };
      
  my ($x_label_skip, $x_label_offset) = $self->_format_x_axis($graph_data,
                                                              $date_count,
                                                              $tick_count);
                                                              
  my $graph = new GD::Graph::lines( $self->{width}, $self->{height});
  
  $graph->set( 
	x_label => $self->{x_label},
	y_label => $self->{y_label},
	title => $self->{symbols},
	y_max_value => $y_max,
	y_min_value => $y_min,
	y_tick_number => $y_max - $y_min,
	x_tick_offset => $x_label_offset,
	x_label_skip => $x_label_skip,
	x_label_position => 1/2,
	box_axis => 0,
	r_margin => 10,
	line_width => 1,

	transparent => 0
  );
  

  $graph->plot(\@{ $graph_data->{$self->{symbols}} });

  ## Keep a copy of the graph  
  $self->{graph} = $graph;
  
}

sub _graph_multiple_symbols
{
  my $self = shift;
  my $graph_data = shift or die "No graph data!";
  
  ## Convert the price data to percentage movements
  $graph_data = $self->_convert_to_percentage_movement($graph_data);
  
  ## Get the percentage range for the data
  my ($y_min, $y_max) = $self->_calculate_price_range($graph_data);
  
  ## Figure out how many days our chart will show  
  my $s_date = Date::Simple->new($self->{start_date}) or croak "Couldn't parse start_date";
  my $e_date = Date::Simple->new($self->{end_date}) or croak "Couldn't parse end_date";
  my $date_count = $e_date - $s_date;
  ## Figure out how many x values exist in the chart
  my $tick_count = scalar @{ $graph_data->{$self->{symbols}[0]}[0] };
      
  my ($x_label_skip, $x_label_offset) = $self->_format_x_axis($graph_data,
                                                              $date_count,
                                                              $tick_count);

  #Produce a title for the graph
  my $title = "";
  foreach (@{ $self->{symbols} }) {
    $title = $title."$_ vs ";
  }
  $title =~ s/ vs $//;
                                                                
  my $graph = new GD::Graph::lines( $self->{width}, $self->{height});
    
  $graph->set( 
	x_label => $self->{x_label},
	y_label => $self->{y_label},
	title => $title,
	y_max_value => $y_max,
	y_min_value => $y_min,
	y_tick_number => $y_max - $y_min,
	x_tick_offset => $x_label_offset,
	x_label_skip => $x_label_skip,
	x_label_position => 1/2,
	box_axis => 0,
	r_margin => 10,
	line_width => 1,

	transparent => 0
  ) or warn $graph->error;
  
  ## Set up the data into the required format
  my @formated_data = ();
  foreach my $symbol (@{ $self->{symbols} }) {
    push @formated_data, $graph_data->{$symbol}[1];
  }
  unshift @formated_data, $graph_data->{$self->{symbols}[0]}[0];

  $graph->plot(\@formated_data) or die $graph->error;
  
  ## Set the legend
  $graph->set_legend( ["BHP", "PIXR"] );

  ## Keep a copy of the graph  
  $self->{graph} = $graph;
  
}

##
## Figure out the range of the share price, and
## calculate what limits we will put on the y-axis
## of the graph
sub _calculate_price_range
{
  my $self = shift;
  my $graph_data = shift or die "No graph data!";
  
  my ($y_max_value, $y_min_value) = (0, 0);
  
  if (scalar keys %{ $graph_data } > 1) {
    foreach my $symbol ( keys %{ $graph_data } ) {
      foreach my $percent (@{ $graph_data->{$symbol}[1] }) {
        if ($percent < $y_min_value) {
          $y_min_value = $percent;
        }

        if ($percent > $y_max_value) {
          $y_max_value = $percent;
        }
      }
    }
  }
  else {
    $y_max_value = $graph_data->{$self->{symbols}}[1][0];
    $y_min_value = $graph_data->{$self->{symbols}}[1][0];
    
    foreach my $price ( @{ $graph_data->{$self->{symbols}}[1] } ) {
      if ($price < $y_min_value) {
        $y_min_value = $price;
      }

      if ($price > $y_max_value) {
        $y_max_value = $price;
      }
    }
  }
  
  ($y_min_value, $y_max_value) = $self->_normalise_range($y_min_value, $y_max_value);
  



( run in 1.189 second using v1.01-cache-2.11-cpan-5a3173703d6 )