#!/usr/bin/perl -w # # Copyright (C) 1998, Dj Padzensky # Copyright (C) 1998, 1999 Linas Vepstas # Copyright (C) 2000, Yannick LE NY # Copyright (C) 2000, Paul Fenwick # Copyright (C) 2000, Brent Neal # # 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 Street, Fifth Floor, Boston, MA # 02110-1301, USA # # # This code derived from Padzensky's work on package Finance::YahooQuote, # but extends its capabilites to encompas a greater number of data sources. # # This code was developed as part of GnuCash package Finance::Quote::Troweprice; require 5.005; use strict; use vars qw( $TROWEPRICE_URL); use LWP::UserAgent; use Time::Piece; use Try::Tiny; our $VERSION = '1.51'; # VERSION # URLs of where to obtain information. $TROWEPRICE_URL = ("https://www3.troweprice.com/fb2/ppfweb/downloadPrices.do"); sub methods { return (troweprice => \&troweprice, troweprice_direct => \&troweprice); } { my @labels = qw/method exchange name nav date isodate price/; sub labels { return (troweprice => \@labels, troweprice_direct => \@labels); } } # ======================================================================= sub troweprice { my $quoter = shift; my @symbols = @_; return if (! scalar @symbols); # for T Rowe Price, we get them all. my %info; my $url = $TROWEPRICE_URL; my $ua = $quoter->user_agent; my $reply = $ua->get( $url, 'Accept-Language' => 'en-US,en' ); if (! $reply->is_success) { for my $stock (@symbols) { $info{ $stock, "success" } = 0; $info{ $stock, "errormsg" } = "Error retrieving quote for $stock. Attempt to fetch the URL $url resulted in HTTP response:i " . $reply->status_line; } return wantarray() ? %info : \%info; } my $quotes; my $csv = $reply->content; open my $in, '<', \$csv; RECORD: while (my $line = <$in>) { next RECORD if ($line !~ /\S/); #$line =~ s/\s+$//; my @q = $quoter->parse_csv($line); my $symbol = $q[0]; next RECORD if (! grep {$_ eq $symbol} @symbols); my $date; try { $date = Time::Piece->strptime($q[2], "%m/%d/%Y"); } catch { $info{ $symbol, "success" } = 0; $info{ $symbol, "errormsg" } = "Failed to parse quote date. Please contact developers"; next RECORD; }; $quotes->{$symbol} = { price => $q[1], date => $date, } } SYMBOL: for my $symbol (@symbols) { # skip if already defined due to earlier parsing error next SYMBOL if (defined $info{ $symbol, 'success' }); if (! defined $quotes->{$symbol}) { $info{ $symbol, "success" } = 0; $info{ $symbol, "errormsg" } = "Error retrieving quote for $symbol - no listing for this" . " name found. Please check symbol."; next SYMBOL; } $info{ $symbol, "success" } = 1; $info{ $symbol, 'symbol' } = $symbol; $info{ $symbol, "exchange" } = "T. Rowe Price"; $info{ $symbol, "method" } = "troweprice"; $info{ $symbol, "name" } = $symbol; # no name supplied ... $info{ $symbol, "nav" } = $quotes->{$symbol}->{price}; $info{ $symbol, "price" } = $info{$symbol,"nav"}; $info{ $symbol, "currency" } = "USD"; $quoter->store_date( \%info, $symbol, {isodate => $quotes->{$symbol}->{date}->ymd} ); } return wantarray() ? %info : \%info; } 1; =head1 NAME Finance::Quote::Troweprice - Obtain quotes from T. Rowe Price =head1 SYNOPSIS use Finance::Quote; $q = Finance::Quote->new; %stockinfo = $q->fetch("troweprice","PRFDX"); =head1 DESCRIPTION This module obtains information about managed funds from T. Rowe Price. Information about T. Rowe Price funds is available from a variety of sources. This module fetches information directly from T. Rowe Price. =head1 LABELS RETURNED Information available from T. Rowe Price may include the following labels: exchange, name, nav, date, price. =head1 SEE ALSO T. Rowe Price website - http://www.troweprice.com/ =cut