App-Chart
view release on metacpan or search on metacpan
lib/App/Chart/Suffix/LJ.pm view on Meta::CPAN
sl => '818');
return "http://www.ljse.si/cgi-bin/jve.cgi?SecurityID=$symbol&doc=$lang";
});
#-----------------------------------------------------------------------------
# latest
#
# This uses the text file at
#
# http://www.ljse.si/cgi-bin/jve.cgi?doc=2111
#
# which is
#
use constant BTS_URL => 'http://www.ljse.si/datoteke/BTStecajEUR.txt';
#
# The charset isn't specified in the http headers nor the file format specs
# but it's codepage 1250. The server provides ETag and Last-Modified.
#
# The symbols in each file are cached, so it's usually possible to go
# straight to the right one. If some symbols aren't where expected then
# both are downloaded to recheck.
#
App::Chart::LatestHandler->new
(pred => $pred,
available_tdate => \&available_tdate,
proc => \&latest_download);
# per specs pdf file, available around 16:30 each day
sub available_tdate {
App::Chart::Download::tdate_today_after (16,30, $timezone_ljubljana);
}
sub latest_download {
my ($symbol_list) = @_;
App::Chart::Download::status (__('LJSE price file'));
my $resp = App::Chart::Download->get (BTS_URL,
url_tags_key => 'LJ-BTStecajEUR');
if (! $resp->is_success) {
return; # 304 not modified
}
App::Chart::Download::write_latest_group (bts_parse ($resp));
}
my ($L0010, $L0020);
sub bts_parse {
my ($resp) = @_;
my @data = ();
my $h = { source => __PACKAGE__,
url_tags_key => 'LJ-BTStecajEUR',
resp => $resp,
currency => 'EUR',
date_format => 'dmy',
suffix => '.TSP',
data => \@data };
# charset not specified, but is codepage 1250
my $content = $resp->decoded_content (raise_error => 1,
default_charset => 'cp1250');
$content =~ s/\r//g;
# 0001 file format marker
# $content =~ /^ 0001 110 /
# or die 'Ljubljana: BTS file missing 0001 id line';
# my $date = txt_to_date ($content);
foreach my $line (split /\n+/, $content) {
my $elem;
if ($line =~ /^ 0010 /) {
# index
$L0010 ||= make_parser (code => 4,
symbol => 8,
name => 40,
close => '15.',
change => '15.',
percent_change => '15.');
$elem = $L0010->($line);
$elem->{'symbol'} = '^' . $elem->{'symbol'};
} elsif ($line =~ /^ 0020 /) {
# stock
$L0020 ||= make_parser (code => 4,
tier => 4,
type => 4,
symbol => 8,
isin => 20,
name => 40,
dividend => '15.',
note_num => 10,
average_price => '15.',
change => '15.',
percent_change => '15.',
last_date => 10,
bid => '15.',
offer => '15.',
high => '15.',
low => '15.',
open => '15.',
close => '15.',
volume => 12,
volume_offmarket => 12,
turnover => 12,
turnover_bas => 12,
IF_1 => 15,
IF_2 => 15,
IF_percent => 15,
note => 10,
shares_issued => 12,
dividend_date => 10,
p_e => 10,
principle => 20,
interest => 20,
coupon_num => 5,
market_discount => 15,
name_and_city => 80,
lib/App/Chart/Suffix/LJ.pm view on Meta::CPAN
# value = prev * (1 + change%/100)
# so prev = value * 100/(100+change%)
# want change = value - prev
# which is change = value * (1 - 100/(100+change%))
# = value * -change% / (100+change%)
# = value * change% / (100+change%)
#
return sprintf '%.*f', $decimals,
$value * $percent_change / ($percent_change + 100);
}
#-----------------------------------------------------------------------------
# download - individual
#
# This uses the data archives at
#
# http://www.ljse.si/cgi-bin/jve.cgi?doc=2069
#
# which gives a csv download like
#
# http://www.ljse.si/cgi-bin/jve.cgi?sid=cUg7wt8bhOKsEJiy&doc=2137&date1=02.07.2007&date2=04.07.2007&IndexCode=SBI20&SecurityId=ACLG&x=53&y=10
#
# "sid" is a session id of some sort, it works to drop it and the x and y.
# The "csv" option isn't shown on the web page any more, but still works.
# Thus,
#
# http://www.ljse.si/cgi-bin/jve.cgi?doc=2137&date1=02.07.2007&date2=04.07.2007&IndexCode=SBI20&SecurityId=ACLG&csv=1
#
# When there's no trading days in the requested range (public holidays),
# the file obtained is empty.
App::Chart::DownloadHandler::IndivChunks->new
(name => __('Yahoo'),
pred => $pred,
available_tdate => \&available_tdate,
url_func => \&podatki_url,
parse => \&podatki_parse,
chunk_size => 2500);
# return a url string, as per the examples shown above
sub podatki_url {
my ($symbol, $lo_tdate, $hi_tdate) = @_;
my $index = ($symbol =~ /^\^/);
$symbol =~ s/^\^//;
$symbol = App::Chart::symbol_sans_suffix ($symbol);
my ($lo_year, $lo_month, $lo_day) = App::Chart::tdate_to_ymd ($lo_tdate);
my ($hi_year, $hi_month, $hi_day) = App::Chart::tdate_to_ymd ($hi_tdate);
return sprintf 'http://www.ljse.si/cgi-bin/jve.cgi?doc=2137&date1=%02d.%02d.%04d&date2=%02d.%02d.%04d&IndexCode=%s&SecurityId=%s&csv=1',
$lo_day, $lo_month, $lo_year,
$hi_day, $hi_month, $hi_year,
($index ? $symbol : ''), # index symbol, or empty
($index ? 'X' : $symbol); # share symbol, or dummy
}
sub podatki_parse {
my ($symbol, $resp) = @_;
my $content = $resp->decoded_content (raise_error => 1);
my $index = ($symbol =~ /^\^/); # if an index symbol
my @data = ();
my $h = { source => __PACKAGE__,
currency => 'EUR',
date_format => 'mdy', # eg. 'Jul 28. 2006'
# last_download => 1,
data => \@data };
foreach my $line (split /\n/, $content) {
my ($date, $index_price, $stock_price) = split /;/, $line;
push @data, { date => $date,
symbol => $symbol,
close => ($index ? $index_price : $stock_price) };
}
return $h;
}
1;
__END__
# @c ---------------------------------------------------------------------------
# @c @node Ljubljana Stock Exchange
# @c @section Ljubljana Stock Exchange
# @c @cindex Ljubljana stock exchange
# @c @cindex Slovenia
# @c
# @c @uref{http://www.ljse.si}
# @c
# @c LJSE provides
# @c
# @c @itemize
# @c @item
# @c Quotes at the end of each day for stocks, indices and bonds.
# @c @item
# @c Historical average prices for stocks and indices.
# @c @end itemize
# @c
# @c The LJSE website information is for non-commercial use only. See the terms at
# @c
# @c @quotation
# @c @uref{http://www.ljse.si/cgi-bin/jve.cgi?doc=1506}
# @c @end quotation
# @c
# @c @cindex @code{.LJ}
# @c In Chart LJSE stock symbols have a @samp{.LJ} suffix, for instance
# @c @samp{ACLG.LJ} for ACH d.d., and similarly bonds like @samp{RS62.LJ}. Indexes
# @c have a @samp{^} prefix, for instance @samp{^SBI20.LJ} for the Slovenian 20.
# @c All prices are in Euros (having converted from Slovenian Tolar in January
# @c 2007).
# @c @c SYMBOL: ACLG.LJ
# @c @c SYMBOL: RS62.LJ
# @c
# @c The data archive downloads only give average daily prices. The whole-day
# @c files (which are used for quotes) have high/low ranges and trading volume, but
# @c at 160k per day it would be too much to download them for a past few years
# @c data.
( run in 1.037 second using v1.01-cache-2.11-cpan-437f7b0c052 )