App-Chart
view release on metacpan or search on metacpan
unused/CommSec.pm view on Meta::CPAN
my $elem
= (List::Util::first {$_->[0] >= $months } @indiv_months_list)
|| $indiv_months_list[-1];
my $period_str = $elem->[1];
my $url
= 'http://charts.commsec.com.au/HistoryData/HistoryData.dll/GetData'
. '?Symbol='
. URI::Escape::uri_escape (App::Chart::symbol_sans_suffix ($symbol))
. '&TimePeriod=' . $period_str
. '&.csv';
App::Chart::Download::status (__x('CommSec {symbol} {period}',
symbol => $symbol,
period => $period_str));
my $resp = App::Chart::Download->get($url);
my $h = indiv_parse ($resp, $months);
if ($h) {
$h->{'last_download'} = 1;
App::Chart::Download::write_daily_group ($h);
}
}
}
# return number of months needed to cover back to TDATE
sub indiv_tdate_to_months {
my ($tdate) = @_;
$tdate -= 5; # bit of leeway
my ($now_year, $now_month, $now_day)
= App::Chart::TZ->sydney->ymd;
my ($td_year, $td_month, $td_day) = App::Chart::tdate_to_ymd ($tdate);
my $now_mdate
= App::Chart::Timebase::Months::ymd_to_mdate ($now_year, $now_month, 1);
my $td_mdate
= App::Chart::Timebase::Months::ymd_to_mdate ($td_year, $td_month, 1);
return $now_mdate - $td_mdate + ($now_day >= $td_day ? 1 : 0);
}
sub indiv_cost_proc {
my ($tdate) = @_;
my $months = indiv_tdate_to_months ($tdate);
return $months
* App::Chart::DownloadCost::cost_get (INDIV_PERMONTH_COST_KEY,
INDIV_PERMONTH_COST_DEFAULT);
}
sub indiv_parse {
my ($resp, $months) = @_;
my @data = ();
my $h = { source => __PACKAGE__,
currency => 'AUD',
suffix => '.AX',
prefer_decimals => 2,
date_format => 'dmy',
resp => $resp,
data => \@data };
my $body = $resp->decoded_content(raise_error=>1);
if ($body =~ /server error/i) {
# an unknown symbol
return $h;
}
$h->{'cost_key'} = INDIV_PERMONTH_COST_KEY;
$h->{'cost_value'} = int (length($body) / $months);
# Sample line
#
# AEZ,"01 Jun 2007",1.35,1.37,1.305,1.325,4008329\r\n
#
# trailing zeros are omitted, like 4.30 or 95.00 in
#
# ETR,"29 May 2007",4.26,4.3,4.25,4.3,50942\r\n
# NABHA,"27 Dec 2000",94.41,95,94.41,94.99,3495\r\n
#
foreach my $line (App::Chart::Download::split_lines($body)) {
my ($symbol, $date, $open, $high, $low, $close, $volume)
= split (/,/, $line);
$symbol .= '.AX';
$open = pad_decimals ($open, 2);
$high = pad_decimals ($high, 2);
$low = pad_decimals ($low, 2);
$close = pad_decimals ($close, 2);
push @data, { symbol => $symbol,
date => $date,
open => $open,
high => $high,
low => $low,
close => $close,
volume => $volume };
}
return $h;
}
sub pad_decimals {
my ($str, $want) = @_;
if ($str =~ /\.([0-9]*)$/) {
my $got = length ($1);
if ($got < $want) {
$str .= '0' x ($want - $got);
}
} else {
# no decimal point at all
$str .= '.' . ('0' x $want);
}
return $str;
}
#-----------------------------------------------------------------------------
# download - by whole day files
#
# Commsec offers the following formats,
#
# metastock - prices in dollars, date yymmdd
# metastock - prices in dollars, date yymmdd, volume in 100s
# ezychart - prices in cents, date yymmdd
# insight - prices in cents, date mm/dd/yy, space separated
# stockeasy - prices in dollars, date yyyymmdd
#
# Ezychart is used because it's the most compact -- there's no decimal
# points in most prices, and no century on the date.
#
# The web page says only the past 20 days are available and that's all the
# little menu presents, but the server actually goes back beyond that,
# apparently unlimited.
# return a url string
sub wholeday_url {
my ($tdate) = @_;
my ($year, $month, $day) = App::Chart::tdate_to_ymd ($tdate);
return sprintf 'http://charts.commsec.com.au/HistoryData/HistoryData.dll/EzyChart-%d%02d%02d?DownloadDate=%d%02d%02d&DownloadFormat=EzyChart&.txt',
$year, $month, $day,
$year, $month, $day;
}
sub wholeday_download {
my ($start_tdate, $avail_tdate) = @_;
foreach my $tdate ($start_tdate .. $avail_tdate) {
App::Chart::Download::status
(__x('CommSec data {date}',
date => App::Chart::Download::tdate_range_string ($tdate)));
my $url = wholeday_url($tdate);
my $resp = App::Chart::Download->get ($url);
# when public holiday, date too old, etc, still get a successful
# download, with an error message in the body
my $h = ezychart_parse ($resp);
App::Chart::Download::write_daily_group ($h);
}
}
sub ezychart_parse {
my ($resp) = @_;
my @data = ();
my $h = { source => __PACKAGE__,
currency => 'AUD',
prefer_decimals => 2,
date_format => 'ymd',
resp => $resp,
data => \@data,
cost_key => WHOLEDAY_COST_KEY };
my $body = $resp->decoded_content(raise_error=>1);
if ($body =~ /server error/i) {
# an unknown symbol
return $h;
}
# Sample line, 5 Sep 2008
# BHP,080905,3640,3720,3630,3700,14390282
#
foreach my $line (App::Chart::Download::split_lines($body)) {
my ($symbol, $date, $open, $high, $low, $close, $volume)
= split (/,/, $line);
$open = App::Chart::Download::cents_to_dollars ($open);
$high = App::Chart::Download::cents_to_dollars ($high);
$low = App::Chart::Download::cents_to_dollars ($low);
$close = App::Chart::Download::cents_to_dollars ($close);
push @data, { symbol => "$symbol.AX",
date => $date,
open => $open,
high => $high,
low => $low,
close => $close,
volume => $volume };
}
return $h;
}
1;
__END__
( run in 4.057 seconds using v1.01-cache-2.11-cpan-5837b0d9d2c )