App-Chart
view release on metacpan or search on metacpan
unused/Yahoo-v7.pm view on Meta::CPAN
open => crunch_trailing_nines($open),
high => crunch_trailing_nines($high),
low => crunch_trailing_nines($low),
close => crunch_trailing_nines($close),
volume => $volume };
}
return $h;
}
sub daily_parse_div {
my ($symbol, $resp, $h) = @_;
my @dividends = ();
$h->{'dividends'} = \@dividends;
my $body = $resp->decoded_content (raise_error => 1);
my @line_list = App::Chart::Download::split_lines($body);
# Date,Dividends
# 2015-11-04,1.4143
# 2016-05-17,1.41428
# 2017-05-16,1.4143
# 2016-11-03,1.4143
unless ($line_list[0] =~ /^Date,Dividends/) {
warn "Yahoo: unrecognised dividend headings: " . $line_list[0];
return;
}
shift @line_list;
foreach my $line (@line_list) {
my ($date, $amount) = split (/,/, $line);
push @dividends, { symbol => $symbol,
ex_date => daily_date_fixup ($symbol, $date),
amount => $amount };
}
return $h;
}
sub daily_parse_split {
my ($symbol, $resp, $h) = @_;
my @splits = ();
$h->{'splits'} = \@splits;
my $body = $resp->decoded_content (raise_error => 1);
my @line_list = App::Chart::Download::split_lines($body);
# For example GXY.AX split so $10 shares become $2
# Date,Stock Splits
# 2017-05-22,1:5
#
# In the past it was a "/" instad of ":"
# 2017-05-22,1/5
unless ($line_list[0] =~ /^Date,Stock Splits/) {
warn "Yahoo: unrecognised split headings: " . $line_list[0];
return;
}
shift @line_list;
foreach my $line (@line_list) {
my ($date, $ratio) = split (/,/, $line);
my ($old, $new) = split m{[:/]}, $ratio;
push @splits, { symbol => $symbol,
date => daily_date_fixup ($symbol, $date),
new => $new,
old => $old };
}
return $h;
}
# ENHANCE-ME: The digits are 23-bit float formatted badly, or so it seems.
# That makes it 23 / (log(10)/log(2)) = 6.92 many high digits good.
# Maybe round-to-nearest of high 7 digits, or maybe only high 6 depending
# where the bit range falls (how many bits used by the high digit).
#
# $str is a string like "30.299999"
# Return it with trailing 9s turned into trailing 0s.
sub crunch_trailing_nines {
my ($str) = @_;
if (defined $str) {
$str =~ s/(\....(99|00)).*/$1/; # trailing garbage
if ($str =~ /(.*)\.(....9+)$/) {
$str = decimal_add_low($str,1);
} elsif ($str =~ /(.*)\.(....*01)$/) {
$str = decimal_add_low($str,-1);
}
if ($str =~ /(.*)\./) {
my $ilen = length($1);
my $decimals = ($ilen >= 4 ? 2
: $ilen == 3 ? 3
: 4);
$str = round_decimals($str,$decimals);
}
$str = pad_decimals($str, 2);
}
return $str;
}
sub decimal_add_low {
my ($str, $add) = @_;
### decimal_add_low(): "$str add $add"
$str =~ /(.*)\.(.+)$/ or return $str+$add;
my $pre = $1;
my $post = $2;
### $pre
### $post
$str = $pre * 10**length($post) + $post + $add;
while (length($post) >= length($str)) { $str = '0'.$str; }
substr($str, -length($post),0, '.');
return $str;
}
sub round_decimals {
my ($str, $decimals) = @_;
if (defined $str && $str =~ /(.*\.[0-9]{$decimals})([0-9])/) {
$str = $1;
if ($2 >= 5) { $str = decimal_add_low($str, 1); }
}
return $str;
}
( run in 4.593 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )