2016-06-06 20:02:00 +02:00
|
|
|
# Finance::Quote Perl module to retrieve prices of funds from DKB
|
|
|
|
# Copyright (C) 2016 Matthias Merz <matthias@merz-ka.de>
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
|
|
|
|
package Finance::Quote::DKB;
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use HTML::TreeBuilder::XPath;
|
2019-04-25 22:16:33 +02:00
|
|
|
use POSIX qw(strftime);
|
2016-06-06 20:02:00 +02:00
|
|
|
|
2017-10-27 20:05:33 +02:00
|
|
|
my $agent_string = 'Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0';
|
|
|
|
|
2016-06-07 22:08:28 +02:00
|
|
|
my %urlmap_wkn = (
|
2018-11-13 21:42:54 +01:00
|
|
|
'532656' => 'https://kurse.dkb.de/MIS/?pid=dkb_fnd_details&id_instrument=4071891&id_notation=3688058&id=0107980',
|
|
|
|
'974515' => 'https://kurse.dkb.de/MIS/?pid=dkb_fnd_details&id_instrument=102918&id_notation=3228063&id=0107980',
|
|
|
|
'a0dpw0' => 'https://kurse.dkb.de/MIS/?pid=dkb_fnd_details&id_instrument=11659733&id_notation=11014630&id=0107980',
|
|
|
|
'a0m430' => 'https://kurse.dkb.de/MIS/?pid=dkb_fnd_details&id_instrument=18085585&id_notation=20644387&id=0107980',
|
|
|
|
'a0m8hd' => 'https://kurse.dkb.de/MIS/?pid=dkb_fnd_details&id_instrument=19179789&id_notation=21240603&id=0107980',
|
|
|
|
'a0m9a2' => 'https://kurse.dkb.de/MIS/?pid=dkb_fnd_details&id_instrument=19035880&id_notation=23679474&id=0107980',
|
|
|
|
'a0ndda' => 'https://kurse.dkb.de/MIS/?pid=dkb_fnd_details&id_instrument=25204090&id_notation=31156472&id=0107980',
|
|
|
|
'a0x754' => 'https://kurse.dkb.de/MIS/?pid=dkb_fnd_details&id_instrument=22407622&id_notation=26567264&id=0107980',
|
|
|
|
'a0x758' => 'https://kurse.dkb.de/MIS/?pid=dkb_fnd_details&id_instrument=22533730&id_notation=26567263&id=0107980',
|
|
|
|
'a0ya5q' => 'https://kurse.dkb.de/MIS/?pid=dkb_fnd_details&id_instrument=26097198&id_notation=32652184&id=0107980',
|
|
|
|
'dws0pr' => 'https://kurse.dkb.de/MIS/?pid=dkb_fnd_details&id_instrument=18286450&id_notation=22946309&id=0107980',
|
|
|
|
'ewg0ld' => 'https://kurse.dkb.de/MIS/?pid=dkb_cer_details&id_instrument=55061564&id_notation=70580062&id=0107980'
|
2016-06-07 22:08:28 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
my %wknmap = (
|
2017-05-05 20:25:18 +02:00
|
|
|
'de0005326565' => '532656',
|
2018-06-09 12:56:54 +02:00
|
|
|
'de000a0m8hd2' => 'a0m8hd',
|
|
|
|
'de000a0x7541' => 'a0x754',
|
2018-06-09 13:05:32 +02:00
|
|
|
'de000a0x7582' => 'a0x758',
|
2017-12-30 14:14:25 +01:00
|
|
|
'de000ewg0ld1' => 'ewg0ld',
|
2018-06-09 12:56:54 +02:00
|
|
|
'fr0010135103' => 'a0dpw0',
|
|
|
|
'lu0087412390' => '974515',
|
|
|
|
'lu0323578657' => 'a0m430',
|
|
|
|
'lu0327386487' => 'dws0pr',
|
|
|
|
'lu0336084032' => 'a0m9a2',
|
2018-06-09 13:05:32 +02:00
|
|
|
'lu0438336264' => 'a0ndda',
|
2018-06-09 12:56:54 +02:00
|
|
|
'lu0454071019' => 'a0ya5q'
|
2016-06-07 22:08:28 +02:00
|
|
|
);
|
2016-06-06 20:02:00 +02:00
|
|
|
|
|
|
|
sub methods {return ('dkb' => \&dkb,
|
|
|
|
'europe' => \&dkb);}
|
2016-06-07 22:57:06 +02:00
|
|
|
{
|
|
|
|
my @labels = ('name', 'date', 'price', 'last', 'currency');
|
|
|
|
sub labels { return (dkb => \@labels, europe => \@labels); }
|
|
|
|
}
|
2016-06-06 20:02:00 +02:00
|
|
|
|
2016-06-07 22:08:28 +02:00
|
|
|
|
|
|
|
sub get_stock_url {
|
|
|
|
my $stock_wkn = shift;
|
|
|
|
|
|
|
|
my $url = $urlmap_wkn{lc($stock_wkn)};
|
|
|
|
if (!defined($url) || length($url) == 0) {
|
|
|
|
my $wkn = $wknmap{lc($stock_wkn)};
|
|
|
|
$url = $urlmap_wkn{$wkn};
|
|
|
|
}
|
|
|
|
return $url;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-06-06 20:02:00 +02:00
|
|
|
sub dkb
|
|
|
|
{
|
|
|
|
my $quoter = shift; # The Finance::Quote object.
|
|
|
|
my @stocks = @_;
|
|
|
|
|
|
|
|
my $ua = $quoter->user_agent();
|
2017-10-27 20:05:33 +02:00
|
|
|
$ua->agent($agent_string);
|
2016-06-06 20:02:00 +02:00
|
|
|
my %info;
|
|
|
|
|
|
|
|
foreach my $stock (@stocks) {
|
2016-06-07 22:08:28 +02:00
|
|
|
my $get_url = get_stock_url($stock);
|
|
|
|
if (!defined($get_url) || length($get_url) == 0) {
|
|
|
|
$info{$stock,"errormsg"} = "undefined DKB-UR";
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
my $response = $ua->get($get_url . "&search_value=" . $stock);
|
2016-06-06 20:02:00 +02:00
|
|
|
#print $response->content, "\n";
|
|
|
|
$info{$stock,"success"} = 0;
|
|
|
|
if (!$response -> is_success()) {
|
|
|
|
$info{$stock,"errormsg"} = "HTTP failure";
|
|
|
|
} else {
|
|
|
|
$info{$stock,"success"} = 1;
|
|
|
|
$info{$stock,'symbol'} = $stock;
|
|
|
|
my $parser = HTML::TreeBuilder::XPath->new_from_content($response->decoded_content);
|
|
|
|
|
2018-11-13 21:42:54 +01:00
|
|
|
my @names = $parser->findnodes( '//span[@class="h2"]');
|
2016-06-06 20:02:00 +02:00
|
|
|
if (@names) {
|
|
|
|
$info{$stock,'name'} = $names[0]->as_text;
|
|
|
|
};
|
2018-11-13 21:42:54 +01:00
|
|
|
my @prices = $parser->findnodes( '//span[@class="quote"]');
|
2016-06-06 20:02:00 +02:00
|
|
|
if (@prices) {
|
|
|
|
my $pricestr = $prices[0]->as_text;
|
|
|
|
my @splitvals = ( $pricestr =~ /((\d|,|\.)*)\s*/g);
|
|
|
|
if (@splitvals) {
|
2016-06-07 22:57:06 +02:00
|
|
|
my $converted_price = $splitvals[0];
|
|
|
|
$converted_price =~ s/\.//g;
|
|
|
|
$converted_price =~ s/,/./g;
|
|
|
|
$info{$stock,'price'} = $converted_price;
|
|
|
|
$info{$stock,'last'} = $converted_price;
|
2016-06-06 20:02:00 +02:00
|
|
|
}
|
|
|
|
};
|
2018-11-13 21:42:54 +01:00
|
|
|
my @units = $parser->findnodes( '//span[@class="unit"]');
|
|
|
|
if (@units) {
|
|
|
|
$info{$stock,'currency'} = $units[0]->as_text;
|
2016-06-06 20:02:00 +02:00
|
|
|
};
|
2019-04-25 21:54:15 +02:00
|
|
|
my @dates = $parser->findnodes( '//div[@class="exchangeLine"]/span');
|
|
|
|
if (@dates) {
|
|
|
|
my $tradedate = $dates[0]->as_text;
|
2020-06-03 21:49:47 +02:00
|
|
|
$tradedate =~ s/.*\|\s*(\d\d.*) $/$1/g;
|
2019-04-25 22:16:33 +02:00
|
|
|
if (length($tradedate) < 10) {
|
|
|
|
$tradedate = POSIX::strftime( '%d.%m.%Y', localtime());
|
|
|
|
}
|
|
|
|
$info{$stock,'date'} = $tradedate;
|
|
|
|
$quoter->store_date(\%info, $stock, {eurodate => $tradedate});
|
2019-04-25 21:54:15 +02:00
|
|
|
};
|
2016-06-07 22:57:06 +02:00
|
|
|
$info{$stock,'timezone'} = 'Europe/Berlin';
|
2016-06-06 20:02:00 +02:00
|
|
|
#$info{$stock,'currency'} = 'EUR';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return wantarray ? %info : \%info;
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|
|
|
|
|
|
|
|
=head1 NAME
|
|
|
|
|
|
|
|
Finance::Quote::DKB - Obtain fonds quotes from DKB.
|
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
|
|
|
|
use Finance::Quote;
|
|
|
|
|
|
|
|
$q = Finance::Quote->new("DKB");
|
|
|
|
|
|
|
|
%info = Finance::Quote->fetch("dkb","A0M9A2");
|
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
|
|
|
|
This module obtains fund prices from DKB,
|
|
|
|
http://www.dkb.de/.
|
|
|
|
|
|
|
|
=head1 LABELS RETURNED
|
|
|
|
|
|
|
|
The following labels may be returned by Finance::Quote::DKB:
|
|
|
|
name, date, price, last, method.
|
|
|
|
|
|
|
|
=head1 SEE ALSO
|
|
|
|
|
|
|
|
DKB, http://www.dkb.de/
|
|
|
|
|
|
|
|
Finance::Quote;
|
|
|
|
|
|
|
|
=cut
|