File Coverage

blib/lib/Finance/YahooQuote.pm
Criterion Covered Total %
statement 54 61 88.5
branch 8 16 50.0
condition 0 9 0.0
subroutine 14 16 87.5
pod 0 7 0.0
total 76 109 69.7


line stmt bran cond sub pod time code
1             # perl -w
2             #
3             # Copyright (C) 1998-2002, Dj Padzensky
4             # Copyright (C) 2002-2010 Dirk Eddelbuettel
5             #
6             # This program is free software; you can redistribute it and/or modify
7             # it under the terms of the GNU General Public License as published by
8             # the Free Software Foundation; either version 2 of the License, or
9             # (at your option) any later version.
10             #
11             # This program is distributed in the hope that it will be useful,
12             # but WITHOUT ANY WARRANTY; without even the implied warranty of
13             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14             # GNU General Public License for more details.
15             #
16             # You should have received a copy of the GNU General Public License
17             # along with this program; if not, write to the Free Software
18             # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19             #
20             # $Id: YahooQuote.pm,v 1.11 2010/03/27 00:44:10 edd Exp $
21              
22             package Finance::YahooQuote;
23             require 5.005;
24              
25             require Exporter;
26 5     5   3074 use strict;
  5         11  
  5         213  
27 5         740 use vars qw($VERSION @EXPORT @ISA
28             $QURL $QURLbase $QURLformat $QURLextended $QURLrealtime $QURLend
29 5     5   23 $TIMEOUT $PROXY $PROXYUSER $PROXYPASSWD);
  5         7  
30              
31 5     5   12424 use HTTP::Request::Common;
  5         223693  
  5         567  
32 5     5   5892 use Text::ParseWords;
  5         8053  
  5         5408  
33              
34             $VERSION = '0.24';
35              
36             ## these variables govern what type of quote the modules is retrieving
37             $QURLbase = "http://download.finance.yahoo.com/d/quotes.csvr?e=.csv&f=";
38             $QURLformat = "snl1d1t1c1p2va2bapomwerr1dyj1x"; # default up to 0.19
39             $QURLextended = "s7t8e7e8e9r6r7r5b4p6p5j4m3m4"; # new in 0.20
40             $QURLrealtime = "b2b3k2k1c6m2j3"; # also new in 0.20
41             $QURLend = "&s=";
42             $QURL = $QURLbase . $QURLformat . $QURLend; # define old format as default
43              
44             @ISA = qw(Exporter);
45             @EXPORT = qw(&getquote &getonequote &getcustomquote
46             &setQueryString &useExtendedQueryFormat
47             &useRealtimeQueryFormat);
48             undef $TIMEOUT;
49              
50             ## simple function to switch to extended format
51             sub useExtendedQueryFormat {
52 1     1 0 33 $QURLformat .= $QURLextended;
53             }
54              
55             ## simple function to append real-time format
56             sub useRealtimeQueryFormat {
57 1     1 0 23 $QURLformat .= $QURLrealtime;
58             }
59              
60             ## allow module user to define a new query string
61             sub setQueryString {
62 0     0 0 0 my $format = shift;
63 0         0 $QURLformat = $format;
64             }
65              
66             ## Common function for reading the yahoo site and retrieving and
67             ## parsing the data returned
68             ## The format used is supplied as a second argument, the default function
69             ## getquoye() below uses the default format $QURLformat, and either one of
70             ## the two preceding functions can be used to select the extended format
71             sub readYahoo {
72              
73 6     6 0 13 my @symbols = @{(shift)};
  6         19  
74 6         15 my $format = shift;
75              
76 6         12 my @qr;
77 6         57 my $ua = RequestAgent->new;
78 6         56 $ua->env_proxy; # proxy settings from *_proxy env. variables.
79 6 50       87539 $ua->proxy('http', $PROXY) if defined $PROXY;
80 6 50       108 $ua->timeout($TIMEOUT) if defined $TIMEOUT;
81              
82             # Loop over the list of symbols, grabbing 199 symbols at a
83             # time, since yahoo only lets you get 200 per request
84 6         155 while ($#symbols > -1) {
85 6 50       45 my @b = $#symbols >= 199 ? splice(@symbols,0,199)
86             : splice(@symbols,0,$#symbols+1);
87              
88 6         44 my $url = "$QURLbase${format}$QURLend".join('+',@b);
89 6         42 foreach (split('\015?\012',$ua->request(GET $url)->content)) {
90 8         3105162 my @q = quotewords(',',0,$_);
91 8         4830 push(@qr,[@q]);
92             }
93             }
94              
95 6         307 return \@qr;
96             }
97              
98             my %fields = (
99             'Symbol' => 's', # old default
100             'Name' => 'n', # old default
101             'Last Trade (With Time)' => 'l',
102             'Last Trade (Price Only)' => 'l1', # old default
103             'Last Trade Date' => 'd1', # old default
104             'Last Trade Time' => 't1', # old default
105             'Last Trade Size' => 'k3',
106             'Change and Percent Change' => 'c',
107             'Change' => 'c1', # old default
108             'Change in Percent' => 'p2', # old default
109             'Ticker Trend' => 't7',
110             'Volume' => 'v', # old default
111             'Average Daily Volume' => 'a2', # old default
112             'More Info' => 'i',
113             'Trade Links' => 't6',
114             'Bid' => 'b', # old default
115             'Bid Size' => 'b6',
116             'Ask' => 'a', # old default
117             'Ask Size' => 'a5',
118             'Previous Close' => 'p', # old default
119             'Open' => 'o', # old default
120             "Day's Range" => 'm', # old default
121             '52-week Range' => 'w', # old default
122             'Change From 52-wk Low' => 'j5',
123             'Pct Chg From 52-wk Low' => 'j6',
124             'Change From 52-wk High' => 'k4',
125             'Pct Chg From 52-wk High' => 'k5',
126             'Earnings/Share' => 'e', # old default
127             'P/E Ratio' => 'r', # old default
128             'Short Ratio' => 's7',
129             'Dividend Pay Date' => 'r1', # old default
130             'Ex-Dividend Date' => 'q',
131             'Dividend/Share' => 'd', # old default
132             'Dividend Yield' => 'y', # old default
133             'Float Shares' => 'f6',
134             'Market Capitalization' => 'j1', # old default
135             '1yr Target Price' => 't8',
136             'EPS Est. Current Yr' => 'e7',
137             'EPS Est. Next Year' => 'e8',
138             'EPS Est. Next Quarter' => 'e9',
139             'Price/EPS Est. Current Yr' => 'r6',
140             'Price/EPS Est. Next Yr' => 'r7',
141             'PEG Ratio' => 'r5',
142             'Book Value' => 'b4',
143             'Price/Book' => 'p6',
144             'Price/Sales' => 'p5',
145             'EBITDA' => 'j4',
146             '50-day Moving Avg' => 'm3',
147             'Change From 50-day Moving Avg' => 'm7',
148             'Pct Chg From 50-day Moving Avg' => 'm8',
149             '200-day Moving Avg' => 'm4',
150             'Change From 200-day Moving Avg' => 'm5',
151             'Pct Chg From 200-day Moving Avg' => 'm6',
152             'Shares Owned' => 's1',
153             'Price Paid' => 'p1',
154             'Commission' => 'c3',
155             'Holdings Value' => 'v1',
156             "Day's Value Change" => 'w1',
157             'Holdings Gain Percent' => 'g1',
158             'Holdings Gain' => 'g4',
159             'Trade Date' => 'd2',
160             'Annualized Gain' => 'g3',
161             'High Limit' => 'l2',
162             'Low Limit' => 'l3',
163             'Notes' => 'n4',
164             'Last Trade (Real-time) with Time'=> 'k1',
165             'Bid (Real-time)' => 'b3',
166             'Ask (Real-time)' => 'b2',
167             'Change Percent (Real-time)' => 'k2',
168             'Change (Real-time)' => 'c6',
169             'Holdings Value (Real-time)' => 'v7',
170             "Day's Value Change (Real-time)" => 'w4',
171             'Holdings Gain Pct (Real-time)' => 'g5',
172             'Holdings Gain (Real-time)' => 'g6',
173             "Day's Range (Real-time)" => 'm2',
174             'Market Cap (Real-time)' => 'j3',
175             'P/E (Real-time)' => 'r2',
176             'After Hours Change (Real-time)' => 'c8',
177             'Order Book (Real-time)' => 'i5',
178             'Stock Exchange' => 'x' # old default
179             );
180              
181             # Let the user define which colums to retrive from yahoo
182             #
183             sub getcustomquote {
184 2     2 0 58 my $symbols = shift;
185 2         5 my $columns = shift;
186              
187 2         5 my $format = join('',map {$fields{$_}} @{$columns});
  6         26  
  2         6  
188              
189 2         12 my $qr = readYahoo($symbols,$format);
190 2 50       18 return wantarray() ? @$qr : $qr;
191             }
192              
193             # get quotes for all symbols in array
194              
195             sub getquote {
196 4     4 0 30 my @symbols = @_;
197              
198 4         9 my $format = $QURLformat; ## Old default from variable
199 4         17 my $qr = readYahoo(\@symbols,$format);
200 4 100       35 return wantarray() ? @$qr : $qr;
201             }
202              
203             # Input: A single stock symbol
204             # Output: An array, containing the list elements mentioned above.
205              
206             sub getonequote {
207 1     1 0 23 my @x;
208 1         6 @x = &getquote($_[0]);
209 1 50       6 return wantarray() ? @{$x[0]} : \@{$x[0]} if @x;
  1 50       41  
  0         0  
210             }
211              
212             BEGIN { # Local variant of LWP::UserAgent that
213 5     5   9721 use LWP; # checks for user/password if document
  5         170783  
  5         352  
214             package RequestAgent; # this code taken from lwp-request, see
215 5     5   56 no strict 'vars'; # the various LWP manual pages
  5         7  
  5         766  
216 5     5   303 @ISA = qw(LWP::UserAgent);
217              
218             sub new {
219 6     6   45 my $self = LWP::UserAgent::new(@_);
220 6         17740 $self->agent("Finance-YahooQuote/0.18");
221 6         387 $self;
222             }
223              
224             sub get_basic_credentials {
225 0     0     my $self = @_;
226 0 0 0       if (defined($PROXYUSER) and defined($PROXYPASSWD) and
      0        
      0        
227             $PROXYUSER ne "" and $PROXYPASSWD ne "") {
228 0           return ($PROXYUSER, $PROXYPASSWD);
229             } else {
230             return (undef, undef)
231 0           }
232             }
233             }
234              
235             1;
236              
237             __END__