File Coverage

blib/lib/Finance/Quote/Cdnfundlibrary.pm
Criterion Covered Total %
statement 26 74 35.1
branch 0 14 0.0
condition n/a
subroutine 10 12 83.3
pod 0 4 0.0
total 36 104 34.6


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2              
3             # Cdnfundlibrary.pm
4             #
5             # Version 0.6 retrieve more data via different fundlibrary.com url
6             # Version 0.5 made functional again
7             # Version 0.4 fixed up multiple lookup (March 3, 2001)
8             # Version 0.3 fixed up yield lookup
9             # Version 0.2 functional with Finance::Quote - added error-checking
10             # Version 0.1 pre trial of parsing of info from www.fundlibrary.com
11              
12              
13             package Finance::Quote::Cdnfundlibrary;
14             require 5.004;
15              
16 5     5   2617 use strict;
  5         11  
  5         166  
17              
18 5     5   26 use vars qw( $FUNDLIB_URL $FUNDLIB_MAIN_URL);
  5         11  
  5         225  
19              
20 5     5   34 use LWP::UserAgent;
  5         10  
  5         30  
21 5     5   535 use HTTP::Request::Common;
  5         9  
  5         288  
22 5     5   27 use HTML::TableExtract;
  5         10  
  5         36  
23 5     5   182 use JSON;
  5         14  
  5         47  
24              
25 5     5   576 use warnings;
  5         11  
  5         180  
26 5     5   2979 use Time::Piece;
  5         36029  
  5         31  
27              
28             our $VERSION = '1.58'; #VERSION
29              
30             # URLs of where to obtain information.
31              
32             $FUNDLIB_URL =
33             ("https://www.fundlibrary.com/MutualFunds/GetFundSearchResults?cifscCategoryId=0&fundCompanyId=0&fundTypeId=0&isGradeA=true&isGradeB=true&isGradeC=true&isGradeD=true&isGradeE=true&sortBy=Default&page=0&searchText=");
34             $FUNDLIB_MAIN_URL=("http://www.fundlibrary.com");
35              
36 5     5 0 26 sub methods { return (canadamutual => \&fundlibrary,
37             fundlibrary => \&fundlibrary); }
38              
39             {
40             my @labels = qw/method source link name currency last date isodate nav yield
41             price net p_change/;
42 5     5 0 18 sub labels { return (canadamutual => \@labels,
43             fundlibrary => \@labels); }
44             }
45              
46 0     0 0   sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
  0            
  0            
47              
48             #
49             # =======================================================================
50              
51             sub fundlibrary {
52 0     0 0   my $quoter = shift;
53 0           my @symbols = @_;
54              
55             # Make sure symbols are requested
56             ##CAN exit more gracefully - add later##
57              
58 0 0         return unless @symbols;
59              
60             # Local Variables
61 0           my(%fundquote, $mutual);
62 0           my($ua, $url, $reply, $ts, $row, $rowhd, $te, @rows, @ts);
63              
64 0           $ua = $quoter->user_agent;
65              
66 0           foreach (@symbols) {
67              
68 0           $mutual = $_;
69              
70 0           $url = "$FUNDLIB_URL$mutual";
71 0           $reply = $ua->request(GET $url);
72              
73 0           $te = new HTML::TableExtract(headers => ["NAVPS"],
74             slice_columns => 0);
75              
76             # Make sure something is returned ##CAN exit more gracefully - add later##
77 0 0         return unless ($reply->is_success);
78              
79 0           my $json = JSON->new;
80 0           my $data = decode_json($reply->decoded_content);
81              
82             # If the fund is not found, "PriceAsOfDateString" is "0001-01-01T00:00"
83 0 0         if ( $$data{'PriceAsOfDateString'} eq "0001-01-01T00:00" )
84             {
85 0           $fundquote {$mutual,"success"} = 0;
86 0           $fundquote {$mutual,"errormsg"} = "Fund name $mutual not found";
87 0           next;
88             }
89              
90 0           my $t = Time::Piece->strptime($$data{'PriceAsOfDateString'}, "%Y-%m-%dT%T");
91              
92 0           $te->parse($$data{'SearchFundResultView'});
93              
94             # Check for a page without tables
95             # This gets returned when a bad symbol name is given
96 0 0         unless ( $te->tables > 0 )
97             {
98 0           $fundquote {$mutual,"success"} = 0;
99 0           $fundquote {$mutual,"errormsg"} = "Fund name $mutual not found";
100 0           next;
101             }
102              
103 0           @rows = $te->rows;
104 0 0         if(@rows) {
105 0           $row = $rows[1];
106              
107 0           $fundquote {$mutual, "name"} = trim($$row[0]);
108 0           $fundquote {$mutual, "symbol"} = $mutual;
109 0           $fundquote {$mutual, "currency"} = "CAD";
110 0           $fundquote {$mutual, "source"} = $FUNDLIB_MAIN_URL;
111 0           $fundquote {$mutual, "link"} = $url;
112 0           $fundquote {$mutual, "method"} = "fundlibrary";
113              
114             # Fund price and date
115              
116 0           $fundquote {$mutual, "price"} = trim($$row[2]);
117 0           $fundquote {$mutual, "nav"} = trim($$row[2]);
118 0           $fundquote {$mutual, "last"} = trim($$row[2]);
119 0           $fundquote {$mutual, "net"} = trim($$row[3]);
120 0           $fundquote {$mutual, "p_change"} = trim($$row[4]);
121              
122 0           $quoter->store_date(\%fundquote, $mutual, {usdate => $t->strftime("%m-%d-%Y")});
123              
124             # Assume things are fine here.
125 0           $fundquote {$mutual, "success"} = 1;
126              
127             # Performance yield
128 0 0         $fundquote {$mutual, "yield"} = trim($$row[5]) if ($$row[5] ne "--");
129             }
130             else {
131 0           $fundquote {$mutual, "success"} = 0;
132 0           $fundquote {$mutual, "errormsg"} = "Fund Not Found";
133             }
134              
135             } #end symbols
136              
137 0 0         return %fundquote if wantarray;
138 0           return \%fundquote;
139              
140             }
141              
142             1;
143              
144             =head1 NAME
145              
146             Finance::Quote::Cdnfundlibrary - Obtain mutual fund prices from
147             www.fundlibrary.com
148              
149             =head1 SYNOPSIS
150              
151             use Finance::Quote;
152              
153             $q = Finance::Quote->new;
154              
155             %stockinfo = $q->fetch("canadamutual","fundlib-code"); # Can
156             failover to other methods
157             %stockinfo = $q->fetch("fundlibrary","fundlib-code"); # Use this
158             module only.
159              
160             # NOTE: currently no failover methods exist for canadamutual
161              
162             =head1 DESCRIPTION
163              
164             This module obtains information about Canadian Mutual Fund prices from
165             www.fundlibrary.com. The information source "canadamutual" can be used
166             if the source of prices is irrelevant, and "fundlibrary" if you
167             specifically want to use www.fundlibrary.com.
168              
169             =head1 FUNDLIB-CODE
170              
171             In Canada a mutual fund does not have a unique global symbol identifier.
172              
173             This module uses an id that represents the mutual fund on an id used by
174             www.fundlibrary.com. There is no easy way of fetching the id except
175             to jump onto the fundlibrary website, look up the fund and view the url
176             for clues to its id number.
177              
178             =head1 LABELS RETURNED
179              
180             Information available from fundlibrary may include the following labels:
181              
182             exchange method link source name currency yield last nav price. The
183             link
184             label will be a url location for a one page snapshot that fundlibrary
185             provides
186             on the fund.
187              
188             =head1 SEE ALSO
189              
190             Fundlibrary website - http://www.fundlibrary.com/
191              
192             Finance::Quote
193              
194             =cut