package QuoteDB; ########################################### # Store and retrieve historical quotes # Mike Schilli, 2002 (m@perlmeister.com) ########################################### use warnings; use strict qw(vars subs); use Date::Calc qw(Add_Delta_Days check_date); use Finance::QuoteHist; use DB_File; use POSIX; our $VERSION = "1.0"; our %QUOTES = (); ########################################### sub import { ########################################### my($class, $filename) = @_; tie %QUOTES, "DB_File", $filename, O_CREAT, 0644; my $callerpkg = caller(0); *{"$callerpkg\::quote"} = *quote; 1; } END { untie %QUOTES; } ########################################### sub quote { ########################################### my($symbol, $year, $month, $day) = @_; if(!exists $QUOTES{$symbol}) { print "Updating ...\n"; db_update($symbol); } return latest_price($symbol, $year, $month, $day); } ########################################### sub db_update { ########################################### my($sym) = @_; my $q = Finance::QuoteHist->new( symbols => [$sym], start_date => '12/20/1994', end_date => 'today'); $QUOTES{$sym}++; foreach my $row ($q->quote_get()) { my ($stock, $date, $open, $high, $low, $close, $volume) = @$row; my($year, $month, $day) = map { sprintf "%d", $_ } split(m#/#, $date); $QUOTES{"$sym,$year,$month,$day"} = $close; } } ########################################### sub latest_price { ########################################### my($symbol, $year, $month, $day) = @_; my @try = ($year, $month, $day); my $maxtries = 10; while($maxtries--) { while(!check_date($year, $month, $day)) { $day--; } my $key = "$symbol,$year,$month,$day"; if(exists($QUOTES{$key})) { return $QUOTES{$key}; } } continue { ($year, $month, $day) = Add_Delta_Days($year, $month, $day, -1); } die "Can't find date (@try)"; } 1;