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__ |