File Coverage

blib/lib/Yahoo/Finance.pm
Criterion Covered Total %
statement 52 60 86.6
branch 7 16 43.7
condition 2 3 66.6
subroutine 12 12 100.0
pod 1 1 100.0
total 74 92 80.4


line stmt bran cond sub pod time code
1             package Yahoo::Finance;
2              
3 1     1   84120 use 5.006;
  1         3  
4 1     1   5 use strict;
  1         1  
  1         17  
5 1     1   4 use warnings;
  1         2  
  1         18  
6 1     1   4 use Carp;
  1         1  
  1         52  
7 1     1   6 use Exporter ();
  1         6  
  1         18  
8              
9 1     1   4 use vars qw($VERSION @EXPORT @ISA $BASE_URL %DEFAULT);
  1         4  
  1         73  
10              
11 1     1   783 use DateTime;
  1         424695  
  1         45  
12 1     1   729 use LWP::UserAgent;
  1         34010  
  1         513  
13              
14             @ISA = qw(Exporter);
15              
16             @EXPORT = qw( get_historic_data );
17              
18             # https://query1.finance.yahoo.com/v7/finance/download/GAIL.BO?period1=864000000&period2=1588032000&interval=1d&events=split
19             ############################################################
20             # DEFAULT base url
21             ############################################################
22             $DEFAULT{BASE_URL} = 'https://query1.finance.yahoo.com/v7/finance/download/';
23             ############################################################
24             # DEFAULT from date 01-01-1800
25             ############################################################
26             $DEFAULT{period1} = '-5364662400';
27             ############################################################
28             # DEFAULT to date todays date
29             ############################################################
30             $DEFAULT{period2} = time();
31             ############################################################
32             # DEFAULT interval 1d
33             ############################################################
34             $DEFAULT{interval} = '1d';
35             ############################################################
36             # DEFAULT event history
37             ############################################################
38             $DEFAULT{events} = 'history';
39             ############################################################
40             # DEFAULT time out 60 sec
41             ############################################################
42             $DEFAULT{timeout} = 60;
43             ############################################################
44             # Set version
45             ############################################################
46              
47             our $VERSION = '0.01';
48              
49             =head1 SYNOPSIS
50              
51             (2020) Yahoo::Finance get the symbols historic data from yahoo
52              
53             Perhaps a little code snippet.
54              
55              
56             #oject oriented interface
57              
58             use Yahoo::Finance;
59              
60             my $fin = Yahoo::Finance->new();
61              
62             my $param = {
63             symbol => 'GAIL.BO',
64             period1 => '25-12-2015', #optional default '01-01-1800'
65             period2 => '25-12-2019', #optional default 'todays date'
66             interval => '1mo', #optional default '1d'
67             events => 'split', #optional default 'history'
68             timeout => '30', #optional default '60'
69             };
70              
71             print $fin->get_historic_data( $param );
72              
73             or
74              
75             #only div for week interval
76             my $param = {
77             symbol => 'GAIL.BO',
78             interval => '1wk',
79             events => 'div',
80             };
81              
82             print $fin->get_historic_data( $param );
83              
84             or
85              
86             print $fin->get_historic_data({ 'symbol' => 'GAIL.BO' });
87              
88              
89              
90             #non-oject oriented interface
91              
92             use Yahoo::Finance;
93             print get_historic_data( { 'symbol' => 'GOLD' } );
94              
95              
96             =head1 SUBROUTINES/METHODS
97              
98             =head2 new
99              
100             used to create a constructor of Yahoo::Finance
101              
102             =cut
103              
104             sub new {
105 2     2 1 694 bless( {}, shift );
106             }
107              
108             =pod
109              
110             =head2 get_historic_data
111              
112             params hash ref of following valid keys
113              
114             =over 7
115              
116             =item * B<invocant> { optional but required when using object oriented interface }
117              
118              
119             =item * B<symbol> { scalar string }
120              
121             C<symbol> name used by the yahoo fianance.
122              
123             Please note yahoo uses suffix on every symbol.
124              
125             Pass the symobl with suffix.
126              
127             eg symbol GAIL listed on BSE represented by yahoo-finance as "GAIL.BO"
128              
129              
130             =item * B<period1>
131              
132             C<period1> B<scalar string optional default is "01-01-1800"> format B<MM-DD-YYYY>
133              
134             period1 is the start date from where the data is needed
135              
136             format is strictly MM-DD-YYYY
137              
138             =item * B<period2>
139              
140             C<period2> B<scalar string optional default is todays date> format B<MM-DD-YYYY>
141              
142             period2 is the to date till when the data is needed.
143              
144             format is strictly MM-DD-YYYY
145              
146             =item * B<interval>
147              
148             C<interval> scalar string (optional default 1d)
149              
150             This is the interval at which data is needed.
151              
152             allowed options "1d" or "1w" or "1mo"
153              
154             1d is 1 day
155             1w is 1 week
156             1mo is 1 month
157              
158              
159             =item * B<events>
160              
161             C<events> scalar string (optional default history)
162             This the event data needed.
163              
164             allowed options "history" or "split" or "div"
165              
166              
167             =item * B<timeout>
168              
169             C<timeout> scalar string in sec (optional default 60)
170              
171             request timeout.
172              
173             in seconds default is 60
174              
175             =back
176              
177             =cut
178              
179             ############################################################
180             # get_historic_data
181             ############################################################
182             sub get_historic_data {
183 1     1   784 my ( $result, $valid_params );
184              
185 1 50       4 if ( scalar @_ > 1 ) {
186 0         0 my ( $self, $params ) = @_;
187 0         0 $valid_params = $self->_validate_set_default( $params );
188 0         0 $result = $self->_get_data( $valid_params );
189             } else {
190 1         2 my $params = shift;
191 1         3 $valid_params = _validate_set_default( $params );
192 1         3 $result = _get_data( $valid_params );
193             }
194              
195 1         1755 return $result;
196             }
197              
198             ############################################################
199             # _validate_set_default internal function
200             ############################################################
201             sub _validate_set_default {
202 1     1   2 my ( $self, $params );
203              
204 1 50       3 if ( scalar @_ > 1 ) {
205 0         0 ( $self, $params ) = @_;
206             } else {
207 1         19 $params = shift;
208             }
209              
210 1 50       5 croak 'key sybmol not provided eg. $params->{symbol} ="GOLD" ' unless ( defined $params->{symbol} );
211              
212 1         2 my $result;
213             ############################################################
214             # mandatory fields iterate or set default
215             ############################################################
216 1         3 foreach ( qw/symbol period1 period2 interval events timeout/ ) {
217 6   66     21 $result->{$_} = $params->{$_} // $DEFAULT{$_};
218             ############################################################
219             # change date to epoch
220             ############################################################
221 6 50       12 if ( $_ =~ /Period\d/ ) {
222              
223             #mm-dd-yyyy
224 0 0       0 if ( $result->{$_} =~ /(\d{1,2})\-(\d{1,2})\-(\d{4})/ ) {
225 0         0 my $dt = DateTime->new(
226             year => $3,
227             month => $1,
228             day => $2,
229             time_zone => 'floating',
230             );
231 0         0 $result->{$_} = $dt->epoch();
232             }
233             }
234             }
235              
236 1         7 return $result;
237             }
238              
239             sub _get_data {
240 1     1   2 my ( $self, $params );
241              
242 1 50       3 if ( scalar @_ > 1 ) {
243 0         0 ( $self, $params ) = @_;
244             } else {
245 1         1 $params = shift;
246             }
247              
248             ############################################################
249             # generate url
250             ############################################################
251 1         10 my $ua = LWP::UserAgent->new( timeout => $params->{timeout} );
252              
253             # https://query1.finance.yahoo.com/v7/finance/download/GAIL.BO?period1=864000000&period2=1588032000&interval=1d&events=split
254 1         2493 $ua->env_proxy;
255              
256             my $url =
257             "$DEFAULT{BASE_URL}"
258             . uc( $params->{symbol} )
259             . "?period1="
260             . $params->{period1}
261             . "&period2="
262             . $params->{period2}
263             . "&interval="
264             . $params->{interval}
265             . "&events="
266 1         12671 . $params->{events};
267              
268 1         3 my $response;
269             ############################################################
270             # retry 3 times
271             ############################################################
272 1         5 foreach ( 1 .. 3 ) {
273 3         25 $response = $ua->get( $url );
274 3 50       13047 last if ( $response->is_success );
275             }
276              
277 1 50       10 unless ( $response->is_success ) {
278 1         7 carp "Error occured while fetching data error: " . $response->status_line . "\n try following url in browser or curl '$url'";
279             }
280             ############################################################
281             # return if valid resposne recieved
282             ############################################################
283 1         175 return $response->decoded_content;
284             }
285              
286             =head1 AUTHOR
287              
288             Sushrut Pajai, C<< <spajai at cpan.org> >>
289              
290             =head1 BUGS
291              
292             Please report any bugs or feature requests to C<bug-yahoo-finance at rt.cpan.org>, or through
293             the web interface at L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Yahoo-Finance>. I will be notified, and then you'll
294             automatically be notified of progress on your bug as I make changes.
295              
296              
297             =head1 SUPPORT
298              
299             You can find documentation for this module with the perldoc command.
300              
301             perldoc Yahoo::Finance
302              
303              
304             You can also look for information at:
305              
306             =over 4
307              
308             =item * RT: CPAN's request tracker (report bugs here)
309              
310             L<https://rt.cpan.org/NoAuth/Bugs.html?Dist=Yahoo-Finance>
311              
312             =item * AnnoCPAN: Annotated CPAN documentation
313              
314             L<http://annocpan.org/dist/Yahoo-Finance>
315              
316             =item * CPAN Ratings
317              
318             L<https://cpanratings.perl.org/d/Yahoo-Finance>
319              
320             =item * Search CPAN
321              
322             L<https://metacpan.org/release/Yahoo-Finance>
323              
324             =back
325              
326              
327             =head1 ACKNOWLEDGEMENTS
328              
329              
330             =head1 LICENSE AND COPYRIGHT
331              
332             This software is Copyright (c) 2020 by Sushrut Pajai.
333              
334             This is free software, licensed under:
335              
336             The Artistic License 2.0 (GPL Compatible)
337              
338              
339             =cut
340              
341             1; # End of Yahoo::Finance