File Coverage

blib/lib/Finance/Quote/MorningstarAU.pm
Criterion Covered Total %
statement 21 61 34.4
branch 0 16 0.0
condition 0 3 0.0
subroutine 8 10 80.0
pod 0 3 0.0
total 29 93 31.1


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2             #
3             # Copyright (C) 2019, Jalon Avens
4             #
5             # This program is free software; you can redistribute it and/or modify
6             # it under the terms of the GNU General Public License as published by
7             # the Free Software Foundation; either version 2 of the License, or
8             # (at your option) any later version.
9             #
10             # This program is distributed in the hope that it will be useful,
11             # but WITHOUT ANY WARRANTY; without even the implied warranty of
12             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13             # GNU General Public License for more details.
14             #
15             # You should have received a copy of the GNU General Public License
16             # along with this program; if not, write to the Free Software
17             # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18             # 02110-1301, USA
19              
20             package Finance::Quote::MorningstarAU;
21              
22 5     5   2611 use strict;
  5         12  
  5         152  
23 5     5   32 use warnings;
  5         12  
  5         189  
24              
25 5     5   32 use constant DEBUG => $ENV{DEBUG};
  5         14  
  5         335  
26 5     5   51 use if DEBUG, 'Smart::Comments';
  5         11  
  5         38  
27              
28 5     5   210 use JSON;
  5         20  
  5         43  
29 5     5   798 use Web::Scraper;
  5         18  
  5         80  
30              
31             our $VERSION = '1.58'; # VERSION
32              
33             sub methods {
34 5     5 0 52 return (aufunds => \&morningstarau, morningstarau => \&morningstarau,);
35             }
36              
37             sub labels {
38 5     5 0 20 my @labels = qw/currency date isodate method name price symbol/;
39 5         24 return (aufund => \@labels, morningstarau => \@labels);
40             }
41              
42             sub morningstarau {
43 0     0 0   my $quoter = shift;
44 0           my @symbols = @_;
45 0           my $ua = $quoter->user_agent();
46              
47 0 0         return unless @symbols;
48              
49 0           my %info;
50              
51 0           foreach my $symbol (@symbols) {
52 0           eval {
53 0           my $lookup = "https://www.morningstar.com.au/Ausearch/SecurityCodeAutoLookup?q=$symbol";
54 0           my $reply = $ua->get($lookup);
55              
56 0 0         die "Failed to find APIR $symbol" unless $reply->code == 200;
57              
58 0           my $json_data = JSON::decode_json $reply->content;
59              
60             ### MorningstarAU lookup: $json_data
61              
62 0 0 0       die "Failed to find unique APIR $symbol" unless $json_data and $json_data->{hits}->{total} == 1;
63              
64 0           my $id = $json_data->{hits}->{hits}[0]->{_source}->{Symbol};
65            
66             ### MorningstarAU input: $symbol
67             ### MorningstarAU id : $id
68              
69 0           my $url = "https://www.morningstar.com.au/Funds/FundReport/$id";
70 0           $reply = $ua->get($url);
71              
72 0 0         die "Failed to fetch quote for $symbol using id $id" unless $reply->code == 200;
73              
74             my $processor = scraper {
75 0     0     process 'div#maincontent h1.RecentHeading', 'name' => ['TEXT', sub {s/^\s*|\s*$//g}];
  0            
76 0           process 'h3 + p.fundreportsubheading', 'date[]' => ['TEXT', qr/^as at ([0-9]{1,2} [A-Za-z]{3} [0-9]{4})/];
77 0           process 'table.tablefundreport td', 'table[]' => ['TEXT', sub {s/\s//g}];
  0            
78 0           };
79              
80 0           my $data = $processor->scrape($reply);
81              
82             ### data: $data
83              
84 0           my %table = @{$data->{table}};
  0            
85              
86 0 0         die "Mismatch symbol $symbol to APIR Code $table{APIRCode}" unless $symbol eq $table{APIRCode};
87              
88 0           $info{$symbol, 'success'} = 1;
89 0 0         $info{$symbol, 'currency'} = $table{BaseCurrency} eq '$A' ? 'AUD' : $table{BaseCurrency};
90              
91 0           my @dates = grep defined, @{$data->{date}};
  0            
92 0           $quoter->store_date(\%info, $symbol, {'eurodate' => $dates[-1]});
93              
94 0           $info{$symbol, 'method'} = 'morningstarau';
95 0           $info{$symbol, 'name'} = $data->{name};
96 0           $info{$symbol, 'price'} = $table{'ExitPrice$'};
97 0           $info{$symbol, 'symbol'} = $table{APIRCode};
98             };
99              
100 0 0         if ($@) {
101 0           chomp($@);
102             ### error: $@
103              
104 0           $info{$symbol, 'success'} = 0;
105 0           $info{$symbol, 'errormsg'} = $@;
106             }
107             }
108              
109 0 0         return wantarray() ? %info : \%info;
110             }
111              
112             1;
113              
114             =head1 NAME
115              
116             Finance::Quote::MorningstarAU - Obtain Australian managed fund quotes from morningstar.com.au
117              
118             =head1 SYNOPSIS
119              
120             $q = Finance::Quote->new;
121              
122             %info = Finance::Quote->fetch("morningstarau","<APIR> ..."); # Only query morningstar.com.au using APIRs
123             %info = Finance::Quote->fetch("aufunds","<APIR> ..."); # Failover to other sources
124              
125             =head1 DESCRIPTION
126              
127             This module fetches information from the MorningStar Funds service
128             https://morningstar.com.au to provide quotes on Australian managed funds in
129             AUD.
130              
131             Funds are identified by their APIR code.
132              
133             This module is loaded by default on a Finance::Quote object. It's also possible
134             to load it explicitly by placing "morningstarau" in the argument list to
135             Finance::Quote->new().
136              
137             =head2 Managed Funds
138              
139             This module provides both the "morningstarau" and "aufunds" fetch methods for
140             fetching Australian funds prices from morningstar.com.au. Please use the
141             "aufunds" fetch method if you wish to have failover with future sources for of
142             Ausralian fund quotations which might be provided by other Finance::Quote
143             modules. Using the "morningstarau" method will guarantee that your information
144             only comes from the morningstar.com.au website.
145              
146             =head1 LABELS RETURNED
147              
148             The following labels may be returned by
149             Finance::Quote::MorningstarAU::morningstarau:
150              
151             currency, date, isodate, method, name, price, symbol
152              
153             =head1 SEE ALSO
154              
155             Morningstart Australia website https://morningstar.com.au
156              
157             =head1 AUTHOR
158              
159             Jalon Avens & others
160              
161             =head1 COPYRIGHT AND LICENSE
162              
163             Copyright (C) 2019 by Jalon Avens
164              
165             This program is free software; you can redistribute it and/or modify
166             it under the terms of the GNU General Public License as published by
167             the Free Software Foundation; either version 2 of the License, or (at
168             your option) any later version.
169              
170             =cut