File Coverage

blib/lib/Finance/Quote/Bloomberg.pm
Criterion Covered Total %
statement 23 64 35.9
branch 0 14 0.0
condition n/a
subroutine 9 10 90.0
pod 0 3 0.0
total 32 91 35.1


line stmt bran cond sub pod time code
1             package Finance::Quote::Bloomberg;
2              
3 5     5   2793 use strict;
  5         13  
  5         215  
4              
5 5     5   32 use LWP::UserAgent;
  5         15  
  5         44  
6 5     5   115 use HTTP::Request::Common;
  5         16  
  5         340  
7 5     5   2282 use HTTP::CookieJar::LWP ();
  5         143651  
  5         155  
8 5     5   51 use HTML::TreeBuilder;
  5         12  
  5         76  
9 5     5   141 use Encode;
  5         11  
  5         544  
10              
11             our $VERSION = '1.58'; # VERSION
12              
13 5     5   38 use vars qw($BLOOMBERG_URL);
  5         11  
  5         2913  
14              
15             $BLOOMBERG_URL = 'https://www.bloomberg.com/quote/';
16              
17 5     5 0 21 sub methods { return (bloomberg => \&bloomberg); }
18              
19             {
20             my @labels = qw/method name last currency symbol isodate/;
21              
22 5     5 0 15 sub labels { return (bloomberg => \@labels); }
23             }
24              
25             sub bloomberg {
26 0     0 0   my $quoter = shift;
27 0           my @symbols = @_;
28              
29 0 0         return unless @symbols;
30 0           my ($ua, $cj, $reply, $url, %funds, $te, $table, $row, @value_currency, $name);
31              
32 0           foreach my $symbol (@symbols) {
33 0           $name = $symbol;
34 0           $url = $BLOOMBERG_URL;
35 0           $url = $url . $name;
36 0           $cj = HTTP::CookieJar::LWP->new;
37 0           $ua = LWP::UserAgent->new(cookie_jar => $cj);
38 0           my @ns_headers = (
39             'User-Agent' => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0',
40             'Referer' => 'https://www.bloomberg.com/',
41             'Accept' => '*/*',
42             'Accept-Encoding' => 'br',
43             'Accept-Language' => 'en-US,en;q=0.5',
44             'Pragma' => 'no-cache', );
45 0           $reply = $ua->get($url, @ns_headers);
46              
47 0 0         unless ($reply->is_success) {
48 0           $funds{$symbol, "success"} = 0;
49 0           $funds{$symbol, "errormsg"} = "HTTP failure";
50 0           next;
51             }
52              
53 0           eval {
54 0           my $tree = HTML::TreeBuilder->new_from_content(decode_utf8 $reply->content);
55 0           my $desc = $tree->look_down(_tag=>'div', 'class'=>qr/SecurityName_extraLarge/)->as_text();
56 0           my $price = $tree->look_down(_tag=>'div', 'class'=>qr/^sized-price SizedPrice_extraLarge/)->as_text();
57 0           my $curr = $tree->look_down(_tag=>'span', 'class'=>qr/^quotePageHeader_securityDetails/)->as_text();
58 0           my $date = $tree->look_down(_tag=>'span', 'class'=>qr/^marketStatus_exchangeDelay/)->right();
59              
60 0           $curr =~ s/.*[(](.*)[)].*/$1/;
61 0           $price =~ s/,//g;
62 0 0         if ($curr eq "GBp") {
63 0           $curr = "GBP";
64 0           $price = $price / 100;
65             }
66 0 0         $date = $1 . "20" . $2 if $date =~ m|([0-9]{1,2}/[0-9]{1,2}/)([0-9]{2})$|;
67 0 0         $date = $1 if $date =~ m|([0-9]{1,2}/[0-9]{1,2}/[0-9]{4})|;
68              
69 0           $funds{$name, 'method'} = 'bloomberg';
70 0           $funds{$name, 'name'} = $desc;
71 0           $funds{$name, 'last'} = $price;
72 0           $funds{$name, 'currency'} = $curr;
73 0           $funds{$name, 'symbol'} = $name;
74              
75 0           $quoter->store_date(\%funds, $name, {usdate => $date});
76              
77 0           $funds{$name, 'success'} = 1;
78             };
79              
80 0 0         if ($@) {
81 0           $funds{$symbol, "success"} = 0;
82 0           $funds{$symbol, "errormsg"} = "parse error";
83             }
84             }
85              
86 0 0         return %funds if wantarray;
87 0           return \%funds;
88             }
89              
90             1;
91              
92             =head1 NAME
93              
94             Finance::Quote::Bloomberg - Obtain fund prices from Bloomberg.com
95              
96             =head1 SYNOPSIS
97              
98             use Finance::Quote;
99              
100             $q = Finance::Quote->new;
101              
102             %fundinfo = $q->fetch("bloomberg", "security");
103              
104             =head1 DESCRIPTION
105              
106             This module obtains information about fund prices from www.bloomberg.com.
107              
108             =head1 SECURITY NAME
109              
110             The security string must match the format expected by the site, such as
111             'AAPL:US' not 'AAPL'.
112              
113             =head1 LABELS RETURNED
114              
115             Labels returned by this module include: name, last, currency, symbol, isodate
116              
117             =head1 SEE ALSO
118              
119             Finance::Quote
120              
121             =cut