#! /usr/bin/perl -T # # stockchecker.pl # # Complete documentation for this code can be found at: # http://www.pettingers.org/code/stockchecker.html # # stockchecker -- perl script to generate VERY simple # CGI page for Blackberry and cell phones # stockchecker (C) 2005, pettingers.org, All Rights reserved under GPL license: # http://www.gnu.org/licenses/gpl.txt use strict; use CGI; use Finance::Quote; use Finance::QuoteHist::Yahoo; $| = 1; # #### # User Defined Variables # ############################### our $stocklist = "/var/www/html/users/stocks"; #Location of user's watchlist ############################### # End User Defined Variables ### # our $query = new CGI; my ($tickers, $marker) = ''; my (@lists, @additional) = ''; # Do initial pull-in from the user's favorite tickers list $tickers = listload(); # Set up web page using CGI module print $query->header(); print $query->start_html(-title=>"Your Stock Checker Page", -BGCOLOR=>'#FFFFF0', -LEFTMARGIN=>'10', -MARGINWIDTH=>'10'); print ''; print "\\"; print "StockChecker\n\n\n"; print "\<\/BIG\>\n"; print $query->br; print "\<\/CENTER\>\n"; print $query->startform(); print $query->textfield(-name=>'newitems', -default=>"$tickers", -size=>20, -maxlength=>80); print $query->submit(-value=>'Add/Remove'); print $query->defaults('Clear'); print $query->br; print $query->textfield(-name=>'looknew', -default=>'', -size=>20, -maxlength=>80); print $query->submit(-value=>'Lookup'); print $query->defaults('Clear'); print $query->endform; if ($query->param('newitems')) { @additional = usercheck($query->param('newitems')); open (USEROUT, ">$stocklist"); foreach $marker(@additional){ print USEROUT "$marker\n"; } close (USEROUT); } print $query->br; print $query->hr; if ($query->param('looknew')) { @additional = usercheck($query->param('looknew')); displayone(@additional); print $query->br; print $query->hr; } displayall(); print ''; print $query->end_html; exit; ##################################################################### sub displayall { # # Used to build the message body with quotes from the watchlist # use Finance::Quote; my $quoter = Finance::Quote->new; my ($stock); my @lists; $quoter->timeout(30); open (USERIN, $stocklist); @lists = ; close (USERIN); my %info = $quoter->fetch("usa", @lists); foreach $stock (@lists) { chomp ($stock); unless ($info{$stock, "success"}) { warn "Lookup of $stock failed - ".$info{$stock, "errormsg"}. "\n"; next; } print $query->br; print ''; print $info{$stock, "name"}, " \($stock\):\n\n"; print ''; print $query->br; # Call for historical quotes historical($stock,'3 weeks ago','3 Weeks Ago','2','1','0'); historical($stock,'2 Weeks ago','2 Weeks Ago','2','1','0'); historical($stock,'1 Week ago','1 Week Ago ','2','1','0'); print '***Current:  ', "Net Change: ", $info{$stock, "net"}, " \(", $info{$stock, "p_change"}, "\%\)", '  ', "Price: " , $info{$stock, "price"}, "\n"; print $query->hr; } } # End displayall ################################################################## sub displayone { # # Used to display quote information for one ore more stocks # that were placed in the Lookup form field. # use Finance::Quote; my $quoter = Finance::Quote->new; my ($stock); my @lists = @_; $quoter->timeout(30); my %info = $quoter->fetch("usa", @lists); foreach $stock (@lists) { chomp ($stock); $stock =~ tr/a-z/A-Z/; unless ($info{$stock, "success"}) { warn "Lookup of $stock failed - ".$info{$stock, "errormsg"}. "\n"; next; } print $query->br; print ''; print $info{$stock, "name"}, " \($stock\):\n\n"; print ''; print $query->br; print '52-wk Range: ', $info{$stock, "year_range"}; print $query->br; # Call for historical quotes historical($stock,'3 months ago','3 Months Ago','2','1','0'); historical($stock,'2 months ago','2 Months Ago','2','1','0'); historical($stock,'2 days ago','2 Days Ago ','2','1','0'); print '***Current:  ', "Net Change: ", $info{$stock, "net"}, " \(", $info{$stock, "p_change"}, "\%\)", '  ', "Price: " , $info{$stock, "price"}, "\n"; print $query->br; print '***Current:  ', "Vol: ", $info{$stock, "volume"}, '  ', "Day Range: ", $info{$stock, "day_range"}, '  ', "Open: ", $info{$stock, "open"}; print $query->hr; } } # End displayone #################################### sub usercheck { my ($entered) = @_; my @adds; for ($entered) { s/,/ /g; s/^\s+//; s/\s+$//; s/\s+/ /g; } $entered =~ tr/a-z/A-Z/; unless (($entered =~ m/^[\w ]+$/) and ($entered =~ m/^[A-Z]{1,5}[, ]*/)){ $entered = ''; } $entered = substr($entered,0,100); @adds = split(/ /,$entered); return @adds; } # End usercheck ############################################################### sub listload { my ($new, $tickers, @lists) = ''; open (USERIN, $stocklist); @lists = ; close USERIN; foreach $tickers(@lists){ chomp($tickers); $new .= " " . $tickers; } return $new; } # End listload ################################################################ sub historical { # Used to provide historical quotes from Yahoo. # # Pass follwing: # # ticker # date of interest (Date::Manip format) # coloquial name for date (e.g. 2 weeks ago) # decimal place precision # attempt number time out for requests # full information (1) or just close price (0) # use Finance::QuoteHist::Yahoo; my ($stock, $datein, $datename, $prec, $attempt, $full) = @_; my ($row, $symbol, $date, $open, $high, $low, $close, $volume) = ''; my $q = Finance::QuoteHist::Yahoo->new ( symbols => $stock, start_date => $datein, end_date => $datein, quote_precision => $prec, attempts => $attempt ); foreach $row ($q->quotes()) { ($symbol, $date, $open, $high, $low, $close, $volume) = @$row; if ($full) { print "$datename: Open:$open High:$high Low:$low Close:$close Vol:$volume\n"; } else { print "$datename: $close\n"; } print $query->br; } } # end historical #end