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 )